am 3a464785: Add a private API to get notified about lockout resets
* commit '3a464785088e7fd206666f640912729533948ce8': Add a private API to get notified about lockout resets
This commit is contained in:
@@ -160,6 +160,7 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl \
|
||||
core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl \
|
||||
core/java/android/hardware/fingerprint/IFingerprintService.aidl \
|
||||
core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl \
|
||||
core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl \
|
||||
core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
|
||||
core/java/android/hardware/hdmi/IHdmiControlService.aidl \
|
||||
|
||||
@@ -391,6 +391,18 @@ public class FingerprintManager {
|
||||
public void onRemovalSucceeded(Fingerprint fingerprint) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static abstract class LockoutResetCallback {
|
||||
|
||||
/**
|
||||
* Called when lockout period expired and clients are allowed to listen for fingerprint
|
||||
* again.
|
||||
*/
|
||||
public void onLockoutReset() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* Request authentication of a crypto object. This call warms up the fingerprint hardware
|
||||
* and starts scanning for a fingerprint. It terminates when
|
||||
@@ -680,10 +692,37 @@ public class FingerprintManager {
|
||||
try {
|
||||
mService.resetTimeout(token);
|
||||
} catch (RemoteException e) {
|
||||
Log.v(TAG, "Remote exception in getAuthenticatorId(): ", e);
|
||||
Log.v(TAG, "Remote exception in resetTimeout(): ", e);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "getAuthenticatorId(): Service not connected!");
|
||||
Log.w(TAG, "resetTimeout(): Service not connected!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void addLockoutResetCallback(final LockoutResetCallback callback) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.addLockoutResetCallback(
|
||||
new IFingerprintServiceLockoutResetCallback.Stub() {
|
||||
|
||||
@Override
|
||||
public void onLockoutReset(long deviceId) throws RemoteException {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onLockoutReset();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (RemoteException e) {
|
||||
Log.v(TAG, "Remote exception in addLockoutResetCallback(): ", e);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "addLockoutResetCallback(): Service not connected!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package android.hardware.fingerprint;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import java.util.List;
|
||||
|
||||
@@ -71,4 +72,7 @@ interface IFingerprintService {
|
||||
|
||||
// Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
|
||||
void resetTimeout(in byte [] cryptoToken);
|
||||
|
||||
// Add a callback which gets notified when the fingerprint lockout period expired.
|
||||
void addLockoutResetCallback(IFingerprintServiceLockoutResetCallback callback);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.fingerprint;
|
||||
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
/**
|
||||
* Callback when lockout period expired and clients are allowed to authenticate again.
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IFingerprintServiceLockoutResetCallback {
|
||||
void onLockoutReset(long deviceId);
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
||||
@@ -472,6 +473,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFingerprintLockoutReset() {
|
||||
updateFingerprintListeningState();
|
||||
}
|
||||
|
||||
private void setFingerprintRunningState(int fingerprintRunningState) {
|
||||
boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
|
||||
boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
|
||||
@@ -681,6 +686,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
}
|
||||
};
|
||||
|
||||
private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
|
||||
= new FingerprintManager.LockoutResetCallback() {
|
||||
@Override
|
||||
public void onLockoutReset() {
|
||||
handleFingerprintLockoutReset();
|
||||
}
|
||||
};
|
||||
|
||||
private FingerprintManager.AuthenticationCallback mAuthenticationCallback
|
||||
= new AuthenticationCallback() {
|
||||
|
||||
@@ -1003,6 +1016,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
|
||||
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
|
||||
updateFingerprintListeningState();
|
||||
if (mFpm != null) {
|
||||
mFpm.addLockoutResetCallback(mLockoutResetCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFingerprintListeningState() {
|
||||
|
||||
@@ -24,7 +24,9 @@ import android.app.IUserSwitchObserver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
|
||||
import android.os.Binder;
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -51,7 +53,6 @@ import android.hardware.fingerprint.IFingerprintService;
|
||||
import android.hardware.fingerprint.IFingerprintDaemon;
|
||||
import android.hardware.fingerprint.IFingerprintDaemonCallback;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.view.Display;
|
||||
|
||||
import static android.Manifest.permission.MANAGE_FINGERPRINT;
|
||||
import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
|
||||
@@ -60,6 +61,7 @@ import static android.Manifest.permission.USE_FINGERPRINT;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -83,6 +85,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
||||
private ClientMonitor mAuthClient = null;
|
||||
private ClientMonitor mEnrollClient = null;
|
||||
private ClientMonitor mRemoveClient = null;
|
||||
private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors =
|
||||
new ArrayList<>();
|
||||
private final AppOpsManager mAppOps;
|
||||
|
||||
private static final long MS_PER_SEC = 1000;
|
||||
@@ -259,6 +263,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
||||
// 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);
|
||||
notifyLockoutResetMonitors();
|
||||
}
|
||||
|
||||
private boolean handleFailedAttempt(ClientMonitor clientMonitor) {
|
||||
@@ -499,6 +504,23 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
||||
opPackageName) == AppOpsManager.MODE_ALLOWED;
|
||||
}
|
||||
|
||||
private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) {
|
||||
if (!mLockoutMonitors.contains(monitor)) {
|
||||
mLockoutMonitors.add(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeLockoutResetCallback(
|
||||
FingerprintServiceLockoutResetMonitor monitor) {
|
||||
mLockoutMonitors.remove(monitor);
|
||||
}
|
||||
|
||||
private void notifyLockoutResetMonitors() {
|
||||
for (int i = 0; i < mLockoutMonitors.size(); i++) {
|
||||
mLockoutMonitors.get(i).sendLockoutReset();
|
||||
}
|
||||
}
|
||||
|
||||
private class ClientMonitor implements IBinder.DeathRecipient {
|
||||
IBinder token;
|
||||
IFingerprintServiceReceiver receiver;
|
||||
@@ -614,7 +636,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
||||
FingerprintUtils.vibrateFingerprintSuccess(getContext());
|
||||
}
|
||||
result |= true; // we have a valid fingerprint
|
||||
mLockoutReset.run();
|
||||
mHandler.post(mLockoutReset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -654,6 +676,36 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
||||
}
|
||||
}
|
||||
|
||||
private class FingerprintServiceLockoutResetMonitor {
|
||||
|
||||
private final IFingerprintServiceLockoutResetCallback mCallback;
|
||||
|
||||
public FingerprintServiceLockoutResetMonitor(
|
||||
IFingerprintServiceLockoutResetCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public void sendLockoutReset() {
|
||||
if (mCallback != null) {
|
||||
try {
|
||||
mCallback.onLockoutReset(mHalDeviceId);
|
||||
} catch (DeadObjectException e) {
|
||||
Slog.w(TAG, "Death object while invoking onLockoutReset: ", e);
|
||||
mHandler.post(mRemoveCallbackRunnable);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to invoke onLockoutReset: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mRemoveCallbackRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeLockoutResetCallback(FingerprintServiceLockoutResetMonitor.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IFingerprintDaemonCallback mDaemonCallback = new IFingerprintDaemonCallback.Stub() {
|
||||
|
||||
@Override
|
||||
@@ -922,7 +974,19 @@ 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.
|
||||
mLockoutReset.run();
|
||||
mHandler.post(mLockoutReset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLockoutResetCallback(final IFingerprintServiceLockoutResetCallback callback)
|
||||
throws RemoteException {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
addLockoutResetMonitor(
|
||||
new FingerprintServiceLockoutResetMonitor(callback));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user