Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 The Android Open Source Project |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 14 | * limitations under the License |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 15 | */ |
| 16 | |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 17 | package com.android.server.biometrics.common; |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 18 | |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 19 | import android.content.Context; |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 20 | import android.hardware.biometrics.BiometricAuthenticator; |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 21 | import android.hardware.biometrics.BiometricConstants; |
Vishwath Mohan | ecf00ce | 2018-04-05 10:28:24 -0700 | [diff] [blame] | 22 | import android.hardware.biometrics.BiometricPrompt; |
| 23 | import android.hardware.biometrics.IBiometricPromptReceiver; |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 24 | import android.hardware.fingerprint.Fingerprint; |
| 25 | import android.hardware.fingerprint.FingerprintManager; |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 26 | import android.os.Bundle; |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 27 | import android.os.IBinder; |
| 28 | import android.os.RemoteException; |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 29 | import android.util.Slog; |
| 30 | |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 31 | import com.android.internal.statusbar.IStatusBarService; |
| 32 | |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 33 | /** |
| 34 | * A class to keep track of the authentication state for a given client. |
| 35 | */ |
| 36 | public abstract class AuthenticationClient extends ClientMonitor { |
| 37 | private long mOpId; |
| 38 | |
Kevin Chyn | df9d33e | 2017-05-03 21:40:12 -0700 | [diff] [blame] | 39 | public abstract int handleFailedAttempt(); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 40 | public abstract void resetFailedAttempts(); |
Kevin Chyn | df9d33e | 2017-05-03 21:40:12 -0700 | [diff] [blame] | 41 | |
| 42 | public static final int LOCKOUT_NONE = 0; |
| 43 | public static final int LOCKOUT_TIMED = 1; |
| 44 | public static final int LOCKOUT_PERMANENT = 2; |
| 45 | |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 46 | // Callback mechanism received from the client |
Vishwath Mohan | ecf00ce | 2018-04-05 10:28:24 -0700 | [diff] [blame] | 47 | // (BiometricPrompt -> FingerprintManager -> FingerprintService -> AuthenticationClient) |
| 48 | private IBiometricPromptReceiver mDialogReceiverFromClient; |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 49 | private Bundle mBundle; |
| 50 | private IStatusBarService mStatusBarService; |
| 51 | private boolean mInLockout; |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 52 | // TODO: BiometricManager, after other biometric modalities are introduced. |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 53 | private final FingerprintManager mFingerprintManager; |
| 54 | protected boolean mDialogDismissed; |
| 55 | |
Kevin Chyn | dba919a | 2018-03-16 14:35:10 -0700 | [diff] [blame] | 56 | // Receives events from SystemUI and handles them before forwarding them to FingerprintDialog |
Vishwath Mohan | ecf00ce | 2018-04-05 10:28:24 -0700 | [diff] [blame] | 57 | protected IBiometricPromptReceiver mDialogReceiver = new IBiometricPromptReceiver.Stub() { |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 58 | @Override // binder call |
| 59 | public void onDialogDismissed(int reason) { |
| 60 | if (mBundle != null && mDialogReceiverFromClient != null) { |
| 61 | try { |
| 62 | mDialogReceiverFromClient.onDialogDismissed(reason); |
Vishwath Mohan | ecf00ce | 2018-04-05 10:28:24 -0700 | [diff] [blame] | 63 | if (reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL) { |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 64 | onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED, |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 65 | 0 /* vendorCode */); |
| 66 | } |
| 67 | mDialogDismissed = true; |
| 68 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 69 | Slog.e(getLogTag(), "Unable to notify dialog dismissed", e); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 70 | } |
| 71 | stop(true /* initiatedByClient */); |
| 72 | } |
| 73 | } |
| 74 | }; |
| 75 | |
Kevin Chyn | d4f43c2 | 2018-03-12 17:33:13 -0700 | [diff] [blame] | 76 | /** |
| 77 | * This method is called when authentication starts. |
| 78 | */ |
| 79 | public abstract void onStart(); |
| 80 | |
| 81 | /** |
| 82 | * This method is called when a fingerprint is authenticated or authentication is stopped |
| 83 | * (cancelled by the user, or an error such as lockout has occurred). |
| 84 | */ |
| 85 | public abstract void onStop(); |
| 86 | |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 87 | public AuthenticationClient(Context context, Metrics metrics, |
| 88 | BiometricService.DaemonWrapper daemon, long halDeviceId, IBinder token, |
| 89 | BiometricService.ServiceListener listener, int targetUserId, int groupId, long opId, |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 90 | boolean restricted, String owner, Bundle bundle, |
Vishwath Mohan | ecf00ce | 2018-04-05 10:28:24 -0700 | [diff] [blame] | 91 | IBiometricPromptReceiver dialogReceiver, IStatusBarService statusBarService) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 92 | super(context, metrics, daemon, halDeviceId, token, listener, targetUserId, groupId, |
| 93 | restricted, owner); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 94 | mOpId = opId; |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 95 | mBundle = bundle; |
| 96 | mDialogReceiverFromClient = dialogReceiver; |
| 97 | mStatusBarService = statusBarService; |
| 98 | mFingerprintManager = (FingerprintManager) getContext() |
| 99 | .getSystemService(Context.FINGERPRINT_SERVICE); |
| 100 | } |
| 101 | |
| 102 | @Override |
| 103 | public void binderDied() { |
| 104 | super.binderDied(); |
| 105 | // When the binder dies, we should stop the client. This probably belongs in |
| 106 | // ClientMonitor's binderDied(), but testing all the cases would be tricky. |
| 107 | // AuthenticationClient is the most user-visible case. |
| 108 | stop(false /* initiatedByClient */); |
| 109 | } |
| 110 | |
| 111 | @Override |
| 112 | public boolean onAcquired(int acquiredInfo, int vendorCode) { |
| 113 | // If the dialog is showing, the client doesn't need to receive onAcquired messages. |
| 114 | if (mBundle != null) { |
| 115 | try { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 116 | if (acquiredInfo != BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) { |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 117 | mStatusBarService.onFingerprintHelp( |
| 118 | mFingerprintManager.getAcquiredString(acquiredInfo, vendorCode)); |
| 119 | } |
| 120 | return false; // acquisition continues |
| 121 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 122 | Slog.e(getLogTag(), "Remote exception when sending acquired message", e); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 123 | return true; // client failed |
| 124 | } finally { |
| 125 | // Good scans will keep the device awake |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 126 | if (acquiredInfo == BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) { |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 127 | notifyUserActivity(); |
| 128 | } |
| 129 | } |
| 130 | } else { |
| 131 | return super.onAcquired(acquiredInfo, vendorCode); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | @Override |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 136 | public boolean onError(long deviceId, int error, int vendorCode) { |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 137 | if (mDialogDismissed) { |
| 138 | // If user cancels authentication, the application has already received the |
| 139 | // FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED message from onDialogDismissed() |
| 140 | // and stopped the fingerprint hardware, so there is no need to send a |
| 141 | // FingerprintManager.FINGERPRINT_ERROR_CANCELED message. |
| 142 | return true; |
| 143 | } |
| 144 | if (mBundle != null) { |
| 145 | try { |
| 146 | mStatusBarService.onFingerprintError( |
| 147 | mFingerprintManager.getErrorString(error, vendorCode)); |
| 148 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 149 | Slog.e(getLogTag(), "Remote exception when sending error", e); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 150 | } |
| 151 | } |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 152 | return super.onError(deviceId, error, vendorCode); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | @Override |
| 156 | public boolean onAuthenticated(int fingerId, int groupId) { |
| 157 | boolean result = false; |
| 158 | boolean authenticated = fingerId != 0; |
| 159 | |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 160 | // If the fingerprint dialog is showing, notify authentication succeeded |
| 161 | if (mBundle != null) { |
| 162 | try { |
| 163 | if (authenticated) { |
| 164 | mStatusBarService.onFingerprintAuthenticated(); |
| 165 | } else { |
| 166 | mStatusBarService.onFingerprintHelp(getContext().getResources().getString( |
| 167 | com.android.internal.R.string.fingerprint_not_recognized)); |
| 168 | } |
| 169 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 170 | Slog.e(getLogTag(), "Failed to notify Authenticated:", e); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 171 | } |
| 172 | } |
| 173 | |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 174 | final BiometricService.ServiceListener listener = getListener(); |
| 175 | if (listener != null) { |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 176 | try { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 177 | mMetricsLogger.action(mMetrics.actionBiometricAuth(), authenticated); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 178 | if (!authenticated) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 179 | listener.onAuthenticationFailed(getHalDeviceId()); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 180 | } else { |
| 181 | if (DEBUG) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 182 | Slog.v(getLogTag(), "onAuthenticated(owner=" + getOwnerString() |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 183 | + ", id=" + fingerId + ", gp=" + groupId + ")"); |
| 184 | } |
| 185 | Fingerprint fp = !getIsRestricted() |
| 186 | ? new Fingerprint("" /* TODO */, groupId, fingerId, getHalDeviceId()) |
| 187 | : null; |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 188 | listener.onAuthenticationSucceeded(getHalDeviceId(), fp, getTargetUserId()); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 189 | } |
| 190 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 191 | Slog.w(getLogTag(), "Failed to notify Authenticated:", e); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 192 | result = true; // client failed |
| 193 | } |
| 194 | } else { |
| 195 | result = true; // client not listening |
| 196 | } |
Jim Miller | d197486 | 2016-05-03 18:35:18 -0700 | [diff] [blame] | 197 | if (!authenticated) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 198 | if (listener != null) { |
Michael Wright | 6726fd5 | 2017-06-27 00:41:45 +0100 | [diff] [blame] | 199 | vibrateError(); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 200 | } |
| 201 | // allow system-defined limit of number of attempts before giving up |
Kevin Chyn | df9d33e | 2017-05-03 21:40:12 -0700 | [diff] [blame] | 202 | int lockoutMode = handleFailedAttempt(); |
| 203 | if (lockoutMode != LOCKOUT_NONE) { |
Jim Miller | d197486 | 2016-05-03 18:35:18 -0700 | [diff] [blame] | 204 | try { |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 205 | mInLockout = true; |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 206 | Slog.w(getLogTag(), "Forcing lockout (fp driver code should do this!), mode(" + |
Kevin Chyn | df9d33e | 2017-05-03 21:40:12 -0700 | [diff] [blame] | 207 | lockoutMode + ")"); |
| 208 | stop(false); |
| 209 | int errorCode = lockoutMode == LOCKOUT_TIMED ? |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 210 | BiometricConstants.BIOMETRIC_ERROR_LOCKOUT : |
| 211 | BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT; |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 212 | |
| 213 | // TODO: if the dialog is showing, this error should be delayed. On a similar |
| 214 | // note, AuthenticationClient should override onError and delay all other errors |
| 215 | // as well, if the dialog is showing |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 216 | listener.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 217 | |
| 218 | // Send the lockout message to the system dialog |
| 219 | if (mBundle != null) { |
| 220 | mStatusBarService.onFingerprintError( |
| 221 | mFingerprintManager.getErrorString(errorCode, 0 /* vendorCode */)); |
| 222 | } |
Jim Miller | d197486 | 2016-05-03 18:35:18 -0700 | [diff] [blame] | 223 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 224 | Slog.w(getLogTag(), "Failed to notify lockout:", e); |
Jim Miller | d197486 | 2016-05-03 18:35:18 -0700 | [diff] [blame] | 225 | } |
| 226 | } |
Kevin Chyn | df9d33e | 2017-05-03 21:40:12 -0700 | [diff] [blame] | 227 | result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 228 | } else { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 229 | if (listener != null) { |
Michael Wright | 6726fd5 | 2017-06-27 00:41:45 +0100 | [diff] [blame] | 230 | vibrateSuccess(); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 231 | } |
| 232 | result |= true; // we have a valid fingerprint, done |
| 233 | resetFailedAttempts(); |
Kevin Chyn | d4f43c2 | 2018-03-12 17:33:13 -0700 | [diff] [blame] | 234 | onStop(); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 235 | } |
| 236 | return result; |
| 237 | } |
| 238 | |
| 239 | /** |
| 240 | * Start authentication |
| 241 | */ |
| 242 | @Override |
| 243 | public int start() { |
Kevin Chyn | d4f43c2 | 2018-03-12 17:33:13 -0700 | [diff] [blame] | 244 | onStart(); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 245 | try { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 246 | final int result = getDaemonWrapper().authenticate(mOpId, getGroupId()); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 247 | if (result != 0) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 248 | Slog.w(getLogTag(), "startAuthentication failed, result=" + result); |
| 249 | mMetricsLogger.histogram(mMetrics.tagAuthStartError(), result); |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 250 | onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE, |
| 251 | 0 /* vendorCode */); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 252 | return result; |
| 253 | } |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 254 | if (DEBUG) Slog.w(getLogTag(), "client " + getOwnerString() + " is authenticating..."); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 255 | |
| 256 | // If authenticating with system dialog, show the dialog |
| 257 | if (mBundle != null) { |
| 258 | try { |
| 259 | mStatusBarService.showFingerprintDialog(mBundle, mDialogReceiver); |
| 260 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 261 | Slog.e(getLogTag(), "Unable to show fingerprint dialog", e); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 262 | } |
| 263 | } |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 264 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 265 | Slog.e(getLogTag(), "startAuthentication failed", e); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 266 | return ERROR_ESRCH; |
| 267 | } |
| 268 | return 0; // success |
| 269 | } |
| 270 | |
| 271 | @Override |
| 272 | public int stop(boolean initiatedByClient) { |
Kevin Chyn | 625a014 | 2017-04-10 14:53:59 -0700 | [diff] [blame] | 273 | if (mAlreadyCancelled) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 274 | Slog.w(getLogTag(), "stopAuthentication: already cancelled!"); |
Kevin Chyn | 625a014 | 2017-04-10 14:53:59 -0700 | [diff] [blame] | 275 | return 0; |
| 276 | } |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 277 | |
Kevin Chyn | d4f43c2 | 2018-03-12 17:33:13 -0700 | [diff] [blame] | 278 | onStop(); |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 279 | |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 280 | try { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 281 | final int result = getDaemonWrapper().cancel(); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 282 | if (result != 0) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 283 | Slog.w(getLogTag(), "stopAuthentication failed, result=" + result); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 284 | return result; |
| 285 | } |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 286 | if (DEBUG) Slog.w(getLogTag(), "client " + getOwnerString() + " is no longer authenticating"); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 287 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 288 | Slog.e(getLogTag(), "stopAuthentication failed", e); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 289 | return ERROR_ESRCH; |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 290 | } finally { |
| 291 | // If the user already cancelled authentication (via some interaction with the |
| 292 | // dialog, we do not need to hide it since it's already hidden. |
| 293 | // If the device is in lockout, don't hide the dialog - it will automatically hide |
Vishwath Mohan | ecf00ce | 2018-04-05 10:28:24 -0700 | [diff] [blame] | 294 | // after BiometricPrompt.HIDE_DIALOG_DELAY |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 295 | if (mBundle != null && !mDialogDismissed && !mInLockout) { |
| 296 | try { |
| 297 | mStatusBarService.hideFingerprintDialog(); |
| 298 | } catch (RemoteException e) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 299 | Slog.e(getLogTag(), "Unable to hide fingerprint dialog", e); |
Kevin Chyn | aae4a15 | 2018-01-18 11:48:09 -0800 | [diff] [blame] | 300 | } |
| 301 | } |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 302 | } |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 303 | |
Kevin Chyn | 625a014 | 2017-04-10 14:53:59 -0700 | [diff] [blame] | 304 | mAlreadyCancelled = true; |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 305 | return 0; // success |
| 306 | } |
| 307 | |
| 308 | @Override |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 309 | public boolean onEnrollResult(BiometricAuthenticator.Identifier identifier, |
| 310 | int remaining) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 311 | if (DEBUG) Slog.w(getLogTag(), "onEnrollResult() called for authenticate!"); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 312 | return true; // Invalid for Authenticate |
| 313 | } |
| 314 | |
| 315 | @Override |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 316 | public boolean onRemoved(BiometricAuthenticator.Identifier identifier, int remaining) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 317 | if (DEBUG) Slog.w(getLogTag(), "onRemoved() called for authenticate!"); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 318 | return true; // Invalid for Authenticate |
| 319 | } |
| 320 | |
| 321 | @Override |
Kevin Chyn | a56dff7 | 2018-06-19 18:41:12 -0700 | [diff] [blame^] | 322 | public boolean onEnumerationResult(BiometricAuthenticator.Identifier identifier, |
| 323 | int remaining) { |
Kevin Chyn | 037c4d5 | 2018-06-11 19:17:32 -0700 | [diff] [blame] | 324 | if (DEBUG) Slog.w(getLogTag(), "onEnumerationResult() called for authenticate!"); |
Jim Miller | cb2ce6f | 2016-04-13 20:28:18 -0700 | [diff] [blame] | 325 | return true; // Invalid for Authenticate |
| 326 | } |
| 327 | } |