AuthenticationClient.java revision d197486f26c223566c75fb2df93c152b1fc3172b
1/** 2 * Copyright (C) 2016 The Android Open Source Project 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 14 * limitations under the License. 15 */ 16 17package com.android.server.fingerprint; 18 19import com.android.internal.logging.MetricsLogger; 20import com.android.internal.logging.MetricsProto.MetricsEvent; 21 22import android.content.Context; 23import android.hardware.fingerprint.Fingerprint; 24import android.hardware.fingerprint.FingerprintManager; 25import android.hardware.fingerprint.IFingerprintDaemon; 26import android.hardware.fingerprint.IFingerprintServiceReceiver; 27import android.os.IBinder; 28import android.os.RemoteException; 29import android.system.ErrnoException; 30import android.util.Slog; 31 32/** 33 * A class to keep track of the authentication state for a given client. 34 */ 35public abstract class AuthenticationClient extends ClientMonitor { 36 private long mOpId; 37 38 public abstract boolean handleFailedAttempt(); 39 public abstract void resetFailedAttempts(); 40 41 public AuthenticationClient(Context context, long halDeviceId, IBinder token, 42 IFingerprintServiceReceiver receiver, int callingUserId, int groupId, long opId, 43 boolean restricted, String owner) { 44 super(context, halDeviceId, token, receiver, callingUserId, groupId, restricted, owner); 45 mOpId = opId; 46 } 47 48 @Override 49 public boolean onAuthenticated(int fingerId, int groupId) { 50 boolean result = false; 51 boolean authenticated = fingerId != 0; 52 53 IFingerprintServiceReceiver receiver = getReceiver(); 54 if (receiver != null) { 55 try { 56 MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_AUTH, 57 authenticated); 58 if (!authenticated) { 59 receiver.onAuthenticationFailed(getHalDeviceId()); 60 } else { 61 if (DEBUG) { 62 Slog.v(TAG, "onAuthenticated(owner=" + getOwnerString() 63 + ", id=" + fingerId + ", gp=" + groupId + ")"); 64 } 65 Fingerprint fp = !getIsRestricted() 66 ? new Fingerprint("" /* TODO */, groupId, fingerId, getHalDeviceId()) 67 : null; 68 receiver.onAuthenticationSucceeded(getHalDeviceId(), fp); 69 } 70 } catch (RemoteException e) { 71 Slog.w(TAG, "Failed to notify Authenticated:", e); 72 result = true; // client failed 73 } 74 } else { 75 result = true; // client not listening 76 } 77 if (!authenticated) { 78 if (receiver != null) { 79 FingerprintUtils.vibrateFingerprintError(getContext()); 80 } 81 // allow system-defined limit of number of attempts before giving up 82 boolean inLockoutMode = handleFailedAttempt(); 83 // send lockout event in case driver doesn't enforce it. 84 if (inLockoutMode) { 85 try { 86 Slog.w(TAG, "Forcing lockout (fp driver code should do this!)"); 87 receiver.onError(getHalDeviceId(), 88 FingerprintManager.FINGERPRINT_ERROR_LOCKOUT); 89 } catch (RemoteException e) { 90 Slog.w(TAG, "Failed to notify lockout:", e); 91 } 92 } 93 result |= inLockoutMode; 94 } else { 95 if (receiver != null) { 96 FingerprintUtils.vibrateFingerprintSuccess(getContext()); 97 } 98 result |= true; // we have a valid fingerprint, done 99 resetFailedAttempts(); 100 } 101 return result; 102 } 103 104 /** 105 * Start authentication 106 */ 107 @Override 108 public int start() { 109 IFingerprintDaemon daemon = getFingerprintDaemon(); 110 if (daemon == null) { 111 Slog.w(TAG, "start authentication: no fingeprintd!"); 112 return ERROR_ESRCH; 113 } 114 try { 115 final int result = daemon.authenticate(mOpId, getGroupId()); 116 if (result != 0) { 117 Slog.w(TAG, "startAuthentication failed, result=" + result); 118 onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); 119 return result; 120 } 121 if (DEBUG) Slog.w(TAG, "client " + getOwnerString() + " is authenticating..."); 122 } catch (RemoteException e) { 123 Slog.e(TAG, "startAuthentication failed", e); 124 return ERROR_ESRCH; 125 } 126 return 0; // success 127 } 128 129 @Override 130 public int stop(boolean initiatedByClient) { 131 IFingerprintDaemon daemon = getFingerprintDaemon(); 132 if (daemon == null) { 133 Slog.w(TAG, "stopAuthentication: no fingeprintd!"); 134 return ERROR_ESRCH; 135 } 136 try { 137 final int result = daemon.cancelAuthentication(); 138 if (result != 0) { 139 Slog.w(TAG, "stopAuthentication failed, result=" + result); 140 return result; 141 } 142 if (DEBUG) Slog.w(TAG, "client " + getOwnerString() + " is no longer authenticating"); 143 } catch (RemoteException e) { 144 Slog.e(TAG, "stopAuthentication failed", e); 145 return ERROR_ESRCH; 146 } 147 return 0; // success 148 } 149 150 @Override 151 public boolean onEnrollResult(int fingerId, int groupId, int rem) { 152 if (DEBUG) Slog.w(TAG, "onEnrollResult() called for authenticate!"); 153 return true; // Invalid for Authenticate 154 } 155 156 @Override 157 public boolean onRemoved(int fingerId, int groupId) { 158 if (DEBUG) Slog.w(TAG, "onRemoved() called for authenticate!"); 159 return true; // Invalid for Authenticate 160 } 161 162 @Override 163 public boolean onEnumerationResult(int fingerId, int groupId) { 164 if (DEBUG) Slog.w(TAG, "onEnumerationResult() called for authenticate!"); 165 return true; // Invalid for Authenticate 166 } 167} 168