diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index cdf7013deb26d..aa109de752e35 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -26,6 +26,7 @@ import android.os.CancellationSignal; import android.os.CancellationSignal.OnCancelListener; import android.os.Handler; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; @@ -757,20 +758,22 @@ public class FingerprintManager { 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() { + public void onLockoutReset(long deviceId, IRemoteCallback serverCallback) + throws RemoteException { + try { + final PowerManager.WakeLock wakeLock = powerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, "lockoutResetCallback"); + wakeLock.acquire(); + mHandler.post(() -> { try { callback.onLockoutReset(); } finally { wakeLock.release(); } - } - }); + }); + } finally { + serverCallback.sendResult(null /* data */); + } } }); } catch (RemoteException e) { diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl index e027a2b3d260f..971e14c7251fb 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl @@ -17,14 +17,17 @@ package android.hardware.fingerprint; import android.hardware.fingerprint.Fingerprint; import android.os.Bundle; +import android.os.IRemoteCallback; import android.os.UserHandle; /** * Callback when lockout period expired and clients are allowed to authenticate again. * @hide */ -interface IFingerprintServiceLockoutResetCallback { +oneway interface IFingerprintServiceLockoutResetCallback { - /** Method is synchronous so wakelock is held when this is called from a WAKEUP alarm. */ - void onLockoutReset(long deviceId); + /** + * A wakelock will be held until the reciever calls back into {@param callback} + */ + void onLockoutReset(long deviceId, IRemoteCallback callback); } diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 273bc6484724f..132967c6b26a9 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -32,11 +32,14 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback; import android.os.Binder; +import android.os.Bundle; import android.os.DeadObjectException; import android.os.Environment; import android.os.Handler; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.PowerManager; +import android.os.PowerManager.WakeLock; import android.os.RemoteException; import android.os.SELinux; import android.os.ServiceManager; @@ -625,17 +628,28 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private class FingerprintServiceLockoutResetMonitor { + private static final long WAKELOCK_TIMEOUT_MS = 2000; private final IFingerprintServiceLockoutResetCallback mCallback; + private final WakeLock mWakeLock; public FingerprintServiceLockoutResetMonitor( IFingerprintServiceLockoutResetCallback callback) { mCallback = callback; + mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + "lockout reset callback"); } public void sendLockoutReset() { if (mCallback != null) { try { - mCallback.onLockoutReset(mHalDeviceId); + mWakeLock.acquire(WAKELOCK_TIMEOUT_MS); + mCallback.onLockoutReset(mHalDeviceId, new IRemoteCallback.Stub() { + + @Override + public void sendResult(Bundle data) throws RemoteException { + mWakeLock.release(); + } + }); } catch (DeadObjectException e) { Slog.w(TAG, "Death object while invoking onLockoutReset: ", e); mHandler.post(mRemoveCallbackRunnable); @@ -648,6 +662,9 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private final Runnable mRemoveCallbackRunnable = new Runnable() { @Override public void run() { + if (mWakeLock.isHeld()) { + mWakeLock.release(); + } removeLockoutResetCallback(FingerprintServiceLockoutResetMonitor.this); } };