refactor omemo fingerprint UI code
This commit is contained in:
parent
2c13740e36
commit
35fca6af27
16 changed files with 482 additions and 340 deletions
54
art/ic_verified_fingerprint.svg
Normal file
54
art/ic_verified_fingerprint.svg
Normal 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 |
|
@ -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],
|
||||
|
|
237
src/main/java/de/pixart/messenger/OmemoActivity.java
Normal file
237
src/main/java/de/pixart/messenger/OmemoActivity.java
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
BIN
src/main/res/drawable-hdpi/ic_verified_fingerprint.png
Normal file
BIN
src/main/res/drawable-hdpi/ic_verified_fingerprint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
src/main/res/drawable-mdpi/ic_verified_fingerprint.png
Normal file
BIN
src/main/res/drawable-mdpi/ic_verified_fingerprint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 KiB |
BIN
src/main/res/drawable-xhdpi/ic_verified_fingerprint.png
Normal file
BIN
src/main/res/drawable-xhdpi/ic_verified_fingerprint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png
Normal file
BIN
src/main/res/drawable-xxhdpi/ic_verified_fingerprint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png
Normal file
BIN
src/main/res/drawable-xxxhdpi/ic_verified_fingerprint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
|
@ -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>
|
9
src/main/res/menu/omemo_key_context.xml
Normal file
9
src/main/res/menu/omemo_key_context.xml
Normal 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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
Reference in a new issue