fixe scan in OmemoActivities

This commit is contained in:
Daniel Gultsch 2018-02-26 12:44:03 +01:00
parent 9a76aff8f9
commit 89bfae14b1
3 changed files with 234 additions and 200 deletions

View file

@ -1,6 +1,7 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.databinding.DataBindingUtil; import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -28,219 +29,224 @@ import eu.siacs.conversations.utils.XmppUri;
public abstract class OmemoActivity extends XmppActivity { public abstract class OmemoActivity extends XmppActivity {
private Account mSelectedAccount; private Account mSelectedAccount;
private String mSelectedFingerprint; private String mSelectedFingerprint;
protected XmppUri mPendingFingerprintVerificationUri = null; protected XmppUri mPendingFingerprintVerificationUri = null;
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu,v,menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
Object account = v.getTag(R.id.TAG_ACCOUNT); Object account = v.getTag(R.id.TAG_ACCOUNT);
Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT); Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT);
Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS); Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS);
if (account != null if (account != null
&& fingerprint != null && fingerprint != null
&& account instanceof Account && account instanceof Account
&& fingerprintStatus != null && fingerprintStatus != null
&& fingerprint instanceof String && fingerprint instanceof String
&& fingerprintStatus instanceof FingerprintStatus) { && fingerprintStatus instanceof FingerprintStatus) {
getMenuInflater().inflate(R.menu.omemo_key_context, menu); getMenuInflater().inflate(R.menu.omemo_key_context, menu);
MenuItem distrust = menu.findItem(R.id.distrust_key); MenuItem distrust = menu.findItem(R.id.distrust_key);
MenuItem verifyScan = menu.findItem(R.id.verify_scan); MenuItem verifyScan = menu.findItem(R.id.verify_scan);
if (this instanceof TrustKeysActivity) { if (this instanceof TrustKeysActivity) {
distrust.setVisible(false); distrust.setVisible(false);
verifyScan.setVisible(false); verifyScan.setVisible(false);
} else { } else {
FingerprintStatus status = (FingerprintStatus) fingerprintStatus; FingerprintStatus status = (FingerprintStatus) fingerprintStatus;
if (!status.isActive() || status.isVerified()) { if (!status.isActive() || status.isVerified()) {
verifyScan.setVisible(false); verifyScan.setVisible(false);
} }
distrust.setVisible(status.isVerified() || (!status.isActive() && status.isTrusted())); distrust.setVisible(status.isVerified() || (!status.isActive() && status.isTrusted()));
} }
this.mSelectedAccount = (Account) account; this.mSelectedAccount = (Account) account;
this.mSelectedFingerprint = (String) fingerprint; this.mSelectedFingerprint = (String) fingerprint;
} }
} }
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.distrust_key: case R.id.distrust_key:
showPurgeKeyDialog(mSelectedAccount,mSelectedFingerprint); showPurgeKeyDialog(mSelectedAccount, mSelectedFingerprint);
break; break;
case R.id.copy_omemo_key: case R.id.copy_omemo_key:
copyOmemoFingerprint(mSelectedFingerprint); copyOmemoFingerprint(mSelectedFingerprint);
break; break;
case R.id.verify_scan: case R.id.verify_scan:
//new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE")); ScanActivity.scan(this);
break; break;
} }
return true; return true;
} }
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) { public void onActivityResult(int requestCode, int resultCode, Intent intent) {
/*IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); super.onActivityResult(requestCode, requestCode, intent);
if (scanResult != null && scanResult.getFormatName() != null) { if (requestCode == ScanActivity.REQUEST_SCAN_QR_CODE && resultCode == RESULT_OK) {
String data = scanResult.getContents(); String result = intent.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT);
XmppUri uri = new XmppUri(data); XmppUri uri = new XmppUri(result == null ? "" : result);
if (xmppConnectionServiceBound) { if (xmppConnectionServiceBound) {
processFingerprintVerification(uri); processFingerprintVerification(uri);
} else { } else {
this.mPendingFingerprintVerificationUri =uri; this.mPendingFingerprintVerificationUri = uri;
} }
}*/ }
} }
protected abstract void processFingerprintVerification(XmppUri uri); protected abstract void processFingerprintVerification(XmppUri uri);
protected void copyOmemoFingerprint(String fingerprint) { protected void copyOmemoFingerprint(String fingerprint) {
if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) { if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) {
Toast.makeText( Toast.makeText(
this, this,
R.string.toast_message_omemo_fingerprint, R.string.toast_message_omemo_fingerprint,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
} }
} }
protected void addFingerprintRow(LinearLayout keys, final XmppAxolotlSession session, boolean highlight) { protected void addFingerprintRow(LinearLayout keys, final XmppAxolotlSession session, boolean highlight) {
final Account account = session.getAccount(); final Account account = session.getAccount();
final String fingerprint = session.getFingerprint(); final String fingerprint = session.getFingerprint();
addFingerprintRowWithListeners(keys, addFingerprintRowWithListeners(keys,
session.getAccount(), session.getAccount(),
fingerprint, fingerprint,
highlight, highlight,
session.getTrust(), session.getTrust(),
true, true,
true, true,
(buttonView, isChecked) -> account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(isChecked))); (buttonView, isChecked) -> account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(isChecked)));
} }
protected void addFingerprintRowWithListeners(LinearLayout keys, final Account account, protected void addFingerprintRowWithListeners(LinearLayout keys, final Account account,
final String fingerprint, final String fingerprint,
boolean highlight, boolean highlight,
FingerprintStatus status, FingerprintStatus status,
boolean showTag, boolean showTag,
boolean undecidedNeedEnablement, boolean undecidedNeedEnablement,
CompoundButton.OnCheckedChangeListener CompoundButton.OnCheckedChangeListener
onCheckedChangeListener) { onCheckedChangeListener) {
ContactKeyBinding binding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.contact_key,keys,true); ContactKeyBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.contact_key, keys, true);
if (Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509) { if (Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509) {
binding.key.setOnClickListener(v -> showX509Certificate(account,fingerprint)); binding.key.setOnClickListener(v -> showX509Certificate(account, fingerprint));
binding.keyType.setOnClickListener(v -> showX509Certificate(account,fingerprint)); binding.keyType.setOnClickListener(v -> showX509Certificate(account, fingerprint));
} }
binding.tglTrust.setVisibility(View.VISIBLE); binding.tglTrust.setVisibility(View.VISIBLE);
registerForContextMenu(binding.getRoot()); registerForContextMenu(binding.getRoot());
binding.getRoot().setTag(R.id.TAG_ACCOUNT,account); binding.getRoot().setTag(R.id.TAG_ACCOUNT, account);
binding.getRoot().setTag(R.id.TAG_FINGERPRINT,fingerprint); binding.getRoot().setTag(R.id.TAG_FINGERPRINT, fingerprint);
binding.getRoot().setTag(R.id.TAG_FINGERPRINT_STATUS,status); binding.getRoot().setTag(R.id.TAG_FINGERPRINT_STATUS, status);
boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509; boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509;
final View.OnClickListener toast; final View.OnClickListener toast;
binding.tglTrust.setChecked(status.isTrusted()); binding.tglTrust.setChecked(status.isTrusted());
if (status.isActive()){ if (status.isActive()) {
binding.key.setTextColor(getPrimaryTextColor()); binding.key.setTextColor(getPrimaryTextColor());
binding.keyType.setTextColor(getSecondaryTextColor()); binding.keyType.setTextColor(getSecondaryTextColor());
if (status.isVerified()) { if (status.isVerified()) {
binding.verifiedFingerprint.setVisibility(View.VISIBLE); binding.verifiedFingerprint.setVisibility(View.VISIBLE);
binding.verifiedFingerprint.setAlpha(1.0f); binding.verifiedFingerprint.setAlpha(1.0f);
binding.tglTrust.setVisibility(View.GONE); binding.tglTrust.setVisibility(View.GONE);
binding.verifiedFingerprint.setOnClickListener(v -> replaceToast(getString(R.string.this_device_has_been_verified), false)); binding.verifiedFingerprint.setOnClickListener(v -> replaceToast(getString(R.string.this_device_has_been_verified), false));
toast = null; toast = null;
} else { } else {
binding.verifiedFingerprint.setVisibility(View.GONE); binding.verifiedFingerprint.setVisibility(View.GONE);
binding.tglTrust.setVisibility(View.VISIBLE); binding.tglTrust.setVisibility(View.VISIBLE);
binding.tglTrust.setOnCheckedChangeListener(onCheckedChangeListener); binding.tglTrust.setOnCheckedChangeListener(onCheckedChangeListener);
if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED && undecidedNeedEnablement) { if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED && undecidedNeedEnablement) {
binding.buttonEnableDevice.setVisibility(View.VISIBLE); binding.buttonEnableDevice.setVisibility(View.VISIBLE);
binding.buttonEnableDevice.setOnClickListener(v -> { binding.buttonEnableDevice.setOnClickListener(v -> {
account.getAxolotlService().setFingerprintTrust(fingerprint,FingerprintStatus.createActive(false)); account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(false));
binding.buttonEnableDevice.setVisibility(View.GONE); binding.buttonEnableDevice.setVisibility(View.GONE);
binding.tglTrust.setVisibility(View.VISIBLE); binding.tglTrust.setVisibility(View.VISIBLE);
}); });
binding.tglTrust.setVisibility(View.GONE); binding.tglTrust.setVisibility(View.GONE);
} else { } else {
binding.tglTrust.setOnClickListener(null); binding.tglTrust.setOnClickListener(null);
binding.tglTrust.setEnabled(true); binding.tglTrust.setEnabled(true);
} }
toast = v -> hideToast(); toast = v -> hideToast();
} }
} else { } else {
binding.key.setTextColor(getTertiaryTextColor()); binding.key.setTextColor(getTertiaryTextColor());
binding.keyType.setTextColor(getTertiaryTextColor()); binding.keyType.setTextColor(getTertiaryTextColor());
toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false);
if (status.isVerified()) { if (status.isVerified()) {
binding.tglTrust.setVisibility(View.GONE); binding.tglTrust.setVisibility(View.GONE);
binding.verifiedFingerprint.setVisibility(View.VISIBLE); binding.verifiedFingerprint.setVisibility(View.VISIBLE);
binding.verifiedFingerprint.setAlpha(0.4368f); binding.verifiedFingerprint.setAlpha(0.4368f);
binding.verifiedFingerprint.setOnClickListener(toast); binding.verifiedFingerprint.setOnClickListener(toast);
} else { } else {
binding.tglTrust.setVisibility(View.VISIBLE); binding.tglTrust.setVisibility(View.VISIBLE);
binding.verifiedFingerprint.setVisibility(View.GONE); binding.verifiedFingerprint.setVisibility(View.GONE);
binding.tglTrust.setEnabled(false); binding.tglTrust.setEnabled(false);
} }
} }
binding.getRoot().setOnClickListener(toast); binding.getRoot().setOnClickListener(toast);
binding.key.setOnClickListener(toast); binding.key.setOnClickListener(toast);
binding.keyType.setOnClickListener(toast); binding.keyType.setOnClickListener(toast);
if (showTag) { if (showTag) {
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
} else { } else {
binding.keyType.setVisibility(View.GONE); binding.keyType.setVisibility(View.GONE);
} }
if (highlight) { if (highlight) {
binding.keyType.setTextColor(ContextCompat.getColor(this, R.color.accent)); binding.keyType.setTextColor(ContextCompat.getColor(this, R.color.accent));
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message)); binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message));
} else { } else {
binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
} }
binding.key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); binding.key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)));
} }
public void showPurgeKeyDialog(final Account account, final String fingerprint) { public void showPurgeKeyDialog(final Account account, final String fingerprint) {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.distrust_omemo_key); builder.setTitle(R.string.distrust_omemo_key);
builder.setMessage(R.string.distrust_omemo_key_text); builder.setMessage(R.string.distrust_omemo_key_text);
builder.setNegativeButton(getString(R.string.cancel), null); builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(R.string.confirm, builder.setPositiveButton(R.string.confirm,
(dialog, which) -> { (dialog, which) -> {
account.getAxolotlService().distrustFingerprint(fingerprint); account.getAxolotlService().distrustFingerprint(fingerprint);
refreshUi(); refreshUi();
}); });
builder.create().show(); builder.create().show();
} }
private void showX509Certificate(Account account, String fingerprint) { private void showX509Certificate(Account account, String fingerprint) {
X509Certificate x509Certificate = account.getAxolotlService().getFingerprintCertificate(fingerprint); X509Certificate x509Certificate = account.getAxolotlService().getFingerprintCertificate(fingerprint);
if (x509Certificate != null) { if (x509Certificate != null) {
showCertificateInformationDialog(CryptoHelper.extractCertificateInformation(x509Certificate)); showCertificateInformationDialog(CryptoHelper.extractCertificateInformation(x509Certificate));
} else { } else {
Toast.makeText(this,R.string.certificate_not_found, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.certificate_not_found, Toast.LENGTH_SHORT).show();
} }
} }
private void showCertificateInformationDialog(Bundle bundle) { private void showCertificateInformationDialog(Bundle bundle) {
View view = getLayoutInflater().inflate(R.layout.certificate_information, null); View view = getLayoutInflater().inflate(R.layout.certificate_information, null);
final String not_available = getString(R.string.certicate_info_not_available); final String not_available = getString(R.string.certicate_info_not_available);
TextView subject_cn = (TextView) view.findViewById(R.id.subject_cn); TextView subject_cn = (TextView) view.findViewById(R.id.subject_cn);
TextView subject_o = (TextView) view.findViewById(R.id.subject_o); TextView subject_o = (TextView) view.findViewById(R.id.subject_o);
TextView issuer_cn = (TextView) view.findViewById(R.id.issuer_cn); TextView issuer_cn = (TextView) view.findViewById(R.id.issuer_cn);
TextView issuer_o = (TextView) view.findViewById(R.id.issuer_o); TextView issuer_o = (TextView) view.findViewById(R.id.issuer_o);
TextView sha1 = (TextView) view.findViewById(R.id.sha1); TextView sha1 = (TextView) view.findViewById(R.id.sha1);
subject_cn.setText(bundle.getString("subject_cn", not_available)); subject_cn.setText(bundle.getString("subject_cn", not_available));
subject_o.setText(bundle.getString("subject_o", not_available)); subject_o.setText(bundle.getString("subject_o", not_available));
issuer_cn.setText(bundle.getString("issuer_cn", not_available)); issuer_cn.setText(bundle.getString("issuer_cn", not_available));
issuer_o.setText(bundle.getString("issuer_o", not_available)); issuer_o.setText(bundle.getString("issuer_o", not_available));
sha1.setText(bundle.getString("sha1", not_available)); sha1.setText(bundle.getString("sha1", not_available));
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.certificate_information); builder.setTitle(R.string.certificate_information);
builder.setView(view); builder.setView(view);
builder.setPositiveButton(R.string.ok, null); builder.setPositiveButton(R.string.ok, null);
builder.create().show(); builder.create().show();
} }
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
ScanActivity.onRequestPermissionResult(this, requestCode, grantResults);
}
} }

View file

@ -54,6 +54,7 @@ import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener; import android.view.TextureView.SurfaceTextureListener;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
@ -67,6 +68,9 @@ import eu.siacs.conversations.ui.widget.ScannerView;
public final class ScanActivity extends Activity implements SurfaceTextureListener, ActivityCompat.OnRequestPermissionsResultCallback { public final class ScanActivity extends Activity implements SurfaceTextureListener, ActivityCompat.OnRequestPermissionsResultCallback {
public static final String INTENT_EXTRA_RESULT = "result"; public static final String INTENT_EXTRA_RESULT = "result";
public static final int REQUEST_SCAN_QR_CODE = 0x0987;
private static final int REQUEST_CAMERA_PERMISSIONS_TO_SCAN = 0x6789;
private static final long VIBRATE_DURATION = 50L; private static final long VIBRATE_DURATION = 50L;
private static final long AUTO_FOCUS_INTERVAL_MS = 2500L; private static final long AUTO_FOCUS_INTERVAL_MS = 2500L;
private static boolean DISABLE_CONTINUOUS_AUTOFOCUS = Build.MODEL.equals("GT-I9100") // Galaxy S2 private static boolean DISABLE_CONTINUOUS_AUTOFOCUS = Build.MODEL.equals("GT-I9100") // Galaxy S2
@ -263,7 +267,30 @@ public final class ScanActivity extends Activity implements SurfaceTextureListen
} }
private void postFinish() { private void postFinish() {
new Handler().postDelayed(() -> finish(), 50); new Handler().postDelayed(this::finish, 50);
}
public static void scan(Activity activity) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(activity, ScanActivity.class);
activity.startActivityForResult(intent, REQUEST_SCAN_QR_CODE);
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSIONS_TO_SCAN);
}
}
public static void onRequestPermissionResult(Activity activity, int requestCode, int[] grantResults) {
if (requestCode != REQUEST_CAMERA_PERMISSIONS_TO_SCAN) {
return;
}
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
scan(activity);
} else {
Toast.makeText(activity, R.string.qr_code_scanner_needs_access_to_camera, Toast.LENGTH_SHORT).show();
}
}
} }
private final class AutoFocusRunnable implements Runnable { private final class AutoFocusRunnable implements Runnable {

View file

@ -133,6 +133,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
if (hasPendingKeyFetches()) { if (hasPendingKeyFetches()) {
Toast.makeText(this, R.string.please_wait_for_keys_to_be_fetched, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.please_wait_for_keys_to_be_fetched, Toast.LENGTH_SHORT).show();
} else { } else {
ScanActivity.scan(this);
//new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE")); //new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE"));
return true; return true;
} }