am 800ebfc1: Merge "Update and cleanup FingerprintManager API to new spec" into mnc-dev
* commit '800ebfc166a96e4125029cd994011ada750e56de': Update and cleanup FingerprintManager API to new spec
This commit is contained in:
@@ -13942,16 +13942,8 @@ package android.hardware.display {
|
|||||||
|
|
||||||
package android.hardware.fingerprint {
|
package android.hardware.fingerprint {
|
||||||
|
|
||||||
public final class Fingerprint implements android.os.Parcelable {
|
|
||||||
ctor public Fingerprint(java.lang.CharSequence, int, int, long);
|
|
||||||
method public int describeContents();
|
|
||||||
method public java.lang.CharSequence getName();
|
|
||||||
method public void writeToParcel(android.os.Parcel, int);
|
|
||||||
field public static final android.os.Parcelable.Creator<android.hardware.fingerprint.Fingerprint> CREATOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FingerprintManager {
|
public class FingerprintManager {
|
||||||
method public void authenticate(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.CancellationSignal, android.hardware.fingerprint.FingerprintManager.AuthenticationCallback, int);
|
method public void authenticate(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.CancellationSignal, int, android.hardware.fingerprint.FingerprintManager.AuthenticationCallback, android.os.Handler);
|
||||||
method public boolean hasEnrolledFingerprints();
|
method public boolean hasEnrolledFingerprints();
|
||||||
method public boolean isHardwareDetected();
|
method public boolean isHardwareDetected();
|
||||||
field public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0
|
field public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0
|
||||||
@@ -13960,14 +13952,12 @@ package android.hardware.fingerprint {
|
|||||||
field public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1
|
field public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1
|
||||||
field public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5; // 0x5
|
field public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5; // 0x5
|
||||||
field public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4; // 0x4
|
field public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4; // 0x4
|
||||||
field public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000; // 0x3e8
|
|
||||||
field public static final int FINGERPRINT_ERROR_CANCELED = 5; // 0x5
|
field public static final int FINGERPRINT_ERROR_CANCELED = 5; // 0x5
|
||||||
field public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1
|
field public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1
|
||||||
field public static final int FINGERPRINT_ERROR_LOCKOUT = 7; // 0x7
|
field public static final int FINGERPRINT_ERROR_LOCKOUT = 7; // 0x7
|
||||||
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
|
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
|
||||||
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
|
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
|
||||||
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
|
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
|
||||||
field public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000; // 0x3e8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class FingerprintManager.AuthenticationCallback {
|
public static abstract class FingerprintManager.AuthenticationCallback {
|
||||||
@@ -13979,11 +13969,10 @@ package android.hardware.fingerprint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final class FingerprintManager.AuthenticationResult {
|
public static final class FingerprintManager.AuthenticationResult {
|
||||||
ctor public FingerprintManager.AuthenticationResult(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.hardware.fingerprint.Fingerprint);
|
|
||||||
method public android.hardware.fingerprint.FingerprintManager.CryptoObject getCryptoObject();
|
method public android.hardware.fingerprint.FingerprintManager.CryptoObject getCryptoObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FingerprintManager.CryptoObject {
|
public static final class FingerprintManager.CryptoObject {
|
||||||
ctor public FingerprintManager.CryptoObject(java.security.Signature);
|
ctor public FingerprintManager.CryptoObject(java.security.Signature);
|
||||||
ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
|
ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
|
||||||
ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
|
ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
|
||||||
|
|||||||
@@ -14260,16 +14260,8 @@ package android.hardware.display {
|
|||||||
|
|
||||||
package android.hardware.fingerprint {
|
package android.hardware.fingerprint {
|
||||||
|
|
||||||
public final class Fingerprint implements android.os.Parcelable {
|
|
||||||
ctor public Fingerprint(java.lang.CharSequence, int, int, long);
|
|
||||||
method public int describeContents();
|
|
||||||
method public java.lang.CharSequence getName();
|
|
||||||
method public void writeToParcel(android.os.Parcel, int);
|
|
||||||
field public static final android.os.Parcelable.Creator<android.hardware.fingerprint.Fingerprint> CREATOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FingerprintManager {
|
public class FingerprintManager {
|
||||||
method public void authenticate(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.CancellationSignal, android.hardware.fingerprint.FingerprintManager.AuthenticationCallback, int);
|
method public void authenticate(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.CancellationSignal, int, android.hardware.fingerprint.FingerprintManager.AuthenticationCallback, android.os.Handler);
|
||||||
method public boolean hasEnrolledFingerprints();
|
method public boolean hasEnrolledFingerprints();
|
||||||
method public boolean isHardwareDetected();
|
method public boolean isHardwareDetected();
|
||||||
field public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0
|
field public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0
|
||||||
@@ -14278,14 +14270,12 @@ package android.hardware.fingerprint {
|
|||||||
field public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1
|
field public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1
|
||||||
field public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5; // 0x5
|
field public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5; // 0x5
|
||||||
field public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4; // 0x4
|
field public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4; // 0x4
|
||||||
field public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000; // 0x3e8
|
|
||||||
field public static final int FINGERPRINT_ERROR_CANCELED = 5; // 0x5
|
field public static final int FINGERPRINT_ERROR_CANCELED = 5; // 0x5
|
||||||
field public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1
|
field public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1
|
||||||
field public static final int FINGERPRINT_ERROR_LOCKOUT = 7; // 0x7
|
field public static final int FINGERPRINT_ERROR_LOCKOUT = 7; // 0x7
|
||||||
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
|
field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
|
||||||
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
|
field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
|
||||||
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
|
field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
|
||||||
field public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000; // 0x3e8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class FingerprintManager.AuthenticationCallback {
|
public static abstract class FingerprintManager.AuthenticationCallback {
|
||||||
@@ -14297,11 +14287,10 @@ package android.hardware.fingerprint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final class FingerprintManager.AuthenticationResult {
|
public static final class FingerprintManager.AuthenticationResult {
|
||||||
ctor public FingerprintManager.AuthenticationResult(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.hardware.fingerprint.Fingerprint);
|
|
||||||
method public android.hardware.fingerprint.FingerprintManager.CryptoObject getCryptoObject();
|
method public android.hardware.fingerprint.FingerprintManager.CryptoObject getCryptoObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FingerprintManager.CryptoObject {
|
public static final class FingerprintManager.CryptoObject {
|
||||||
ctor public FingerprintManager.CryptoObject(java.security.Signature);
|
ctor public FingerprintManager.CryptoObject(java.security.Signature);
|
||||||
ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
|
ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
|
||||||
ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
|
ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
|
||||||
|
|||||||
@@ -18,32 +18,30 @@ package android.hardware.fingerprint;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.RequiresPermission;
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.CancellationSignal.OnCancelListener;
|
import android.os.CancellationSignal.OnCancelListener;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Parcel;
|
import android.os.Looper;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
|
|
||||||
import android.security.keystore.AndroidKeyStoreProvider;
|
import android.security.keystore.AndroidKeyStoreProvider;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.USE_FINGERPRINT;
|
||||||
|
import static android.Manifest.permission.MANAGE_FINGERPRINT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that coordinates access to the fingerprint hardware.
|
* A class that coordinates access to the fingerprint hardware.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -57,9 +55,10 @@ public class FingerprintManager {
|
|||||||
private static final boolean DEBUG = true;
|
private static final boolean DEBUG = true;
|
||||||
private static final int MSG_ENROLL_RESULT = 100;
|
private static final int MSG_ENROLL_RESULT = 100;
|
||||||
private static final int MSG_ACQUIRED = 101;
|
private static final int MSG_ACQUIRED = 101;
|
||||||
private static final int MSG_AUTHENTICATED = 102;
|
private static final int MSG_AUTHENTICATION_SUCCEEDED = 102;
|
||||||
private static final int MSG_ERROR = 103;
|
private static final int MSG_AUTHENTICATION_FAILED = 103;
|
||||||
private static final int MSG_REMOVED = 104;
|
private static final int MSG_ERROR = 104;
|
||||||
|
private static final int MSG_REMOVED = 105;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Error messages from fingerprint hardware during initilization, enrollment, authentication or
|
// Error messages from fingerprint hardware during initilization, enrollment, authentication or
|
||||||
@@ -112,6 +111,7 @@ public class FingerprintManager {
|
|||||||
/**
|
/**
|
||||||
* Hardware vendors may extend this list if there are conditions that do not fall under one of
|
* Hardware vendors may extend this list if there are conditions that do not fall under one of
|
||||||
* the above categories. Vendors are responsible for providing error strings for these errors.
|
* the above categories. Vendors are responsible for providing error strings for these errors.
|
||||||
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
|
public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
|
||||||
|
|
||||||
@@ -162,6 +162,7 @@ public class FingerprintManager {
|
|||||||
/**
|
/**
|
||||||
* Hardware vendors may extend this list if there are conditions that do not fall under one of
|
* Hardware vendors may extend this list if there are conditions that do not fall under one of
|
||||||
* the above categories. Vendors are responsible for providing error strings for these errors.
|
* the above categories. Vendors are responsible for providing error strings for these errors.
|
||||||
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
|
public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
|
||||||
|
|
||||||
@@ -173,6 +174,7 @@ public class FingerprintManager {
|
|||||||
private RemovalCallback mRemovalCallback;
|
private RemovalCallback mRemovalCallback;
|
||||||
private CryptoObject mCryptoObject;
|
private CryptoObject mCryptoObject;
|
||||||
private Fingerprint mRemovalFingerprint;
|
private Fingerprint mRemovalFingerprint;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
private class OnEnrollCancelListener implements OnCancelListener {
|
private class OnEnrollCancelListener implements OnCancelListener {
|
||||||
@Override
|
@Override
|
||||||
@@ -198,72 +200,71 @@ public class FingerprintManager {
|
|||||||
* A wrapper class for the crypto objects supported by FingerprintManager. Currently the
|
* A wrapper class for the crypto objects supported by FingerprintManager. Currently the
|
||||||
* framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
|
* framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
|
||||||
*/
|
*/
|
||||||
public static class CryptoObject {
|
public static final class CryptoObject {
|
||||||
|
|
||||||
public CryptoObject(@NonNull Signature signature) {
|
public CryptoObject(@NonNull Signature signature) {
|
||||||
mSignature = signature;
|
mCrypto = signature;
|
||||||
mCipher = null;
|
|
||||||
mMac = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CryptoObject(@NonNull Cipher cipher) {
|
public CryptoObject(@NonNull Cipher cipher) {
|
||||||
mCipher = cipher;
|
mCrypto = cipher;
|
||||||
mSignature = null;
|
|
||||||
mMac = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CryptoObject(@NonNull Mac mac) {
|
public CryptoObject(@NonNull Mac mac) {
|
||||||
mMac = mac;
|
mCrypto = mac;
|
||||||
mCipher = null;
|
|
||||||
mSignature = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get {@link Signature} object.
|
* Get {@link Signature} object.
|
||||||
* @return {@link Signature} object or null if this doesn't contain one.
|
* @return {@link Signature} object or null if this doesn't contain one.
|
||||||
*/
|
*/
|
||||||
public Signature getSignature() { return mSignature; }
|
public Signature getSignature() {
|
||||||
|
return mCrypto instanceof Signature ? (Signature) mCrypto : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get {@link Cipher} object.
|
* Get {@link Cipher} object.
|
||||||
* @return {@link Cipher} object or null if this doesn't contain one.
|
* @return {@link Cipher} object or null if this doesn't contain one.
|
||||||
*/
|
*/
|
||||||
public Cipher getCipher() { return mCipher; }
|
public Cipher getCipher() {
|
||||||
|
return mCrypto instanceof Cipher ? (Cipher) mCrypto : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get {@link Mac} object.
|
* Get {@link Mac} object.
|
||||||
* @return {@link Mac} object or null if this doesn't contain one.
|
* @return {@link Mac} object or null if this doesn't contain one.
|
||||||
*/
|
*/
|
||||||
public Mac getMac() { return mMac; }
|
public Mac getMac() {
|
||||||
|
return mCrypto instanceof Mac ? (Mac) mCrypto : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
* @return the opId associated with this object or 0 if none
|
* @return the opId associated with this object or 0 if none
|
||||||
*/
|
*/
|
||||||
public long getOpId() {
|
public long getOpId() {
|
||||||
if (mSignature != null) {
|
return mCrypto != null ?
|
||||||
return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mSignature);
|
AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCrypto) : 0;
|
||||||
} else if (mCipher != null) {
|
|
||||||
return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCipher);
|
|
||||||
} else if (mMac != null) {
|
|
||||||
return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mMac);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Signature mSignature;
|
private final Object mCrypto;
|
||||||
private final Cipher mCipher;
|
|
||||||
private final Mac mMac;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
|
* Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
|
||||||
* CancellationSignal, AuthenticationCallback, int)}.
|
* CancellationSignal, int, AuthenticationCallback, Handler)}.
|
||||||
*/
|
*/
|
||||||
public static final class AuthenticationResult {
|
public static final class AuthenticationResult {
|
||||||
private Fingerprint mFingerprint;
|
private Fingerprint mFingerprint;
|
||||||
private CryptoObject mCryptoObject;
|
private CryptoObject mCryptoObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication result
|
||||||
|
*
|
||||||
|
* @param crypto the crypto object
|
||||||
|
* @param fingerprint the recognized fingerprint data, if allowed.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
|
public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
|
||||||
mCryptoObject = crypto;
|
mCryptoObject = crypto;
|
||||||
mFingerprint = fingerprint;
|
mFingerprint = fingerprint;
|
||||||
@@ -272,7 +273,7 @@ public class FingerprintManager {
|
|||||||
/**
|
/**
|
||||||
* Obtain the crypto object associated with this transaction
|
* Obtain the crypto object associated with this transaction
|
||||||
* @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
|
* @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
|
||||||
* CancellationSignal, AuthenticationCallback, int)}.
|
* CancellationSignal, int, AuthenticationCallback, Handler)}.
|
||||||
*/
|
*/
|
||||||
public CryptoObject getCryptoObject() { return mCryptoObject; }
|
public CryptoObject getCryptoObject() { return mCryptoObject; }
|
||||||
|
|
||||||
@@ -287,28 +288,28 @@ public class FingerprintManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
|
* Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
|
||||||
* CancellationSignal, AuthenticationCallback, int)}. Users of {@link
|
* CancellationSignal, int, AuthenticationCallback, Handler)}. Users of {@link
|
||||||
* FingerprintManager#authenticate(CryptoObject, CancellationSignal,
|
* FingerprintManager#authenticate(CryptoObject, CancellationSignal,
|
||||||
* AuthenticationCallback, int) } must provide an implementation of this for listening to
|
* int, AuthenticationCallback, Handler) } must provide an implementation of this for listening to
|
||||||
* fingerprint events.
|
* fingerprint events.
|
||||||
*/
|
*/
|
||||||
public static abstract class AuthenticationCallback {
|
public static abstract class AuthenticationCallback {
|
||||||
/**
|
/**
|
||||||
* Called when an unrecoverable error has been encountered and the operation is complete.
|
* Called when an unrecoverable error has been encountered and the operation is complete.
|
||||||
* No further callbacks will be made on this object.
|
* No further callbacks will be made on this object.
|
||||||
* @param errMsgId An integer identifying the error message
|
* @param errorCode An integer identifying the error message
|
||||||
* @param errString A human-readable error string that can be shown in UI
|
* @param errString A human-readable error string that can be shown in UI
|
||||||
*/
|
*/
|
||||||
public void onAuthenticationError(int errMsgId, CharSequence errString) { }
|
public void onAuthenticationError(int errorCode, CharSequence errString) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a recoverable error has been encountered during authentication. The help
|
* Called when a recoverable error has been encountered during authentication. The help
|
||||||
* string is provided to give the user guidance for what went wrong, such as
|
* string is provided to give the user guidance for what went wrong, such as
|
||||||
* "Sensor dirty, please clean it."
|
* "Sensor dirty, please clean it."
|
||||||
* @param helpMsgId An integer identifying the error message
|
* @param helpCode An integer identifying the error message
|
||||||
* @param helpString A human-readable string that can be shown in UI
|
* @param helpString A human-readable string that can be shown in UI
|
||||||
*/
|
*/
|
||||||
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { }
|
public void onAuthenticationHelp(int helpCode, CharSequence helpString) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a fingerprint is recognized.
|
* Called when a fingerprint is recognized.
|
||||||
@@ -326,7 +327,7 @@ public class FingerprintManager {
|
|||||||
* Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
|
* Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
|
||||||
* CancellationSignal, int). Users of {@link #FingerprintManager()}
|
* CancellationSignal, int). Users of {@link #FingerprintManager()}
|
||||||
* must provide an implementation of this to {@link FingerprintManager#enroll(long,
|
* must provide an implementation of this to {@link FingerprintManager#enroll(long,
|
||||||
* CancellationSignal, EnrollmentCallback, int) for listening to fingerprint events.
|
* CancellationSignal, int, EnrollmentCallback) for listening to fingerprint events.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -392,31 +393,35 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @param crypto object associated with the call or null if none required.
|
* @param crypto object associated with the call or null if none required.
|
||||||
* @param cancel an object that can be used to cancel authentication
|
* @param cancel an object that can be used to cancel authentication
|
||||||
* @param callback an object to receive authentication events
|
|
||||||
* @param flags optional flags; should be 0
|
* @param flags optional flags; should be 0
|
||||||
|
* @param callback an object to receive authentication events
|
||||||
|
* @param handler an optional handler to handle callback events
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(USE_FINGERPRINT)
|
||||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||||
@NonNull AuthenticationCallback callback, int flags) {
|
int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
|
||||||
authenticate(crypto, cancel, callback, flags, UserHandle.myUserId());
|
authenticate(crypto, cancel, flags, callback, handler, UserHandle.myUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request authentication of a crypto object. This call warms up the fingerprint hardware
|
* Use the provided handler thread for events.
|
||||||
* and starts scanning for a fingerprint. It terminates when
|
* @param handler
|
||||||
* {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
|
*/
|
||||||
* {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
|
private void useHandler(Handler handler) {
|
||||||
* which point the object is no longer valid. The operation can be canceled by using the
|
if (handler != null) {
|
||||||
* provided cancel object.
|
mHandler = new MyHandler(handler.getLooper());
|
||||||
*
|
} else if (mHandler.getLooper() != mContext.getMainLooper()){
|
||||||
* @param crypto object associated with the call or null if none required.
|
mHandler = new MyHandler(mContext.getMainLooper());
|
||||||
* @param cancel an object that can be used to cancel authentication
|
}
|
||||||
* @param callback an object to receive authentication events
|
}
|
||||||
* @param flags optional flags; should be 0
|
|
||||||
* @param userId the userId the fingerprint belongs to
|
/**
|
||||||
|
* Per-user version
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(USE_FINGERPRINT)
|
||||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||||
@NonNull AuthenticationCallback callback, int flags, int userId) {
|
int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId) {
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
throw new IllegalArgumentException("Must supply an authentication callback");
|
throw new IllegalArgumentException("Must supply an authentication callback");
|
||||||
}
|
}
|
||||||
@@ -431,6 +436,7 @@ public class FingerprintManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mService != null) try {
|
if (mService != null) try {
|
||||||
|
useHandler(handler);
|
||||||
mAuthenticationCallback = callback;
|
mAuthenticationCallback = callback;
|
||||||
mCryptoObject = crypto;
|
mCryptoObject = crypto;
|
||||||
long sessionId = crypto != null ? crypto.getOpId() : 0;
|
long sessionId = crypto != null ? crypto.getOpId() : 0;
|
||||||
@@ -458,12 +464,13 @@ public class FingerprintManager {
|
|||||||
* @param token a unique token provided by a recent creation or verification of device
|
* @param token a unique token provided by a recent creation or verification of device
|
||||||
* credentials (e.g. pin, pattern or password).
|
* credentials (e.g. pin, pattern or password).
|
||||||
* @param cancel an object that can be used to cancel enrollment
|
* @param cancel an object that can be used to cancel enrollment
|
||||||
* @param callback an object to receive enrollment events
|
|
||||||
* @param flags optional flags
|
* @param flags optional flags
|
||||||
|
* @param callback an object to receive enrollment events
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void enroll(byte [] token, CancellationSignal cancel, EnrollmentCallback callback,
|
@RequiresPermission(MANAGE_FINGERPRINT)
|
||||||
int flags) {
|
public void enroll(byte [] token, CancellationSignal cancel, int flags,
|
||||||
|
EnrollmentCallback callback) {
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
throw new IllegalArgumentException("Must supply an enrollment callback");
|
throw new IllegalArgumentException("Must supply an enrollment callback");
|
||||||
}
|
}
|
||||||
@@ -496,6 +503,7 @@ public class FingerprintManager {
|
|||||||
* existing device credentials (e.g. pin/pattern/password).
|
* existing device credentials (e.g. pin/pattern/password).
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(MANAGE_FINGERPRINT)
|
||||||
public long preEnroll() {
|
public long preEnroll() {
|
||||||
long result = 0;
|
long result = 0;
|
||||||
if (mService != null) try {
|
if (mService != null) try {
|
||||||
@@ -514,6 +522,7 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(MANAGE_FINGERPRINT)
|
||||||
public void remove(Fingerprint fp, RemovalCallback callback) {
|
public void remove(Fingerprint fp, RemovalCallback callback) {
|
||||||
if (mService != null) try {
|
if (mService != null) try {
|
||||||
mRemovalCallback = callback;
|
mRemovalCallback = callback;
|
||||||
@@ -535,6 +544,7 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(MANAGE_FINGERPRINT)
|
||||||
public void rename(int fpId, String newName) {
|
public void rename(int fpId, String newName) {
|
||||||
// Renames the given fpId
|
// Renames the given fpId
|
||||||
if (mService != null) {
|
if (mService != null) {
|
||||||
@@ -554,6 +564,7 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(USE_FINGERPRINT)
|
||||||
public List<Fingerprint> getEnrolledFingerprints(int userId) {
|
public List<Fingerprint> getEnrolledFingerprints(int userId) {
|
||||||
if (mService != null) try {
|
if (mService != null) try {
|
||||||
return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
|
return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
|
||||||
@@ -569,6 +580,7 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(USE_FINGERPRINT)
|
||||||
public List<Fingerprint> getEnrolledFingerprints() {
|
public List<Fingerprint> getEnrolledFingerprints() {
|
||||||
return getEnrolledFingerprints(UserHandle.myUserId());
|
return getEnrolledFingerprints(UserHandle.myUserId());
|
||||||
}
|
}
|
||||||
@@ -578,6 +590,7 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @return true if at least one fingerprint is enrolled, false otherwise
|
* @return true if at least one fingerprint is enrolled, false otherwise
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(USE_FINGERPRINT)
|
||||||
public boolean hasEnrolledFingerprints() {
|
public boolean hasEnrolledFingerprints() {
|
||||||
if (mService != null) try {
|
if (mService != null) try {
|
||||||
return mService.hasEnrolledFingerprints(UserHandle.myUserId(),
|
return mService.hasEnrolledFingerprints(UserHandle.myUserId(),
|
||||||
@@ -593,6 +606,7 @@ public class FingerprintManager {
|
|||||||
*
|
*
|
||||||
* @return true if hardware is present and functional, false otherwise.
|
* @return true if hardware is present and functional, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
@RequiresPermission(USE_FINGERPRINT)
|
||||||
public boolean isHardwareDetected() {
|
public boolean isHardwareDetected() {
|
||||||
if (mService != null) {
|
if (mService != null) {
|
||||||
try {
|
try {
|
||||||
@@ -626,13 +640,15 @@ public class FingerprintManager {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Handler mHandler;
|
|
||||||
|
|
||||||
private class MyHandler extends Handler {
|
private class MyHandler extends Handler {
|
||||||
private MyHandler(Context context) {
|
private MyHandler(Context context) {
|
||||||
super(context.getMainLooper());
|
super(context.getMainLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MyHandler(Looper looper) {
|
||||||
|
super(looper);
|
||||||
|
}
|
||||||
|
|
||||||
public void handleMessage(android.os.Message msg) {
|
public void handleMessage(android.os.Message msg) {
|
||||||
switch(msg.what) {
|
switch(msg.what) {
|
||||||
case MSG_ENROLL_RESULT:
|
case MSG_ENROLL_RESULT:
|
||||||
@@ -641,8 +657,11 @@ public class FingerprintManager {
|
|||||||
case MSG_ACQUIRED:
|
case MSG_ACQUIRED:
|
||||||
sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
|
sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
|
||||||
break;
|
break;
|
||||||
case MSG_AUTHENTICATED:
|
case MSG_AUTHENTICATION_SUCCEEDED:
|
||||||
sendAuthenticatedResult((Fingerprint) msg.obj);
|
sendAuthenticatedSucceeded((Fingerprint) msg.obj);
|
||||||
|
break;
|
||||||
|
case MSG_AUTHENTICATION_FAILED:
|
||||||
|
sendAuthenticatedFailed();
|
||||||
break;
|
break;
|
||||||
case MSG_ERROR:
|
case MSG_ERROR:
|
||||||
sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
|
sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
|
||||||
@@ -684,15 +703,16 @@ public class FingerprintManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendAuthenticatedResult(Fingerprint fp) {
|
private void sendAuthenticatedSucceeded(Fingerprint fp) {
|
||||||
if (mAuthenticationCallback != null) {
|
if (mAuthenticationCallback != null) {
|
||||||
if (fp.getFingerId() == 0) {
|
final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
|
||||||
// Fingerprint template valid but doesn't match one in database
|
mAuthenticationCallback.onAuthenticationSucceeded(result);
|
||||||
mAuthenticationCallback.onAuthenticationFailed();
|
}
|
||||||
} else {
|
}
|
||||||
final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
|
|
||||||
mAuthenticationCallback.onAuthenticationSucceeded(result);
|
private void sendAuthenticatedFailed() {
|
||||||
}
|
if (mAuthenticationCallback != null) {
|
||||||
|
mAuthenticationCallback.onAuthenticationFailed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -809,24 +829,33 @@ public class FingerprintManager {
|
|||||||
|
|
||||||
private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
|
private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
|
||||||
|
|
||||||
|
@Override // binder call
|
||||||
public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
|
public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
|
||||||
mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
|
mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
|
||||||
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
|
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // binder call
|
||||||
public void onAcquired(long deviceId, int acquireInfo) {
|
public void onAcquired(long deviceId, int acquireInfo) {
|
||||||
mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
|
mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAuthenticated(long deviceId, int fingerId, int groupId) {
|
@Override // binder call
|
||||||
mHandler.obtainMessage(MSG_AUTHENTICATED,
|
public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) {
|
||||||
new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
|
mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // binder call
|
||||||
|
public void onAuthenticationFailed(long deviceId) {
|
||||||
|
mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // binder call
|
||||||
public void onError(long deviceId, int error) {
|
public void onError(long deviceId, int error) {
|
||||||
mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
|
mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // binder call
|
||||||
public void onRemoved(long deviceId, int fingerId, int groupId) {
|
public void onRemoved(long deviceId, int fingerId, int groupId) {
|
||||||
mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
|
mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package android.hardware.fingerprint;
|
package android.hardware.fingerprint;
|
||||||
|
|
||||||
|
import android.hardware.fingerprint.Fingerprint;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ import android.os.UserHandle;
|
|||||||
oneway interface IFingerprintServiceReceiver {
|
oneway interface IFingerprintServiceReceiver {
|
||||||
void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining);
|
void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining);
|
||||||
void onAcquired(long deviceId, int acquiredInfo);
|
void onAcquired(long deviceId, int acquiredInfo);
|
||||||
void onAuthenticated(long deviceId, int fingerId, int groupId);
|
void onAuthenticationSucceeded(long deviceId, in Fingerprint fp);
|
||||||
|
void onAuthenticationFailed(long deviceId);
|
||||||
void onError(long deviceId, int error);
|
void onError(long deviceId, int error);
|
||||||
void onRemoved(long deviceId, int fingerId, int groupId);
|
void onRemoved(long deviceId, int fingerId, int groupId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ of the two modes:
|
|||||||
reset (e.g. by a Device Admin).</li>
|
reset (e.g. by a Device Admin).</li>
|
||||||
<li>User authentication is required for every use of the key. In this mode, a specific operation
|
<li>User authentication is required for every use of the key. In this mode, a specific operation
|
||||||
involving a specific key is authorized by the user. Currently, the only means of such
|
involving a specific key is authorized by the user. Currently, the only means of such
|
||||||
authorization is fingerprint authentication: {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, int) FingerprintManager.authenticate}.
|
authorization is fingerprint authentication: {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}.
|
||||||
Such keys can only be generated or imported if at least one fingerprint is enrolled (see {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
|
Such keys can only be generated or imported if at least one fingerprint is enrolled (see {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
|
||||||
These keys become permanently invalidated once all fingerprints are unenrolled.</li>
|
These keys become permanently invalidated once all fingerprints are unenrolled.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -796,7 +796,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
mFingerprintCancelSignal.cancel();
|
mFingerprintCancelSignal.cancel();
|
||||||
}
|
}
|
||||||
mFingerprintCancelSignal = new CancellationSignal();
|
mFingerprintCancelSignal = new CancellationSignal();
|
||||||
mFpm.authenticate(null, mFingerprintCancelSignal, mAuthenticationCallback, 0, userId);
|
mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
|
||||||
setFingerprintRunningDetectionRunning(true);
|
setFingerprintRunningDetectionRunning(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.app.AppOpsManager;
|
|||||||
import android.app.IUserSwitchObserver;
|
import android.app.IUserSwitchObserver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -73,13 +74,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
private ClientMonitor mRemoveClient = null;
|
private ClientMonitor mRemoveClient = null;
|
||||||
private final AppOpsManager mAppOps;
|
private final AppOpsManager mAppOps;
|
||||||
|
|
||||||
// Message types. Used internally to dispatch messages to the correct callback.
|
|
||||||
// Must agree with the list in fingerprint.h
|
|
||||||
private static final int FINGERPRINT_ERROR = -1;
|
|
||||||
private static final int FINGERPRINT_ACQUIRED = 1;
|
|
||||||
private static final int FINGERPRINT_TEMPLATE_ENROLLING = 3;
|
|
||||||
private static final int FINGERPRINT_TEMPLATE_REMOVED = 4;
|
|
||||||
private static final int FINGERPRINT_AUTHENTICATED = 5;
|
|
||||||
private static final long MS_PER_SEC = 1000;
|
private static final long MS_PER_SEC = 1000;
|
||||||
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
|
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
|
||||||
private static final int MAX_FAILED_ATTEMPTS = 5;
|
private static final int MAX_FAILED_ATTEMPTS = 5;
|
||||||
@@ -207,7 +201,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
if (mEnrollClient != null) {
|
if (mEnrollClient != null) {
|
||||||
if (mEnrollClient.sendEnrollResult(fingerId, groupId, remaining)) {
|
if (mEnrollClient.sendEnrollResult(fingerId, groupId, remaining)) {
|
||||||
if (remaining == 0) {
|
if (remaining == 0) {
|
||||||
ContentResolver res = mContext.getContentResolver();
|
|
||||||
addTemplateForUser(mEnrollClient, fingerId);
|
addTemplateForUser(mEnrollClient, fingerId);
|
||||||
removeClient(mEnrollClient);
|
removeClient(mEnrollClient);
|
||||||
}
|
}
|
||||||
@@ -262,14 +255,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startEnrollment(IBinder token, byte[] cryptoToken, int groupId,
|
void startEnrollment(IBinder token, byte[] cryptoToken, int groupId,
|
||||||
IFingerprintServiceReceiver receiver, int flags) {
|
IFingerprintServiceReceiver receiver, int flags, boolean restricted) {
|
||||||
IFingerprintDaemon daemon = getFingerprintDaemon();
|
IFingerprintDaemon daemon = getFingerprintDaemon();
|
||||||
if (daemon == null) {
|
if (daemon == null) {
|
||||||
Slog.w(TAG, "enroll: no fingeprintd!");
|
Slog.w(TAG, "enroll: no fingeprintd!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stopPendingOperations();
|
stopPendingOperations();
|
||||||
mEnrollClient = new ClientMonitor(token, receiver, groupId);
|
mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted);
|
||||||
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
|
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
|
||||||
try {
|
try {
|
||||||
final int result = daemon.enroll(cryptoToken, groupId, timeout);
|
final int result = daemon.enroll(cryptoToken, groupId, timeout);
|
||||||
@@ -328,14 +321,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startAuthentication(IBinder token, long opId, int groupId,
|
void startAuthentication(IBinder token, long opId, int groupId,
|
||||||
IFingerprintServiceReceiver receiver, int flags) {
|
IFingerprintServiceReceiver receiver, int flags, boolean restricted) {
|
||||||
IFingerprintDaemon daemon = getFingerprintDaemon();
|
IFingerprintDaemon daemon = getFingerprintDaemon();
|
||||||
if (daemon == null) {
|
if (daemon == null) {
|
||||||
Slog.w(TAG, "startAuthentication: no fingeprintd!");
|
Slog.w(TAG, "startAuthentication: no fingeprintd!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stopPendingOperations();
|
stopPendingOperations();
|
||||||
mAuthClient = new ClientMonitor(token, receiver, groupId);
|
mAuthClient = new ClientMonitor(token, receiver, groupId, restricted);
|
||||||
if (inLockoutMode()) {
|
if (inLockoutMode()) {
|
||||||
Slog.v(TAG, "In lockout mode; disallowing authentication");
|
Slog.v(TAG, "In lockout mode; disallowing authentication");
|
||||||
if (!mAuthClient.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
|
if (!mAuthClient.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
|
||||||
@@ -344,7 +337,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
mAuthClient = null;
|
mAuthClient = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
|
|
||||||
try {
|
try {
|
||||||
final int result = daemon.authenticate(opId, groupId);
|
final int result = daemon.authenticate(opId, groupId);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
@@ -378,13 +370,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startRemove(IBinder token, int fingerId, int userId,
|
void startRemove(IBinder token, int fingerId, int userId,
|
||||||
IFingerprintServiceReceiver receiver) {
|
IFingerprintServiceReceiver receiver, boolean restricted) {
|
||||||
IFingerprintDaemon daemon = getFingerprintDaemon();
|
IFingerprintDaemon daemon = getFingerprintDaemon();
|
||||||
if (daemon == null) {
|
if (daemon == null) {
|
||||||
Slog.w(TAG, "startRemove: no fingeprintd!");
|
Slog.w(TAG, "startRemove: no fingeprintd!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mRemoveClient = new ClientMonitor(token, receiver, userId);
|
|
||||||
|
mRemoveClient = new ClientMonitor(token, receiver, userId, restricted);
|
||||||
// The fingerprint template ids will be removed when we get confirmation from the HAL
|
// The fingerprint template ids will be removed when we get confirmation from the HAL
|
||||||
try {
|
try {
|
||||||
final int result = daemon.remove(fingerId, userId);
|
final int result = daemon.remove(fingerId, userId);
|
||||||
@@ -404,6 +397,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
return mFingerprintUtils.getFingerprintsForUser(mContext, groupId).size() > 0;
|
return mFingerprintUtils.getFingerprintsForUser(mContext, groupId).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean hasPermission(String permission) {
|
||||||
|
return getContext().checkCallingOrSelfPermission(permission)
|
||||||
|
== PackageManager.PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
void checkPermission(String permission) {
|
void checkPermission(String permission) {
|
||||||
getContext().enforceCallingOrSelfPermission(permission,
|
getContext().enforceCallingOrSelfPermission(permission,
|
||||||
"Must have " + permission + " permission.");
|
"Must have " + permission + " permission.");
|
||||||
@@ -420,11 +418,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
IBinder token;
|
IBinder token;
|
||||||
IFingerprintServiceReceiver receiver;
|
IFingerprintServiceReceiver receiver;
|
||||||
int userId;
|
int userId;
|
||||||
|
boolean restricted; // True if client does not have MANAGE_FINGERPRINT permission
|
||||||
|
|
||||||
public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId) {
|
public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId,
|
||||||
|
boolean restricted) {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
|
this.restricted = restricted;
|
||||||
try {
|
try {
|
||||||
token.linkToDeath(this, 0);
|
token.linkToDeath(this, 0);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -498,7 +499,13 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
boolean result = false;
|
boolean result = false;
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
try {
|
try {
|
||||||
receiver.onAuthenticated(mHalDeviceId, fpId, groupId);
|
if (fpId == 0) {
|
||||||
|
receiver.onAuthenticationFailed(mHalDeviceId);
|
||||||
|
} else {
|
||||||
|
Fingerprint fp = !restricted ?
|
||||||
|
new Fingerprint("" /* TODO */, groupId, fpId, mHalDeviceId) : null;
|
||||||
|
receiver.onAuthenticationSucceeded(mHalDeviceId, fp);
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "Failed to notify Authenticated:", e);
|
Slog.w(TAG, "Failed to notify Authenticated:", e);
|
||||||
result = true; // client failed
|
result = true; // client failed
|
||||||
@@ -592,14 +599,22 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
final IFingerprintServiceReceiver receiver, final int flags) {
|
final IFingerprintServiceReceiver receiver, final int flags) {
|
||||||
checkPermission(MANAGE_FINGERPRINT);
|
checkPermission(MANAGE_FINGERPRINT);
|
||||||
final byte [] cryptoClone = Arrays.copyOf(cryptoToken, cryptoToken.length);
|
final byte [] cryptoClone = Arrays.copyOf(cryptoToken, cryptoToken.length);
|
||||||
|
|
||||||
|
final boolean restricted = isRestricted();
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
startEnrollment(token, cryptoClone, groupId, receiver, flags);
|
startEnrollment(token, cryptoClone, groupId, receiver, flags, restricted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRestricted() {
|
||||||
|
// Only give privileged apps (like Settings) access to fingerprint info
|
||||||
|
final boolean restricted = !hasPermission(MANAGE_FINGERPRINT);
|
||||||
|
return restricted;
|
||||||
|
}
|
||||||
|
|
||||||
@Override // Binder call
|
@Override // Binder call
|
||||||
public void cancelEnrollment(final IBinder token) {
|
public void cancelEnrollment(final IBinder token) {
|
||||||
checkPermission(MANAGE_FINGERPRINT);
|
checkPermission(MANAGE_FINGERPRINT);
|
||||||
@@ -614,14 +629,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
@Override // Binder call
|
@Override // Binder call
|
||||||
public void authenticate(final IBinder token, final long opId, final int groupId,
|
public void authenticate(final IBinder token, final long opId, final int groupId,
|
||||||
final IFingerprintServiceReceiver receiver, final int flags, String opPackageName) {
|
final IFingerprintServiceReceiver receiver, final int flags, String opPackageName) {
|
||||||
checkPermission(USE_FINGERPRINT);
|
|
||||||
if (!canUseFingerprint(opPackageName)) {
|
if (!canUseFingerprint(opPackageName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final boolean restricted = isRestricted();
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
startAuthentication(token, opId, groupId, receiver, flags);
|
startAuthentication(token, opId, groupId, receiver, flags, restricted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -643,10 +659,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
|
|||||||
public void remove(final IBinder token, final int fingerId, final int groupId,
|
public void remove(final IBinder token, final int fingerId, final int groupId,
|
||||||
final IFingerprintServiceReceiver receiver) {
|
final IFingerprintServiceReceiver receiver) {
|
||||||
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
|
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
|
||||||
|
final boolean restricted = isRestricted();
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
startRemove(token, fingerId, groupId, receiver);
|
startRemove(token, fingerId, groupId, receiver, restricted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class FingerprintsUserState {
|
|||||||
private final File mFile;
|
private final File mFile;
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private final ArrayList<Fingerprint> mFingerprints = new ArrayList<>();
|
private final ArrayList<Fingerprint> mFingerprints = new ArrayList<Fingerprint>();
|
||||||
private final Context mCtx;
|
private final Context mCtx;
|
||||||
|
|
||||||
public FingerprintsUserState(Context ctx, int userId) {
|
public FingerprintsUserState(Context ctx, int userId) {
|
||||||
@@ -127,7 +127,7 @@ class FingerprintsUserState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Fingerprint> getCopy(ArrayList<Fingerprint> array) {
|
private ArrayList<Fingerprint> getCopy(ArrayList<Fingerprint> array) {
|
||||||
ArrayList<Fingerprint> result = new ArrayList<>(array.size());
|
ArrayList<Fingerprint> result = new ArrayList<Fingerprint>(array.size());
|
||||||
for (int i = 0; i < array.size(); i++) {
|
for (int i = 0; i < array.size(); i++) {
|
||||||
Fingerprint fp = array.get(i);
|
Fingerprint fp = array.get(i);
|
||||||
result.add(new Fingerprint(fp.getName(), fp.getGroupId(), fp.getFingerId(),
|
result.add(new Fingerprint(fp.getName(), fp.getGroupId(), fp.getFingerId(),
|
||||||
|
|||||||
Reference in New Issue
Block a user