diff --git a/art/ic_verified_fingerprint.svg b/art/ic_verified_fingerprint.svg new file mode 100644 index 000000000..7ac6da02f --- /dev/null +++ b/art/ic_verified_fingerprint.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/art/render.rb b/art/render.rb index fe39e66bf..93c049969 100755 --- a/art/render.rb +++ b/art/render.rb @@ -50,6 +50,7 @@ images = { 'ic_notifications_off_white80.svg' => ['ic_notifications_off_white80', 24], 'ic_notifications_paused_white80.svg' => ['ic_notifications_paused_white80', 24], 'ic_notifications_white80.svg' => ['ic_notifications_white80', 24], + 'ic_verified_fingerprint.svg' => ['ic_verified_fingerprint', 36], 'md_switch_thumb_disable.svg' => ['switch_thumb_disable', 48], 'md_switch_thumb_off_normal.svg' => ['switch_thumb_off_normal', 48], 'md_switch_thumb_off_pressed.svg' => ['switch_thumb_off_pressed', 48], @@ -57,7 +58,7 @@ images = { 'md_switch_thumb_on_pressed.svg' => ['switch_thumb_on_pressed', 48], 'message_bubble_received.svg' => ['message_bubble_received.9', 0], 'message_bubble_received_grey.svg' => ['message_bubble_received_grey.9', 0], - 'message_bubble_received_dark.svg' => ['message_bubble_received_dark.9', 0], + 'message_bubble_received_dark.svg' => ['message_bubble_received_dark.9', 0], 'message_bubble_received_warning.svg' => ['message_bubble_received_warning.9', 0], 'message_bubble_received_white.svg' => ['message_bubble_received_white.9', 0], 'message_bubble_sent.svg' => ['message_bubble_sent.9', 0], 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 000000000..27f1dcf65 --- /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 9653ea057..a567f151f 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 cd35ffb55..0f38173be 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 f5a4789fd..76081a962 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 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 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 1454381a7..d961497c9 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 new file mode 100644 index 000000000..297dea0d0 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_verified_fingerprint.png differ diff --git a/src/main/res/drawable-hdpi/message_bubble_received.9.png b/src/main/res/drawable-hdpi/message_bubble_received.9.png index 605d9a390..baadc8343 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_received.9.png and b/src/main/res/drawable-hdpi/message_bubble_received.9.png differ 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 index 84d56bc80..17d87b64d 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_received_dark.9.png and b/src/main/res/drawable-hdpi/message_bubble_received_dark.9.png differ 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 index b6b40f912..75918728e 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_received_grey.9.png and b/src/main/res/drawable-hdpi/message_bubble_received_grey.9.png differ 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 index e0db0b1d4..ac79f7310 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png and b/src/main/res/drawable-hdpi/message_bubble_received_warning.9.png differ 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 index 48e3705e4..c4854a959 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_received_white.9.png and b/src/main/res/drawable-hdpi/message_bubble_received_white.9.png differ diff --git a/src/main/res/drawable-hdpi/message_bubble_sent.9.png b/src/main/res/drawable-hdpi/message_bubble_sent.9.png index b7971a426..42eba56ab 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_sent.9.png and b/src/main/res/drawable-hdpi/message_bubble_sent.9.png differ 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 index ce6f37345..99a1af9ac 100644 Binary files a/src/main/res/drawable-hdpi/message_bubble_sent_grey.9.png and b/src/main/res/drawable-hdpi/message_bubble_sent_grey.9.png differ diff --git a/src/main/res/drawable-mdpi/ic_verified_fingerprint.png b/src/main/res/drawable-mdpi/ic_verified_fingerprint.png new file mode 100644 index 000000000..250ea4cd4 Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_verified_fingerprint.png differ diff --git a/src/main/res/drawable-mdpi/message_bubble_received.9.png b/src/main/res/drawable-mdpi/message_bubble_received.9.png index e2f063555..249e239b4 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_received.9.png and b/src/main/res/drawable-mdpi/message_bubble_received.9.png differ 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 index eb7682335..14e299f57 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_received_dark.9.png and b/src/main/res/drawable-mdpi/message_bubble_received_dark.9.png differ 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 index 7cd4ca330..8be648d88 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_received_grey.9.png and b/src/main/res/drawable-mdpi/message_bubble_received_grey.9.png differ 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 index 16d468b4d..e727575d5 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png and b/src/main/res/drawable-mdpi/message_bubble_received_warning.9.png differ 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 index febb8bfbe..9dbcc3153 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_received_white.9.png and b/src/main/res/drawable-mdpi/message_bubble_received_white.9.png differ diff --git a/src/main/res/drawable-mdpi/message_bubble_sent.9.png b/src/main/res/drawable-mdpi/message_bubble_sent.9.png index cd891b0f2..2e1286364 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_sent.9.png and b/src/main/res/drawable-mdpi/message_bubble_sent.9.png differ 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 index 240b1237f..c314d34e1 100644 Binary files a/src/main/res/drawable-mdpi/message_bubble_sent_grey.9.png and b/src/main/res/drawable-mdpi/message_bubble_sent_grey.9.png differ diff --git a/src/main/res/drawable-xhdpi/ic_verified_fingerprint.png b/src/main/res/drawable-xhdpi/ic_verified_fingerprint.png new file mode 100644 index 000000000..ba8162601 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_verified_fingerprint.png differ diff --git a/src/main/res/drawable-xhdpi/message_bubble_received.9.png b/src/main/res/drawable-xhdpi/message_bubble_received.9.png index b950cb914..89f49dd95 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_received.9.png and b/src/main/res/drawable-xhdpi/message_bubble_received.9.png differ 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 index f29649d84..8da938741 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_received_dark.9.png and b/src/main/res/drawable-xhdpi/message_bubble_received_dark.9.png differ 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 index b9fb79574..6a6046dd0 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_received_grey.9.png and b/src/main/res/drawable-xhdpi/message_bubble_received_grey.9.png differ 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 index 18d36ed58..751bcb9eb 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png and b/src/main/res/drawable-xhdpi/message_bubble_received_warning.9.png differ 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 index b005d170d..595ff84ea 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png and b/src/main/res/drawable-xhdpi/message_bubble_received_white.9.png differ diff --git a/src/main/res/drawable-xhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xhdpi/message_bubble_sent.9.png index 8f2fd5710..b3f01dcda 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_sent.9.png and b/src/main/res/drawable-xhdpi/message_bubble_sent.9.png differ 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 index af6c76088..c32c51018 100644 Binary files a/src/main/res/drawable-xhdpi/message_bubble_sent_grey.9.png and b/src/main/res/drawable-xhdpi/message_bubble_sent_grey.9.png differ diff --git a/src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png b/src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png new file mode 100644 index 000000000..e86e8efcc Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png differ diff --git a/src/main/res/drawable-xxhdpi/message_bubble_received.9.png b/src/main/res/drawable-xxhdpi/message_bubble_received.9.png index 3dd995624..4bb38a159 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_received.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_received.9.png differ 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 index 2cf9f699b..8ad8fdd4b 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_received_dark.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_received_dark.9.png differ 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 index 20ae5f186..c9ef4638d 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_received_grey.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_received_grey.9.png differ 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 index 101302399..07b9a050f 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_received_warning.9.png differ 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 index e2bb6f801..74401c2e6 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_received_white.9.png differ diff --git a/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png index 31c5fa13e..89140290c 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_sent.9.png differ 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 index 2c4864079..47057f23c 100644 Binary files a/src/main/res/drawable-xxhdpi/message_bubble_sent_grey.9.png and b/src/main/res/drawable-xxhdpi/message_bubble_sent_grey.9.png differ diff --git a/src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png b/src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png new file mode 100644 index 000000000..5c78ac272 Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png differ diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png index 1620e8bcc..9601d5a4a 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_received.9.png differ 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 index a62faee5e..bd93e9682 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_received_dark.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_received_dark.9.png differ 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 index 5e9b6b2de..e8633e690 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_received_grey.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_received_grey.9.png differ 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 index 99ec1efa3..bfbffc5c6 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_received_warning.9.png differ 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 index 333aaf68e..4f6ed0cf7 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_received_white.9.png differ diff --git a/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png b/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png index f82c72a2a..95d26a29d 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png differ 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 index ff6e8349b..abdfb98b6 100644 Binary files a/src/main/res/drawable-xxxhdpi/message_bubble_sent_grey.9.png and b/src/main/res/drawable-xxxhdpi/message_bubble_sent_grey.9.png differ diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/contact_key.xml index 7076dad23..c16d5e089 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/contact_key.xml @@ -1,37 +1,40 @@ + android:layout_height="match_parent" + android:longClickable="true"> + android:paddingTop="8dp"> + android:longClickable="true"/> + android:textColor="?attr/color_text_secondary" + android:textSize="?attr/TextSizeInfo" + android:longClickable="true"/> + android:textSize="?attr/TextSizeInfo" + android:visibility="gone" + android:longClickable="true"/> + + - + - - + + \ 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 000000000..2e2fc5dac --- /dev/null +++ b/src/main/res/menu/omemo_key_context.xml @@ -0,0 +1,9 @@ + + + + + \ 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 000000000..7daad46d2 --- /dev/null +++ b/src/main/res/values/ids.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d52d7b889..f4d4262d1 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -699,4 +699,7 @@ Data saver enabled 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. Your device does not support disabling Data saver for Conversations. + Unable to create temporary file + This device has been verified + Copy fingerprint