From 6f67469bda0ffe97cb8cd8d400affed5a17c34c5 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sun, 19 Jul 2015 14:09:49 +0200 Subject: [PATCH] Refactor trust key ui and show in account details Refactored the trust key row UI element so it can be used in multiple places. It now also uses a slider to toggle the trust state, and the redundant trust state description was removed. EditAccountActivity now shows the keys of other devices associated with that account. --- build.gradle | 1 + .../ui/ContactDetailsActivity.java | 49 +----------- .../conversations/ui/EditAccountActivity.java | 22 ++++++ .../siacs/conversations/ui/XmppActivity.java | 79 +++++++++++++++++++ src/main/res/layout/activity_edit_account.xml | 33 +++++++- src/main/res/layout/contact_key.xml | 20 ++--- src/main/res/values/strings.xml | 2 + src/main/res/values/styles.xml | 6 ++ 8 files changed, 154 insertions(+), 58 deletions(-) diff --git a/build.gradle b/build.gradle index d16fd3b88..5031c01f6 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,7 @@ dependencies { compile 'me.leolin:ShortcutBadger:1.1.1@aar' compile 'com.kyleduo.switchbutton:library:1.2.8' compile 'org.whispersystems:axolotl-android:1.3.4' + compile 'com.kyleduo.switchbutton:library:1.2.8' } android { diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index ef99b4915..e7a8ffb75 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -35,7 +35,6 @@ import java.util.List; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.ListItem; @@ -381,53 +380,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys( contact.getAccount(), contact.getJid().toBareJid().toString())) { hasKeys = true; - View view = inflater.inflate(R.layout.contact_key, keys, false); - TextView key = (TextView) view.findViewById(R.id.key); - TextView keyType = (TextView) view.findViewById(R.id.key_type); - TextView keyTrust = (TextView) view.findViewById(R.id.key_trust); - ImageButton removeButton = (ImageButton) view - .findViewById(R.id.button_remove); - ImageButton trustButton = (ImageButton) view - .findViewById(R.id.button_trust); - final AxolotlService axolotlService = contact.getAccount().getAxolotlService(); - final String fingerprint = identityKey.getFingerprint().replaceAll("\\s", ""); - final Jid bareJid = contactJid.toBareJid(); - AxolotlService.SQLiteAxolotlStore.Trust trust = contact.getAccount().getAxolotlService() - .getFingerprintTrust(fingerprint); - switch (trust) { - case TRUSTED: - removeButton.setVisibility(View.VISIBLE); - //Log.d(Config.LOGTAG, AxolotlService.getLogprefix(contact.getAccount()) + "Setting remove button visible!"); - break; - case UNDECIDED: - case UNTRUSTED: - //Log.d(Config.LOGTAG, AxolotlService.getLogprefix(contact.getAccount()) + "Setting trust button visible!"); - trustButton.setVisibility(View.VISIBLE); - break; - } - keyType.setText("Axolotl Fingerprint"); - key.setText(CryptoHelper.prettifyFingerprint(identityKey.getFingerprint())); - keyTrust.setText(trust.toString()); - keyTrust.setVisibility(View.VISIBLE); - keys.addView(view); - removeButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - axolotlService.setFingerprintTrust(fingerprint, - AxolotlService.SQLiteAxolotlStore.Trust.UNTRUSTED); - refreshUi(); - xmppConnectionService.updateConversationUi(); - } - }); - trustButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - axolotlService.setFingerprintTrust(fingerprint, - AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED); - refreshUi(); - xmppConnectionService.updateConversationUi(); - } - }); + addFingerprintRow(keys, contact.getAccount(), identityKey); } if (contact.getPgpKeyId() != 0) { hasKeys = true; diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index e3a43b8b3..77ca2a679 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -26,6 +26,8 @@ import android.widget.TableLayout; import android.widget.TextView; import android.widget.Toast; +import org.whispersystems.libaxolotl.IdentityKey; + import java.util.Set; import eu.siacs.conversations.R; @@ -69,6 +71,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate private ImageButton mAxolotlFingerprintToClipboardButton; private ImageButton mWipeAxolotlPepButton; private ImageButton mRegenerateAxolotlKeyButton; + private LinearLayout keys; + private LinearLayout keysCard; private Jid jidToEdit; private Account mAccount; @@ -329,6 +333,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate this.mAxolotlDevicelist = (TextView) findViewById(R.id.axolotl_devicelist); this.mAxolotlDevicelistBox = (RelativeLayout) findViewById(R.id.axolotl_devices_box); this.mWipeAxolotlPepButton = (ImageButton) findViewById(R.id.action_wipe_axolotl_pep); + this.keysCard = (LinearLayout) findViewById(R.id.other_device_keys_card); + this.keys = (LinearLayout) findViewById(R.id.other_device_keys); this.mSaveButton = (Button) findViewById(R.id.save_button); this.mCancelButton = (Button) findViewById(R.id.cancel_button); this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener); @@ -568,6 +574,22 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } else { this.mAxolotlFingerprintBox.setVisibility(View.GONE); } + final IdentityKey ownKey = mAccount.getAxolotlService().getOwnPublicKey(); + boolean hasKeys = false; + keys.removeAllViews(); + for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys( + mAccount, mAccount.getJid().toBareJid().toString())) { + if(ownKey.equals(identityKey)) { + continue; + } + hasKeys = true; + addFingerprintRow(keys, mAccount, identityKey); + } + if (hasKeys) { + keysCard.setVisibility(View.VISIBLE); + } else { + keysCard.setVisibility(View.GONE); + } } else { if (this.mAccount.errorStatus()) { this.mAccountJid.setError(getString(this.mAccount.getStatus().getReadableId())); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 7c994c31a..9dfece2f5 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -43,8 +43,11 @@ import android.util.Log; 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; @@ -53,9 +56,12 @@ import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import com.kyleduo.switchbutton.SwitchButton; import net.java.otr4j.session.SessionID; +import org.whispersystems.libaxolotl.IdentityKey; + import java.io.FileNotFoundException; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -65,6 +71,7 @@ import java.util.concurrent.RejectedExecutionException; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -74,6 +81,8 @@ import eu.siacs.conversations.entities.Presences; 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.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -588,6 +597,76 @@ public abstract class XmppActivity extends Activity { builder.create().show(); } + protected void addFingerprintRow(LinearLayout keys, final Account account, IdentityKey identityKey) { + final String fingerprint = identityKey.getFingerprint().replaceAll("\\s", ""); + final AxolotlService.SQLiteAxolotlStore.Trust trust = account.getAxolotlService() + .getFingerprintTrust(fingerprint); + addFingerprintRowWithListeners(keys, account, identityKey, trust, true, + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked != (trust == AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED)) { + account.getAxolotlService().setFingerprintTrust(fingerprint, + (isChecked) ? AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED : + AxolotlService.SQLiteAxolotlStore.Trust.UNTRUSTED); + } + refreshUi(); + xmppConnectionService.updateAccountUi(); + xmppConnectionService.updateConversationUi(); + } + }, + new View.OnClickListener() { + @Override + public void onClick(View v) { + account.getAxolotlService().setFingerprintTrust(fingerprint, + AxolotlService.SQLiteAxolotlStore.Trust.UNTRUSTED); + refreshUi(); + xmppConnectionService.updateAccountUi(); + xmppConnectionService.updateConversationUi(); + } + } + + ); + } + + protected void addFingerprintRowWithListeners(LinearLayout keys, final Account account, + IdentityKey identityKey, + AxolotlService.SQLiteAxolotlStore.Trust trust, + boolean showTag, + CompoundButton.OnCheckedChangeListener + onCheckedChangeListener, + View.OnClickListener onClickListener) { + 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); + Switch trustToggle = (Switch) view.findViewById(R.id.tgl_trust); + trustToggle.setVisibility(View.VISIBLE); + trustToggle.setOnCheckedChangeListener(onCheckedChangeListener); + trustToggle.setOnClickListener(onClickListener); + + switch (trust) { + case UNTRUSTED: + case TRUSTED: + trustToggle.setChecked(trust == AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED, false); + trustToggle.setEnabled(true); + break; + case UNDECIDED: + trustToggle.setChecked(false, false); + trustToggle.setEnabled(false); + break; + } + + if (showTag) { + keyType.setText(getString(R.string.axolotl_fingerprint)); + } else { + keyType.setVisibility(View.GONE); + } + + key.setText(CryptoHelper.prettifyFingerprint(identityKey.getFingerprint())); + keys.addView(view); + + } + public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) { final Contact contact = conversation.getContact(); diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml index df20e6f2d..3d65365d6 100644 --- a/src/main/res/layout/activity_edit_account.xml +++ b/src/main/res/layout/activity_edit_account.xml @@ -368,7 +368,7 @@ android:layout_height="wrap_content" android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo" - android:text="@string/axolotl_fingerprint"/> + android:text="@string/this_device_axolotl_fingerprint"/> + + + + + + + diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/contact_key.xml index a43f8083b..64f6075ca 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/contact_key.xml @@ -4,10 +4,10 @@ android:layout_height="match_parent" > @@ -37,27 +38,28 @@ android:visibility="gone" android:textColor="@color/black54" android:textSize="?attr/TextSizeInfo"/> - + android:visibility="gone" /> - + style="@style/MaterialDesignButton"/> + + \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 6808f1bb5..f4c75ee1f 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -209,6 +209,8 @@ Your fingerprint OTR fingerprint Axolotl fingerprint + Own Axolotl fingerprint + Other devices Other own Axolotl Devices Verify Decrypt diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index e8572d9d4..d609b5fb3 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -18,4 +18,10 @@ 16dp + + \ No newline at end of file