diff --git a/src/com/android/settings/fingerprint/FingerprintAuthenticateSidecar.java b/src/com/android/settings/fingerprint/FingerprintAuthenticateSidecar.java new file mode 100644 index 00000000000..b419b722520 --- /dev/null +++ b/src/com/android/settings/fingerprint/FingerprintAuthenticateSidecar.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.settings.fingerprint; + +import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintManager.AuthenticationResult; +import android.os.CancellationSignal; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settings.core.InstrumentedPreferenceFragment; + +/** + * Sidecar fragment to handle the state around fingerprint authentication + */ +public class FingerprintAuthenticateSidecar extends InstrumentedPreferenceFragment { + + private static final String TAG = "FingerprintAuthenticateSidecar"; + + private FingerprintManager mFingerprintManager; + private Listener mListener; + private AuthenticationResult mAuthenticationResult; + private CancellationSignal mCancellationSignal; + private AuthenticationError mAuthenticationError; + + public interface Listener { + void onAuthenticationSucceeded(AuthenticationResult result); + void onAuthenticationFailed(); + void onAuthenticationError(int errMsgId, CharSequence errString); + void onAuthenticationHelp(int helpMsgId, CharSequence helpString); + } + + private class AuthenticationError { + int error; + CharSequence errorString; + + public AuthenticationError(int errMsgId, CharSequence errString) { + error = errMsgId; + errorString = errString; + } + } + + @Override + public int getMetricsCategory() { + return MetricsEvent.FINGERPRINT_AUTHENTICATE_SIDECAR; + } + + private FingerprintManager.AuthenticationCallback mAuthenticationCallback = + new FingerprintManager.AuthenticationCallback() { + @Override + public void onAuthenticationSucceeded(AuthenticationResult result) { + mCancellationSignal = null; + if (mListener != null) { + mListener.onAuthenticationSucceeded(result); + } else { + mAuthenticationResult = result; + mAuthenticationError = null; + } + } + + @Override + public void onAuthenticationFailed() { + if (mListener != null) { + mListener.onAuthenticationFailed(); + } + } + + @Override + public void onAuthenticationError(int errMsgId, CharSequence errString) { + mCancellationSignal = null; + if (mListener != null) { + mListener.onAuthenticationError(errMsgId, errString); + } else { + mAuthenticationError = new AuthenticationError(errMsgId, errString); + mAuthenticationResult = null; + } + } + + @Override + public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { + if (mListener != null) { + mListener.onAuthenticationHelp(helpMsgId, helpString); + } + } + }; + + public void setFingerprintManager(FingerprintManager fingerprintManager) { + mFingerprintManager = fingerprintManager; + } + + public void startAuthentication(int userId) { + mCancellationSignal = new CancellationSignal(); + mFingerprintManager.authenticate(null, mCancellationSignal, 0 /* flags */, + mAuthenticationCallback, null, userId); + } + + public void stopAuthentication() { + if (mCancellationSignal != null && !mCancellationSignal.isCanceled()) { + mCancellationSignal.cancel(); + } + mCancellationSignal = null; + } + + public void setListener(Listener listener) { + if (mListener == null && listener != null) { + if (mAuthenticationResult != null) { + mListener.onAuthenticationSucceeded(mAuthenticationResult); + mAuthenticationResult = null; + } + if (mAuthenticationError != null && + mAuthenticationError.error != FingerprintManager.FINGERPRINT_ERROR_CANCELED) { + mListener.onAuthenticationError(mAuthenticationError.error, + mAuthenticationError.errorString); + mAuthenticationError = null; + } + } + mListener = listener; + } +} \ No newline at end of file diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java index 6a8a1fd57f0..fb09f7ab0c4 100644 --- a/src/com/android/settings/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/fingerprint/FingerprintSettings.java @@ -29,8 +29,6 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback; -import android.hardware.fingerprint.FingerprintManager.AuthenticationResult; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Handler; @@ -152,41 +150,44 @@ public class FingerprintSettings extends SubSettings { protected static final boolean DEBUG = true; private FingerprintManager mFingerprintManager; - private CancellationSignal mFingerprintCancel; private boolean mInFingerprintLockout; private byte[] mToken; private boolean mLaunchedConfirm; private Drawable mHighlightDrawable; private int mUserId; + private static final String TAG_AUTHENTICATE_SIDECAR = "authenticate_sidecar"; private static final String TAG_REMOVAL_SIDECAR = "removal_sidecar"; + private FingerprintAuthenticateSidecar mAuthenticateSidecar; private FingerprintRemoveSidecar mRemovalSidecar; private HashMap mFingerprintsRenaming; - private AuthenticationCallback mAuthCallback = new AuthenticationCallback() { - @Override - public void onAuthenticationSucceeded(AuthenticationResult result) { - int fingerId = result.getFingerprint().getFingerId(); - mHandler.obtainMessage(MSG_FINGER_AUTH_SUCCESS, fingerId, 0).sendToTarget(); - } + FingerprintAuthenticateSidecar.Listener mAuthenticateListener = + new FingerprintAuthenticateSidecar.Listener() { + @Override + public void onAuthenticationSucceeded( + FingerprintManager.AuthenticationResult result) { + int fingerId = result.getFingerprint().getFingerId(); + mHandler.obtainMessage(MSG_FINGER_AUTH_SUCCESS, fingerId, 0).sendToTarget(); + } - @Override - public void onAuthenticationFailed() { - mHandler.obtainMessage(MSG_FINGER_AUTH_FAIL).sendToTarget(); - } + @Override + public void onAuthenticationFailed() { + mHandler.obtainMessage(MSG_FINGER_AUTH_FAIL).sendToTarget(); + } - @Override - public void onAuthenticationError(int errMsgId, CharSequence errString) { - mHandler.obtainMessage(MSG_FINGER_AUTH_ERROR, errMsgId, 0, errString) - .sendToTarget(); - } + @Override + public void onAuthenticationError(int errMsgId, CharSequence errString) { + mHandler.obtainMessage(MSG_FINGER_AUTH_ERROR, errMsgId, 0, errString) + .sendToTarget(); + } - @Override - public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { - mHandler.obtainMessage(MSG_FINGER_AUTH_HELP, helpMsgId, 0, helpString) - .sendToTarget(); - } - }; + @Override + public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { + mHandler.obtainMessage(MSG_FINGER_AUTH_HELP, helpMsgId, 0, helpString) + .sendToTarget(); + } + }; FingerprintRemoveSidecar.Listener mRemovalListener = new FingerprintRemoveSidecar.Listener() { @@ -223,7 +224,6 @@ public class FingerprintSettings extends SubSettings { retryFingerprint(); break; case MSG_FINGER_AUTH_SUCCESS: - mFingerprintCancel = null; highlightFingerprintItem(msg.arg1); retryFingerprint(); break; @@ -241,18 +241,10 @@ public class FingerprintSettings extends SubSettings { } }; - private void stopFingerprint() { - if (mFingerprintCancel != null && !mFingerprintCancel.isCanceled()) { - mFingerprintCancel.cancel(); - } - mFingerprintCancel = null; - } - /** * @param errMsgId */ protected void handleError(int errMsgId, CharSequence msg) { - mFingerprintCancel = null; switch (errMsgId) { case FingerprintManager.FINGERPRINT_ERROR_CANCELED: return; // Only happens if we get preempted by another activity. Ignored. @@ -290,9 +282,8 @@ public class FingerprintSettings extends SubSettings { return; } if (!mInFingerprintLockout) { - mFingerprintCancel = new CancellationSignal(); - mFingerprintManager.authenticate(null, mFingerprintCancel, 0 /* flags */, - mAuthCallback, null, mUserId); + mAuthenticateSidecar.startAuthentication(mUserId); + mAuthenticateSidecar.setListener(mAuthenticateListener); } } @@ -308,6 +299,15 @@ public class FingerprintSettings extends SubSettings { Activity activity = getActivity(); mFingerprintManager = Utils.getFingerprintManagerOrNull(activity); + mAuthenticateSidecar = (FingerprintAuthenticateSidecar) + getFragmentManager().findFragmentByTag(TAG_AUTHENTICATE_SIDECAR); + if (mAuthenticateSidecar == null) { + mAuthenticateSidecar = new FingerprintAuthenticateSidecar(); + getFragmentManager().beginTransaction() + .add(mAuthenticateSidecar, TAG_AUTHENTICATE_SIDECAR).commit(); + } + mAuthenticateSidecar.setFingerprintManager(mFingerprintManager); + mRemovalSidecar = (FingerprintRemoveSidecar) getFragmentManager().findFragmentByTag(TAG_REMOVAL_SIDECAR); if (mRemovalSidecar == null) { @@ -454,10 +454,13 @@ public class FingerprintSettings extends SubSettings { @Override public void onPause() { super.onPause(); - stopFingerprint(); if (mRemovalSidecar != null) { mRemovalSidecar.setListener(null); } + if (mAuthenticateSidecar != null) { + mAuthenticateSidecar.setListener(null); + mAuthenticateSidecar.stopAuthentication(); + } } @Override