Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21bb7a3e authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android Git Automerger
Browse files

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

* commit '463bf7cc':
  Use AlarmManager for lockout reset
parents 8b4d28a3 463bf7cc
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.CancellationSignal.OnCancelListener;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.keystore.AndroidKeyStoreProvider;
@@ -705,15 +706,23 @@ public class FingerprintManager {
    public void addLockoutResetCallback(final LockoutResetCallback callback) {
        if (mService != null) {
            try {
                final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
                mService.addLockoutResetCallback(
                        new IFingerprintServiceLockoutResetCallback.Stub() {

                    @Override
                    public void onLockoutReset(long deviceId) throws RemoteException {
                        final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
                                PowerManager.PARTIAL_WAKE_LOCK, "lockoutResetCallback");
                        wakeLock.acquire();
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    callback.onLockoutReset();
                                } finally {
                                    wakeLock.release();
                                }
                            }
                        });
                    }
+3 −1
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.os.UserHandle;
 * Callback when lockout period expired and clients are allowed to authenticate again.
 * @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);
}
+43 −10
Original line number Diff line number Diff line
@@ -21,10 +21,15 @@ import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.IUserSwitchObserver;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
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 int MSG_USER_SWITCHING = 10;
    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 mEnrollClient = null;
@@ -118,9 +125,19 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
    private long mHalDeviceId;
    private int mFailedAttempts;
    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
        public void run() {
            resetFailedAttempts();
@@ -133,7 +150,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        mKeyguardPackage = ComponentName.unflattenFromString(context.getResources().getString(
                com.android.internal.R.string.config_keyguardComponent)).getPackageName();
        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
@@ -262,14 +282,28 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        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() {
        if (DEBUG && inLockoutMode()) {
            Slog.v(TAG, "Reset fingerprint lockout");
        }
        mFailedAttempts = 0;
        // If we're asked to reset failed attempts externally (i.e. from Keyguard), the runnable
        // may still be in the queue; remove it.
        mHandler.removeCallbacks(mLockoutReset);
        // If we're asked to reset failed attempts externally (i.e. from Keyguard), the alarm might
        // still be pending; remove it.
        cancelLockoutReset();
        notifyLockoutResetMonitors();
    }

@@ -277,8 +311,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        mFailedAttempts++;
        if (inLockoutMode()) {
            // Failing multiple times will continue to push out the lockout time.
            mHandler.removeCallbacks(mLockoutReset);
            mHandler.postDelayed(mLockoutReset, FAIL_LOCKOUT_TIMEOUT_MS);
            scheduleLockoutReset();
            if (clientMonitor != null
                    && !clientMonitor.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
                Slog.w(TAG, "Cannot send lockout message to client");
@@ -683,7 +716,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
                    FingerprintUtils.vibrateFingerprintSuccess(getContext());
                }
                result |= true; // we have a valid fingerprint
                mHandler.post(mLockoutReset);
                resetFailedAttempts();
            }
            return result;
        }
@@ -1016,7 +1049,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        public void resetTimeout(byte [] token) {
            checkPermission(RESET_FINGERPRINT_LOCKOUT);
            // TODO: confirm security token when we move timeout management into the HAL layer.
            mHandler.post(mLockoutReset);
            mHandler.post(mResetFailedAttemptsRunnable);
        }

        @Override