am 46154b8f: am b5304547: am 5e354223: Use AlarmManager for lockout reset

* commit '46154b8fa50c4e8176225981500ad95a5b667cea':
  Use AlarmManager for lockout reset
This commit is contained in:
Jorim Jaggi
2015-09-09 21:48:23 +00:00
committed by Android Git Automerger
3 changed files with 56 additions and 12 deletions

View File

@@ -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() {
try {
callback.onLockoutReset(); callback.onLockoutReset();
} finally {
wakeLock.release();
}
} }
}); });
} }

View File

@@ -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);
} }

View File

@@ -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