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"
208de4a16cea6f80c1e53c3e2f1faee5b8256e49c8Jeff Brown#include <inttypes.h>
2108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include <android_runtime/AndroidRuntime.h>
2308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include <android_runtime/Log.h>
24ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller#include <android_os_MessageQueue.h>
25af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales#include <binder/IServiceManager.h>
26af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales#include <utils/String16.h>
27af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales#include <utils/Looper.h>
28af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales#include <keystore/IKeystoreService.h>
29fe66955503c74515c7e2f07aa152276010d7f5a6Andres Morales#include <keystore/keystore.h> // for error code
30af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales
31a7596147b43940cad3f76c53ed154ef088b9269bJim Miller#include <hardware/hardware.h>
32a7596147b43940cad3f76c53ed154ef088b9269bJim Miller#include <hardware/fingerprint.h>
337ba38ef0df0eb0065c3d060e5fb1133beeb271b5Sasha Levitskiy#include <hardware/hw_auth_token.h>
34af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales
3508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller#include <utils/Log.h>
36987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h"
37a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
38af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales
3908fa40c5cb5229b7969b2a5146855a337870f45aJim Millernamespace android {
4008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
41c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiystatic const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0);
42a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
43a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic const char* FINGERPRINT_SERVICE = "com/android/server/fingerprint/FingerprintService";
4408fa40c5cb5229b7969b2a5146855a337870f45aJim Millerstatic struct {
4508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    jclass clazz;
4608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    jmethodID notify;
47a7596147b43940cad3f76c53ed154ef088b9269bJim Miller} gFingerprintServiceClassInfo;
48a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
49a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic struct {
50a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    fingerprint_module_t const* module;
51a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    fingerprint_device_t *device;
52a7596147b43940cad3f76c53ed154ef088b9269bJim Miller} gContext;
53a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
54ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerstatic sp<Looper> gLooper;
55ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerstatic jobject gCallback;
56ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
57ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerclass CallbackHandler : public MessageHandler {
58ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    int type;
599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    int arg1, arg2, arg3;
60ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerpublic:
619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    CallbackHandler(int type, int arg1, int arg2, int arg3)
629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        : type(type), arg1(arg1), arg2(arg2), arg3(arg3) { }
63ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
64ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    virtual void handleMessage(const Message& message) {
65ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        //ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
66ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        JNIEnv* env = AndroidRuntime::getJNIEnv();
679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        env->CallVoidMethod(gCallback, gFingerprintServiceClassInfo.notify, type, arg1, arg2, arg3);
68ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
69ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller};
70ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
71af0479d16d381c7569b81c450f9ba947207d82fcAndres Moralesstatic void notifyKeystore(uint8_t *auth_token, size_t auth_token_length) {
72af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales    if (auth_token != NULL && auth_token_length > 0) {
73af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        // TODO: cache service?
74af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        sp<IServiceManager> sm = defaultServiceManager();
75af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
76af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
77af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        if (service != NULL) {
78fe66955503c74515c7e2f07aa152276010d7f5a6Andres Morales            status_t ret = service->addAuthToken(auth_token, auth_token_length);
79fe66955503c74515c7e2f07aa152276010d7f5a6Andres Morales            if (ret != ResponseCode::NO_ERROR) {
80fe66955503c74515c7e2f07aa152276010d7f5a6Andres Morales                ALOGE("Falure sending auth token to KeyStore: %d", ret);
81af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales            }
82af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        } else {
83af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales            ALOGE("Unable to communicate with KeyStore");
84af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales        }
85af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales    }
86af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales}
87af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales
88a7596147b43940cad3f76c53ed154ef088b9269bJim Miller// Called by the HAL to notify us of fingerprint events
89a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic void hal_notify_callback(fingerprint_msg_t msg) {
90a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    uint32_t arg1 = 0;
91a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    uint32_t arg2 = 0;
929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    uint32_t arg3 = 0;
93a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    switch (msg.type) {
94a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_ERROR:
95a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            arg1 = msg.data.error;
96a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
97a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_ACQUIRED:
98a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            arg1 = msg.data.acquired.acquired_info;
99a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
1007ba38ef0df0eb0065c3d060e5fb1133beeb271b5Sasha Levitskiy        case FINGERPRINT_AUTHENTICATED:
1017ba38ef0df0eb0065c3d060e5fb1133beeb271b5Sasha Levitskiy            arg1 = msg.data.authenticated.finger.fid;
1027ba38ef0df0eb0065c3d060e5fb1133beeb271b5Sasha Levitskiy            arg2 = msg.data.authenticated.finger.gid;
103af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales            if (arg1 != 0) {
104205bbc40b4a3046ca3dba256535f0322f5b336e9Andres Morales                notifyKeystore(reinterpret_cast<uint8_t *>(&msg.data.authenticated.hat),
105af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales                        sizeof(msg.data.authenticated.hat));
106af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales            }
107a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
108a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_TEMPLATE_ENROLLING:
109c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy            arg1 = msg.data.enroll.finger.fid;
1109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            arg2 = msg.data.enroll.finger.gid;
1119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            arg3 = msg.data.enroll.samples_remaining;
112a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
113a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        case FINGERPRINT_TEMPLATE_REMOVED:
114c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy            arg1 = msg.data.removed.finger.fid;
1159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            arg2 = msg.data.removed.finger.gid;
116a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            break;
117a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        default:
118a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            ALOGE("fingerprint: invalid msg: %d", msg.type);
119a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            return;
120a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
121ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    // This call potentially comes in on a thread not owned by us. Hand it off to our
122ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    // looper so it runs on our thread when calling back to FingerprintService.
123ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    // CallbackHandler object is reference-counted, so no cleanup necessary.
1249f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    gLooper->sendMessage(new CallbackHandler(msg.type, arg1, arg2, arg3), Message());
125a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
126a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
127ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerstatic void nativeInit(JNIEnv *env, jobject clazz, jobject mQueue, jobject callbackObj) {
128a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeInit()\n");
129ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gCallback = MakeGlobalRefOrDie(env, callbackObj);
130ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gLooper = android_os_MessageQueue_getMessageQueue(env, mQueue)->getLooper();
131a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
13208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
133fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Millerstatic jint nativeEnroll(JNIEnv* env, jobject clazz, jbyteArray token, jint groupId, jint timeout) {
1349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeEnroll(gid=%d, timeout=%d)\n", groupId, timeout);
135fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    const int tokenSize = env->GetArrayLength(token);
136fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    jbyte* tokenData = env->GetByteArrayElements(token, 0);
137fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    if (tokenSize != sizeof(hw_auth_token_t)) {
138fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller        ALOG(LOG_VERBOSE, LOG_TAG, "nativeEnroll() : invalid token size %d\n", tokenSize);
139fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller        return -1;
140fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    }
1415e7ae3190000b53d5e45d3bcb98dde89e8d8cd88Jim Miller    int ret = gContext.device->enroll(gContext.device,
1425e7ae3190000b53d5e45d3bcb98dde89e8d8cd88Jim Miller            reinterpret_cast<const hw_auth_token_t*>(tokenData), groupId, timeout);
143fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    env->ReleaseByteArrayElements(token, tokenData, 0);
1449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    return reinterpret_cast<jint>(ret);
1459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller}
1469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
1475e7ae3190000b53d5e45d3bcb98dde89e8d8cd88Jim Millerstatic jlong nativePreEnroll(JNIEnv* env, jobject clazz) {
148ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    uint64_t ret = gContext.device->pre_enroll(gContext.device);
1495e7ae3190000b53d5e45d3bcb98dde89e8d8cd88Jim Miller    // ALOG(LOG_VERBOSE, LOG_TAG, "nativePreEnroll(), result = %llx", ret);
150ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    return reinterpret_cast<jlong>((int64_t)ret);
151ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller}
152ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
153ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerstatic jint nativeStopEnrollment(JNIEnv* env, jobject clazz) {
154ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeStopEnrollment()\n");
155ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    int ret = gContext.device->cancel(gContext.device);
156ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    return reinterpret_cast<jint>(ret);
157ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller}
158ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
1599f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerstatic jint nativeAuthenticate(JNIEnv* env, jobject clazz, jlong sessionId, jint groupId) {
1608de4a16cea6f80c1e53c3e2f1faee5b8256e49c8Jeff Brown    ALOG(LOG_VERBOSE, LOG_TAG, "nativeAuthenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId);
1619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    int ret = gContext.device->authenticate(gContext.device, sessionId, groupId);
162a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jint>(ret);
163a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
164a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
165fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Millerstatic jint nativeStopAuthentication(JNIEnv* env, jobject clazz) {
166ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeStopAuthentication()\n");
167ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    int ret = gContext.device->cancel(gContext.device);
168a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jint>(ret);
16908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}
17008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
1719f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerstatic jint nativeRemove(JNIEnv* env, jobject clazz, jint fingerId, jint groupId) {
1729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeRemove(fid=%d, gid=%d)\n", fingerId, groupId);
173c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    fingerprint_finger_id_t finger;
1749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    finger.fid = fingerId;
1759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    finger.gid = groupId;
176c31dd3bdffa5e8861da648bf6cd9f9cffde17616Sasha Levitskiy    int ret = gContext.device->remove(gContext.device, finger);
177a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jint>(ret);
178a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
179a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
1804d41a203a08c55b3f3190519535ccee6557ea4feAndres Moralesstatic jlong nativeGetAuthenticatorId(JNIEnv *, jobject clazz) {
1814d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    return gContext.device->get_authenticator_id(gContext.device);
1824d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales}
1834d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales
18480db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiystatic jint nativeSetActiveGroup(JNIEnv *env, jobject clazz, jint gid, jbyteArray path) {
18580db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    const int pathSize = env->GetArrayLength(path);
18680db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    jbyte* pathData = env->GetByteArrayElements(path, 0);
18780db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    if (pathSize >= PATH_MAX) {
18880db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy	ALOGE("Path name is too long\n");
18980db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy        return -1;
19080db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    }
19180db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    char path_name[PATH_MAX] = {0};
19280db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    memcpy(path_name, pathData, pathSize);
19380db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    ALOG(LOG_VERBOSE, LOG_TAG, "nativeSetActiveGroup() path: %s, gid: %d\n", path_name, gid);
19480db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    int result = gContext.device->set_active_group(gContext.device, gid, path_name);
19580db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    env->ReleaseByteArrayElements(path, pathData, 0);
19680db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    return result;
19780db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy}
19880db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy
199a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic jint nativeOpenHal(JNIEnv* env, jobject clazz) {
200a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n");
201a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    int err;
202a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    const hw_module_t *hw_module = NULL;
203a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) {
204a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Can't open fingerprint HW Module, error: %d", err);
205a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
206a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
207a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (NULL == hw_module) {
208a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("No valid fingerprint module");
209a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
210a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
211a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
212a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    gContext.module = reinterpret_cast<const fingerprint_module_t*>(hw_module);
213a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
214a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (gContext.module->common.methods->open == NULL) {
215a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("No valid open method");
216a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
217a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
218a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
219a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    hw_device_t *device = NULL;
220a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
221a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (0 != (err = gContext.module->common.methods->open(hw_module, NULL, &device))) {
222a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Can't open fingerprint methods, error: %d", err);
223a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
224a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
225a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
226a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (kVersion != device->version) {
227a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
228a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        // return 0; // FIXME
229a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
230a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
231a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    gContext.device = reinterpret_cast<fingerprint_device_t*>(device);
232a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    err = gContext.device->set_notify(gContext.device, hal_notify_callback);
233a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (err < 0) {
234a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("Failed in call to set_notify(), err=%d", err);
235a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        return 0;
236a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
237a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
238a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    // Sanity check - remove
239a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    if (gContext.device->notify != hal_notify_callback) {
240a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        ALOGE("NOTIFY not set properly: %p != %p", gContext.device->notify, hal_notify_callback);
241a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
242a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
243a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized");
244a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return reinterpret_cast<jlong>(gContext.device);
245a7596147b43940cad3f76c53ed154ef088b9269bJim Miller}
246a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
247a7596147b43940cad3f76c53ed154ef088b9269bJim Millerstatic jint nativeCloseHal(JNIEnv* env, jobject clazz) {
248a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return -ENOSYS; // TODO
24908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}
25008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2514d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales
25208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller// ----------------------------------------------------------------------------
25308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
254af0479d16d381c7569b81c450f9ba947207d82fcAndres Morales
255a7596147b43940cad3f76c53ed154ef088b9269bJim Miller// TODO: clean up void methods
25608fa40c5cb5229b7969b2a5146855a337870f45aJim Millerstatic const JNINativeMethod g_methods[] = {
2579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    { "nativeAuthenticate", "(JI)I", (void*)nativeAuthenticate },
258fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    { "nativeStopAuthentication", "()I", (void*)nativeStopAuthentication },
259fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    { "nativeEnroll", "([BII)I", (void*)nativeEnroll },
26080db9baf9766dc40f9d1b6bf60797ee5cc64a48cSasha Levitskiy    { "nativeSetActiveGroup", "(I[B)I", (void*)nativeSetActiveGroup },
261ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    { "nativePreEnroll", "()J", (void*)nativePreEnroll },
262ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    { "nativeStopEnrollment", "()I", (void*)nativeStopEnrollment },
2639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    { "nativeRemove", "(II)I", (void*)nativeRemove },
2644d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    { "nativeGetAuthenticatorId", "()J", (void*)nativeGetAuthenticatorId },
265a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    { "nativeOpenHal", "()I", (void*)nativeOpenHal },
266a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    { "nativeCloseHal", "()I", (void*)nativeCloseHal },
267ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    { "nativeInit","(Landroid/os/MessageQueue;"
268ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller            "Lcom/android/server/fingerprint/FingerprintService;)V", (void*)nativeInit }
26908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller};
27008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
271a7596147b43940cad3f76c53ed154ef088b9269bJim Millerint register_android_server_fingerprint_FingerprintService(JNIEnv* env) {
272987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    jclass clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
273987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
274ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    gFingerprintServiceClassInfo.notify =
2759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,"notify", "(IIII)V");
276987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    int result = RegisterMethodsOrDie(env, FINGERPRINT_SERVICE, g_methods, NELEM(g_methods));
277a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    ALOG(LOG_VERBOSE, LOG_TAG, "FingerprintManager JNI ready.\n");
278a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    return result;
27908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}
28008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
28108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller} // namespace android
282