Auto-advance when fingerprint touch is detected.

Because there's no way to listen to the fingerprint
sensor without enrolling or authenticating, we start a short
enrollment session to detect first press of a finger to
advance to the next stage.

Change-Id: If242ade8729f34464171cda54deab0922ad85b1d
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
index fe0bb63..322a92c 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
@@ -50,7 +50,7 @@
 public class FingerprintEnrollEnrolling extends FingerprintEnrollBase
         implements FingerprintEnrollSidecar.Listener {
 
-    private static final String TAG_SIDECAR = "sidecar";
+    static final String TAG_SIDECAR = "sidecar";
 
     private static final int PROGRESS_BAR_MAX = 10000;
     private static final int FINISH_DELAY = 250;
@@ -170,6 +170,8 @@
         mSidecar.setListener(null);
         stopIconAnimation();
         if (!isChangingConfigurations()) {
+            mSidecar.cancelEnrollment();
+            getFragmentManager().beginTransaction().remove(mSidecar).commit();
             finish();
         }
     }
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
index b246bdf..c97ffe7 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
@@ -23,6 +23,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.settings.ChooseLockSettingsHelper;
 import com.android.settings.R;
+import com.android.settings.fingerprint.FingerprintEnrollSidecar.Listener;
 
 /**
  * Activity explaining the fingerprint sensor location for fingerprint enrollment.
@@ -35,16 +36,23 @@
 
     private FingerprintFindSensorAnimation mAnimation;
     private boolean mLaunchedConfirmLock;
+    private FingerprintEnrollSidecar mSidecar;
+    private boolean mNextClicked;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fingerprint_enroll_find_sensor);
         setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
-        mLaunchedConfirmLock = savedInstanceState != null && savedInstanceState.getBoolean(
-                EXTRA_KEY_LAUNCHED_CONFIRM);
+        if (savedInstanceState != null) {
+            mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM);
+            mToken = savedInstanceState.getByteArray(
+                    ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
+        }
         if (mToken == null && !mLaunchedConfirmLock) {
             launchConfirmLock();
+        } else if (mToken != null) {
+            startLookingForFingerprint(); // already confirmed, so start looking for fingerprint
         }
         mAnimation = (FingerprintFindSensorAnimation) findViewById(
                 R.id.fingerprint_sensor_location_animation);
@@ -56,6 +64,37 @@
         mAnimation.startAnimation();
     }
 
+    private void startLookingForFingerprint() {
+        mSidecar = (FingerprintEnrollSidecar) getFragmentManager().findFragmentByTag(
+                FingerprintEnrollEnrolling.TAG_SIDECAR);
+        if (mSidecar == null) {
+            mSidecar = new FingerprintEnrollSidecar();
+            getFragmentManager().beginTransaction()
+                    .add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR).commit();
+        }
+        mSidecar.setListener(new Listener() {
+            @Override
+            public void onEnrollmentProgressChange(int steps, int remaining) {
+                mNextClicked = true;
+                if (!mSidecar.cancelEnrollment()) {
+                    proceedToEnrolling();
+                }
+            }
+
+            @Override
+            public void onEnrollmentHelp(CharSequence helpString) {
+            }
+
+            @Override
+            public void onEnrollmentError(int errMsgId, CharSequence errString) {
+                if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
+                    mNextClicked = false;
+                    proceedToEnrolling();
+                }
+            }
+        });
+    }
+
     @Override
     protected void onStop() {
         super.onStop();
@@ -66,10 +105,20 @@
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putBoolean(EXTRA_KEY_LAUNCHED_CONFIRM, mLaunchedConfirmLock);
+        outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
     }
 
     @Override
     protected void onNextButtonClick() {
+        mNextClicked = true;
+        if (mSidecar == null || (mSidecar != null && !mSidecar.cancelEnrollment())) {
+            proceedToEnrolling();
+        }
+    }
+
+    private void proceedToEnrolling() {
+        getFragmentManager().beginTransaction().remove(mSidecar).commit();
+        mSidecar = null;
         startActivityForResult(getEnrollingIntent(), ENROLLING);
     }
 
@@ -79,6 +128,8 @@
             if (resultCode == RESULT_OK) {
                 mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
                 overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out);
+                getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
+                startLookingForFingerprint();
             } else {
                 finish();
             }
@@ -99,6 +150,9 @@
                         com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
                 if (enrolled >= max) {
                     finish();
+                } else {
+                    // We came back from enrolling but it wasn't completed, start again.
+                    startLookingForFingerprint();
                 }
             }
         } else {
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java b/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java
index da055b0..72c06db 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java
@@ -79,13 +79,15 @@
         mEnrolling = true;
     }
 
-    private void cancelEnrollment() {
+    boolean cancelEnrollment() {
         mHandler.removeCallbacks(mTimeoutRunnable);
         if (mEnrolling) {
             mEnrollmentCancel.cancel();
             mEnrolling = false;
             mEnrollmentSteps = -1;
+            return true;
         }
+        return false;
     }
 
     public void setListener(Listener listener) {
@@ -131,6 +133,7 @@
             if (mListener != null) {
                 mListener.onEnrollmentError(errMsgId, errString);
             }
+            mEnrolling = false;
         }
     };
 
@@ -151,4 +154,8 @@
         void onEnrollmentError(int errMsgId, CharSequence errString);
         void onEnrollmentProgressChange(int steps, int remaining);
     }
+
+    public boolean isEnrolling() {
+        return mEnrolling;
+    }
 }