com_android_server_fingerprint_FingerprintService.cpp revision ba67aee02cf864793129976cd8a8a46e60c60577
108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller/*
208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Copyright (C) 2014 The Android Open Source Project
308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * you may not use this file except in compliance with the License.
608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * You may obtain a copy of the License at
708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
1008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Unless required by applicable law or agreed to in writing, software
1108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
1208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * See the License for the specific language governing permissions and
1408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * limitations under the License.
1508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller */
1608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
1708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#define LOG_TAG "Fingerprint-JNI"
1808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
1908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include "JNIHelp.h"
2008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include <android_runtime/AndroidRuntime.h>
2208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include <android_runtime/Log.h>
23ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller#include <android_os_MessageQueue.h>
24a7596147b43940cad3f76c53ed154ef088b9269bJim Miller#include <hardware/hardware.h>
25a7596147b43940cad3f76c53ed154ef088b9269bJim Miller#include <hardware/fingerprint.h>
2608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include <utils/Log.h>
27ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller#include <utils/Looper.h>
28987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h"
29a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
3008fa40c5cb5229b7969b2a5146855a337870f45aJim Millernamespace android {
3108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
32c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiystatic const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0);
33a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
34a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic const char* FINGERPRINT_SERVICE = "com/android/server/fingerprint/FingerprintService";
3508fa40c5cb5229b7969b2a5146855a337870f45aJim Millerstatic struct {
3608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    jclass clazz;
3708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    jmethodID notify;
38a7596147b43940cad3f76c53ed154ef088b9269bJim Miller} gFingerprintServiceClassInfo;
39a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
40a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic struct {
41a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    fingerprint_module_t const* module;
42a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    fingerprint_device_t *device;
43a7596147b43940cad3f76c53ed154ef088b9269bJim Miller} gContext;
44a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
45ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerstatic sp<Looper> gLooper;
46ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerstatic jobject gCallback;
47ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
48ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerclass CallbackHandler : public MessageHandler {
49ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    int type;
50ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    int arg1, arg2;
51ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerpublic:
52ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    CallbackHandler(int type, int arg1, int arg2) : type(type), arg1(arg1), arg2(arg2) { }
53ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
54ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    virtual void handleMessage(const Message& message) {
55ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        //ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
56ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        JNIEnv* env = AndroidRuntime::getJNIEnv();
57ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        env->CallVoidMethod(gCallback, gFingerprintServiceClassInfo.notify, type, arg1, arg2);
58ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
59ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller};
60ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
61a7596147b43940cad3f76c53ed154ef088b9269bJim Miller// Called by the HAL to notify us of fingerprint events
62a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic void hal_notify_callback(fingerprint_msg_t msg) {
63a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    uint32_t arg1 = 0;
64a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    uint32_t arg2 = 0;
65a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    switch (msg.type) {
66a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_ERROR:
67a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            arg1 = msg.data.error;
68a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
69a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_ACQUIRED:
70a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            arg1 = msg.data.acquired.acquired_info;
71a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
72a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_PROCESSED:
73c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy            arg1 = msg.data.processed.finger.fid;
74a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
75a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_TEMPLATE_ENROLLING:
76c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy            arg1 = msg.data.enroll.finger.fid;
77a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            arg2 = msg.data.enroll.samples_remaining;
78a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
79a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_TEMPLATE_REMOVED:
80c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy            arg1 = msg.data.removed.finger.fid;
81a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
82a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        default:
83a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            ALOGE("fingerprint: invalid msg: %d", msg.type);
84a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            return;
85a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
86ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    // This call potentially comes in on a thread not owned by us. Hand it off to our
87ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    // looper so it runs on our thread when calling back to FingerprintService.
88ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    // CallbackHandler object is reference-counted, so no cleanup necessary.
89ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gLooper->sendMessage(new CallbackHandler(msg.type, arg1, arg2), Message());
90a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
91a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
92ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerstatic void nativeInit(JNIEnv *env, jobject clazz, jobject mQueue, jobject callbackObj) {
93a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeInit()\n");
94ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gCallback = MakeGlobalRefOrDie(env, callbackObj);
95ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gLooper = android_os_MessageQueue_getMessageQueue(env, mQueue)->getLooper();
96a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
9708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
9808fa40c5cb5229b7969b2a5146855a337870f45aJim Millerstatic jint nativeEnroll(JNIEnv* env, jobject clazz, jint timeout) {
99a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeEnroll()\n");
100c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    int ret = gContext.device->enroll(gContext.device, 0, timeout);
101a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jint>(ret);
102a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
103a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
104a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic jint nativeEnrollCancel(JNIEnv* env, jobject clazz) {
105a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeEnrollCancel()\n");
106a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    int ret = gContext.device->enroll_cancel(gContext.device);
107a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jint>(ret);
10808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}
10908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
11008fa40c5cb5229b7969b2a5146855a337870f45aJim Millerstatic jint nativeRemove(JNIEnv* env, jobject clazz, jint fingerprintId) {
111a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeRemove(%d)\n", fingerprintId);
112c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    fingerprint_finger_id_t finger;
113c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    finger.gid = 0;
114c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    finger.fid = fingerprintId;
115c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    int ret = gContext.device->remove(gContext.device, finger);
116a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jint>(ret);
117a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
118a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
119a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic jint nativeOpenHal(JNIEnv* env, jobject clazz) {
120a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n");
121a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    int err;
122a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    const hw_module_t *hw_module = NULL;
123a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) {
124a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Can't open fingerprint HW Module, error: %d", err);
125a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
126a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
127a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (NULL == hw_module) {
128a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("No valid fingerprint module");
129a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
130a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
131a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
132a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    gContext.module = reinterpret_cast<const fingerprint_module_t*>(hw_module);
133a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
134a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (gContext.module->common.methods->open == NULL) {
135a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("No valid open method");
136a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
137a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
138a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
139a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    hw_device_t *device = NULL;
140a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
141a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (0 != (err = gContext.module->common.methods->open(hw_module, NULL, &device))) {
142a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Can't open fingerprint methods, error: %d", err);
143a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
144a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
145a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
146a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (kVersion != device->version) {
147a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
148a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        // return 0; // FIXME
149a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
150a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
151a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    gContext.device = reinterpret_cast<fingerprint_device_t*>(device);
152a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    err = gContext.device->set_notify(gContext.device, hal_notify_callback);
153a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (err < 0) {
154a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Failed in call to set_notify(), err=%d", err);
155a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
156a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
157a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
158a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    // Sanity check - remove
159a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (gContext.device->notify != hal_notify_callback) {
160a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("NOTIFY not set properly: %p != %p", gContext.device->notify, hal_notify_callback);
161a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
162a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
163a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized");
164a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jlong>(gContext.device);
165a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
166a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
167a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic jint nativeCloseHal(JNIEnv* env, jobject clazz) {
168a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return -ENOSYS; // TODO
16908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}
17008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
17108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller// ----------------------------------------------------------------------------
17208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
173a7596147b43940cad3f76c53ed154ef088b9269bJim Miller// TODO: clean up void methods
17408fa40c5cb5229b7969b2a5146855a337870f45aJim Millerstatic const JNINativeMethod g_methods[] = {
17508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    { "nativeEnroll", "(I)I", (void*)nativeEnroll },
1767c8201b61f318845addecd158accada2c5428a95Andreas Gampe    { "nativeEnrollCancel", "()I", (void*)nativeEnrollCancel },
17708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    { "nativeRemove", "(I)I", (void*)nativeRemove },
178a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    { "nativeOpenHal", "()I", (void*)nativeOpenHal },
179a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    { "nativeCloseHal", "()I", (void*)nativeCloseHal },
180ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    { "nativeInit","(Landroid/os/MessageQueue;"
181ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller            "Lcom/android/server/fingerprint/FingerprintService;)V", (void*)nativeInit }
18208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller};
18308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
184a7596147b43940cad3f76c53ed154ef088b9269bJim Millerint register_android_server_fingerprint_FingerprintService(JNIEnv* env) {
185987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    jclass clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
186987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
187ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gFingerprintServiceClassInfo.notify =
188ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller            GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,"notify", "(III)V");
189987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    int result = RegisterMethodsOrDie(env, FINGERPRINT_SERVICE, g_methods, NELEM(g_methods));
190a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "FingerprintManager JNI ready.\n");
191a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return result;
19208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}
19308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
19408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller} // namespace android
195