Add fingerprint settings support to the framework
- cleanup thread issue and simplify native FingerprintService methods - add new permissions and enforce them - add fingerprint hardware detection API Change-Id: I87c2243ea2412061f1e85b044138480d0161bcdf
This commit is contained in:
@@ -141,6 +141,7 @@ package android {
|
||||
field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
|
||||
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
|
||||
field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
|
||||
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
|
||||
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
|
||||
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
|
||||
field public static final java.lang.String WAKE_LOCK = "android.permission.WAKE_LOCK";
|
||||
|
||||
@@ -210,6 +210,7 @@ package android {
|
||||
field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
|
||||
field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
|
||||
field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
|
||||
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
|
||||
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
|
||||
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
|
||||
field public static final java.lang.String WAKE_LOCK = "android.permission.WAKE_LOCK";
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.BaseBundle;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -31,6 +32,9 @@ import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class that coordinates access to the fingerprint hardware.
|
||||
* @hide
|
||||
@@ -97,6 +101,15 @@ public class FingerprintManager {
|
||||
}
|
||||
};
|
||||
|
||||
public static final class FingerprintItem {
|
||||
CharSequence name;
|
||||
int id;
|
||||
FingerprintItem(CharSequence name, int id) {
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -248,4 +261,38 @@ public class FingerprintManager {
|
||||
private void sendError(int msg, int arg1, int arg2) {
|
||||
mHandler.obtainMessage(msg, arg1, arg2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of current fingerprint items
|
||||
* @hide
|
||||
*/
|
||||
public List<FingerprintItem> getEnrolledFingerprints() {
|
||||
int[] ids = FingerprintUtils.getFingerprintIdsForUser(mContext.getContentResolver(),
|
||||
getCurrentUserId());
|
||||
List<FingerprintItem> result = new ArrayList<FingerprintItem>();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
// TODO: persist names in Settings
|
||||
FingerprintItem item = new FingerprintItem("Finger" + ids[i], ids[i]);
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if fingerprint hardware is present and functional.
|
||||
* @return true if hardware is present and functional, false otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isHardwareDetected() {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.isHardwareDetected();
|
||||
} catch (RemoteException e) {
|
||||
Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,11 @@ import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with fingerprints and fingerprint settings.
|
||||
@@ -32,34 +36,50 @@ class FingerprintUtils {
|
||||
private static final boolean DEBUG = true;
|
||||
private static final String TAG = "FingerprintUtils";
|
||||
|
||||
private static int[] toIntArray(List<Integer> list) {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
int[] arr = new int[list.size()];
|
||||
int i = 0;
|
||||
for (int elem : list) {
|
||||
arr[i] = elem;
|
||||
i++;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static int[] getFingerprintIdsForUser(ContentResolver res, int userId) {
|
||||
String fingerIdsRaw = Settings.Secure.getStringForUser(res,
|
||||
Settings.Secure.USER_FINGERPRINT_IDS, userId);
|
||||
|
||||
int result[] = {};
|
||||
ArrayList<Integer> tmp = new ArrayList<Integer>();
|
||||
if (!TextUtils.isEmpty(fingerIdsRaw)) {
|
||||
String[] fingerStringIds = fingerIdsRaw.replace("[","").replace("]","").split(", ");
|
||||
result = new int[fingerStringIds.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
int length = fingerStringIds.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
result[i] = Integer.decode(fingerStringIds[i]);
|
||||
tmp.add(Integer.decode(fingerStringIds[i]));
|
||||
} catch (NumberFormatException e) {
|
||||
if (DEBUG) Log.d(TAG, "Error when parsing finger id " + fingerStringIds[i]);
|
||||
if (DEBUG) Log.w(TAG, "Error parsing finger id: '" + fingerStringIds[i] + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return toIntArray(tmp);
|
||||
}
|
||||
|
||||
public static void addFingerprintIdForUser(int fingerId, ContentResolver res, int userId) {
|
||||
// FingerId 0 has special meaning.
|
||||
if (fingerId == 0) {
|
||||
Log.w(TAG, "Tried to add fingerId 0");
|
||||
return;
|
||||
}
|
||||
|
||||
int[] fingerIds = getFingerprintIdsForUser(res, userId);
|
||||
|
||||
// FingerId 0 has special meaning.
|
||||
if (fingerId == 0) return;
|
||||
|
||||
// Don't allow dups
|
||||
for (int i = 0; i < fingerIds.length; i++) {
|
||||
if (fingerIds[i] == fingerId) return;
|
||||
if (ArrayUtils.contains(fingerIds, fingerId)) {
|
||||
Log.w(TAG, "finger already added " + fingerId);
|
||||
return;
|
||||
}
|
||||
int[] newList = Arrays.copyOf(fingerIds, fingerIds.length + 1);
|
||||
newList[fingerIds.length] = fingerId;
|
||||
@@ -72,19 +92,13 @@ class FingerprintUtils {
|
||||
// FingerId 0 has special meaning. The HAL layer is supposed to remove each finger one
|
||||
// at a time and invoke notify() for each fingerId. If we get called with 0 here, it means
|
||||
// something bad has happened.
|
||||
if (fingerId == 0) throw new IllegalStateException("Bad fingerId");
|
||||
if (fingerId == 0) throw new IllegalArgumentException("fingerId can't be 0");
|
||||
|
||||
int[] fingerIds = getFingerprintIdsForUser(res, userId);
|
||||
int[] resultIds = Arrays.copyOf(fingerIds, fingerIds.length);
|
||||
int resultCount = 0;
|
||||
for (int i = 0; i < fingerIds.length; i++) {
|
||||
if (fingerId != fingerIds[i]) {
|
||||
resultIds[resultCount++] = fingerIds[i];
|
||||
}
|
||||
}
|
||||
if (resultCount > 0) {
|
||||
final int[] fingerIds = getFingerprintIdsForUser(res, userId);
|
||||
if (ArrayUtils.contains(fingerIds, fingerId)) {
|
||||
final int[] result = ArrayUtils.removeInt(fingerIds, fingerId);
|
||||
Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
|
||||
Arrays.toString(Arrays.copyOf(resultIds, resultCount)), userId);
|
||||
Arrays.toString(result), userId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -22,10 +22,10 @@ import android.service.fingerprint.IFingerprintServiceReceiver;
|
||||
* Communication channel from client to the fingerprint service.
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IFingerprintService {
|
||||
interface IFingerprintService {
|
||||
// Any errors resulting from this call will be returned to the listener
|
||||
void enroll(IBinder token, long timeout, int userId);
|
||||
|
||||
|
||||
// Any errors resulting from this call will be returned to the listener
|
||||
void enrollCancel(IBinder token, int userId);
|
||||
|
||||
@@ -38,4 +38,7 @@ oneway interface IFingerprintService {
|
||||
|
||||
// Stops listening for fingerprints
|
||||
void stopListening(IBinder token, int userId);
|
||||
|
||||
// Determine if HAL is loaded and ready
|
||||
boolean isHardwareDetected();
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <android_runtime/Log.h>
|
||||
#include <android_os_MessageQueue.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/fingerprint.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <utils/Looper.h>
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
namespace android {
|
||||
@@ -34,7 +35,6 @@ static const char* FINGERPRINT_SERVICE = "com/android/server/fingerprint/Fingerp
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID notify;
|
||||
jobject callbackObject;
|
||||
} gFingerprintServiceClassInfo;
|
||||
|
||||
static struct {
|
||||
@@ -42,11 +42,26 @@ static struct {
|
||||
fingerprint_device_t *device;
|
||||
} gContext;
|
||||
|
||||
static sp<Looper> gLooper;
|
||||
static jobject gCallback;
|
||||
|
||||
class CallbackHandler : public MessageHandler {
|
||||
int type;
|
||||
int arg1, arg2;
|
||||
public:
|
||||
CallbackHandler(int type, int arg1, int arg2) : type(type), arg1(arg1), arg2(arg2) { }
|
||||
|
||||
virtual void handleMessage(const Message& message) {
|
||||
//ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
env->CallVoidMethod(gCallback, gFingerprintServiceClassInfo.notify, type, arg1, arg2);
|
||||
}
|
||||
};
|
||||
|
||||
// Called by the HAL to notify us of fingerprint events
|
||||
static void hal_notify_callback(fingerprint_msg_t msg) {
|
||||
uint32_t arg1 = 0;
|
||||
uint32_t arg2 = 0;
|
||||
uint32_t arg3 = 0; // TODO
|
||||
switch (msg.type) {
|
||||
case FINGERPRINT_ERROR:
|
||||
arg1 = msg.data.error;
|
||||
@@ -60,7 +75,6 @@ static void hal_notify_callback(fingerprint_msg_t msg) {
|
||||
case FINGERPRINT_TEMPLATE_ENROLLING:
|
||||
arg1 = msg.data.enroll.finger.fid;
|
||||
arg2 = msg.data.enroll.samples_remaining;
|
||||
arg3 = 0;
|
||||
break;
|
||||
case FINGERPRINT_TEMPLATE_REMOVED:
|
||||
arg1 = msg.data.removed.finger.fid;
|
||||
@@ -69,32 +83,16 @@ static void hal_notify_callback(fingerprint_msg_t msg) {
|
||||
ALOGE("fingerprint: invalid msg: %d", msg.type);
|
||||
return;
|
||||
}
|
||||
(void)arg3;
|
||||
//ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
|
||||
|
||||
// TODO: fix gross hack to attach JNI to calling thread
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
if (env == NULL) {
|
||||
JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
|
||||
JavaVM* vm = AndroidRuntime::getJavaVM();
|
||||
int result = vm->AttachCurrentThread(&env, (void*) &args);
|
||||
if (result != JNI_OK) {
|
||||
ALOGE("Can't call JNI method: attach failed: %#x", result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
env->CallVoidMethod(gFingerprintServiceClassInfo.callbackObject,
|
||||
gFingerprintServiceClassInfo.notify, msg.type, arg1, arg2);
|
||||
// This call potentially comes in on a thread not owned by us. Hand it off to our
|
||||
// looper so it runs on our thread when calling back to FingerprintService.
|
||||
// CallbackHandler object is reference-counted, so no cleanup necessary.
|
||||
gLooper->sendMessage(new CallbackHandler(msg.type, arg1, arg2), Message());
|
||||
}
|
||||
|
||||
static void nativeInit(JNIEnv *env, jobject clazz, jobject callbackObj) {
|
||||
static void nativeInit(JNIEnv *env, jobject clazz, jobject mQueue, jobject callbackObj) {
|
||||
ALOG(LOG_VERBOSE, LOG_TAG, "nativeInit()\n");
|
||||
gFingerprintServiceClassInfo.clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
|
||||
gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env,
|
||||
gFingerprintServiceClassInfo.clazz);
|
||||
gFingerprintServiceClassInfo.notify = GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,
|
||||
"notify", "(III)V");
|
||||
gFingerprintServiceClassInfo.callbackObject = MakeGlobalRefOrDie(env, callbackObj);
|
||||
gCallback = MakeGlobalRefOrDie(env, callbackObj);
|
||||
gLooper = android_os_MessageQueue_getMessageQueue(env, mQueue)->getLooper();
|
||||
}
|
||||
|
||||
static jint nativeEnroll(JNIEnv* env, jobject clazz, jint timeout) {
|
||||
@@ -179,14 +177,15 @@ static const JNINativeMethod g_methods[] = {
|
||||
{ "nativeRemove", "(I)I", (void*)nativeRemove },
|
||||
{ "nativeOpenHal", "()I", (void*)nativeOpenHal },
|
||||
{ "nativeCloseHal", "()I", (void*)nativeCloseHal },
|
||||
{ "nativeInit", "(Lcom/android/server/fingerprint/FingerprintService;)V", (void*)nativeInit }
|
||||
{ "nativeInit","(Landroid/os/MessageQueue;"
|
||||
"Lcom/android/server/fingerprint/FingerprintService;)V", (void*)nativeInit }
|
||||
};
|
||||
|
||||
int register_android_server_fingerprint_FingerprintService(JNIEnv* env) {
|
||||
jclass clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
|
||||
gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
|
||||
gFingerprintServiceClassInfo.notify = GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,
|
||||
"notify", "(III)V");
|
||||
gFingerprintServiceClassInfo.notify =
|
||||
GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,"notify", "(III)V");
|
||||
int result = RegisterMethodsOrDie(env, FINGERPRINT_SERVICE, g_methods, NELEM(g_methods));
|
||||
ALOG(LOG_VERBOSE, LOG_TAG, "FingerprintManager JNI ready.\n");
|
||||
return result;
|
||||
|
||||
@@ -2835,6 +2835,18 @@
|
||||
android:label="@string/permlab_access_keyguard_secure_storage"
|
||||
android:description="@string/permdesc_access_keyguard_secure_storage" />
|
||||
|
||||
<!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
|
||||
<permission android:name="android.permission.MANAGE_FINGERPRINT"
|
||||
android:protectionLevel="signature"
|
||||
android:label="@string/permlab_manageFingerprint"
|
||||
android:description="@string/permdesc_manageFingerprint" />
|
||||
|
||||
<!-- Allows an app to use fingerprint hardware. -->
|
||||
<permission android:name="android.permission.USE_FINGERPRINT"
|
||||
android:protectionLevel="dangerous"
|
||||
android:label="@string/permlab_useFingerprint"
|
||||
android:description="@string/permdesc_useFingerprint" />
|
||||
|
||||
<!-- Allows an application to control keyguard. Only allowed for system processes.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.CONTROL_KEYGUARD"
|
||||
|
||||
@@ -2208,6 +2208,15 @@
|
||||
disables the keylock when receiving an incoming phone call, then
|
||||
re-enables the keylock when the call is finished.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_manageFingerprint">manage fingerprint hardware</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_manageFingerprint">Allows the app to invoke methods to add and delete fingerprint templates for use.</string>
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_useFingerprint">use fingerprint hardware</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_useFingerprint">Allows the app to use fingerprint hardware for authentication</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_readSyncSettings">read sync settings</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
|
||||
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
|
||||
<uses-permission android:name="android.permission.TRUST_LISTENER" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
|
||||
<application android:label="@string/app_name"
|
||||
android:process="com.android.systemui"
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
|
||||
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
|
||||
<uses-permission android:name="android.permission.TRUST_LISTENER" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
|
||||
<!-- Recents -->
|
||||
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
|
||||
|
||||
@@ -20,8 +20,11 @@ import android.app.Service;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
@@ -34,6 +37,8 @@ import com.android.server.SystemService;
|
||||
import android.service.fingerprint.FingerprintUtils;
|
||||
import android.service.fingerprint.IFingerprintService;
|
||||
import android.service.fingerprint.IFingerprintServiceReceiver;
|
||||
import static android.Manifest.permission.MANAGE_FINGERPRINT;
|
||||
import static android.Manifest.permission.USE_FINGERPRINT;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -68,14 +73,13 @@ public class FingerprintService extends SystemService {
|
||||
}
|
||||
};
|
||||
private Context mContext;
|
||||
private int mHalDeviceId;
|
||||
|
||||
private static final int STATE_IDLE = 0;
|
||||
private static final int STATE_LISTENING = 1;
|
||||
private static final int STATE_ENROLLING = 2;
|
||||
private static final int STATE_REMOVING = 3;
|
||||
private static final long MS_PER_SEC = 1000;
|
||||
public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
|
||||
public static final String ENROLL_FINGERPRINT = "android.permission.ENROLL_FINGERPRINT";
|
||||
|
||||
private static final class ClientData {
|
||||
public IFingerprintServiceReceiver receiver;
|
||||
@@ -113,17 +117,17 @@ public class FingerprintService extends SystemService {
|
||||
public FingerprintService(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
nativeInit(this);
|
||||
nativeInit(Looper.getMainLooper().getQueue(), this);
|
||||
}
|
||||
|
||||
// TODO: Move these into separate process
|
||||
// JNI methods to communicate from FingerprintManagerService to HAL
|
||||
native int nativeEnroll(int timeout);
|
||||
native int nativeEnrollCancel();
|
||||
native int nativeRemove(int fingerprintId);
|
||||
native int nativeOpenHal();
|
||||
native int nativeCloseHal();
|
||||
native void nativeInit(FingerprintService service);
|
||||
static native int nativeEnroll(int timeout);
|
||||
static native int nativeEnrollCancel();
|
||||
static native int nativeRemove(int fingerprintId);
|
||||
static native int nativeOpenHal();
|
||||
static native int nativeCloseHal();
|
||||
static native void nativeInit(MessageQueue queue, FingerprintService service);
|
||||
|
||||
// JNI methods for communicating from HAL to clients
|
||||
void notify(int msg, int arg1, int arg2) {
|
||||
@@ -131,11 +135,13 @@ public class FingerprintService extends SystemService {
|
||||
}
|
||||
|
||||
void handleNotify(int msg, int arg1, int arg2) {
|
||||
Slog.v(TAG, "handleNotify(msg=" + msg + ", arg1=" + arg1 + ", arg2=" + arg2 + ")");
|
||||
Slog.v(TAG, "handleNotify(msg=" + msg + ", arg1=" + arg1 + ", arg2=" + arg2 + ")"
|
||||
+ ", " + mClients.size() + " clients");
|
||||
for (int i = 0; i < mClients.size(); i++) {
|
||||
if (DEBUG) Slog.v(TAG, "Client[" + i + "] binder token: " + mClients.keyAt(i));
|
||||
ClientData clientData = mClients.valueAt(i);
|
||||
if (clientData == null || clientData.receiver == null) {
|
||||
if (DEBUG) Slog.v(TAG, "clientData at " + i + " is invalid!!");
|
||||
if (DEBUG) Slog.v(TAG, "clientData is invalid!!");
|
||||
continue;
|
||||
}
|
||||
switch (msg) {
|
||||
@@ -282,26 +288,27 @@ public class FingerprintService extends SystemService {
|
||||
mClients.remove(token);
|
||||
}
|
||||
|
||||
void checkPermission(String permisison) {
|
||||
// TODO
|
||||
void checkPermission(String permission) {
|
||||
getContext().enforceCallingOrSelfPermission(permission, "Must have "
|
||||
+ permission + " permission.");
|
||||
}
|
||||
|
||||
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
|
||||
@Override // Binder call
|
||||
public void enroll(IBinder token, long timeout, int userId) {
|
||||
checkPermission(ENROLL_FINGERPRINT);
|
||||
checkPermission(MANAGE_FINGERPRINT);
|
||||
startEnroll(token, timeout, userId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void enrollCancel(IBinder token,int userId) {
|
||||
checkPermission(ENROLL_FINGERPRINT);
|
||||
checkPermission(MANAGE_FINGERPRINT);
|
||||
startEnrollCancel(token, userId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void remove(IBinder token, int fingerprintId, int userId) {
|
||||
checkPermission(ENROLL_FINGERPRINT); // TODO: Maybe have another permission
|
||||
checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
|
||||
startRemove(token, fingerprintId, userId);
|
||||
}
|
||||
|
||||
@@ -317,12 +324,19 @@ public class FingerprintService extends SystemService {
|
||||
checkPermission(USE_FINGERPRINT);
|
||||
removeListener(token, userId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public boolean isHardwareDetected() {
|
||||
checkPermission(USE_FINGERPRINT);
|
||||
return mHalDeviceId != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
|
||||
nativeOpenHal();
|
||||
mHalDeviceId = nativeOpenHal();
|
||||
if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user