am 5e354223: Use AlarmManager for lockout reset
* commit '5e354223d817477efac9a6a2e3ce3d9161e046a4': Use AlarmManager for lockout reset
This commit is contained in:
@@ -27,6 +27,7 @@ import android.os.CancellationSignal.OnCancelListener;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.os.PowerManager;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.security.keystore.AndroidKeyStoreProvider;
|
import android.security.keystore.AndroidKeyStoreProvider;
|
||||||
@@ -705,15 +706,23 @@ public class FingerprintManager {
|
|||||||
public void addLockoutResetCallback(final LockoutResetCallback callback) {
|
public void addLockoutResetCallback(final LockoutResetCallback callback) {
|
||||||
if (mService != null) {
|
if (mService != null) {
|
||||||
try {
|
try {
|
||||||
|
final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
|
||||||
mService.addLockoutResetCallback(
|
mService.addLockoutResetCallback(
|
||||||
new IFingerprintServiceLockoutResetCallback.Stub() {
|
new IFingerprintServiceLockoutResetCallback.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLockoutReset(long deviceId) throws RemoteException {
|
public void onLockoutReset(long deviceId) throws RemoteException {
|
||||||
|
final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
|
||||||
|
PowerManager.PARTIAL_WAKE_LOCK, "lockoutResetCallback");
|
||||||
|
wakeLock.acquire();
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
callback.onLockoutReset();
|
try {
|
||||||
|
callback.onLockoutReset();
|
||||||
|
} finally {
|
||||||
|
wakeLock.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import android.os.UserHandle;
|
|||||||
* Callback when lockout period expired and clients are allowed to authenticate again.
|
* Callback when lockout period expired and clients are allowed to authenticate again.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
oneway interface IFingerprintServiceLockoutResetCallback {
|
interface IFingerprintServiceLockoutResetCallback {
|
||||||
|
|
||||||
|
/** Method is synchronous so wakelock is held when this is called from a WAKEUP alarm. */
|
||||||
void onLockoutReset(long deviceId);
|
void onLockoutReset(long deviceId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,15 @@ import android.app.ActivityManager;
|
|||||||
import android.app.ActivityManager.RunningAppProcessInfo;
|
import android.app.ActivityManager.RunningAppProcessInfo;
|
||||||
import android.app.ActivityManager.RunningTaskInfo;
|
import android.app.ActivityManager.RunningTaskInfo;
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
|
import android.app.AlarmManager;
|
||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
import android.app.IUserSwitchObserver;
|
import android.app.IUserSwitchObserver;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
|
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
|
||||||
@@ -85,6 +90,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
private static final String FINGERPRINTD = "android.hardware.fingerprint.IFingerprintDaemon";
|
private static final String FINGERPRINTD = "android.hardware.fingerprint.IFingerprintDaemon";
|
||||||
private static final int MSG_USER_SWITCHING = 10;
|
private static final int MSG_USER_SWITCHING = 10;
|
||||||
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
|
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
|
||||||
|
private static final String ACTION_LOCKOUT_RESET =
|
||||||
|
"com.android.server.fingerprint.ACTION_LOCKOUT_RESET";
|
||||||
|
|
||||||
private ClientMonitor mAuthClient = null;
|
private ClientMonitor mAuthClient = null;
|
||||||
private ClientMonitor mEnrollClient = null;
|
private ClientMonitor mEnrollClient = null;
|
||||||
@@ -118,9 +125,19 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
private long mHalDeviceId;
|
private long mHalDeviceId;
|
||||||
private int mFailedAttempts;
|
private int mFailedAttempts;
|
||||||
private IFingerprintDaemon mDaemon;
|
private IFingerprintDaemon mDaemon;
|
||||||
private PowerManager mPowerManager;
|
private final PowerManager mPowerManager;
|
||||||
|
private final AlarmManager mAlarmManager;
|
||||||
|
|
||||||
private final Runnable mLockoutReset = new Runnable() {
|
private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (ACTION_LOCKOUT_RESET.equals(intent.getAction())) {
|
||||||
|
resetFailedAttempts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Runnable mResetFailedAttemptsRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
resetFailedAttempts();
|
resetFailedAttempts();
|
||||||
@@ -133,7 +150,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
|
mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
|
||||||
com.android.internal.R.string.config_keyguardComponent)).getPackageName();
|
com.android.internal.R.string.config_keyguardComponent)).getPackageName();
|
||||||
mAppOps = context.getSystemService(AppOpsManager.class);
|
mAppOps = context.getSystemService(AppOpsManager.class);
|
||||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
mPowerManager = mContext.getSystemService(PowerManager.class);
|
||||||
|
mAlarmManager = mContext.getSystemService(AlarmManager.class);
|
||||||
|
mContext.registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET),
|
||||||
|
RESET_FINGERPRINT_LOCKOUT, null /* handler */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -262,14 +282,28 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
return mFailedAttempts >= MAX_FAILED_ATTEMPTS;
|
return mFailedAttempts >= MAX_FAILED_ATTEMPTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void scheduleLockoutReset() {
|
||||||
|
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||||
|
SystemClock.elapsedRealtime() + FAIL_LOCKOUT_TIMEOUT_MS, getLockoutResetIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelLockoutReset() {
|
||||||
|
mAlarmManager.cancel(getLockoutResetIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingIntent getLockoutResetIntent() {
|
||||||
|
return PendingIntent.getBroadcast(mContext, 0,
|
||||||
|
new Intent(ACTION_LOCKOUT_RESET), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
}
|
||||||
|
|
||||||
private void resetFailedAttempts() {
|
private void resetFailedAttempts() {
|
||||||
if (DEBUG && inLockoutMode()) {
|
if (DEBUG && inLockoutMode()) {
|
||||||
Slog.v(TAG, "Reset fingerprint lockout");
|
Slog.v(TAG, "Reset fingerprint lockout");
|
||||||
}
|
}
|
||||||
mFailedAttempts = 0;
|
mFailedAttempts = 0;
|
||||||
// If we're asked to reset failed attempts externally (i.e. from Keyguard), the runnable
|
// If we're asked to reset failed attempts externally (i.e. from Keyguard), the alarm might
|
||||||
// may still be in the queue; remove it.
|
// still be pending; remove it.
|
||||||
mHandler.removeCallbacks(mLockoutReset);
|
cancelLockoutReset();
|
||||||
notifyLockoutResetMonitors();
|
notifyLockoutResetMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +311,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
mFailedAttempts++;
|
mFailedAttempts++;
|
||||||
if (inLockoutMode()) {
|
if (inLockoutMode()) {
|
||||||
// Failing multiple times will continue to push out the lockout time.
|
// Failing multiple times will continue to push out the lockout time.
|
||||||
mHandler.removeCallbacks(mLockoutReset);
|
scheduleLockoutReset();
|
||||||
mHandler.postDelayed(mLockoutReset, FAIL_LOCKOUT_TIMEOUT_MS);
|
|
||||||
if (clientMonitor != null
|
if (clientMonitor != null
|
||||||
&& !clientMonitor.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
|
&& !clientMonitor.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
|
||||||
Slog.w(TAG, "Cannot send lockout message to client");
|
Slog.w(TAG, "Cannot send lockout message to client");
|
||||||
@@ -683,7 +716,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
FingerprintUtils.vibrateFingerprintSuccess(getContext());
|
FingerprintUtils.vibrateFingerprintSuccess(getContext());
|
||||||
}
|
}
|
||||||
result |= true; // we have a valid fingerprint
|
result |= true; // we have a valid fingerprint
|
||||||
mHandler.post(mLockoutReset);
|
resetFailedAttempts();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1049,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
public void resetTimeout(byte [] token) {
|
public void resetTimeout(byte [] token) {
|
||||||
checkPermission(RESET_FINGERPRINT_LOCKOUT);
|
checkPermission(RESET_FINGERPRINT_LOCKOUT);
|
||||||
// TODO: confirm security token when we move timeout management into the HAL layer.
|
// TODO: confirm security token when we move timeout management into the HAL layer.
|
||||||
mHandler.post(mLockoutReset);
|
mHandler.post(mResetFailedAttemptsRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user