Request enroll or verify lock before FP enroll

Also pipe through challenge token

Change-Id: I9d6afdbadf3832aeeb18a0b5a9620277e2070872
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index d9622c0..975882f 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -170,15 +170,7 @@
 
         @Override
         protected void authenticationSucceeded(@Nullable String password) {
-            Intent intent = new Intent();
-            if (getActivity() instanceof ConfirmLockPassword.InternalActivity) {
-                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
-                        mIsAlpha ? StorageManager.CRYPT_TYPE_PASSWORD
-                                : StorageManager.CRYPT_TYPE_PIN);
-                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
-            }
-            getActivity().setResult(RESULT_OK, intent);
-            getActivity().finish();
+            // TODO: make this play nice with challenge
         }
 
         private void handleNext() {
@@ -208,7 +200,6 @@
             }
 
             if (matched) {
-                authenticationSucceeded(pin);
                 getActivity().setResult(RESULT_OK, intent);
                 getActivity().finish();
             } else {
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
index 9db1719..0b2bec3 100644
--- a/src/com/android/settings/ConfirmLockPattern.java
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -233,14 +233,7 @@
 
         @Override
         protected void authenticationSucceeded(@Nullable String password) {
-            Intent intent = new Intent();
-            if (getActivity() instanceof ConfirmLockPattern.InternalActivity) {
-                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE,
-                        StorageManager.CRYPT_TYPE_PATTERN);
-                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, password);
-            }
-            getActivity().setResult(Activity.RESULT_OK, intent);
-            getActivity().finish();
+            // TODO: make this play nice with challenge
         }
 
         @Override
@@ -299,7 +292,6 @@
                 }
 
                 if (matched) {
-                    authenticationSucceeded(LockPatternUtils.patternToString(pattern));
                     getActivity().setResult(Activity.RESULT_OK, intent);
                     getActivity().finish();
                 } else {
diff --git a/src/com/android/settings/FingerprintEnroll.java b/src/com/android/settings/FingerprintEnroll.java
index a6424e5..61bebdf 100644
--- a/src/com/android/settings/FingerprintEnroll.java
+++ b/src/com/android/settings/FingerprintEnroll.java
@@ -105,6 +105,7 @@
         private ProgressBar mProgressBar;
         private ImageView mFingerprintAnimator;
         private ObjectAnimator mProgressAnim;
+        private byte[] mToken;
 
         // Give the user a chance to see progress completed before jumping to the next stage.
         Runnable mDelayedFinishRunnable = new Runnable() {
@@ -253,8 +254,8 @@
 
                 case EnrollingStart:
                     mEnrollmentSteps = -1;
-                    long challenge = 0x12345; // TODO: get from keyguard confirmation
-                    mFingerprintManager.enroll(challenge, mEnrollmentCancel, mEnrollmentCallback, 0);
+                    // TODO: pass in mToken
+                    mFingerprintManager.enroll(0, mEnrollmentCancel, mEnrollmentCallback, 0);
                     mProgressBar.setProgress(0);
                     mEnrolling = true;
                     startFingerprintAnimator(); // XXX hack - this should follow fingerprint detection
@@ -350,9 +351,12 @@
         public void onActivityResult(int requestCode, int resultCode, Intent data) {
             super.onActivityResult(requestCode, resultCode, data);
 
-            if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
-                if (resultCode == RESULT_FINISHED) {
+            if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST
+                    || requestCode == CONFIRM_REQUEST) {
+                if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) {
                     // The lock pin/pattern/password was set. Start enrolling!
+                    mToken = data.getByteArrayExtra(
+                            ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
                     updateStage(Stage.EnrollingFindSensor);
                 }
             }
@@ -381,8 +385,8 @@
             }
 
             LockPatternUtils utils = new LockPatternUtils(activity);
-            if (!utils.isSecure()) {
-                // Device doesn't have any security. Set that up first.
+            if (mToken == null) {
+                // need to choose or confirm lock
                 updateStage(Stage.EnrollingOnboard);
             } else if (ALWAYS_SHOW_FIND_SCREEN
                     || mFingerprintManager.getEnrolledFingerprints().size() == 0) {
@@ -397,6 +401,8 @@
         public void onSaveInstanceState(final Bundle outState) {
             super.onSaveInstanceState(outState);
             outState.putString(EXTRA_STAGE, mStage.toString());
+            outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
+                    mToken);
             if (mStage == Stage.EnrollingRepeat) {
                 outState.putInt(EXTRA_PROGRESS, mProgressBar.getProgress());
             }
@@ -406,6 +412,8 @@
         public void onActivityCreated(Bundle savedInstanceState) {
             super.onActivityCreated(savedInstanceState);
             if (savedInstanceState != null) {
+                mToken = savedInstanceState.getByteArray(
+                        ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
                 //probably orientation change
                 String stageSaved = savedInstanceState.getString(EXTRA_STAGE, null);
                 if (stageSaved != null) {
@@ -426,7 +434,7 @@
                     break;
                 case R.id.fingerprint_enroll_button_next:
                     if (mStage == Stage.EnrollingOnboard) {
-                        launchChooseLock();
+                        launchChooseOrConfirmLock();
                     } else if (mStage == Stage.EnrollingFindSensor) {
                         updateStage(Stage.EnrollingStart);
                     } else if (mStage == Stage.EnrollingFinish) {
@@ -438,13 +446,20 @@
             }
         }
 
-        private void launchChooseLock() {
+        private void launchChooseOrConfirmLock() {
             Intent intent = new Intent();
-            intent.setClassName("com.android.settings", ChooseLockGeneric.class.getName());
-            intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
-                    DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
-            intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
-            startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
+            long challenge = mFingerprintManager.preEnroll();
+            ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this);
+            if (!helper.launchConfirmationActivity(CONFIRM_REQUEST, null,
+                        null, null, challenge)) {
+                intent.setClassName("com.android.settings", ChooseLockGeneric.class.getName());
+                intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
+                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+                intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
+                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
+                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+                startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
+            }
         }
     }
 }
diff --git a/src/com/android/settings/FingerprintSettings.java b/src/com/android/settings/FingerprintSettings.java
index b4d6a4f..78e5ec6c 100644
--- a/src/com/android/settings/FingerprintSettings.java
+++ b/src/com/android/settings/FingerprintSettings.java
@@ -19,6 +19,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -50,6 +51,16 @@
  * Settings screen for fingerprints
  */
 public class FingerprintSettings extends SettingsActivity {
+    /**
+     * Used by the FP settings wizard to indicate the wizard is
+     * finished, and each activity in the wizard should finish.
+     * <p>
+     * Previously, each activity in the wizard would finish itself after
+     * starting the next activity. However, this leads to broken 'Back'
+     * behavior. So, now an activity does not finish itself until it gets this
+     * result.
+     */
+    static final int RESULT_FINISHED = RESULT_FIRST_USER;
 
     @Override
     public Intent getIntent() {
@@ -85,6 +96,9 @@
         private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000;
         private static final int MSG_HIGHLIGHT_FINGERPRINT_ITEM = 1001;
 
+        private static final int CONFIRM_REQUEST = 101;
+        private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
+
         private static final int ADD_FINGERPRINT_REQUEST = 10;
 
         private static final boolean ENABLE_USAGE_CATEGORY = false;
@@ -95,6 +109,7 @@
         private PreferenceGroup mManageCategory;
         private CancellationSignal mFingerprintCancel;
         private int mMaxFingerprintAttempts;
+        private byte[] mToken;
 
         private AuthenticationCallback mAuthCallback = new AuthenticationCallback() {
             @Override
@@ -173,8 +188,18 @@
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
+            if (savedInstanceState != null) {
+                mToken = savedInstanceState.getByteArray(
+                        ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
+            }
+
             mFingerprintManager = (FingerprintManager) getActivity().getSystemService(
                     Context.FINGERPRINT_SERVICE);
+
+            // Need to authenticate a session token if none
+            if (mToken == null) {
+                launchChooseOrConfirmLock();
+            }
         }
 
         protected void removeFingerprintPreference(int fingerprintId) {
@@ -268,6 +293,7 @@
             // Make sure we reload the preference hierarchy since fingerprints may be added,
             // deleted or renamed.
             createPreferenceHierarchy();
+
             retryFingerprint(true);
         }
 
@@ -278,6 +304,12 @@
         }
 
         @Override
+        public void onSaveInstanceState(final Bundle outState) {
+            outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
+                    mToken);
+        }
+
+        @Override
         public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
             final String key = pref.getKey();
             if (KEY_FINGERPRINT_ADD.equals(key)) {
@@ -343,6 +375,43 @@
         protected int getHelpResource() {
             return R.string.help_url_security;
         }
+
+        @Override
+        public void onActivityResult(int requestCode, int resultCode, Intent data) {
+            super.onActivityResult(requestCode, resultCode, data);
+            if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST
+                    || requestCode == CONFIRM_REQUEST) {
+                if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) {
+                    // The lock pin/pattern/password was set. Start enrolling!
+                    if (data != null) {
+                        mToken = data.getByteArrayExtra(
+                                ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
+                    }
+                }
+            }
+
+            if (mToken == null) {
+                // Didn't get an authentication, finishing
+                getActivity().finish();
+            }
+        }
+
+        private void launchChooseOrConfirmLock() {
+            Intent intent = new Intent();
+            long challenge = mFingerprintManager.preEnroll();
+            ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this);
+            // TODO: update text or remove params from method
+            if (!helper.launchConfirmationActivity(CONFIRM_REQUEST, null,
+                        null, null, challenge)) {
+                intent.setClassName("com.android.settings", ChooseLockGeneric.class.getName());
+                intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
+                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+                intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
+                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true);
+                intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+                startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
+            }
+        }
     }
 
     public static class FingerprintPreference extends Preference {