diff options
Diffstat (limited to 'src')
49 files changed, 315 insertions, 230 deletions
diff --git a/src/main/java/eu/siacs/conversations/OmemoActivity.java b/src/main/java/eu/siacs/conversations/OmemoActivity.java new file mode 100644 index 00000000..27f1dcf6 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/OmemoActivity.java @@ -0,0 +1,237 @@ +package eu.siacs.conversations; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.security.cert.X509Certificate; + +import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.ui.XmppActivity; +import eu.siacs.conversations.ui.widget.Switch; +import eu.siacs.conversations.utils.CryptoHelper; + + +public abstract class OmemoActivity extends XmppActivity { + + private Account mSelectedAccount; + private String mSelectedFingerprint; + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu,v,menuInfo); + Object account = v.getTag(R.id.TAG_ACCOUNT); + Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT); + if (account != null && fingerprint != null && account instanceof Account && fingerprint instanceof String) { + getMenuInflater().inflate(R.menu.omemo_key_context, menu); + this.mSelectedAccount = (Account) account; + this.mSelectedFingerprint = (String) fingerprint; + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.purge_omemo_key: + showPurgeKeyDialog(mSelectedAccount,mSelectedFingerprint); + break; + case R.id.copy_omemo_key: + copyOmemoFingerprint(mSelectedFingerprint); + break; + } + return true; + } + + protected void copyOmemoFingerprint(String fingerprint) { + if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) { + Toast.makeText( + this, + R.string.toast_message_omemo_fingerprint, + Toast.LENGTH_SHORT).show(); + } + } + + protected boolean addFingerprintRow(LinearLayout keys, final Account account, final String fingerprint, boolean highlight) { + final FingerprintStatus status = account.getAxolotlService().getFingerprintTrust(fingerprint); + return status != null && addFingerprintRowWithListeners(keys, account, fingerprint, highlight, status, true, true, new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(isChecked)); + } + }); + } + + protected boolean addFingerprintRowWithListeners(LinearLayout keys, final Account account, + final String fingerprint, + boolean highlight, + FingerprintStatus status, + boolean showTag, + boolean undecidedNeedEnablement, + CompoundButton.OnCheckedChangeListener + onCheckedChangeListener) { + if (status.isCompromised()) { + return false; + } + View view = getLayoutInflater().inflate(R.layout.contact_key, keys, false); + TextView key = (TextView) view.findViewById(R.id.key); + TextView keyType = (TextView) view.findViewById(R.id.key_type); + if (Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509) { + View.OnClickListener listener = new View.OnClickListener() { + @Override + public void onClick(View v) { + showX509Certificate(account,fingerprint); + } + }; + key.setOnClickListener(listener); + keyType.setOnClickListener(listener); + } + Switch trustToggle = (Switch) view.findViewById(R.id.tgl_trust); + ImageView verifiedFingerprintSymbol = (ImageView) view.findViewById(R.id.verified_fingerprint); + trustToggle.setVisibility(View.VISIBLE); + registerForContextMenu(view); + view.setTag(R.id.TAG_ACCOUNT,account); + view.setTag(R.id.TAG_FINGERPRINT,fingerprint); + boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509; + final View.OnClickListener toast; + trustToggle.setChecked(status.isTrusted(), false); + + if (status.isActive()){ + key.setTextColor(getPrimaryTextColor()); + keyType.setTextColor(getSecondaryTextColor()); + if (status.isVerified()) { + verifiedFingerprintSymbol.setVisibility(View.VISIBLE); + trustToggle.setVisibility(View.GONE); + verifiedFingerprintSymbol.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + replaceToast(getString(R.string.this_device_has_been_verified), false); + } + }); + toast = null; + } else { + verifiedFingerprintSymbol.setVisibility(View.GONE); + trustToggle.setVisibility(View.VISIBLE); + trustToggle.setOnCheckedChangeListener(onCheckedChangeListener); + if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED && undecidedNeedEnablement) { + trustToggle.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + account.getAxolotlService().setFingerprintTrust(fingerprint,FingerprintStatus.createActive(false)); + v.setEnabled(true); + v.setOnClickListener(null); + } + }); + trustToggle.setEnabled(false); + } else { + trustToggle.setOnClickListener(null); + trustToggle.setEnabled(true); + } + toast = new View.OnClickListener() { + @Override + public void onClick(View v) { + hideToast(); + } + }; + } + } else { + key.setTextColor(getTertiaryTextColor()); + keyType.setTextColor(getTertiaryTextColor()); + toast = new View.OnClickListener() { + @Override + public void onClick(View v) { + replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); + } + }; + if (status.isVerified()) { + trustToggle.setVisibility(View.GONE); + verifiedFingerprintSymbol.setVisibility(View.VISIBLE); + verifiedFingerprintSymbol.setOnClickListener(toast); + } else { + trustToggle.setVisibility(View.VISIBLE); + verifiedFingerprintSymbol.setVisibility(View.GONE); + trustToggle.setOnClickListener(null); + trustToggle.setEnabled(false); + trustToggle.setOnClickListener(toast); + } + } + + view.setOnClickListener(toast); + key.setOnClickListener(toast); + keyType.setOnClickListener(toast); + if (showTag) { + keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); + } else { + keyType.setVisibility(View.GONE); + } + if (highlight) { + keyType.setTextColor(getResources().getColor(R.color.accent)); + keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message)); + } else { + keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); + } + + key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); + + keys.addView(view); + return true; + } + + public void showPurgeKeyDialog(final Account account, final String fingerprint) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.purge_key)); + builder.setIconAttribute(android.R.attr.alertDialogIcon); + builder.setMessage(getString(R.string.purge_key_desc_part1) + + "\n\n" + CryptoHelper.prettifyFingerprint(fingerprint.substring(2)) + + "\n\n" + getString(R.string.purge_key_desc_part2)); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.setPositiveButton(getString(R.string.purge_key), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + account.getAxolotlService().purgeKey(fingerprint); + refreshUi(); + } + }); + builder.create().show(); + } + + private void showX509Certificate(Account account, String fingerprint) { + X509Certificate x509Certificate = account.getAxolotlService().getFingerprintCertificate(fingerprint); + if (x509Certificate != null) { + showCertificateInformationDialog(CryptoHelper.extractCertificateInformation(x509Certificate)); + } else { + Toast.makeText(this,R.string.certificate_not_found, Toast.LENGTH_SHORT).show(); + } + } + + private void showCertificateInformationDialog(Bundle bundle) { + View view = getLayoutInflater().inflate(R.layout.certificate_information, null); + final String not_available = getString(R.string.certicate_info_not_available); + TextView subject_cn = (TextView) view.findViewById(R.id.subject_cn); + TextView subject_o = (TextView) view.findViewById(R.id.subject_o); + TextView issuer_cn = (TextView) view.findViewById(R.id.issuer_cn); + TextView issuer_o = (TextView) view.findViewById(R.id.issuer_o); + TextView sha1 = (TextView) view.findViewById(R.id.sha1); + + subject_cn.setText(bundle.getString("subject_cn", not_available)); + subject_o.setText(bundle.getString("subject_o", not_available)); + issuer_cn.setText(bundle.getString("issuer_cn", not_available)); + issuer_o.setText(bundle.getString("issuer_o", not_available)); + sha1.setText(bundle.getString("sha1", not_available)); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.certificate_information); + builder.setView(view); + builder.setPositiveButton(R.string.ok, null); + builder.create().show(); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 9653ea05..a567f151 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -36,15 +36,14 @@ import java.security.cert.X509Certificate; import java.util.List; import eu.siacs.conversations.Config; +import eu.siacs.conversations.OmemoActivity; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; -import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.ListItem; -import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.utils.CryptoHelper; @@ -55,7 +54,7 @@ import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; -public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated { +public class ContactDetailsActivity extends OmemoActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated { public static final String ACTION_VIEW_CONTACT = "view_contact"; private Contact contact; @@ -448,12 +447,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd if (Config.supportOmemo()) { for (final String fingerprint : contact.getAccount().getAxolotlService().getFingerprintsForContact(contact)) { boolean highlight = fingerprint.equals(messageFingerprint); - hasKeys |= addFingerprintRow(keys, contact.getAccount(), fingerprint, highlight, new OnClickListener() { - @Override - public void onClick(View v) { - onOmemoKeyClicked(contact.getAccount(), fingerprint); - } - }); + hasKeys |= addFingerprintRow(keys, contact.getAccount(), fingerprint, highlight); } } if (Config.supportOpenPgp() && contact.getPgpKeyId() != 0) { @@ -509,40 +503,6 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } } - private void onOmemoKeyClicked(Account account, String fingerprint) { - FingerprintStatus status = account.getAxolotlService().getFingerprintTrust(fingerprint); - if (Config.X509_VERIFICATION && status != null && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509) { - X509Certificate x509Certificate = account.getAxolotlService().getFingerprintCertificate(fingerprint); - if (x509Certificate != null) { - showCertificateInformationDialog(CryptoHelper.extractCertificateInformation(x509Certificate)); - } else { - Toast.makeText(this,R.string.certificate_not_found, Toast.LENGTH_SHORT).show(); - } - } - } - - private void showCertificateInformationDialog(Bundle bundle) { - View view = getLayoutInflater().inflate(R.layout.certificate_information, null); - final String not_available = getString(R.string.certicate_info_not_available); - TextView subject_cn = (TextView) view.findViewById(R.id.subject_cn); - TextView subject_o = (TextView) view.findViewById(R.id.subject_o); - TextView issuer_cn = (TextView) view.findViewById(R.id.issuer_cn); - TextView issuer_o = (TextView) view.findViewById(R.id.issuer_o); - TextView sha1 = (TextView) view.findViewById(R.id.sha1); - - subject_cn.setText(bundle.getString("subject_cn", not_available)); - subject_o.setText(bundle.getString("subject_o", not_available)); - issuer_cn.setText(bundle.getString("issuer_cn", not_available)); - issuer_o.setText(bundle.getString("issuer_o", not_available)); - sha1.setText(bundle.getString("sha1", not_available)); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.certificate_information); - builder.setView(view); - builder.setPositiveButton(R.string.ok, null); - builder.create().show(); - } - protected void confirmToDeleteFingerprint(final String fingerprint) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.delete_fingerprint); @@ -563,7 +523,6 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd builder.create().show(); } - @Override public void onBackendConnected() { if ((accountJid != null) && (contactJid != null)) { Account account = xmppConnectionService diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index cd35ffb5..0f38173b 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -41,6 +41,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import eu.siacs.conversations.Config; +import eu.siacs.conversations.OmemoActivity; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; @@ -59,7 +60,7 @@ import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.pep.Avatar; -public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, +public class EditAccountActivity extends OmemoActivity implements OnAccountUpdate, OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnMamPreferencesFetched { private static final int REQUEST_DATA_SAVER = 0x37af244; @@ -635,7 +636,6 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate super.onSaveInstanceState(savedInstanceState); } - @Override protected void onBackendConnected() { boolean init = true; if (mSavedInstanceAccount != null) { @@ -884,13 +884,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate @Override public void onClick(final View v) { - - if (copyTextToClipboard(ownAxolotlFingerprint.substring(2), R.string.omemo_fingerprint)) { - Toast.makeText( - EditAccountActivity.this, - R.string.toast_message_omemo_fingerprint, - Toast.LENGTH_SHORT).show(); - } + copyOmemoFingerprint(ownAxolotlFingerprint); } }); if (Config.SHOW_REGENERATE_AXOLOTL_KEYS_BUTTON) { @@ -915,7 +909,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate continue; } boolean highlight = fingerprint.equals(messageFingerprint); - hasKeys |= addFingerprintRow(keys, mAccount, fingerprint, highlight, null); + hasKeys |= addFingerprintRow(keys, mAccount, fingerprint, highlight); } if (hasKeys && Config.supportOmemo()) { keysCard.setVisibility(View.VISIBLE); diff --git a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java index f5a4789f..76081a96 100644 --- a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import eu.siacs.conversations.OmemoActivity; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; @@ -28,7 +29,7 @@ import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; -public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdated { +public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdated { private List<Jid> contactJids; private Account mAccount; @@ -109,16 +110,14 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate for(final String fingerprint : ownKeysToTrust.keySet()) { hasOwnKeys = true; addFingerprintRowWithListeners(ownKeys, mAccount, fingerprint, false, - FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint)), false, + FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint)), false, false, new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ownKeysToTrust.put(fingerprint, isChecked); // own fingerprints have no impact on locked status. } - }, - null, - null + } ); } @@ -134,16 +133,14 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate final Map<String, Boolean> fingerprints = entry.getValue(); for (final String fingerprint : fingerprints.keySet()) { addFingerprintRowWithListeners(keysContainer, mAccount, fingerprint, false, - FingerprintStatus.createActive(fingerprints.get(fingerprint)), false, + FingerprintStatus.createActive(fingerprints.get(fingerprint)), false, false, new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { fingerprints.put(fingerprint, isChecked); lockOrUnlockAsNeeded(); } - }, - null, - null + } ); } if (fingerprints.size() == 0) { @@ -212,7 +209,6 @@ public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdate return ownKeysSet.size() + foreignKeysToTrust.size() > 0; } - @Override public void onBackendConnected() { Intent intent = getIntent(); this.mAccount = extractAccount(intent); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 1454381a..d961497c 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -49,11 +49,8 @@ import android.util.Pair; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.CompoundButton; import android.widget.EditText; import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; import android.widget.Toast; import com.google.zxing.BarcodeFormat; @@ -69,7 +66,6 @@ import java.io.FileNotFoundException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -78,20 +74,15 @@ import java.util.concurrent.atomic.AtomicInteger; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; -import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Presences; -import eu.siacs.conversations.entities.ServiceDiscoveryResult; import eu.siacs.conversations.services.AvatarService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; -import eu.siacs.conversations.ui.widget.Switch; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.UIHelper; @@ -780,132 +771,6 @@ public abstract class XmppActivity extends Activity { builder.create().show(); } - protected boolean addFingerprintRow(LinearLayout keys, final Account account, final String fingerprint, boolean highlight, View.OnClickListener onKeyClickedListener) { - final FingerprintStatus status = account.getAxolotlService().getFingerprintTrust(fingerprint); - if (status == null) { - return false; - } - return addFingerprintRowWithListeners(keys, account, fingerprint, highlight, status, true, - new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - account.getAxolotlService().setFingerprintTrust(fingerprint,FingerprintStatus.createActive(isChecked)); - } - }, - new View.OnClickListener() { - @Override - public void onClick(View v) { - account.getAxolotlService().setFingerprintTrust(fingerprint,FingerprintStatus.createActive(false)); - v.setEnabled(true); - } - }, - onKeyClickedListener - - ); - } - - protected boolean addFingerprintRowWithListeners(LinearLayout keys, final Account account, - final String fingerprint, - boolean highlight, - FingerprintStatus status, - boolean showTag, - CompoundButton.OnCheckedChangeListener - onCheckedChangeListener, - View.OnClickListener onClickListener, - View.OnClickListener onKeyClickedListener) { - if (status.isCompromised()) { - return false; - } - View view = getLayoutInflater().inflate(R.layout.contact_key, keys, false); - TextView key = (TextView) view.findViewById(R.id.key); - key.setOnClickListener(onKeyClickedListener); - TextView keyType = (TextView) view.findViewById(R.id.key_type); - keyType.setOnClickListener(onKeyClickedListener); - Switch trustToggle = (Switch) view.findViewById(R.id.tgl_trust); - trustToggle.setVisibility(View.VISIBLE); - final View.OnLongClickListener purge = new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - showPurgeKeyDialog(account, fingerprint); - return true; - } - }; - view.setOnLongClickListener(purge); - key.setOnLongClickListener(purge); - keyType.setOnLongClickListener(purge); - boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509; - final View.OnClickListener toast; - trustToggle.setChecked(status.isTrusted(), false); - if (status.isActive()) { - key.setTextColor(getPrimaryTextColor()); - keyType.setTextColor(getSecondaryTextColor()); - trustToggle.setOnCheckedChangeListener(onCheckedChangeListener); - if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED) { - trustToggle.setOnClickListener(onClickListener); - trustToggle.setEnabled(false); - } else { - trustToggle.setOnClickListener(null); - trustToggle.setEnabled(true); - } - toast = new View.OnClickListener() { - @Override - public void onClick(View v) { - hideToast(); - } - }; - } else { - key.setTextColor(getTertiaryTextColor()); - keyType.setTextColor(getTertiaryTextColor()); - trustToggle.setOnClickListener(null); - trustToggle.setEnabled(false); - toast = new View.OnClickListener() { - @Override - public void onClick(View v) { - replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); - } - }; - trustToggle.setOnClickListener(toast); - } - view.setOnClickListener(toast); - key.setOnClickListener(toast); - keyType.setOnClickListener(toast); - if (showTag) { - keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); - } else { - keyType.setVisibility(View.GONE); - } - if (highlight) { - keyType.setTextColor(getResources().getColor(R.color.accent)); - keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message)); - } else { - keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); - } - - key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); - - keys.addView(view); - return true; - } - - public void showPurgeKeyDialog(final Account account, final String fingerprint) { - Builder builder = new Builder(this); - builder.setTitle(getString(R.string.purge_key)); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage(getString(R.string.purge_key_desc_part1) - + "\n\n" + CryptoHelper.prettifyFingerprint(fingerprint.substring(2)) - + "\n\n" + getString(R.string.purge_key_desc_part2)); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.purge_key), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - account.getAxolotlService().purgeKey(fingerprint); - refreshUi(); - } - }); - builder.create().show(); - } - public boolean hasStoragePermission(int requestCode) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { diff --git a/src/main/res/drawable-hdpi/ic_verified_fingerprint.png b/src/main/res/drawable-hdpi/ic_verified_fingerprint.png Binary files differnew file mode 100644 index 00000000..297dea0d --- /dev/null +++ b/src/main/res/drawable-hdpi/ic_verified_fingerprint.png diff --git a/src/main/res/drawable-hdpi/message_bubble_received.9.png b/src/main/res/drawable-hdpi/message_bubble_received.9.png Binary files differindex 605d9a39..baadc834 100644 --- a/src/main/res/drawable-hdpi/message_bubble_received.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_received.9.png diff --git a/src/main/res/drawable-hdpi/message_bubble_received_dark.9.png b/src/main/res/drawable-hdpi/message_bubble_received_dark.9.png Binary files differindex 84d56bc8..17d87b64 100644 --- a/src/main/res/drawable-hdpi/message_bubble_received_dark.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_received_dark.9.png diff --git a/src/main/res/drawable-hdpi/message_bubble_received_grey.9.png b/src/main/res/drawable-hdpi/message_bubble_received_grey.9.png Binary files differindex b6b40f91..75918728 100644 --- a/src/main/res/drawable-hdpi/message_bubble_received_grey.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_received_grey.9.png diff --git a/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png Binary files differindex e0db0b1d..ac79f731 100644 --- a/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png diff --git a/src/main/res/drawable-hdpi/message_bubble_received_white.9.png b/src/main/res/drawable-hdpi/message_bubble_received_white.9.png Binary files differindex 48e3705e..c4854a95 100644 --- a/src/main/res/drawable-hdpi/message_bubble_received_white.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_received_white.9.png diff --git a/src/main/res/drawable-hdpi/message_bubble_sent.9.png b/src/main/res/drawable-hdpi/message_bubble_sent.9.png Binary files differindex b7971a42..42eba56a 100644 --- a/src/main/res/drawable-hdpi/message_bubble_sent.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_sent.9.png diff --git a/src/main/res/drawable-hdpi/message_bubble_sent_grey.9.png b/src/main/res/drawable-hdpi/message_bubble_sent_grey.9.png Binary files differindex ce6f3734..99a1af9a 100644 --- a/src/main/res/drawable-hdpi/message_bubble_sent_grey.9.png +++ b/src/main/res/drawable-hdpi/message_bubble_sent_grey.9.png diff --git a/src/main/res/drawable-mdpi/ic_verified_fingerprint.png b/src/main/res/drawable-mdpi/ic_verified_fingerprint.png Binary files differnew file mode 100644 index 00000000..250ea4cd --- /dev/null +++ b/src/main/res/drawable-mdpi/ic_verified_fingerprint.png diff --git a/src/main/res/drawable-mdpi/message_bubble_received.9.png b/src/main/res/drawable-mdpi/message_bubble_received.9.png Binary files differindex e2f06355..249e239b 100644 --- a/src/main/res/drawable-mdpi/message_bubble_received.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_received.9.png diff --git a/src/main/res/drawable-mdpi/message_bubble_received_dark.9.png b/src/main/res/drawable-mdpi/message_bubble_received_dark.9.png Binary files differindex eb768233..14e299f5 100644 --- a/src/main/res/drawable-mdpi/message_bubble_received_dark.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_received_dark.9.png diff --git a/src/main/res/drawable-mdpi/message_bubble_received_grey.9.png b/src/main/res/drawable-mdpi/message_bubble_received_grey.9.png Binary files differindex 7cd4ca33..8be648d8 100644 --- a/src/main/res/drawable-mdpi/message_bubble_received_grey.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_received_grey.9.png diff --git a/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png Binary files differindex 16d468b4..e727575d 100644 --- a/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png diff --git a/src/main/res/drawable-mdpi/message_bubble_received_white.9.png b/src/main/res/drawable-mdpi/message_bubble_received_white.9.png Binary files differindex febb8bfb..9dbcc315 100644 --- a/src/main/res/drawable-mdpi/message_bubble_received_white.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_received_white.9.png diff --git a/src/main/res/drawable-mdpi/message_bubble_sent.9.png b/src/main/res/drawable-mdpi/message_bubble_sent.9.png Binary files differindex cd891b0f..2e128636 100644 --- a/src/main/res/drawable-mdpi/message_bubble_sent.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_sent.9.png diff --git a/src/main/res/drawable-mdpi/message_bubble_sent_grey.9.png b/src/main/res/drawable-mdpi/message_bubble_sent_grey.9.png Binary files differindex 240b1237..c314d34e 100644 --- a/src/main/res/drawable-mdpi/message_bubble_sent_grey.9.png +++ b/src/main/res/drawable-mdpi/message_bubble_sent_grey.9.png diff --git a/src/main/res/drawable-xhdpi/ic_verified_fingerprint.png b/src/main/res/drawable-xhdpi/ic_verified_fingerprint.png Binary files differnew file mode 100644 index 00000000..ba816260 --- /dev/null +++ b/src/main/res/drawable-xhdpi/ic_verified_fingerprint.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_received.9.png b/src/main/res/drawable-xhdpi/message_bubble_received.9.png Binary files differindex b950cb91..89f49dd9 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_received.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_received.9.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_received_dark.9.png b/src/main/res/drawable-xhdpi/message_bubble_received_dark.9.png Binary files differindex f29649d8..8da93874 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_received_dark.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_received_dark.9.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_received_grey.9.png b/src/main/res/drawable-xhdpi/message_bubble_received_grey.9.png Binary files differindex b9fb7957..6a6046dd 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_received_grey.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_received_grey.9.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png Binary files differindex 18d36ed5..751bcb9e 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png b/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png Binary files differindex b005d170..595ff84e 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xhdpi/message_bubble_sent.9.png Binary files differindex 8f2fd571..b3f01dcd 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_sent.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_sent.9.png diff --git a/src/main/res/drawable-xhdpi/message_bubble_sent_grey.9.png b/src/main/res/drawable-xhdpi/message_bubble_sent_grey.9.png Binary files differindex af6c7608..c32c5101 100644 --- a/src/main/res/drawable-xhdpi/message_bubble_sent_grey.9.png +++ b/src/main/res/drawable-xhdpi/message_bubble_sent_grey.9.png diff --git a/src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png b/src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png Binary files differnew file mode 100644 index 00000000..e86e8efc --- /dev/null +++ b/src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received.9.png Binary files differindex 3dd99562..4bb38a15 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_received.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_received.9.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received_dark.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received_dark.9.png Binary files differindex 2cf9f699..8ad8fdd4 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_received_dark.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_received_dark.9.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received_grey.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received_grey.9.png Binary files differindex 20ae5f18..c9ef4638 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_received_grey.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_received_grey.9.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png Binary files differindex 10130239..07b9a050 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png Binary files differindex e2bb6f80..74401c2e 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png Binary files differindex 31c5fa13..89140290 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png diff --git a/src/main/res/drawable-xxhdpi/message_bubble_sent_grey.9.png b/src/main/res/drawable-xxhdpi/message_bubble_sent_grey.9.png Binary files differindex 2c486407..47057f23 100644 --- a/src/main/res/drawable-xxhdpi/message_bubble_sent_grey.9.png +++ b/src/main/res/drawable-xxhdpi/message_bubble_sent_grey.9.png diff --git a/src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png b/src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png Binary files differnew file mode 100644 index 00000000..5c78ac27 --- /dev/null +++ b/src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png Binary files differindex 1620e8bc..9601d5a4 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received_dark.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received_dark.9.png Binary files differindex a62faee5..bd93e968 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_received_dark.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_received_dark.9.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received_grey.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received_grey.9.png Binary files differindex 5e9b6b2d..e8633e69 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_received_grey.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_received_grey.9.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png Binary files differindex 99ec1efa..bfbffc5c 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png Binary files differindex 333aaf68..4f6ed0cf 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png Binary files differindex f82c72a2..95d26a29 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_sent_grey.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_sent_grey.9.png Binary files differindex ff6e8349..abdfb98b 100644 --- a/src/main/res/drawable-xxxhdpi/message_bubble_sent_grey.9.png +++ b/src/main/res/drawable-xxxhdpi/message_bubble_sent_grey.9.png diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/contact_key.xml index 7076dad2..c16d5e08 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/contact_key.xml @@ -1,37 +1,40 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" - android:layout_height="match_parent" > + android:layout_height="match_parent" + android:longClickable="true"> <RelativeLayout android:id="@+id/key_data" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" - android:paddingTop="8dp" + android:paddingBottom="8dp" android:paddingLeft="8dp" - android:paddingBottom="8dp"> + android:paddingTop="8dp"> <TextView android:id="@+id/key" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="?attr/color_text_primary" android:layout_alignParentLeft="true" - android:layout_toLeftOf="@+id/tgl_trust" + android:layout_toLeftOf="@+id/action_container" + android:fontFamily="monospace" + android:textColor="?attr/color_text_primary" android:textSize="?attr/TextSizeBody" android:typeface="monospace" - android:fontFamily="monospace"/> + android:longClickable="true"/> <TextView android:id="@+id/key_type" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="?attr/color_text_secondary" android:layout_alignParentLeft="true" android:layout_below="@+id/key" android:maxLines="1" - android:textSize="?attr/TextSizeInfo"/> + android:textColor="?attr/color_text_secondary" + android:textSize="?attr/TextSizeInfo" + android:longClickable="true"/> <TextView android:id="@+id/key_trust" @@ -39,32 +42,46 @@ android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@+id/key" - android:visibility="gone" android:textColor="?attr/color_text_secondary" - android:textSize="?attr/TextSizeInfo"/> - - <ImageButton - android:id="@+id/button_remove" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentRight="true" - android:layout_toRightOf="@+id/key" - android:layout_centerVertical="true" - android:background="?android:selectableItemBackground" - android:padding="@dimen/image_button_padding" - android:alpha="?attr/icon_alpha" - android:src="?attr/icon_remove" - android:visibility="gone" /> + android:textSize="?attr/TextSizeInfo" + android:visibility="gone" + android:longClickable="true"/> + <LinearLayout + android:id="@+id/action_container" + android:layout_width="96dp" + android:layout_marginRight="-32dp" + android:layout_height="wrap_content" + android:orientation="vertical" + android:layout_alignParentRight="true" + android:layout_centerVertical="true"> + <ImageButton + android:layout_gravity="center_horizontal" + android:id="@+id/button_remove" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:alpha="?attr/icon_alpha" + android:background="?android:selectableItemBackground" + android:padding="@dimen/image_button_padding" + android:src="?attr/icon_remove" + android:layout_marginRight="16dp" + android:visibility="gone" /> + <ImageView + android:visibility="gone" + android:id="@+id/verified_fingerprint" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginRight="16dp" + android:src="@drawable/ic_verified_fingerprint" /> - <eu.siacs.conversations.ui.widget.Switch - android:id="@+id/tgl_trust" - android:visibility="invisible" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentRight="true" - android:layout_centerVertical="true" - style="@style/MD"/> + <eu.siacs.conversations.ui.widget.Switch + android:id="@+id/tgl_trust" + style="@style/MD" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" /> + </LinearLayout> </RelativeLayout> </RelativeLayout>
\ No newline at end of file diff --git a/src/main/res/menu/omemo_key_context.xml b/src/main/res/menu/omemo_key_context.xml new file mode 100644 index 00000000..2e2fc5da --- /dev/null +++ b/src/main/res/menu/omemo_key_context.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/purge_omemo_key" + android:title="@string/purge_key"/> + <item + android:id="@+id/copy_omemo_key" + android:title="@string/copy_fingerprint"/> +</menu>
\ No newline at end of file diff --git a/src/main/res/values/ids.xml b/src/main/res/values/ids.xml new file mode 100644 index 00000000..7daad46d --- /dev/null +++ b/src/main/res/values/ids.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <item type="id" name="TAG_ACCOUNT"/> + <item type="id" name="TAG_FINGERPRINT"/> +</resources>
\ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d52d7b88..f4d4262d 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -699,4 +699,7 @@ <string name="data_saver_enabled">Data saver enabled</string> <string name="data_saver_enabled_explained">Your operating system is restricting Conversations from accessing the Internet when in background. To receive notifications of new messages you should allow Conversations unrestricted access when Data saver is on.\nConversations will still make an effort to save data when possible.</string> <string name="device_does_not_support_data_saver">Your device does not support disabling Data saver for Conversations.</string> + <string name="error_unable_to_create_temporary_file">Unable to create temporary file</string> + <string name="this_device_has_been_verified">This device has been verified</string> + <string name="copy_fingerprint">Copy fingerprint</string> </resources> |