* commit 'd302508d2838000b1dde05d9bfaf5e5181dcf9dc': 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/IFingerprintDaemon.aidl \
|
||||||
core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl \
|
core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl \
|
||||||
core/java/android/hardware/fingerprint/IFingerprintService.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/fingerprint/IFingerprintServiceReceiver.aidl \
|
||||||
core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
|
core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
|
||||||
core/java/android/hardware/hdmi/IHdmiControlService.aidl \
|
core/java/android/hardware/hdmi/IHdmiControlService.aidl \
|
||||||
|
|||||||
@@ -391,6 +391,18 @@ public class FingerprintManager {
|
|||||||
public void onRemovalSucceeded(Fingerprint fingerprint) { }
|
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
|
* Request authentication of a crypto object. This call warms up the fingerprint hardware
|
||||||
* and starts scanning for a fingerprint. It terminates when
|
* and starts scanning for a fingerprint. It terminates when
|
||||||
@@ -680,10 +692,37 @@ public class FingerprintManager {
|
|||||||
try {
|
try {
|
||||||
mService.resetTimeout(token);
|
mService.resetTimeout(token);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.v(TAG, "Remote exception in getAuthenticatorId(): ", e);
|
Log.v(TAG, "Remote exception in resetTimeout(): ", e);
|
||||||
}
|
}
|
||||||
} else {
|
} 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.os.Bundle;
|
||||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||||
|
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
|
||||||
import android.hardware.fingerprint.Fingerprint;
|
import android.hardware.fingerprint.Fingerprint;
|
||||||
import java.util.List;
|
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)
|
// Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
|
||||||
void resetTimeout(in byte [] cryptoToken);
|
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.content.IntentFilter;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.hardware.fingerprint.Fingerprint;
|
||||||
import android.hardware.fingerprint.FingerprintManager;
|
import android.hardware.fingerprint.FingerprintManager;
|
||||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
||||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
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) {
|
private void setFingerprintRunningState(int fingerprintRunningState) {
|
||||||
boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
|
boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
|
||||||
boolean isRunning = fingerprintRunningState == 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
|
private FingerprintManager.AuthenticationCallback mAuthenticationCallback
|
||||||
= new AuthenticationCallback() {
|
= new AuthenticationCallback() {
|
||||||
|
|
||||||
@@ -1003,6 +1016,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
|
|
||||||
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
|
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
|
||||||
updateFingerprintListeningState();
|
updateFingerprintListeningState();
|
||||||
|
if (mFpm != null) {
|
||||||
|
mFpm.addLockoutResetCallback(mLockoutResetCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFingerprintListeningState() {
|
private void updateFingerprintListeningState() {
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ import android.app.IUserSwitchObserver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
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.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.DeadObjectException;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -51,7 +53,6 @@ import android.hardware.fingerprint.IFingerprintService;
|
|||||||
import android.hardware.fingerprint.IFingerprintDaemon;
|
import android.hardware.fingerprint.IFingerprintDaemon;
|
||||||
import android.hardware.fingerprint.IFingerprintDaemonCallback;
|
import android.hardware.fingerprint.IFingerprintDaemonCallback;
|
||||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||||
import android.view.Display;
|
|
||||||
|
|
||||||
import static android.Manifest.permission.MANAGE_FINGERPRINT;
|
import static android.Manifest.permission.MANAGE_FINGERPRINT;
|
||||||
import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
|
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.File;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -83,6 +85,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
private ClientMonitor mAuthClient = null;
|
private ClientMonitor mAuthClient = null;
|
||||||
private ClientMonitor mEnrollClient = null;
|
private ClientMonitor mEnrollClient = null;
|
||||||
private ClientMonitor mRemoveClient = null;
|
private ClientMonitor mRemoveClient = null;
|
||||||
|
private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors =
|
||||||
|
new ArrayList<>();
|
||||||
private final AppOpsManager mAppOps;
|
private final AppOpsManager mAppOps;
|
||||||
|
|
||||||
private static final long MS_PER_SEC = 1000;
|
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
|
// If we're asked to reset failed attempts externally (i.e. from Keyguard), the runnable
|
||||||
// may still be in the queue; remove it.
|
// may still be in the queue; remove it.
|
||||||
mHandler.removeCallbacks(mLockoutReset);
|
mHandler.removeCallbacks(mLockoutReset);
|
||||||
|
notifyLockoutResetMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleFailedAttempt(ClientMonitor clientMonitor) {
|
private boolean handleFailedAttempt(ClientMonitor clientMonitor) {
|
||||||
@@ -499,6 +504,23 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
opPackageName) == AppOpsManager.MODE_ALLOWED;
|
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 {
|
private class ClientMonitor implements IBinder.DeathRecipient {
|
||||||
IBinder token;
|
IBinder token;
|
||||||
IFingerprintServiceReceiver receiver;
|
IFingerprintServiceReceiver receiver;
|
||||||
@@ -614,7 +636,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
|
||||||
mLockoutReset.run();
|
mHandler.post(mLockoutReset);
|
||||||
}
|
}
|
||||||
return result;
|
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() {
|
private IFingerprintDaemonCallback mDaemonCallback = new IFingerprintDaemonCallback.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -922,7 +974,19 @@ 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.
|
||||||
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