refactor omemo fingerprint UI code

This commit is contained in:
Christian Schneppe 2016-11-17 21:30:31 +01:00
parent 2c13740e36
commit 35fca6af27
16 changed files with 482 additions and 340 deletions

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
viewBox="0 0 48 48"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="ic_verified_fingerprint.svg">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1916"
inkscape:window-height="1156"
id="namedview6"
showgrid="false"
inkscape:zoom="4.9166667"
inkscape:cx="-3.3559322"
inkscape:cy="24"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<path
d="M24 2L6 10v12c0 11.11 7.67 21.47 18 24 10.33-2.53 18-12.89 18-24V10L24 2zm-4 32l-8-8 2.83-2.83L20 28.34l13.17-13.17L36 18 20 34z"
id="path4"
style="fill:#259b24;fill-opacity:0.627451" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -41,6 +41,7 @@ images = {
'ic_send_picture_offline.svg' => ['ic_send_picture_offline', 36],
'ic_send_picture_away.svg' => ['ic_send_picture_away', 36],
'ic_send_picture_dnd.svg' => ['ic_send_picture_dnd', 36],
'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],

View file

@ -0,0 +1,237 @@
package de.pixart.messenger;
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 de.pixart.messenger.crypto.axolotl.FingerprintStatus;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.ui.XmppActivity;
import de.pixart.messenger.ui.widget.Switch;
import de.pixart.messenger.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();
}
}

View file

@ -27,20 +27,18 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.QuickContactBadge;
import android.widget.TextView;
import android.widget.Toast;
import com.wefika.flowlayout.FlowLayout;
import org.openintents.openpgp.util.OpenPgpUtils;
import java.security.cert.X509Certificate;
import java.util.List;
import de.pixart.messenger.Config;
import de.pixart.messenger.OmemoActivity;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.PgpEngine;
import de.pixart.messenger.crypto.axolotl.AxolotlService;
import de.pixart.messenger.crypto.axolotl.FingerprintStatus;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Contact;
import de.pixart.messenger.entities.Conversation;
@ -55,7 +53,7 @@ import de.pixart.messenger.xmpp.XmppConnection;
import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.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 Conversation mConversation;
@ -462,12 +460,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) {
@ -523,40 +516,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);
@ -577,7 +536,6 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
builder.create().show();
}
@Override
public void onBackendConnected() {
if ((accountJid != null) && (contactJid != null)) {
Account account = xmppConnectionService

View file

@ -41,6 +41,7 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import de.pixart.messenger.Config;
import de.pixart.messenger.OmemoActivity;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.axolotl.AxolotlService;
import de.pixart.messenger.entities.Account;
@ -59,7 +60,7 @@ import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.xmpp.jid.Jid;
import de.pixart.messenger.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;
@ -642,7 +643,6 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onBackendConnected() {
boolean init = true;
if (mSavedInstanceAccount != null) {
@ -901,13 +901,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) {
@ -932,7 +926,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);

View file

@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import de.pixart.messenger.OmemoActivity;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.axolotl.AxolotlService;
import de.pixart.messenger.crypto.axolotl.FingerprintStatus;
@ -27,7 +28,7 @@ import de.pixart.messenger.xmpp.OnKeyStatusUpdated;
import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.xmpp.jid.Jid;
public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdated {
public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdated {
private List<Jid> contactJids;
private Account mAccount;
@ -108,16 +109,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
}
);
}
@ -133,16 +132,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) {
@ -211,7 +208,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);

View file

@ -48,11 +48,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;
@ -76,7 +73,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.axolotl.FingerprintStatus;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Contact;
import de.pixart.messenger.entities.Conversation;
@ -86,7 +82,6 @@ import de.pixart.messenger.entities.Presences;
import de.pixart.messenger.services.AvatarService;
import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.services.XmppConnectionService.XmppConnectionBinder;
import de.pixart.messenger.ui.widget.Switch;
import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.ExceptionHelper;
import de.pixart.messenger.utils.UIHelper;
@ -775,131 +770,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) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -1,16 +1,17 @@
<?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"
@ -18,10 +19,11 @@
android:layout_height="wrap_content"
android:textColor="@color/black87"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/tgl_trust"
android:layout_toLeftOf="@+id/action_container"
android:textSize="?attr/TextSizeBody"
android:typeface="monospace"
android:fontFamily="monospace"/>
android:fontFamily="monospace"
android:longClickable="true"/>
<TextView
android:id="@+id/key_type"
@ -31,7 +33,8 @@
android:layout_alignParentLeft="true"
android:layout_below="@+id/key"
android:maxLines="1"
android:textSize="?attr/TextSizeInfo"/>
android:textSize="?attr/TextSizeInfo"
android:longClickable="true"/>
<TextView
android:id="@+id/key_trust"
@ -41,29 +44,45 @@
android:layout_below="@+id/key"
android:visibility="gone"
android:textColor="@color/black54"
android:textSize="?attr/TextSizeInfo"/>
android:textSize="?attr/TextSizeInfo"
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:layout_alignParentRight="true"
android:layout_toRightOf="@+id/key"
android:layout_centerVertical="true"
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" />
<de.pixart.messenger.ui.widget.Switch
android:id="@+id/tgl_trust"
android:visibility="invisible"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
style="@style/MD"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>

View file

@ -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>

View file

@ -4,4 +4,6 @@
<item name="message_image_view" type="id" />
<item name="message_video_view" type="id" />
<item name="import_text" type="id" />
<item type="id" name="TAG_ACCOUNT"/>
<item type="id" name="TAG_FINGERPRINT"/>
</resources>

View file

@ -705,5 +705,7 @@
<string name="received_contact">Received contact</string>
<string name="contact">Contact</string>
<string name="unable_to_start_recording">Unable to start recording</string>
<string name="error_unable_to_create_temporary_file">Error: unable to create temporary file</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>