1959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He/* 2a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * Copyright (C) 2014 The Android Open Source Project 3a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 4a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 5a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * you may not use this file except in compliance with the License. 6a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * You may obtain a copy of the License at 7a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 8a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * http://www.apache.org/licenses/LICENSE-2.0 9a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 10a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * Unless required by applicable law or agreed to in writing, software 11a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 12a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * See the License for the specific language governing permissions and 14a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * limitations under the License. 15a7596147b43940cad3f76c53ed154ef088b9269bJim Miller */ 16a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 17a7596147b43940cad3f76c53ed154ef088b9269bJim Millerpackage com.android.server.fingerprint; 18a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 19959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport static android.Manifest.permission.INTERACT_ACROSS_USERS; 20959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport static android.Manifest.permission.MANAGE_FINGERPRINT; 21959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT; 22cf87df15310611ae4e5229b19c5a4942e54185b5Vishwath Mohanimport static android.Manifest.permission.USE_BIOMETRIC; 23959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport static android.Manifest.permission.USE_FINGERPRINT; 243121760e70fb6a1b8de0274c724170f7e87b7e5bSvet Ganovimport static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; 25959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He 2680db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiyimport android.app.ActivityManager; 27975f145c018de9affffee5e89d94ce0ed78ad9dfJim Millerimport android.app.ActivityManager.RunningAppProcessInfo; 285e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggiimport android.app.AlarmManager; 294af76a51d5082c740609563e07cf35f30bc2224eSvetoslavimport android.app.AppOpsManager; 3009da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chynimport android.app.IActivityManager; 315e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggiimport android.app.PendingIntent; 326005b3f87b063ee7ab7e8877a6a8c90b480f3341Fyodor Kupolovimport android.app.SynchronousUserSwitchObserver; 3309da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chynimport android.app.TaskStackListener; 345e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggiimport android.content.BroadcastReceiver; 3529b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles Heimport android.content.ComponentName; 36a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.content.Context; 375e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggiimport android.content.Intent; 385e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggiimport android.content.IntentFilter; 39f501b58de8f467a80fef49c704555781bc61ea6fJim Millerimport android.content.pm.PackageManager; 40cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Millerimport android.content.pm.UserInfo; 41ecf00cedb64d2e7b9082d540d49972fe391760adVishwath Mohanimport android.hardware.biometrics.IBiometricPromptReceiver; 42959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; 43959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback; 44959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.hardware.fingerprint.Fingerprint; 45959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.hardware.fingerprint.FingerprintManager; 4627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport android.hardware.fingerprint.IFingerprintClientActiveCallback; 47959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.hardware.fingerprint.IFingerprintService; 483a464785088e7fd206666f640912729533948ce8Jorim Jaggiimport android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback; 49959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.hardware.fingerprint.IFingerprintServiceReceiver; 504af76a51d5082c740609563e07cf35f30bc2224eSvetoslavimport android.os.Binder; 517fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huberimport android.os.Build; 5257e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggiimport android.os.Bundle; 533a464785088e7fd206666f640912729533948ce8Jorim Jaggiimport android.os.DeadObjectException; 5480db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiyimport android.os.Environment; 55a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.Handler; 56a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.IBinder; 5740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Millerimport android.os.IHwBinder; 5857e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggiimport android.os.IRemoteCallback; 59dca15d22e8f37d4bc2dfb6db4522ea166149525bJim Millerimport android.os.PowerManager; 6057e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggiimport android.os.PowerManager.WakeLock; 61a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.RemoteException; 6216ef71f4f5a01158fdc07dbbd0963aa2fb04e359Jim Millerimport android.os.SELinux; 63aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chynimport android.os.ServiceManager; 64dca15d22e8f37d4bc2dfb6db4522ea166149525bJim Millerimport android.os.SystemClock; 65599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Millerimport android.os.UserHandle; 66cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Millerimport android.os.UserManager; 67959ac8e04d3c25da11ed6fca1babf56a69a032baCharles Heimport android.security.KeyStore; 68a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.util.Slog; 695457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chynimport android.util.SparseBooleanArray; 705457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chynimport android.util.SparseIntArray; 711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoimport android.util.proto.ProtoOutputStream; 72a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 73449e708abe4e1e85845d319dc701579a6b553c2cFyodor Kupolovimport com.android.internal.annotations.GuardedBy; 74c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wrenimport com.android.internal.logging.MetricsLogger; 75aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chynimport com.android.internal.statusbar.IStatusBarService; 76fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport com.android.internal.util.DumpUtils; 77e29a5a11529dc7df82911b48b9f95461383cbcc2Fyodor Kupolovimport com.android.server.SystemServerInitThreadPool; 78a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport com.android.server.SystemService; 79a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 80c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wrenimport org.json.JSONArray; 81c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wrenimport org.json.JSONException; 82c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wrenimport org.json.JSONObject; 83c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren 8480db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiyimport java.io.File; 85c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wrenimport java.io.FileDescriptor; 86c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wrenimport java.io.PrintWriter; 873a464785088e7fd206666f640912729533948ce8Jorim Jaggiimport java.util.ArrayList; 884af76a51d5082c740609563e07cf35f30bc2224eSvetoslavimport java.util.Collections; 89bcc100aae93bdae85c3f3679dfdda0508450f94eJim Millerimport java.util.HashMap; 909f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport java.util.List; 91da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles Heimport java.util.Map; 9227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaverimport java.util.concurrent.CopyOnWriteArrayList; 93a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 94a7596147b43940cad3f76c53ed154ef088b9269bJim Miller/** 95a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * A service to manage multiple clients that want to access the fingerprint HAL API. 96a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * The service is responsible for maintaining a list of clients and dispatching all 97edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn * fingerprint-related events. 98a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 99a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * @hide 100a7596147b43940cad3f76c53ed154ef088b9269bJim Miller */ 10140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Millerpublic class FingerprintService extends SystemService implements IHwBinder.DeathRecipient { 102cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller static final String TAG = "FingerprintService"; 103cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller static final boolean DEBUG = true; 104edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn private static final boolean CLEANUP_UNUSED_FP = true; 105be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller private static final String FP_DATA_DIR = "fpdata"; 106be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller private static final int MSG_USER_SWITCHING = 10; 1075e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi private static final String ACTION_LOCKOUT_RESET = 1085e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi "com.android.server.fingerprint.ACTION_LOCKOUT_RESET"; 1095457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private static final String KEY_LOCKOUT_RESET_USER = "lockout_reset_user"; 110be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 111bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller private class PerformanceStats { 112bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller int accept; // number of accepted fingerprints 113bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller int reject; // number of rejected fingerprints 114bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller int acquire; // total number of acquisitions. Should be >= accept+reject due to poor image 115bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // acquisition in some cases (too fast, too slow, dirty sensor, etc.) 116bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller int lockout; // total number of lockouts 117df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn int permanentLockout; // total number of permanent lockouts 118bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller } 119bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller 1203a464785088e7fd206666f640912729533948ce8Jorim Jaggi private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors = 1213a464785088e7fd206666f640912729533948ce8Jorim Jaggi new ArrayList<>(); 12227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private final CopyOnWriteArrayList<IFingerprintClientActiveCallback> mClientActiveCallbacks = 12327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver new CopyOnWriteArrayList<>(); 124da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He private final Map<Integer, Long> mAuthenticatorIds = 125da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He Collections.synchronizedMap(new HashMap<>()); 1264af76a51d5082c740609563e07cf35f30bc2224eSvetoslav private final AppOpsManager mAppOps; 127af281ca0d3fad6aaafde0d1979123368390779dcJim Miller private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000; 128df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED = 5; 129df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT = 20; 130df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn 1313d5e396583a845e63e102ff449d856c01125f550Jim Miller private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms 132975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller private final String mKeyguardPackage; 133959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He private int mCurrentUserId = UserHandle.USER_NULL; 134cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance(); 135cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private Context mContext; 136cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private long mHalDeviceId; 1375457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private SparseBooleanArray mTimedLockoutCleared; 1385457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private SparseIntArray mFailedAttempts; 139449e708abe4e1e85845d319dc701579a6b553c2cFyodor Kupolov @GuardedBy("this") 14040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller private IBiometricsFingerprint mDaemon; 141aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn private IStatusBarService mStatusBarService; 14209da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn private final IActivityManager mActivityManager; 143cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private final PowerManager mPowerManager; 144cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private final AlarmManager mAlarmManager; 145cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private final UserManager mUserManager; 146cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private ClientMonitor mCurrentClient; 147cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private ClientMonitor mPendingClient; 148bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller private PerformanceStats mPerformanceStats; 149bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller 150d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn private IBinder mToken = new Binder(); // used for internal FingerprintService enumeration 151edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn private ArrayList<UserFingerprint> mUnknownFingerprints = new ArrayList<>(); // hw fingerprints 152d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 153d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn private class UserFingerprint { 154d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn Fingerprint f; 155d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn int userId; 156d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public UserFingerprint(Fingerprint f, int userId) { 157d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn this.f = f; 158d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn this.userId = userId; 159d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 160d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 161d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 162bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // Normal fingerprint authentications are tracked by mPerformanceMap. 16340e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller private HashMap<Integer, PerformanceStats> mPerformanceMap = new HashMap<>(); 164bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller 165bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // Transactions that make use of CryptoObjects are tracked by mCryptoPerformaceMap. 16640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller private HashMap<Integer, PerformanceStats> mCryptoPerformanceMap = new HashMap<>(); 167ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller 168cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private Handler mHandler = new Handler() { 16980a776e5fecef1160aa9d2b9fdaf7bf9d9c95973Jim Miller @Override 170a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void handleMessage(android.os.Message msg) { 171a7596147b43940cad3f76c53ed154ef088b9269bJim Miller switch (msg.what) { 172aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi case MSG_USER_SWITCHING: 173aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi handleUserSwitching(msg.arg1); 174aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi break; 175aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi 176a7596147b43940cad3f76c53ed154ef088b9269bJim Miller default: 177a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "Unknown message:" + msg.what); 178a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 179a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 180a7596147b43940cad3f76c53ed154ef088b9269bJim Miller }; 181be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1825e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() { 1835e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi @Override 1845e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi public void onReceive(Context context, Intent intent) { 1855e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi if (ACTION_LOCKOUT_RESET.equals(intent.getAction())) { 1865457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn final int user = intent.getIntExtra(KEY_LOCKOUT_RESET_USER, 0); 1875457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn resetFailedAttemptsForUser(false /* clearAttemptCounter */, user); 1885e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi } 1895e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi } 1905e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi }; 1915e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi 1925457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private final Runnable mResetFailedAttemptsForCurrentUserRunnable = new Runnable() { 193fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller @Override 194fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller public void run() { 1955457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn resetFailedAttemptsForUser(true /* clearAttemptCounter */, 1965457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn ActivityManager.getCurrentUser()); 197fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 198fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller }; 199a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 200cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private final Runnable mResetClientState = new Runnable() { 201cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 202cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller public void run() { 203cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // Warning: if we get here, the driver never confirmed our call to cancel the current 204cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // operation (authenticate, enroll, remove, enumerate, etc), which is 205cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // really bad. The result will be a 3-second delay in starting each new client. 206cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // If you see this on a device, make certain the driver notifies with 207cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // {@link FingerprintManager#FINGERPRINT_ERROR_CANCEL} in response to cancel() 208cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // once it has successfully switched to the IDLE state in the fingerprint HAL. 209cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // Additionally,{@link FingerprintManager#FINGERPRINT_ERROR_CANCEL} should only be sent 210cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // in response to an actual cancel() call. 211cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller Slog.w(TAG, "Client " 212cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller + (mCurrentClient != null ? mCurrentClient.getOwnerString() : "null") 213cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller + " failed to respond to cancel, starting client " 214cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller + (mPendingClient != null ? mPendingClient.getOwnerString() : "null")); 215d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 216cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mCurrentClient = null; 217cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller startClient(mPendingClient, false); 218cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 219cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller }; 220cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller 22109da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn private final TaskStackListener mTaskStackListener = new TaskStackListener() { 22209da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn @Override 22309da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn public void onTaskStackChanged() { 22409da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn try { 22509da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn if (!(mCurrentClient instanceof AuthenticationClient)) { 22609da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn return; 22709da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } 228a792fa64ffb891e49b30642c1430e0ccfccd1429Kevin Chyn final String currentClient = mCurrentClient.getOwnerString(); 229a792fa64ffb891e49b30642c1430e0ccfccd1429Kevin Chyn if (isKeyguard(currentClient)) { 23009da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn return; // Keyguard is always allowed 23109da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } 23209da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn List<ActivityManager.RunningTaskInfo> runningTasks = mActivityManager.getTasks(1); 23309da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn if (!runningTasks.isEmpty()) { 234da1b2ab430cbb07ec724c2b54d14d1f8c707134dKevin Chyn final String topPackage = runningTasks.get(0).topActivity.getPackageName(); 235a792fa64ffb891e49b30642c1430e0ccfccd1429Kevin Chyn if (!topPackage.contentEquals(currentClient)) { 236da1b2ab430cbb07ec724c2b54d14d1f8c707134dKevin Chyn Slog.e(TAG, "Stopping background authentication, top: " + topPackage 237a792fa64ffb891e49b30642c1430e0ccfccd1429Kevin Chyn + " currentClient: " + currentClient); 238a792fa64ffb891e49b30642c1430e0ccfccd1429Kevin Chyn mCurrentClient.stop(false /* initiatedByClient */); 23909da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } 24009da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } 24109da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } catch (RemoteException e) { 24209da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn Slog.e(TAG, "Unable to get running tasks", e); 24309da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } 24409da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn } 24509da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn }; 24609da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn 247a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public FingerprintService(Context context) { 248a7596147b43940cad3f76c53ed154ef088b9269bJim Miller super(context); 249a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mContext = context; 250975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString( 251975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller com.android.internal.R.string.config_keyguardComponent)).getPackageName(); 2524af76a51d5082c740609563e07cf35f30bc2224eSvetoslav mAppOps = context.getSystemService(AppOpsManager.class); 2535e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi mPowerManager = mContext.getSystemService(PowerManager.class); 2545e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi mAlarmManager = mContext.getSystemService(AlarmManager.class); 2555e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi mContext.registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET), 2565e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi RESET_FINGERPRINT_LOCKOUT, null /* handler */); 257d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri mUserManager = UserManager.get(mContext); 2585457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mTimedLockoutCleared = new SparseBooleanArray(); 2595457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mFailedAttempts = new SparseIntArray(); 260aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn mStatusBarService = IStatusBarService.Stub.asInterface( 261aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 26209da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn mActivityManager = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)) 26309da294c7a3fc65aa3d9b34bb332fa962fa04f4cKevin Chyn .getService(); 264be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 265be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 266be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 26740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void serviceDied(long cookie) { 26880e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn Slog.v(TAG, "fingerprint HAL died"); 269c57c8d934cf77673154bc81d767365b4d6cda33fJim Miller MetricsLogger.count(mContext, "fingerprintd_died", 1); 27040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 27140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller 0 /*vendorCode */); 272be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 273be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 27440e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public synchronized IBiometricsFingerprint getFingerprintDaemon() { 27540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (mDaemon == null) { 276edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn Slog.v(TAG, "mDaemon was null, reconnect to fingerprint"); 27740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller try { 27825d5eaa14ccdfa767588f9b15d05ec37d860fbc7Yifan Hong mDaemon = IBiometricsFingerprint.getService(); 27940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } catch (java.util.NoSuchElementException e) { 28040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller // Service doesn't exist or cannot be opened. Logged below. 28140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } catch (RemoteException e) { 28240e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller Slog.e(TAG, "Failed to get biometric interface", e); 28340e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 284449e708abe4e1e85845d319dc701579a6b553c2cFyodor Kupolov if (mDaemon == null) { 28540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller Slog.w(TAG, "fingerprint HIDL not available"); 28640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller return null; 28740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 28840e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller 28940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller mDaemon.asBinder().linkToDeath(this, 0); 29040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller 29140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller try { 29240e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller mHalDeviceId = mDaemon.setNotify(mDaemonCallback); 29340e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } catch (RemoteException e) { 29480e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn Slog.e(TAG, "Failed to open fingerprint HAL", e); 29540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller mDaemon = null; // try again later! 29640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 29740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller 29840e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId); 29940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (mHalDeviceId != 0) { 300da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He loadAuthenticatorIds(); 30140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller updateActiveGroup(ActivityManager.getCurrentUser(), null); 302edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn doFingerprintCleanupForUser(ActivityManager.getCurrentUser()); 30340e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } else { 30440e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller Slog.w(TAG, "Failed to open Fingerprint HAL!"); 30540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1); 30640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller mDaemon = null; 307be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 308be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 30940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller return mDaemon; 310be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 311be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 312da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He /** Populates existing authenticator ids. To be used only during the start of the service. */ 313da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He private void loadAuthenticatorIds() { 314da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He // This operation can be expensive, so keep track of the elapsed time. Might need to move to 315da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He // background if it takes too long. 316da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He long t = System.currentTimeMillis(); 317da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He mAuthenticatorIds.clear(); 318da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) { 319da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He int userId = getUserOrWorkProfileId(null, user.id); 320da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He if (!mAuthenticatorIds.containsKey(userId)) { 321da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He updateActiveGroup(userId, null); 322da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 323da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 324da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He 325da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He t = System.currentTimeMillis() - t; 326da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He if (t > 1000) { 327da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He Slog.w(TAG, "loadAuthenticatorIds() taking too long: " + t + "ms"); 328da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 329da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 330da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He 331edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn /** 332edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn * This method should be called upon connection to the daemon, and when user switches. 333edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn * @param userId 334edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn */ 335edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn private void doFingerprintCleanupForUser(int userId) { 336d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (CLEANUP_UNUSED_FP) { 337edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn enumerateUser(userId); 338d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 339d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 340d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 341edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn private void clearEnumerateState() { 342edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn if (DEBUG) Slog.v(TAG, "clearEnumerateState()"); 343d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn mUnknownFingerprints.clear(); 344d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 345d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 346edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn private void enumerateUser(int userId) { 347edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn if (DEBUG) Slog.v(TAG, "Enumerating user(" + userId + ")"); 348d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn boolean restricted = !hasPermission(MANAGE_FINGERPRINT); 349edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn startEnumerate(mToken, userId, null, restricted, true /* internal */); 350d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 351d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 352d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn // Remove unknown fingerprints from hardware 353d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn private void cleanupUnknownFingerprints() { 354d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (!mUnknownFingerprints.isEmpty()) { 355d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn UserFingerprint uf = mUnknownFingerprints.get(0); 356d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn mUnknownFingerprints.remove(uf); 357d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn boolean restricted = !hasPermission(MANAGE_FINGERPRINT); 358d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startRemove(mToken, uf.f.getFingerId(), uf.f.getGroupId(), uf.userId, null, 359d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn restricted, true /* internal */); 360d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } else { 361edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn clearEnumerateState(); 362d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 363d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 364d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 36540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller protected void handleEnumerate(long deviceId, int fingerId, int groupId, int remaining) { 366d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn ClientMonitor client = mCurrentClient; 367d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 368d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if ( !(client instanceof InternalRemovalClient) && !(client instanceof EnumerateClient) ) { 369d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn return; 370d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 371d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn client.onEnumerationResult(fingerId, groupId, remaining); 372d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 373d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn // All fingerprints in hardware for this user were enumerated 374d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (remaining == 0) { 375d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (client instanceof InternalEnumerateClient) { 376edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn List<Fingerprint> unknownFingerprints = 377edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn ((InternalEnumerateClient) client).getUnknownFingerprints(); 378edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn 379edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn if (!unknownFingerprints.isEmpty()) { 380edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn Slog.w(TAG, "Adding " + unknownFingerprints.size() + 381edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn " fingerprints for deletion"); 382edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn } 383edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn for (Fingerprint f : unknownFingerprints) { 384d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn mUnknownFingerprints.add(new UserFingerprint(f, client.getTargetUserId())); 385d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 386edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn removeClient(client); 387d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn cleanupUnknownFingerprints(); 388edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn } else { 389edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn removeClient(client); 390d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 391d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 392be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 393be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 39440e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller protected void handleError(long deviceId, int error, int vendorCode) { 395cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor client = mCurrentClient; 396d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (client instanceof InternalRemovalClient || client instanceof InternalEnumerateClient) { 397edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn clearEnumerateState(); 398d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 39940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (client != null && client.onError(error, vendorCode)) { 40007dbd63153b523f960eb7052a852661303aa7eacJim Miller removeClient(client); 401be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 402df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn 403cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (DEBUG) Slog.v(TAG, "handleError(client=" 404c1e61b83c2fc3fa7a7111ec72081a8fa647bc354Jim Miller + (client != null ? client.getOwnerString() : "null") + ", error = " + error + ")"); 405cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // This is the magic code that starts the next client when the old client finishes. 406cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (error == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { 407cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mHandler.removeCallbacks(mResetClientState); 408cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (mPendingClient != null) { 409cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (DEBUG) Slog.v(TAG, "start pending client " + mPendingClient.getOwnerString()); 410cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller startClient(mPendingClient, false); 411cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mPendingClient = null; 412cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 4138eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller } else if (error == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) { 4148eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller // If we get HW_UNAVAILABLE, try to connect again later... 4158eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller Slog.w(TAG, "Got ERROR_HW_UNAVAILABLE; try reconnecting next client."); 4168eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller synchronized (this) { 4178eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller mDaemon = null; 4188eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller mHalDeviceId = 0; 419959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He mCurrentUserId = UserHandle.USER_NULL; 4208eddd33a01ad8eeb99c380c14be181d7e4930c29Jim Miller } 421cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 422be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 423be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 42440e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller protected void handleRemoved(long deviceId, int fingerId, int groupId, int remaining) { 425d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (DEBUG) Slog.w(TAG, "Removed: fid=" + fingerId 426d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn + ", gid=" + groupId 427d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn + ", dev=" + deviceId 428d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn + ", rem=" + remaining); 429d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 430cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor client = mCurrentClient; 43140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (client != null && client.onRemoved(fingerId, groupId, remaining)) { 432cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller removeClient(client); 43329b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He // When the last fingerprint of a group is removed, update the authenticator id 43429b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He if (!hasEnrolledFingerprints(groupId)) { 43529b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He updateActiveGroup(groupId, null); 43629b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He } 437ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 438d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (client instanceof InternalRemovalClient && !mUnknownFingerprints.isEmpty()) { 439d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn cleanupUnknownFingerprints(); 440d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } else if (client instanceof InternalRemovalClient){ 441edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn clearEnumerateState(); 442d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 443be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 444be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 445a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller protected void handleAuthenticated(long deviceId, int fingerId, int groupId, 446a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller ArrayList<Byte> token) { 447cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor client = mCurrentClient; 448a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller if (fingerId != 0) { 449a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller // Ugh... 450a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller final byte[] byteToken = new byte[token.size()]; 451a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller for (int i = 0; i < token.size(); i++) { 452a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller byteToken[i] = token.get(i); 453a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller } 454a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller // Send to Keystore 455da82e2cb7193032867f86b996467bcd117545616Brian Young KeyStore.getInstance().addAuthToken(byteToken); 456a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller } 457cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (client != null && client.onAuthenticated(fingerId, groupId)) { 458cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller removeClient(client); 459ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 460bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller if (fingerId != 0) { 461bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller mPerformanceStats.accept++; 462bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller } else { 463bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller mPerformanceStats.reject++; 464bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller } 465be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 466be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 46740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller protected void handleAcquired(long deviceId, int acquiredInfo, int vendorCode) { 468cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor client = mCurrentClient; 46940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (client != null && client.onAcquired(acquiredInfo, vendorCode)) { 470cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller removeClient(client); 471ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 472df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (mPerformanceStats != null && getLockoutMode() == AuthenticationClient.LOCKOUT_NONE 473bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller && client instanceof AuthenticationClient) { 474bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // ignore enrollment acquisitions or acquisitions when we're locked out 475bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller mPerformanceStats.acquire++; 476bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller } 477dca15d22e8f37d4bc2dfb6db4522ea166149525bJim Miller } 478be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 4798b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller protected void handleEnrollResult(long deviceId, int fingerId, int groupId, int remaining) { 480cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor client = mCurrentClient; 481cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (client != null && client.onEnrollResult(fingerId, groupId, remaining)) { 482cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller removeClient(client); 48329b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He // When enrollment finishes, update this group's authenticator id, as the HAL has 48429b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He // already generated a new authenticator id when the new fingerprint is enrolled. 48529b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He updateActiveGroup(groupId, null); 486a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 487a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 488a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 4898b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller private void userActivity() { 4908b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller long now = SystemClock.uptimeMillis(); 4918b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); 4928b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 4938b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller 4948b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller void handleUserSwitching(int userId) { 495edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn if (mCurrentClient instanceof InternalRemovalClient 496edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn || mCurrentClient instanceof InternalEnumerateClient) { 497edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn Slog.w(TAG, "User switched while performing cleanup"); 498edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn removeClient(mCurrentClient); 499edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn clearEnumerateState(); 500edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn } 501d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri updateActiveGroup(userId, null); 502edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn doFingerprintCleanupForUser(userId); 5038b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 5048b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller 505be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller private void removeClient(ClientMonitor client) { 506cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (client != null) { 507cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller client.destroy(); 508cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (client != mCurrentClient && mCurrentClient != null) { 509cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller Slog.w(TAG, "Unexpected client: " + client.getOwnerString() + "expected: " 510cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller + mCurrentClient != null ? mCurrentClient.getOwnerString() : "null"); 511cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 512cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 513cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (mCurrentClient != null) { 514cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (DEBUG) Slog.v(TAG, "Done with client: " + client.getOwnerString()); 515cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mCurrentClient = null; 516fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 51727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver if (mPendingClient == null) { 51827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver notifyClientActiveCallbacks(false); 51927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 520fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 521fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 522df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn private int getLockoutMode() { 5235457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn final int currentUser = ActivityManager.getCurrentUser(); 5245457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn final int failedAttempts = mFailedAttempts.get(currentUser, 0); 5255457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn if (failedAttempts >= MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT) { 526df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn return AuthenticationClient.LOCKOUT_PERMANENT; 5275457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn } else if (failedAttempts > 0 && 5285457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mTimedLockoutCleared.get(currentUser, false) == false 5295457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn && (failedAttempts % MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED == 0)) { 530df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn return AuthenticationClient.LOCKOUT_TIMED; 531df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn } 532df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn return AuthenticationClient.LOCKOUT_NONE; 533fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 534fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 5355457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private void scheduleLockoutResetForUser(int userId) { 5365457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5375457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn SystemClock.elapsedRealtime() + FAIL_LOCKOUT_TIMEOUT_MS, 5385457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn getLockoutResetIntentForUser(userId)); 5395e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi } 5405e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi 5415457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private void cancelLockoutResetForUser(int userId) { 5425457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mAlarmManager.cancel(getLockoutResetIntentForUser(userId)); 5435e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi } 5445e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi 5455457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn private PendingIntent getLockoutResetIntentForUser(int userId) { 5465457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn return PendingIntent.getBroadcast(mContext, userId, 5475457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn new Intent(ACTION_LOCKOUT_RESET).putExtra(KEY_LOCKOUT_RESET_USER, userId), 5485457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn PendingIntent.FLAG_UPDATE_CURRENT); 5495e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi } 5505e354223d817477efac9a6a2e3ce3d9161e046a4Jorim Jaggi 551ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public long startPreEnroll(IBinder token) { 55240e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller IBiometricsFingerprint daemon = getFingerprintDaemon(); 553be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller if (daemon == null) { 55480e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn Slog.w(TAG, "startPreEnroll: no fingerprint HAL!"); 555be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller return 0; 556be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 557be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller try { 558be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller return daemon.preEnroll(); 559be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } catch (RemoteException e) { 560be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller Slog.e(TAG, "startPreEnroll failed", e); 561be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 562be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller return 0; 563ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 564ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller 565e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy public int startPostEnroll(IBinder token) { 56640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller IBiometricsFingerprint daemon = getFingerprintDaemon(); 567e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy if (daemon == null) { 56880e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn Slog.w(TAG, "startPostEnroll: no fingerprint HAL!"); 569e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy return 0; 570e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy } 571e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy try { 572e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy return daemon.postEnroll(); 573e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy } catch (RemoteException e) { 574e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy Slog.e(TAG, "startPostEnroll failed", e); 575e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy } 576e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy return 0; 577e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy } 578e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy 57980a776e5fecef1160aa9d2b9fdaf7bf9d9c95973Jim Miller /** 58080e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn * Calls fingerprint HAL to switch states to the new task. If there's already a current task, 581cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller * it calls cancel() and sets mPendingClient to begin when the current task finishes 582cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller * ({@link FingerprintManager#FINGERPRINT_ERROR_CANCELED}). 583cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller * @param newClient the new client that wants to connect 584cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller * @param initiatedByClient true for authenticate, remove and enroll 58580a776e5fecef1160aa9d2b9fdaf7bf9d9c95973Jim Miller */ 586cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller private void startClient(ClientMonitor newClient, boolean initiatedByClient) { 587cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor currentClient = mCurrentClient; 588cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (currentClient != null) { 589cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (DEBUG) Slog.v(TAG, "request stop current client " + currentClient.getOwnerString()); 590d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (currentClient instanceof InternalEnumerateClient || 591d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn currentClient instanceof InternalRemovalClient) { 592d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn // This condition means we're currently running internal diagnostics to 593d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn // remove extra fingerprints in the hardware and/or the software 594d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn // TODO: design an escape hatch in case client never finishes 595edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn if (newClient != null) { 596edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn Slog.w(TAG, "Internal cleanup in progress but trying to start client " 597edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn + newClient.getClass().getSuperclass().getSimpleName() 598edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn + "(" + newClient.getOwnerString() + ")" 599edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn + ", initiatedByClient = " + initiatedByClient); 600edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn } 601d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 602d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn else { 603d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn currentClient.stop(initiatedByClient); 604d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 605cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mPendingClient = newClient; 606cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mHandler.removeCallbacks(mResetClientState); 607cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT); 608cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } else if (newClient != null) { 609cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller mCurrentClient = newClient; 610cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (DEBUG) Slog.v(TAG, "starting client " 611cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller + newClient.getClass().getSuperclass().getSimpleName() 612cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller + "(" + newClient.getOwnerString() + ")" 613edd71f9ab6d2cbbd13407e5284b06d64a3687634Kevin Chyn + ", initiatedByClient = " + initiatedByClient); 61427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver notifyClientActiveCallbacks(true); 61527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 616cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller newClient.start(); 6171304137918e41d1ad98555d9d7daf77583407d3fJim Miller } 618a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 619a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 6208f2aca0ee4ff0eff6226df05d1531d2f2fa2f3c1Jim Miller void startRemove(IBinder token, int fingerId, int groupId, int userId, 621d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) { 622606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin if (token == null) { 623606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin Slog.w(TAG, "startRemove: token is null"); 624606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin return; 625606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin } 626606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin if (receiver == null) { 627606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin Slog.w(TAG, "startRemove: receiver is null"); 628606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin return; 629606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin } 630606f17154407bc53dd9fc894111b0927985d38ccIlya Matyukhin 63140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller IBiometricsFingerprint daemon = getFingerprintDaemon(); 632be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller if (daemon == null) { 63380e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn Slog.w(TAG, "startRemove: no fingerprint HAL!"); 634be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller return; 635be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 636f501b58de8f467a80fef49c704555781bc61ea6fJim Miller 637d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (internal) { 638d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn Context context = getContext(); 639d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn InternalRemovalClient client = new InternalRemovalClient(context, mHalDeviceId, 640d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn token, receiver, fingerId, groupId, userId, restricted, 641d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn context.getOpPackageName()) { 642d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 643d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public void notifyUserActivity() { 644d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 645d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 646d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 647d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public IBiometricsFingerprint getFingerprintDaemon() { 648d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn return FingerprintService.this.getFingerprintDaemon(); 649d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 650d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn }; 651d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startClient(client, true); 652d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 653d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn else { 654d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn RemovalClient client = new RemovalClient(getContext(), mHalDeviceId, token, 655d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn receiver, fingerId, groupId, userId, restricted, token.toString()) { 656d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 657d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public void notifyUserActivity() { 658d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn FingerprintService.this.userActivity(); 659d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 660d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 661d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 662d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public IBiometricsFingerprint getFingerprintDaemon() { 663d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn return FingerprintService.this.getFingerprintDaemon(); 664d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 665d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn }; 666d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startClient(client, true); 667d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 66840e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 66940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller 67040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller void startEnumerate(IBinder token, int userId, 671d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) { 67240e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller IBiometricsFingerprint daemon = getFingerprintDaemon(); 67340e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller if (daemon == null) { 67480e40ccf49bca22a6eb1846a582574092f3e0c1aKevin Chyn Slog.w(TAG, "startEnumerate: no fingerprint HAL!"); 67540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller return; 67640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 677d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn if (internal) { 678d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn List<Fingerprint> enrolledList = getEnrolledFingerprints(userId); 679d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn Context context = getContext(); 680d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn InternalEnumerateClient client = new InternalEnumerateClient(context, mHalDeviceId, 681d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn token, receiver, userId, userId, restricted, context.getOpPackageName(), 682d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn enrolledList) { 683d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 684d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public void notifyUserActivity() { 685f8ff36c47f9f8d60cf825e6b43eb75d1eae81df5Kevin Chyn 686d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 687d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 688d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 689d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public IBiometricsFingerprint getFingerprintDaemon() { 690d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn return FingerprintService.this.getFingerprintDaemon(); 691d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 692d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn }; 693d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startClient(client, true); 694d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 695d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn else { 696d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token, 697d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn receiver, userId, userId, restricted, token.toString()) { 698d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 699d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public void notifyUserActivity() { 700d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn FingerprintService.this.userActivity(); 701d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 702d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn 703d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override 704d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn public IBiometricsFingerprint getFingerprintDaemon() { 705d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn return FingerprintService.this.getFingerprintDaemon(); 706d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 707d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn }; 708d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startClient(client, true); 709d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn } 710a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 711a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 712599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller public List<Fingerprint> getEnrolledFingerprints(int userId) { 713599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller return mFingerprintUtils.getFingerprintsForUser(mContext, userId); 7149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller } 7159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller 716599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller public boolean hasEnrolledFingerprints(int userId) { 7171fd298bdcb192b6a513216773d4de58a505da665Jim Miller if (userId != UserHandle.getCallingUserId()) { 71833fd3cf2d90ca877b139e7f47824683b774f122aClara Bayarri checkPermission(INTERACT_ACROSS_USERS); 71933fd3cf2d90ca877b139e7f47824683b774f122aClara Bayarri } 720599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller return mFingerprintUtils.getFingerprintsForUser(mContext, userId).size() > 0; 7212aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi } 7222aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi 723f501b58de8f467a80fef49c704555781bc61ea6fJim Miller boolean hasPermission(String permission) { 724f501b58de8f467a80fef49c704555781bc61ea6fJim Miller return getContext().checkCallingOrSelfPermission(permission) 725f501b58de8f467a80fef49c704555781bc61ea6fJim Miller == PackageManager.PERMISSION_GRANTED; 726f501b58de8f467a80fef49c704555781bc61ea6fJim Miller } 727f501b58de8f467a80fef49c704555781bc61ea6fJim Miller 728ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller void checkPermission(String permission) { 7299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller getContext().enforceCallingOrSelfPermission(permission, 7309f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller "Must have " + permission + " permission."); 731a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 732a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 733494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales int getEffectiveUserId(int userId) { 734494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales UserManager um = UserManager.get(mContext); 735494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales if (um != null) { 736494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales final long callingIdentity = Binder.clearCallingIdentity(); 737494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales userId = um.getCredentialOwnerProfile(userId); 738494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales Binder.restoreCallingIdentity(callingIdentity); 739494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales } else { 740494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales Slog.e(TAG, "Unable to acquire UserManager"); 741494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales } 742494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales return userId; 743494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales } 744494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales 745cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller boolean isCurrentUserOrProfile(int userId) { 746cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller UserManager um = UserManager.get(mContext); 747da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He if (um == null) { 748da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He Slog.e(TAG, "Unable to acquire UserManager"); 749da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He return false; 750da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 751cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller 752da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He final long token = Binder.clearCallingIdentity(); 753da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He try { 754da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He // Allow current user or profiles of the current user... 755959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) { 756da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He if (profileId == userId) { 757da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He return true; 758da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 759cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller } 760da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } finally { 761da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He Binder.restoreCallingIdentity(token); 762cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller } 763959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He 764959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He return false; 765cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller } 766cb7d9e933234233410e1f761cb9804bb8b7a00d3Jim Miller 767975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller private boolean isForegroundActivity(int uid, int pid) { 768975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller try { 769975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller List<RunningAppProcessInfo> procs = 770dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka ActivityManager.getService().getRunningAppProcesses(); 771975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller int N = procs.size(); 772975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller for (int i = 0; i < N; i++) { 773975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller RunningAppProcessInfo proc = procs.get(i); 774975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller if (proc.pid == pid && proc.uid == uid 7753121760e70fb6a1b8de0274c724170f7e87b7e5bSvet Ganov && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) { 776975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return true; 777975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 778975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 779975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } catch (RemoteException e) { 780975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller Slog.w(TAG, "am.getRunningAppProcesses() failed"); 781975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 782975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return false; 783975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 784975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller 785975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller /** 786975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller * @param opPackageName name of package for caller 78737979c9db0a88039bb098645f4180dc04e987b96Jim Miller * @param requireForeground only allow this call while app is in the foreground 788975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller * @return true if caller can use fingerprint API 789975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller */ 79037979c9db0a88039bb098645f4180dc04e987b96Jim Miller private boolean canUseFingerprint(String opPackageName, boolean requireForeground, int uid, 791f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn int pid, int userId) { 792cf87df15310611ae4e5229b19c5a4942e54185b5Vishwath Mohan if (getContext().checkCallingPermission(USE_FINGERPRINT) 793cf87df15310611ae4e5229b19c5a4942e54185b5Vishwath Mohan != PackageManager.PERMISSION_GRANTED) { 794cf87df15310611ae4e5229b19c5a4942e54185b5Vishwath Mohan checkPermission(USE_BIOMETRIC); 795cf87df15310611ae4e5229b19c5a4942e54185b5Vishwath Mohan } 796cf87df15310611ae4e5229b19c5a4942e54185b5Vishwath Mohan 797d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri if (isKeyguard(opPackageName)) { 798975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return true; // Keyguard is always allowed 799975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 800f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn if (!isCurrentUserOrProfile(userId)) { 801975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller Slog.w(TAG,"Rejecting " + opPackageName + " ; not a current user or profile"); 802975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return false; 803975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 804975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName) 805975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller != AppOpsManager.MODE_ALLOWED) { 8061adb4a7693406e7f984d7b1512e0e6aa40aa40e2Jim Miller Slog.w(TAG, "Rejecting " + opPackageName + " ; permission denied"); 807975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return false; 808975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 80937979c9db0a88039bb098645f4180dc04e987b96Jim Miller if (requireForeground && !(isForegroundActivity(uid, pid) || currentClient(opPackageName))){ 8101adb4a7693406e7f984d7b1512e0e6aa40aa40e2Jim Miller Slog.w(TAG, "Rejecting " + opPackageName + " ; not in foreground"); 811975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return false; 812975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller } 813975f145c018de9affffee5e89d94ce0ed78ad9dfJim Miller return true; 8144af76a51d5082c740609563e07cf35f30bc2224eSvetoslav } 8154af76a51d5082c740609563e07cf35f30bc2224eSvetoslav 816d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri /** 81737979c9db0a88039bb098645f4180dc04e987b96Jim Miller * @param opPackageName package of the caller 81837979c9db0a88039bb098645f4180dc04e987b96Jim Miller * @return true if this is the same client currently using fingerprint 81937979c9db0a88039bb098645f4180dc04e987b96Jim Miller */ 82037979c9db0a88039bb098645f4180dc04e987b96Jim Miller private boolean currentClient(String opPackageName) { 82137979c9db0a88039bb098645f4180dc04e987b96Jim Miller return mCurrentClient != null && mCurrentClient.getOwnerString().equals(opPackageName); 82237979c9db0a88039bb098645f4180dc04e987b96Jim Miller } 82337979c9db0a88039bb098645f4180dc04e987b96Jim Miller 82437979c9db0a88039bb098645f4180dc04e987b96Jim Miller /** 825d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri * @param clientPackage 826d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri * @return true if this is keyguard package 827d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri */ 828d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri private boolean isKeyguard(String clientPackage) { 829d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri return mKeyguardPackage.equals(clientPackage); 830d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 831d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri 8323a464785088e7fd206666f640912729533948ce8Jorim Jaggi private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) { 8333a464785088e7fd206666f640912729533948ce8Jorim Jaggi if (!mLockoutMonitors.contains(monitor)) { 8343a464785088e7fd206666f640912729533948ce8Jorim Jaggi mLockoutMonitors.add(monitor); 8353a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 8363a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 8373a464785088e7fd206666f640912729533948ce8Jorim Jaggi 8383a464785088e7fd206666f640912729533948ce8Jorim Jaggi private void removeLockoutResetCallback( 8393a464785088e7fd206666f640912729533948ce8Jorim Jaggi FingerprintServiceLockoutResetMonitor monitor) { 8403a464785088e7fd206666f640912729533948ce8Jorim Jaggi mLockoutMonitors.remove(monitor); 8413a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 8423a464785088e7fd206666f640912729533948ce8Jorim Jaggi 8433a464785088e7fd206666f640912729533948ce8Jorim Jaggi private void notifyLockoutResetMonitors() { 8443a464785088e7fd206666f640912729533948ce8Jorim Jaggi for (int i = 0; i < mLockoutMonitors.size(); i++) { 8453a464785088e7fd206666f640912729533948ce8Jorim Jaggi mLockoutMonitors.get(i).sendLockoutReset(); 8463a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 8473a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 8483a464785088e7fd206666f640912729533948ce8Jorim Jaggi 84927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver private void notifyClientActiveCallbacks(boolean isActive) { 85027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver List<IFingerprintClientActiveCallback> callbacks = mClientActiveCallbacks; 85127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver for (int i = 0; i < callbacks.size(); i++) { 85227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver try { 85327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver callbacks.get(i).onClientActiveChanged(isActive); 85427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } catch (RemoteException re) { 85527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver // If the remote is dead, stop notifying it 85627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mClientActiveCallbacks.remove(callbacks.get(i)); 857959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He } 85827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 85927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 86027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 861ff715ac551fcb09640acdf28278384ca2d5f85c0Tony Mak private void startAuthentication(IBinder token, long opId, int callingUserId, int groupId, 862cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller IFingerprintServiceReceiver receiver, int flags, boolean restricted, 863ecf00cedb64d2e7b9082d540d49972fe391760adVishwath Mohan String opPackageName, Bundle bundle, IBiometricPromptReceiver dialogReceiver) { 864cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller updateActiveGroup(groupId, opPackageName); 865fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 866cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (DEBUG) Slog.v(TAG, "startAuthentication(" + opPackageName + ")"); 867cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller 868cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller AuthenticationClient client = new AuthenticationClient(getContext(), mHalDeviceId, token, 869aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn receiver, mCurrentUserId, groupId, opId, restricted, opPackageName, bundle, 870aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn dialogReceiver, mStatusBarService) { 871cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 872d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn public void onStart() { 873d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn try { 874d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn mActivityManager.registerTaskStackListener(mTaskStackListener); 875d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn } catch (RemoteException e) { 876d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn Slog.e(TAG, "Could not register task stack listener", e); 877d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn } 878d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn } 879d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn 880d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn @Override 881d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn public void onStop() { 882d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn try { 883d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn mActivityManager.unregisterTaskStackListener(mTaskStackListener); 884d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn } catch (RemoteException e) { 885d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn Slog.e(TAG, "Could not unregister task stack listener", e); 886d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn } 887d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn } 888d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn 889d4f43c2f55131f75410d387da2dd7d0878d7c8fcKevin Chyn @Override 890df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn public int handleFailedAttempt() { 8915457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn final int currentUser = ActivityManager.getCurrentUser(); 8925457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mFailedAttempts.put(currentUser, mFailedAttempts.get(currentUser, 0) + 1); 8935457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mTimedLockoutCleared.put(ActivityManager.getCurrentUser(), false); 894df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn final int lockoutMode = getLockoutMode(); 895df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) { 896df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn mPerformanceStats.permanentLockout++; 897df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) { 898bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller mPerformanceStats.lockout++; 899bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller } 900df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn 901df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn // Failing multiple times will continue to push out the lockout time 902df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) { 9035457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn scheduleLockoutResetForUser(currentUser); 904df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn return lockoutMode; 90516ef71f4f5a01158fdc07dbbd0963aa2fb04e359Jim Miller } 906df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn return AuthenticationClient.LOCKOUT_NONE; 907fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 908fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 909cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 910cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller public void resetFailedAttempts() { 9115457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn FingerprintService.this.resetFailedAttemptsForUser(true /* clearAttemptCounter */, 9125457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn ActivityManager.getCurrentUser()); 913fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 914fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 915cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 916cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller public void notifyUserActivity() { 917cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller FingerprintService.this.userActivity(); 918fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 919fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 920cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 92140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public IBiometricsFingerprint getFingerprintDaemon() { 922cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller return FingerprintService.this.getFingerprintDaemon(); 923fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 924cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller }; 925fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 926df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn int lockoutMode = getLockoutMode(); 927df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) { 928df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn Slog.v(TAG, "In lockout mode(" + lockoutMode + 929df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn ") ; disallowing authentication"); 930df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn int errorCode = lockoutMode == AuthenticationClient.LOCKOUT_TIMED ? 931df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn FingerprintManager.FINGERPRINT_ERROR_LOCKOUT : 932df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT; 933df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (!client.onError(errorCode, 0 /* vendorCode */)) { 934df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn Slog.w(TAG, "Cannot send permanent lockout message to client"); 9351304137918e41d1ad98555d9d7daf77583407d3fJim Miller } 936cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller return; 937fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 938cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller startClient(client, true /* initiatedByClient */); 939cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 940fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 941c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller private void startEnrollment(IBinder token, byte [] cryptoToken, int userId, 942cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller IFingerprintServiceReceiver receiver, int flags, boolean restricted, 943cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller String opPackageName) { 944c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller updateActiveGroup(userId, opPackageName); 945c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller 946c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller final int groupId = userId; // default group for fingerprint enrollment 947cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller 948cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller EnrollClient client = new EnrollClient(getContext(), mHalDeviceId, token, receiver, 949c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller userId, groupId, cryptoToken, restricted, opPackageName) { 950cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller 951cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 95240e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public IBiometricsFingerprint getFingerprintDaemon() { 953cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller return FingerprintService.this.getFingerprintDaemon(); 954dca15d22e8f37d4bc2dfb6db4522ea166149525bJim Miller } 955fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller 956cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller @Override 957cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller public void notifyUserActivity() { 958cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller FingerprintService.this.userActivity(); 959fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller } 960cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller }; 961cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller startClient(client, true /* initiatedByClient */); 962cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 963cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller 964df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn // attempt counter should only be cleared when Keyguard goes away or when 965df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn // a fingerprint is successfully authenticated 9665457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn protected void resetFailedAttemptsForUser(boolean clearAttemptCounter, int userId) { 967df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (DEBUG && getLockoutMode() != AuthenticationClient.LOCKOUT_NONE) { 968df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn Slog.v(TAG, "Reset fingerprint lockout, clearAttemptCounter=" + clearAttemptCounter); 969df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn } 970df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn if (clearAttemptCounter) { 9715457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mFailedAttempts.put(userId, 0); 972ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 9735457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mTimedLockoutCleared.put(userId, true); 974cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // If we're asked to reset failed attempts externally (i.e. from Keyguard), 975cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller // the alarm might still be pending; remove it. 9765457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn cancelLockoutResetForUser(userId); 977cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller notifyLockoutResetMonitors(); 978ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 979ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller 9803883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn private class FingerprintServiceLockoutResetMonitor implements IBinder.DeathRecipient { 9813a464785088e7fd206666f640912729533948ce8Jorim Jaggi 98257e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi private static final long WAKELOCK_TIMEOUT_MS = 2000; 9833a464785088e7fd206666f640912729533948ce8Jorim Jaggi private final IFingerprintServiceLockoutResetCallback mCallback; 98457e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi private final WakeLock mWakeLock; 9853a464785088e7fd206666f640912729533948ce8Jorim Jaggi 9863a464785088e7fd206666f640912729533948ce8Jorim Jaggi public FingerprintServiceLockoutResetMonitor( 9873a464785088e7fd206666f640912729533948ce8Jorim Jaggi IFingerprintServiceLockoutResetCallback callback) { 9883a464785088e7fd206666f640912729533948ce8Jorim Jaggi mCallback = callback; 98957e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 99057e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi "lockout reset callback"); 9913883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn try { 9923883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn mCallback.asBinder().linkToDeath(FingerprintServiceLockoutResetMonitor.this, 0); 9933883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn } catch (RemoteException e) { 9943883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn Slog.w(TAG, "caught remote exception in linkToDeath", e); 9953883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn } 9963a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 9973a464785088e7fd206666f640912729533948ce8Jorim Jaggi 9983a464785088e7fd206666f640912729533948ce8Jorim Jaggi public void sendLockoutReset() { 9993a464785088e7fd206666f640912729533948ce8Jorim Jaggi if (mCallback != null) { 10003a464785088e7fd206666f640912729533948ce8Jorim Jaggi try { 100157e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi mWakeLock.acquire(WAKELOCK_TIMEOUT_MS); 100257e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi mCallback.onLockoutReset(mHalDeviceId, new IRemoteCallback.Stub() { 100357e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi 100457e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi @Override 100557e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi public void sendResult(Bundle data) throws RemoteException { 100671d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn releaseWakelock(); 100757e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi } 100857e2f4db3535fb059ac278499018951deddc4c82Jorim Jaggi }); 10093a464785088e7fd206666f640912729533948ce8Jorim Jaggi } catch (DeadObjectException e) { 10103a464785088e7fd206666f640912729533948ce8Jorim Jaggi Slog.w(TAG, "Death object while invoking onLockoutReset: ", e); 10113a464785088e7fd206666f640912729533948ce8Jorim Jaggi mHandler.post(mRemoveCallbackRunnable); 10123a464785088e7fd206666f640912729533948ce8Jorim Jaggi } catch (RemoteException e) { 10133a464785088e7fd206666f640912729533948ce8Jorim Jaggi Slog.w(TAG, "Failed to invoke onLockoutReset: ", e); 101471d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn releaseWakelock(); 10153a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 10163a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 10173a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 10183a464785088e7fd206666f640912729533948ce8Jorim Jaggi 10193a464785088e7fd206666f640912729533948ce8Jorim Jaggi private final Runnable mRemoveCallbackRunnable = new Runnable() { 10203a464785088e7fd206666f640912729533948ce8Jorim Jaggi @Override 10213a464785088e7fd206666f640912729533948ce8Jorim Jaggi public void run() { 102271d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn releaseWakelock(); 10233a464785088e7fd206666f640912729533948ce8Jorim Jaggi removeLockoutResetCallback(FingerprintServiceLockoutResetMonitor.this); 10243a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 10253a464785088e7fd206666f640912729533948ce8Jorim Jaggi }; 10263883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn 10273883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn @Override 10283883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn public void binderDied() { 10293883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn Slog.e(TAG, "Lockout reset callback binder died"); 10303883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn mHandler.post(mRemoveCallbackRunnable); 10313883563d9277af0654fd7fca977e2e2437bb9509Kevin Chyn } 103271d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn 103371d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn private void releaseWakelock() { 103471d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn if (mWakeLock.isHeld()) { 103571d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn mWakeLock.release(); 103671d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn } 103771d04218a7066d9b8467d7b717ac2bdab0950fd5Kevin Chyn } 10383a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 10393a464785088e7fd206666f640912729533948ce8Jorim Jaggi 104040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller private IBiometricsFingerprintClientCallback mDaemonCallback = 104140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller new IBiometricsFingerprintClientCallback.Stub() { 1042be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1043be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 10448b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void onEnrollResult(final long deviceId, final int fingerId, final int groupId, 10458b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller final int remaining) { 10468b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mHandler.post(new Runnable() { 10478b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller @Override 10488b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void run() { 10498b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller handleEnrollResult(deviceId, fingerId, groupId, remaining); 10508b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 10518b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller }); 1052be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1053be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1054be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 105540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void onAcquired(final long deviceId, final int acquiredInfo, final int vendorCode) { 10568b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mHandler.post(new Runnable() { 10578b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller @Override 10588b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void run() { 105940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller handleAcquired(deviceId, acquiredInfo, vendorCode); 10608b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 10618b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller }); 1062be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1063be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1064be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 1065a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller public void onAuthenticated(final long deviceId, final int fingerId, final int groupId, 1066a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller ArrayList<Byte> token) { 10678b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mHandler.post(new Runnable() { 10688b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller @Override 10698b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void run() { 1070a8eaeeb7549f9783fee850a5921b56a949eb6498Jim Miller handleAuthenticated(deviceId, fingerId, groupId, token); 10718b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 10728b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller }); 1073be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1074be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1075be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 107640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void onError(final long deviceId, final int error, final int vendorCode) { 10778b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mHandler.post(new Runnable() { 10788b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller @Override 10798b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void run() { 108040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller handleError(deviceId, error, vendorCode); 10818b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 10828b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller }); 1083be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1084be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1085be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 108640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void onRemoved(final long deviceId, final int fingerId, final int groupId, final int remaining) { 10878b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mHandler.post(new Runnable() { 10888b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller @Override 10898b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void run() { 109040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller handleRemoved(deviceId, fingerId, groupId, remaining); 10918b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 10928b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller }); 1093be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1094be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 10959f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller @Override 109640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void onEnumerate(final long deviceId, final int fingerId, final int groupId, 109740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller final int remaining) { 10988b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller mHandler.post(new Runnable() { 10998b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller @Override 11008b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller public void run() { 110140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller handleEnumerate(deviceId, fingerId, groupId, remaining); 11028b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller } 11038b3c25a34a0bfe5fa3ed697ee6a552ea1373f077Jim Miller }); 1104be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1105be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller }; 1106be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1107be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller private final class FingerprintServiceWrapper extends IFingerprintService.Stub { 1108be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1109ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public long preEnroll(IBinder token) { 1110ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller checkPermission(MANAGE_FINGERPRINT); 1111ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller return startPreEnroll(token); 1112a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1113a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 1114be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1115e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy public int postEnroll(IBinder token) { 1116e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy checkPermission(MANAGE_FINGERPRINT); 1117e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy return startPostEnroll(token); 1118e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy } 1119e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy 1120e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy @Override // Binder call 1121c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller public void enroll(final IBinder token, final byte[] cryptoToken, final int userId, 1122cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller final IFingerprintServiceReceiver receiver, final int flags, 1123cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller final String opPackageName) { 1124ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller checkPermission(MANAGE_FINGERPRINT); 1125aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn final int limit = mContext.getResources().getInteger( 1126599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser); 1127c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller 1128c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller final int enrolled = FingerprintService.this.getEnrolledFingerprints(userId).size(); 1129599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller if (enrolled >= limit) { 1130599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller Slog.w(TAG, "Too many fingerprints registered"); 1131599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller return; 1132599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller } 1133f501b58de8f467a80fef49c704555781bc61ea6fJim Miller 1134494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales // Group ID is arbitrarily set to parent profile user ID. It just represents 1135494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales // the default fingerprints for the user. 1136c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller if (!isCurrentUserOrProfile(userId)) { 113735fd93810541430615b2f1118abc756b717d379cClara Bayarri return; 113835fd93810541430615b2f1118abc756b717d379cClara Bayarri } 1139494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales 1140f501b58de8f467a80fef49c704555781bc61ea6fJim Miller final boolean restricted = isRestricted(); 1141ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller mHandler.post(new Runnable() { 1142ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller @Override 1143ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void run() { 1144c12eca8b5964dfc37836e1c0f2dad8c88c76d90fJim Miller startEnrollment(token, cryptoToken, userId, receiver, flags, 1145cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller restricted, opPackageName); 1146ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1147ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller }); 1148a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1149a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 1150f501b58de8f467a80fef49c704555781bc61ea6fJim Miller private boolean isRestricted() { 1151f501b58de8f467a80fef49c704555781bc61ea6fJim Miller // Only give privileged apps (like Settings) access to fingerprint info 1152f501b58de8f467a80fef49c704555781bc61ea6fJim Miller final boolean restricted = !hasPermission(MANAGE_FINGERPRINT); 1153f501b58de8f467a80fef49c704555781bc61ea6fJim Miller return restricted; 1154f501b58de8f467a80fef49c704555781bc61ea6fJim Miller } 1155f501b58de8f467a80fef49c704555781bc61ea6fJim Miller 1156be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1157ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void cancelEnrollment(final IBinder token) { 1158ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller checkPermission(MANAGE_FINGERPRINT); 1159ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller mHandler.post(new Runnable() { 1160ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller @Override 1161ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void run() { 1162cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller ClientMonitor client = mCurrentClient; 1163cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (client instanceof EnrollClient && client.getToken() == token) { 1164cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller client.stop(client.getToken() == token); 1165cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 1166ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1167ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller }); 1168a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1169a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 1170be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1171ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void authenticate(final IBinder token, final long opId, final int groupId, 1172dca15d22e8f37d4bc2dfb6db4522ea166149525bJim Miller final IFingerprintServiceReceiver receiver, final int flags, 1173aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn final String opPackageName, final Bundle bundle, 1174ecf00cedb64d2e7b9082d540d49972fe391760adVishwath Mohan final IBiometricPromptReceiver dialogReceiver) { 1175ff715ac551fcb09640acdf28278384ca2d5f85c0Tony Mak final int callingUid = Binder.getCallingUid(); 117633fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn final int callingPid = Binder.getCallingPid(); 1177ff715ac551fcb09640acdf28278384ca2d5f85c0Tony Mak final int callingUserId = UserHandle.getCallingUserId(); 1178f501b58de8f467a80fef49c704555781bc61ea6fJim Miller final boolean restricted = isRestricted(); 117933fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn 118033fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, callingUid, callingPid, 118133fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn callingUserId)) { 118233fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName); 118333fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn return; 118433fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn } 118533fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn 1186ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller mHandler.post(new Runnable() { 1187ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller @Override 1188ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void run() { 1189bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0); 1190bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller 1191bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // Get performance stats object for this user. 1192bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller HashMap<Integer, PerformanceStats> pmap 1193bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller = (opId == 0) ? mPerformanceMap : mCryptoPerformanceMap; 1194bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller PerformanceStats stats = pmap.get(mCurrentUserId); 1195bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller if (stats == null) { 1196bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller stats = new PerformanceStats(); 1197bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller pmap.put(mCurrentUserId, stats); 1198bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller } 1199bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller mPerformanceStats = stats; 1200bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller 1201ff715ac551fcb09640acdf28278384ca2d5f85c0Tony Mak startAuthentication(token, opId, callingUserId, groupId, receiver, 1202aae4a15a2288c20e73b995a590bde4626c887d03Kevin Chyn flags, restricted, opPackageName, bundle, dialogReceiver); 1203ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1204ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller }); 1205a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1206a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 1207be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1208cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller public void cancelAuthentication(final IBinder token, final String opPackageName) { 120933fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn final int callingUid = Binder.getCallingUid(); 121033fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn final int callingPid = Binder.getCallingPid(); 1211f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn final int callingUserId = UserHandle.getCallingUserId(); 121233fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn 121333fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, callingUid, callingPid, 121433fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn callingUserId)) { 121533fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (DEBUG) Slog.v(TAG, "cancelAuthentication(): reject " + opPackageName); 121633fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn return; 121733fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn } 121833fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn 1219ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller mHandler.post(new Runnable() { 1220ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller @Override 1221ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void run() { 122233fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn ClientMonitor client = mCurrentClient; 122333fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (client instanceof AuthenticationClient) { 122433fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (client.getToken() == token) { 122533fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (DEBUG) Slog.v(TAG, "stop client " + client.getOwnerString()); 122633fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn client.stop(client.getToken() == token); 122733fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn } else { 122833fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (DEBUG) Slog.v(TAG, "can't stop client " 122933fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn + client.getOwnerString() + " since tokens don't match"); 1230cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 123133fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn } else if (client != null) { 123233fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn if (DEBUG) Slog.v(TAG, "can't cancel non-authenticating client " 123333fdf11c65e10556d204aafd644c4567226d9d62Kevin Chyn + client.getOwnerString()); 1234cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller } 1235ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1236ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller }); 1237ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1238ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller 1239be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1240d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri public void setActiveUser(final int userId) { 1241d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri checkPermission(MANAGE_FINGERPRINT); 1242d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri mHandler.post(new Runnable() { 1243d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri @Override 1244d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri public void run() { 1245d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri updateActiveGroup(userId, null); 1246d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 1247d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri }); 1248d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 1249d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri 1250d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri @Override // Binder call 1251ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void remove(final IBinder token, final int fingerId, final int groupId, 12528f2aca0ee4ff0eff6226df05d1531d2f2fa2f3c1Jim Miller final int userId, final IFingerprintServiceReceiver receiver) { 1253ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission 1254f501b58de8f467a80fef49c704555781bc61ea6fJim Miller final boolean restricted = isRestricted(); 1255ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller mHandler.post(new Runnable() { 1256ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller @Override 1257ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void run() { 1258d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startRemove(token, fingerId, groupId, userId, receiver, 1259d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn restricted, false /* internal */); 1260ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1261ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller }); 1262a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1263ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller 1264d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn @Override // Binder call 126540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void enumerate(final IBinder token, final int userId, 126640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller final IFingerprintServiceReceiver receiver) { 126740e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission 126840e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller final boolean restricted = isRestricted(); 126940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller mHandler.post(new Runnable() { 127040e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller @Override 127140e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller public void run() { 1272d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn startEnumerate(token, userId, receiver, restricted, false /* internal */); 127340e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 127440e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller }); 127540e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller } 127640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller 1277be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 12784af76a51d5082c740609563e07cf35f30bc2224eSvetoslav public boolean isHardwareDetected(long deviceId, String opPackageName) { 1279cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (!canUseFingerprint(opPackageName, false /* foregroundOnly */, 1280f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn Binder.getCallingUid(), Binder.getCallingPid(), 1281f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn UserHandle.getCallingUserId())) { 12824af76a51d5082c740609563e07cf35f30bc2224eSvetoslav return false; 12834af76a51d5082c740609563e07cf35f30bc2224eSvetoslav } 1284959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He 1285959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He final long token = Binder.clearCallingIdentity(); 1286959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He try { 1287959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He IBiometricsFingerprint daemon = getFingerprintDaemon(); 1288959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He return daemon != null && mHalDeviceId != 0; 1289959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He } finally { 1290959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He Binder.restoreCallingIdentity(token); 1291959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He } 1292ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller } 129399d6019bead4705b7e126e65b856d538417d4934Jim Miller 1294be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1295ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void rename(final int fingerId, final int groupId, final String name) { 129699d6019bead4705b7e126e65b856d538417d4934Jim Miller checkPermission(MANAGE_FINGERPRINT); 129735fd93810541430615b2f1118abc756b717d379cClara Bayarri if (!isCurrentUserOrProfile(groupId)) { 129835fd93810541430615b2f1118abc756b717d379cClara Bayarri return; 129935fd93810541430615b2f1118abc756b717d379cClara Bayarri } 1300ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller mHandler.post(new Runnable() { 1301ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller @Override 1302ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller public void run() { 1303494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales mFingerprintUtils.renameFingerprintForUser(mContext, fingerId, 130435fd93810541430615b2f1118abc756b717d379cClara Bayarri groupId, name); 1305ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller } 1306ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller }); 130799d6019bead4705b7e126e65b856d538417d4934Jim Miller } 13089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller 1309be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1310599ef0e3cd848bbf8faa45147ac680d04d3ba333Jim Miller public List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) { 1311cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (!canUseFingerprint(opPackageName, false /* foregroundOnly */, 1312f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn Binder.getCallingUid(), Binder.getCallingPid(), 1313f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn UserHandle.getCallingUserId())) { 13144af76a51d5082c740609563e07cf35f30bc2224eSvetoslav return Collections.emptyList(); 13154af76a51d5082c740609563e07cf35f30bc2224eSvetoslav } 1316494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales 131735fd93810541430615b2f1118abc756b717d379cClara Bayarri return FingerprintService.this.getEnrolledFingerprints(userId); 13189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller } 13192aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi 1320be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 1321494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales public boolean hasEnrolledFingerprints(int userId, String opPackageName) { 1322cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller if (!canUseFingerprint(opPackageName, false /* foregroundOnly */, 1323f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn Binder.getCallingUid(), Binder.getCallingPid(), 1324f4023b570c0170bde67484b6c58952dc6ca93136Kevin Chyn UserHandle.getCallingUserId())) { 13254af76a51d5082c740609563e07cf35f30bc2224eSvetoslav return false; 13264af76a51d5082c740609563e07cf35f30bc2224eSvetoslav } 1327494d6e9b030e757cef996bcbfd68a80a7d1526e7Andres Morales 132835fd93810541430615b2f1118abc756b717d379cClara Bayarri return FingerprintService.this.hasEnrolledFingerprints(userId); 13292aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi } 13304d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales 1331be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override // Binder call 13324af76a51d5082c740609563e07cf35f30bc2224eSvetoslav public long getAuthenticatorId(String opPackageName) { 1333a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // In this method, we're not checking whether the caller is permitted to use fingerprint 1334a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // API because current authenticator ID is leaked (in a more contrived way) via Android 1335a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // Keystore (android.security.keystore package): the user of that API can create a key 1336a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // which requires fingerprint authentication for its use, and then query the key's 1337a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // characteristics (hidden API) which returns, among other things, fingerprint 1338a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // authenticator ID which was active at key creation time. 1339a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // 1340a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // Reason: The part of Android Keystore which runs inside an app's process invokes this 1341a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // method in certain cases. Those cases are not always where the developer demonstrates 1342a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // explicit intent to use fingerprint functionality. Thus, to avoiding throwing an 1343a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // unexpected SecurityException this method does not check whether its caller is 1344a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // permitted to use fingerprint API. 1345a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // 1346a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // The permission check should be restored once Android Keystore no longer invokes this 1347a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // method from inside app processes. 1348a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin 1349cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller return FingerprintService.this.getAuthenticatorId(opPackageName); 13504d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales } 1351c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren 1352c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren @Override // Binder call 1353c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1354fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkey if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1355c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren 1356c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren final long ident = Binder.clearCallingIdentity(); 1357c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren try { 13581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (args.length > 0 && "--proto".equals(args[0])) { 13591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato dumpProto(fd); 13601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 13611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato dumpInternal(pw); 13621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1363c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } finally { 1364c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren Binder.restoreCallingIdentity(ident); 1365c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } 1366c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } 1367959ac8e04d3c25da11ed6fca1babf56a69a032baCharles He 1368e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller @Override // Binder call 1369e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller public void resetTimeout(byte [] token) { 1370e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller checkPermission(RESET_FINGERPRINT_LOCKOUT); 1371e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller // TODO: confirm security token when we move timeout management into the HAL layer. 13725457cba8bee14e3ca7239f9b30cc0f67be5d6a96Kevin Chyn mHandler.post(mResetFailedAttemptsForCurrentUserRunnable); 13733a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 13743a464785088e7fd206666f640912729533948ce8Jorim Jaggi 13753a464785088e7fd206666f640912729533948ce8Jorim Jaggi @Override 13763a464785088e7fd206666f640912729533948ce8Jorim Jaggi public void addLockoutResetCallback(final IFingerprintServiceLockoutResetCallback callback) 13773a464785088e7fd206666f640912729533948ce8Jorim Jaggi throws RemoteException { 13783a464785088e7fd206666f640912729533948ce8Jorim Jaggi mHandler.post(new Runnable() { 13793a464785088e7fd206666f640912729533948ce8Jorim Jaggi @Override 13803a464785088e7fd206666f640912729533948ce8Jorim Jaggi public void run() { 13813a464785088e7fd206666f640912729533948ce8Jorim Jaggi addLockoutResetMonitor( 13823a464785088e7fd206666f640912729533948ce8Jorim Jaggi new FingerprintServiceLockoutResetMonitor(callback)); 13833a464785088e7fd206666f640912729533948ce8Jorim Jaggi } 13843a464785088e7fd206666f640912729533948ce8Jorim Jaggi }); 1385e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller } 138627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 138727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver @Override 138827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public boolean isClientActive() { 138927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver checkPermission(MANAGE_FINGERPRINT); 139027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver synchronized(FingerprintService.this) { 139127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver return (mCurrentClient != null) || (mPendingClient != null); 139227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 139327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 139427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 139527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver @Override 139627fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public void addClientActiveCallback(IFingerprintClientActiveCallback callback) { 139727fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver checkPermission(MANAGE_FINGERPRINT); 139827fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mClientActiveCallbacks.add(callback); 139927fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 140027fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver 140127fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver @Override 140227fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) { 140327fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver checkPermission(MANAGE_FINGERPRINT); 140427fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver mClientActiveCallbacks.remove(callback); 140527fcd9c97a2ceb50bab026237390207e5ee9e290Phil Weaver } 1406c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } 1407c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren 1408c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren private void dumpInternal(PrintWriter pw) { 1409c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren JSONObject dump = new JSONObject(); 1410c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren try { 1411c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren dump.put("service", "Fingerprint Manager"); 1412c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren 1413c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren JSONArray sets = new JSONArray(); 1414c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren for (UserInfo user : UserManager.get(getContext()).getUsers()) { 1415c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren final int userId = user.getUserHandle().getIdentifier(); 1416c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren final int N = mFingerprintUtils.getFingerprintsForUser(mContext, userId).size(); 1417bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller PerformanceStats stats = mPerformanceMap.get(userId); 1418bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller PerformanceStats cryptoStats = mCryptoPerformanceMap.get(userId); 1419c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren JSONObject set = new JSONObject(); 1420c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren set.put("id", userId); 1421c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren set.put("count", N); 1422bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("accept", (stats != null) ? stats.accept : 0); 1423bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("reject", (stats != null) ? stats.reject : 0); 1424bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("acquire", (stats != null) ? stats.acquire : 0); 1425bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("lockout", (stats != null) ? stats.lockout : 0); 1426df9d33e9039d8567ea82f67a76d95a7ae7ab8df8Kevin Chyn set.put("permanentLockout", (stats != null) ? stats.permanentLockout : 0); 1427bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // cryptoStats measures statistics about secure fingerprint transactions 1428bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller // (e.g. to unlock password storage, make secure purchases, etc.) 1429bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("acceptCrypto", (cryptoStats != null) ? cryptoStats.accept : 0); 1430bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("rejectCrypto", (cryptoStats != null) ? cryptoStats.reject : 0); 1431bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("acquireCrypto", (cryptoStats != null) ? cryptoStats.acquire : 0); 1432bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller set.put("lockoutCrypto", (cryptoStats != null) ? cryptoStats.lockout : 0); 1433cd7c35cfae7265f7ed32836ee09b5c341487470bKweku Adams set.put("permanentLockoutCrypto", 1434cd7c35cfae7265f7ed32836ee09b5c341487470bKweku Adams (cryptoStats != null) ? cryptoStats.permanentLockout : 0); 1435c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren sets.put(set); 1436c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } 1437c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren 1438c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren dump.put("prints", sets); 1439c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } catch (JSONException e) { 1440c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren Slog.e(TAG, "dump formatting failure", e); 1441c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren } 1442c510ad56a8e01626a711e60ba97b01fd2121a72fChris Wren pw.println(dump); 1443a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1444a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 14451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato private void dumpProto(FileDescriptor fd) { 14461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato final ProtoOutputStream proto = new ProtoOutputStream(fd); 14471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (UserInfo user : UserManager.get(getContext()).getUsers()) { 14481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato final int userId = user.getUserHandle().getIdentifier(); 14491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 14501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato final long userToken = proto.start(FingerprintServiceDumpProto.USERS); 14511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 14521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato proto.write(FingerprintUserStatsProto.USER_ID, userId); 14531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato proto.write(FingerprintUserStatsProto.NUM_FINGERPRINTS, 14541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mFingerprintUtils.getFingerprintsForUser(mContext, userId).size()); 14551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 14561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Normal fingerprint authentications (e.g. lockscreen) 14571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato final PerformanceStats normal = mPerformanceMap.get(userId); 14581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (normal != null) { 14591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato final long countsToken = proto.start(FingerprintUserStatsProto.NORMAL); 1460fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.ACCEPT, normal.accept); 1461fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.REJECT, normal.reject); 1462fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.ACQUIRE, normal.acquire); 1463fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.LOCKOUT, normal.lockout); 1464fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, normal.permanentLockout); 14651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato proto.end(countsToken); 14661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 14671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 14681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Statistics about secure fingerprint transactions (e.g. to unlock password 14691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // storage, make secure purchases, etc.) 14709310f5c9b88938c6d3b6081dcc8e1676aa5e5cf5Kevin Chyn final PerformanceStats crypto = mCryptoPerformanceMap.get(userId); 14711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (crypto != null) { 14721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato final long countsToken = proto.start(FingerprintUserStatsProto.CRYPTO); 1473fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.ACCEPT, crypto.accept); 1474fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.REJECT, crypto.reject); 1475fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.ACQUIRE, crypto.acquire); 1476fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.LOCKOUT, crypto.lockout); 1477fd257d60900dab144877ac559326ece02a2d5b71Kweku Adams proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, crypto.permanentLockout); 14781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato proto.end(countsToken); 14791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 14801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 14811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato proto.end(userToken); 14821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 14831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato proto.flush(); 148489a55cb83d8d9f9a187e9319936273042e91f8f9Kevin Chyn mPerformanceMap.clear(); 148589a55cb83d8d9f9a187e9319936273042e91f8f9Kevin Chyn mCryptoPerformanceMap.clear(); 14861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 14871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1488a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override 1489a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void onStart() { 14909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper()); 1491e29a5a11529dc7df82911b48b9f95461383cbcc2Fyodor Kupolov SystemServerInitThreadPool.get().submit(this::getFingerprintDaemon, TAG + ".onStart"); 1492aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi listenForUserSwitches(); 1493a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 1494a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 1495d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri private void updateActiveGroup(int userId, String clientPackage) { 149640e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller IBiometricsFingerprint daemon = getFingerprintDaemon(); 1497bcc100aae93bdae85c3f3679dfdda0508450f94eJim Miller 1498be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller if (daemon != null) { 1499be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller try { 1500d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri userId = getUserOrWorkProfileId(clientPackage, userId); 1501d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri if (userId != mCurrentUserId) { 15025670247168820bdbfdc3c91b954ca6779ca401ecYifan Hong int firstSdkInt = Build.VERSION.FIRST_SDK_INT; 1503456461238f86e1ff42b5b07de22c3231bee9bc6fYifan Hong if (firstSdkInt < Build.VERSION_CODES.BASE) { 1504456461238f86e1ff42b5b07de22c3231bee9bc6fYifan Hong Slog.e(TAG, "First SDK version " + firstSdkInt + " is invalid; must be " + 1505456461238f86e1ff42b5b07de22c3231bee9bc6fYifan Hong "at least VERSION_CODES.BASE"); 1506456461238f86e1ff42b5b07de22c3231bee9bc6fYifan Hong } 15077fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber File baseDir; 15085670247168820bdbfdc3c91b954ca6779ca401ecYifan Hong if (firstSdkInt <= Build.VERSION_CODES.O_MR1) { 15097fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber baseDir = Environment.getUserSystemDirectory(userId); 15107fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber } else { 15117fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber baseDir = Environment.getDataVendorDeDirectory(userId); 15127fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber } 15137fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber 15147fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber File fpDir = new File(baseDir, FP_DATA_DIR); 1515d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri if (!fpDir.exists()) { 1516d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri if (!fpDir.mkdir()) { 1517d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri Slog.v(TAG, "Cannot make directory: " + fpDir.getAbsolutePath()); 1518d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri return; 1519d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 1520d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri // Calling mkdir() from this process will create a directory with our 1521d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri // permissions (inherited from the containing dir). This command fixes 1522d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri // the label. 1523d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri if (!SELinux.restorecon(fpDir)) { 1524d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri Slog.w(TAG, "Restorecons failed. Directory will have wrong label."); 1525d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri return; 1526d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 152716ef71f4f5a01158fdc07dbbd0963aa2fb04e359Jim Miller } 15287fe2053a55ed071bc28d44cb2f34dfc9f4efd520Andreas Huber 152940e4645e6e564b962bb73c85c5325ec54ad34cc1Jim Miller daemon.setActiveGroup(userId, fpDir.getAbsolutePath()); 1530d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri mCurrentUserId = userId; 1531be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 153229b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He mAuthenticatorIds.put(userId, 153329b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He hasEnrolledFingerprints(userId) ? daemon.getAuthenticatorId() : 0L); 1534be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } catch (RemoteException e) { 1535be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller Slog.e(TAG, "Failed to setActiveGroup():", e); 1536be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1537dbe780f293163c478933a1f2ce97189703656c10Jim Miller } 1538aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi } 1539aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi 1540d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri /** 1541d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri * @param clientPackage the package of the caller 1542d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri * @return the profile id 1543d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri */ 1544d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri private int getUserOrWorkProfileId(String clientPackage, int userId) { 1545d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri if (!isKeyguard(clientPackage) && isWorkProfile(userId)) { 1546d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri return userId; 1547d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 1548d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri return getEffectiveUserId(userId); 1549d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 1550d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri 1551d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri /** 1552d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri * @param userId 1553d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri * @return true if this is a work profile 1554d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri */ 1555d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri private boolean isWorkProfile(int userId) { 1556da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He UserInfo userInfo = null; 1557da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He final long token = Binder.clearCallingIdentity(); 1558da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He try { 1559da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He userInfo = mUserManager.getUserInfo(userId); 1560da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } finally { 1561da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He Binder.restoreCallingIdentity(token); 1562da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He } 1563da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He return userInfo != null && userInfo.isManagedProfile(); 1564d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri } 1565d1f722d906f66ef05cd329feb9edbed178314d46Clara Bayarri 1566aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi private void listenForUserSwitches() { 1567aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi try { 1568dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka ActivityManager.getService().registerUserSwitchObserver( 15696005b3f87b063ee7ab7e8877a6a8c90b480f3341Fyodor Kupolov new SynchronousUserSwitchObserver() { 1570be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller @Override 15716005b3f87b063ee7ab7e8877a6a8c90b480f3341Fyodor Kupolov public void onUserSwitching(int newUserId) throws RemoteException { 1572be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */) 1573be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller .sendToTarget(); 1574be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 15750b77ef9f5199b7cd0956f2bfe049cbd699ca03b4Fyodor Kupolov }, TAG); 1576aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi } catch (RemoteException e) { 1577aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi Slog.w(TAG, "Failed to listen for user switching event" ,e); 1578aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi } 1579aa4d32add72fa728f9cfe4eeb014b26eb5d091c2Jorim Jaggi } 1580be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller 1581d0063106b67c9aa44d9473102a1116aad136f50fJim Miller /*** 1582d0063106b67c9aa44d9473102a1116aad136f50fJim Miller * @param opPackageName the name of the calling package 1583da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He * @return authenticator id for the calling user 1584d0063106b67c9aa44d9473102a1116aad136f50fJim Miller */ 1585cb2ce6f1f0deef80943ece093ae40bacc1f57c44Jim Miller public long getAuthenticatorId(String opPackageName) { 1586da88f0e6b8bde99b1d65c73f20c9704b06cf5f5aCharles He final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId()); 158729b3a8ad26cc416c4fd6ca3444e9c22507bc3778Charles He return mAuthenticatorIds.getOrDefault(userId, 0L); 1588be67542182e41a6e31cf002db72ec42ee717bd1cJim Miller } 1589a7596147b43940cad3f76c53ed154ef088b9269bJim Miller} 1590