Better YubiKey UX flow for error handling
This commit is contained in:
@@ -9,7 +9,9 @@ package org.sufficientlysecure.keychain.ui;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ViewAnimator;
|
||||
|
||||
@@ -49,6 +51,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
||||
|
||||
public ViewAnimator vAnimator;
|
||||
public TextView vErrorText;
|
||||
public Button vErrorTryAgainButton;
|
||||
|
||||
private RequiredInputParcel mRequiredInput;
|
||||
private Intent mServiceIntent;
|
||||
@@ -68,7 +71,20 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
||||
|
||||
vAnimator = (ViewAnimator) findViewById(R.id.view_animator);
|
||||
vAnimator.setDisplayedChild(0);
|
||||
vErrorText = (TextView) findViewById(R.id.nfc_activity_error_text);
|
||||
vErrorText = (TextView) findViewById(R.id.nfc_activity_3_error_text);
|
||||
vErrorTryAgainButton = (Button) findViewById(R.id.nfc_activity_3_error_try_again);
|
||||
vErrorTryAgainButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
resumeTagHandling();
|
||||
|
||||
// obtain passphrase for this subkey
|
||||
if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_MOVE_KEY_TO_CARD) {
|
||||
obtainYubiKeyPin(mRequiredInput);
|
||||
}
|
||||
vAnimator.setDisplayedChild(0);
|
||||
}
|
||||
});
|
||||
|
||||
Intent intent = getIntent();
|
||||
Bundle data = intent.getExtras();
|
||||
@@ -84,7 +100,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
setContentView(R.layout.nfc_activity);
|
||||
setContentView(R.layout.nfc_operation_activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,8 +237,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
||||
if (isNfcConnected()) {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
// never mind
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
@@ -239,7 +254,9 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
||||
|
||||
@Override
|
||||
protected void onNfcError(String error) {
|
||||
vErrorText.setText(error);
|
||||
pauseTagHandling();
|
||||
|
||||
vErrorText.setText(error + "\n\n" + getString(R.string.nfc_try_again_text));
|
||||
vAnimator.setDisplayedChild(3);
|
||||
}
|
||||
|
||||
@@ -270,8 +287,6 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
||||
// clear (invalid) passphrase
|
||||
PassphraseCacheService.clearCachedPassphrase(
|
||||
this, mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId());
|
||||
|
||||
obtainYubiKeyPin(mRequiredInput);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.TagLostException;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
@@ -72,6 +73,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
||||
protected boolean mPw3Validated;
|
||||
private NfcAdapter mNfcAdapter;
|
||||
private IsoDep mIsoDep;
|
||||
private boolean mTagHandlingEnabled;
|
||||
|
||||
private static final int TIMEOUT = 100000;
|
||||
|
||||
@@ -168,10 +170,20 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected void pauseTagHandling() {
|
||||
mTagHandlingEnabled = false;
|
||||
}
|
||||
|
||||
protected void resumeTagHandling() {
|
||||
mTagHandlingEnabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mTagHandlingEnabled = true;
|
||||
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
|
||||
@@ -186,7 +198,8 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
||||
*/
|
||||
@Override
|
||||
public void onNewIntent(final Intent intent) {
|
||||
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
|
||||
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())
|
||||
&& mTagHandlingEnabled) {
|
||||
handleIntentInBackground(intent);
|
||||
}
|
||||
}
|
||||
@@ -194,6 +207,11 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
||||
private void handleNfcError(Exception e) {
|
||||
Log.e(Constants.TAG, "nfc error", e);
|
||||
|
||||
if (e instanceof TagLostException) {
|
||||
onNfcError(getString(R.string.error_nfc_tag_lost));
|
||||
return;
|
||||
}
|
||||
|
||||
short status;
|
||||
if (e instanceof CardException) {
|
||||
status = ((CardException) e).getResponseCode();
|
||||
@@ -202,7 +220,8 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
||||
}
|
||||
// When entering a PIN, a status of 63CX indicates X attempts remaining.
|
||||
if ((status & (short)0xFFF0) == 0x63C0) {
|
||||
onNfcError(getString(R.string.error_pin, status & 0x000F));
|
||||
int tries = status & 0x000F;
|
||||
onNfcError(getResources().getQuantityString(R.plurals.error_pin, tries, tries));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user