diff --git a/fingerprint/Android.mk b/fingerprint/Android.mk new file mode 100644 index 0000000..7ba5599 --- /dev/null +++ b/fingerprint/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2016 The CyanogenMod Project +# Copyright (C) 2016 The Mokee Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := fingerprint.msm8974 +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SRC_FILES := fingerprint.c +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/fingerprint/fingerprint.c b/fingerprint/fingerprint.c new file mode 100644 index 0000000..699a6e5 --- /dev/null +++ b/fingerprint/fingerprint.c @@ -0,0 +1,599 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "FingerprintHal_msm8974" +#define LOG_NDEBUG 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fp_klte.h" + +#define MAX_COMM_CHARS 128 +#define MAX_NUM_FINGERS 5 +#define SOCKET_NAME_SEND "validityservice" +#define SOCKET_NAME_RECEIVE "validityservice_callback" + +/******************************************************************************/ +static void checkinit(vcs_fingerprint_device_t* vdev) { //wait for hal connect validity service + while(!vdev->init) + sleep(1); +} + +static int sendcommand(vcs_fingerprint_device_t* vdev, uint8_t* command, int num) { + int ret = -1; + char answer[255]; + if (fd_write(vdev->send_fd, command, num) != num) { + ALOGE("cannot send command to service"); + //close(vdev->send_fd); + return ret; + } + if (fd_read(vdev->send_fd, answer, 255)) + ret = atoi(answer); + return ret; +} + +static int getfingermask(vcs_fingerprint_device_t* vdev) { + uint8_t command_getlist[2] = {CALL_GET_ENROLLED_FINGER_LIST, (uint8_t)vdev->active_gid}; + return sendcommand(vdev, command_getlist, 2); +} + +static int initService(vcs_fingerprint_device_t* vdev) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + int ret = -EINVAL; + while (vdev->send_fd <= 0) { + vdev->send_fd = socket_local_client(SOCKET_NAME_SEND, ANDROID_SOCKET_NAMESPACE_ABSTRACT,SOCK_STREAM); + if (vdev->send_fd < 0) { + ALOGW("cannot open validity service!"); + sleep(1); + } + } + uint8_t command[1] = {CALL_INITSERVICE}; + + ret = sendcommand(vdev, command, 1); + vdev->authenticator_id = getfingermask(vdev); + vdev->init = true; + return ret; +} + +static void send_error_notice(vcs_fingerprint_device_t* vdev, fingerprint_error_t error_info) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + + fingerprint_msg_t msg = {0}; + msg.type = FINGERPRINT_ERROR; + msg.data.error = error_info; + ALOGI("error_info=%d", (int)error_info); + + pthread_mutex_lock(&vdev->lock); + vdev->device.notify(&msg); + pthread_mutex_unlock(&vdev->lock); + + return; +} + +static void send_acquired_notice(vcs_fingerprint_device_t* vdev, fingerprint_acquired_info_t acquired_info) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + + fingerprint_msg_t acqu_msg = {0}; + acqu_msg.type = FINGERPRINT_ACQUIRED; + acqu_msg.data.acquired.acquired_info = acquired_info; + ALOGI("acqu_info=%d", (int)acquired_info); + + pthread_mutex_lock(&vdev->lock); + vdev->device.notify(&acqu_msg); + pthread_mutex_unlock(&vdev->lock); + + return; +} + +static void send_enroll_notice(vcs_fingerprint_device_t* vdev, int fid, int remaining) { + ALOGV("----------------> %s -----------------> fid %d", __FUNCTION__, fid); + + if (fid == 0) { + ALOGD("Fingerprint ID is zero (invalid)"); + return; + } + if (vdev->secure_user_id == 0) { + ALOGD("Secure user ID is zero (invalid)"); + return; + } + + pthread_mutex_lock(&vdev->lock); + + vdev->listener.state = STATE_SCAN; + + fingerprint_msg_t msg = {0}; + msg.type = FINGERPRINT_TEMPLATE_ENROLLING; + msg.data.enroll.finger.fid = fid; + msg.data.enroll.samples_remaining = remaining; + vdev->device.notify(&msg); + + pthread_mutex_unlock(&vdev->lock); + + return; +} + +static void send_authenticated_notice(vcs_fingerprint_device_t* vdev, int fid) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + + send_acquired_notice(vdev, FINGERPRINT_ACQUIRED_GOOD); + + fingerprint_msg_t auth_msg = {0}; + auth_msg.type = FINGERPRINT_AUTHENTICATED; + auth_msg.data.authenticated.finger.fid = fid; + auth_msg.data.authenticated.finger.gid = 0; // unused + auth_msg.data.authenticated.hat.version = HW_AUTH_TOKEN_VERSION; + auth_msg.data.authenticated.hat.authenticator_type = + htobe32(HW_AUTH_FINGERPRINT); + auth_msg.data.authenticated.hat.challenge = vdev->op_id; + auth_msg.data.authenticated.hat.authenticator_id = vdev->authenticator_id; + auth_msg.data.authenticated.hat.user_id = vdev->secure_user_id; + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + auth_msg.data.authenticated.hat.timestamp = + htobe64((uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000); + + pthread_mutex_lock(&vdev->lock); + vdev->device.notify(&auth_msg); + pthread_mutex_unlock(&vdev->lock); + + return; +} + +static void send_remove_notice(vcs_fingerprint_device_t* vdev, int fid) { + ALOGV("----------------> %s ----------------->fid=%d", __FUNCTION__, fid); + + fingerprint_msg_t msg = {0}; + msg.type = FINGERPRINT_TEMPLATE_REMOVED; + msg.data.removed.finger.fid = fid; + + pthread_mutex_lock(&vdev->lock); + vdev->device.notify(&msg); + pthread_mutex_unlock(&vdev->lock); + + return; +} + +/******************************************************************************/ + +static uint64_t get_64bit_rand() { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + uint64_t r = (((uint64_t)rand()) << 32) | ((uint64_t)rand()); + return r != 0 ? r : 1; +} + +static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device) { + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + ALOGV("----------------> %s ----------------->", __FUNCTION__); + uint64_t authenticator_id = 0; + pthread_mutex_lock(&vdev->lock); + vdev->authenticator_id = getfingermask(vdev); + authenticator_id = vdev->authenticator_id; + pthread_mutex_unlock(&vdev->lock); + + return authenticator_id; +} + +static int fingerprint_set_active_group(struct fingerprint_device *device, uint32_t gid, + const char __unused *path) { + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + pthread_mutex_lock(&vdev->lock); + vdev->active_gid = gid; + pthread_mutex_unlock(&vdev->lock); + + return 0; +} + +static int fingerprint_authenticate(struct fingerprint_device *device, + uint64_t operation_id, __unused uint32_t gid) +{ + ALOGV("----------------> %s ----------------->", __FUNCTION__); + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + int ret = 0; + ALOGI("auth: op_id=%llu ",operation_id); + + checkinit(vdev); + + pthread_mutex_lock(&vdev->lock); + + vdev->op_id = operation_id; + vdev->listener.state = STATE_SCAN; + uint8_t command[2] = {CALL_IDENTIFY, (uint8_t)vdev->active_gid}; + ret = sendcommand(vdev, command, 2); + + pthread_mutex_unlock(&vdev->lock); + + // Always return successful + return 0; +} + +static int fingerprint_enroll(struct fingerprint_device *device, + const hw_auth_token_t *hat, + uint32_t __unused gid, + uint32_t __unused timeout_sec) { + ALOGD("fingerprint_enroll"); + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + int ret = -EINVAL; + int fingermask = 0; + int idx = 1; + uint8_t command[3] = {CALL_ENROLL, (uint8_t)vdev->active_gid, 0}; + + checkinit(vdev); + + if (!hat) { + ALOGW("%s: null auth token", __func__); + return -EPROTONOSUPPORT; + } + if (hat->challenge == vdev->challenge) { + vdev->secure_user_id = hat->user_id; + } else { + ALOGW("%s: invalid auth token", __func__); + } + + if (hat->version != HW_AUTH_TOKEN_VERSION) { + return -EPROTONOSUPPORT; + } + if (hat->challenge != vdev->challenge && !(hat->authenticator_type & HW_AUTH_FINGERPRINT)) { + return -EPERM; + } + + vdev->user_id = hat->user_id; + + pthread_mutex_lock(&vdev->lock); + vdev->listener.state = STATE_ENROLL; + + fingermask = getfingermask(vdev); + ALOGI("fingerprint_enroll: fingermask=%d", fingermask); + for (idx = 1; idx <= MAX_NUM_FINGERS; idx++) + if (!((fingermask >> idx) & 1)) + break; + + command[2] = (uint8_t)idx; + ret = sendcommand(vdev, command, 3); + + pthread_mutex_unlock(&vdev->lock); + ALOGI("enroll ret=%d",ret); + + // workaround + if (ret == 1) { + ret = 0; + } + + vdev->authenticator_id = getfingermask(vdev); + + return ret; +} + +static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + uint64_t challenge = 0; + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + + challenge = get_64bit_rand(); + + pthread_mutex_lock(&vdev->lock); + vdev->challenge = challenge; + pthread_mutex_unlock(&vdev->lock); + + return challenge; +} + +static int fingerprint_post_enroll(struct fingerprint_device* device) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + + pthread_mutex_lock(&vdev->lock); + vdev->challenge = 0; + pthread_mutex_unlock(&vdev->lock); + + return 0; +} + +static int fingerprint_cancel(struct fingerprint_device *device) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + int ret = 0; + + checkinit(vdev); + + pthread_mutex_lock(&vdev->lock); + vdev->listener.state = STATE_IDLE; + + uint8_t command[1] = {CALL_CANCEL}; + ret = sendcommand(vdev, command, 1); + pthread_mutex_unlock(&vdev->lock); + + return ret; +} + +static int fingerprint_enumerate(struct fingerprint_device *device, + fingerprint_finger_id_t *results, uint32_t *max_size) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + if (device == NULL || results == NULL || max_size == NULL) { + ALOGE("Cannot enumerate saved fingerprints with uninitialized params"); + return -1; + } + + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + int num = 0; + pthread_mutex_lock(&vdev->lock); + + int fingermask = getfingermask(vdev); + + ALOGI("fingerprint_enumerate: fingermask=%d", fingermask); + int idx = 0; + for (idx = 0; idx < MAX_NUM_FINGERS; idx++) + if ((fingermask >> (idx + 1)) & 1) + num++; + pthread_mutex_unlock(&vdev->lock); + + return num; +} + +static int fingerprint_remove(struct fingerprint_device *device, + uint32_t __unused gid, uint32_t fid) { + int idx = 0, ret = 0; + ALOGV("----------------> %s -----------------> fid %d", __FUNCTION__, fid); + if (device == NULL) { + ALOGE("Can't remove fingerprint (gid=%d, fid=%d); " + "device not initialized properly", + gid, fid); + return -1; + } + + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + + uint8_t command[3] = {CALL_REMOVE, (uint8_t)vdev->active_gid, 0}; + + checkinit(vdev); + + if (fid == 0) { + // Delete all fingerprints + command[2] = 21; + pthread_mutex_lock(&vdev->lock); + ret = sendcommand(vdev, command, 3); + pthread_mutex_unlock(&vdev->lock); + if (ret == 0){ + pthread_mutex_lock(&vdev->lock); + int fingermask = getfingermask(vdev); + pthread_mutex_unlock(&vdev->lock); + int idx = 0; + for (idx = 0; idx < MAX_NUM_FINGERS; idx++) + if ((fingermask >> (idx + 1)) & 1) { + send_remove_notice(vdev, idx + 1); + } + } // end if + vdev->listener.state = STATE_IDLE; + } else { + // Delete one fingerprint + pthread_mutex_lock(&vdev->lock); + + command[2] = (uint8_t)fid; + ret = sendcommand(vdev, command, 3); + vdev->listener.state = STATE_IDLE; + pthread_mutex_unlock(&vdev->lock); + + if (ret == 0) { + send_remove_notice(vdev, fid); + } + + } + pthread_mutex_lock(&vdev->lock); + + int fingermask = getfingermask(vdev); + if (fingermask == 0) { // All finger are removed + command[2] = 21; + sendcommand(vdev, command, 3); + } + + pthread_mutex_unlock(&vdev->lock); + + if (ret) { + send_error_notice(vdev, FINGERPRINT_ERROR_UNABLE_TO_REMOVE); + } + + return ret; +} + +static int set_notify_callback(struct fingerprint_device *device, + fingerprint_notify_t notify) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + if (device == NULL || notify == NULL) { + ALOGE("Failed to set notify callback @ %p for fingerprint device %p", + device, notify); + return -1; + } + + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + pthread_mutex_lock(&vdev->lock); + vdev->listener.state = STATE_IDLE; + device->notify = notify; + pthread_mutex_unlock(&vdev->lock); + ALOGD("fingerprint callback notification set"); + + return 0; +} + +static worker_state_t getListenerState(vcs_fingerprint_device_t* dev) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + worker_state_t state = STATE_IDLE; + + pthread_mutex_lock(&dev->lock); + state = dev->listener.state; + pthread_mutex_unlock(&dev->lock); + + return state; +} + +static void* listenerSocket(void* data) { + ALOGI("----------------> %s ----------------->", __FUNCTION__); + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)data; + + while (vdev->receive_fd <= 0) { + vdev->receive_fd = socket_local_client(SOCKET_NAME_RECEIVE, ANDROID_SOCKET_NAMESPACE_ABSTRACT,SOCK_STREAM); + if (vdev->receive_fd < 0) { + ALOGW("listener cannot open fingerprint listener service"); + sleep(1); + } + } + initService(vdev); + pthread_mutex_lock(&vdev->lock); + vdev->listener.state = STATE_IDLE; + pthread_mutex_unlock(&vdev->lock); + + while (1) { + int size = 0; + char buffer[MAX_COMM_CHARS] = {0}; + if (getListenerState(vdev) == STATE_EXIT) { + ALOGD("Received request to exit listener thread"); + goto done; + } + + if ((size = fd_read(vdev->receive_fd, buffer, + sizeof(buffer) - 1)) > 0) { + buffer[size] = '\0'; + int type, info, info_ex; + sscanf(buffer, "%d:%d:%d", &type, &info, &info_ex); + switch (type) { + case 1: //error + send_error_notice(vdev, info); + break; + case 2: //enroll + send_enroll_notice(vdev, info, info_ex); + break; + case 3: //removed + send_remove_notice(vdev, info); + break; + case 4: //acquired + send_acquired_notice(vdev, info); + break; + case 5: //authenticated + send_authenticated_notice(vdev, info); + break; + default: + ALOGE("unknow type:%d", type); + } + } else { + ALOGE("fingerprint listener receive failure"); + break; + } + } + +done: + ALOGD("Listener exit !!"); +done_quiet: + close(vdev->receive_fd); + return NULL; +} + +static int fingerprint_close(hw_device_t* device) { + ALOGV("----------------> %s ----------------->", __FUNCTION__); + if (device == NULL) { + ALOGE("fingerprint hw device is NULL"); + return -1; + } + + vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device; + + checkinit(vdev); + + pthread_mutex_lock(&vdev->lock); + // Ask listener thread to exit + vdev->listener.state = STATE_EXIT; + uint8_t command[1] = {CALL_CLEANUP}; + sendcommand(vdev, command, 1); + pthread_mutex_unlock(&vdev->lock); + + pthread_join(vdev->listener.thread, NULL); + pthread_mutex_destroy(&vdev->lock); + close(vdev->send_fd); + free(vdev); + + return 0; +} + +static int fingerprint_open(const hw_module_t* module, const char __unused *id, + hw_device_t** device) +{ + + ALOGV("----------------> %s ----------------->", __FUNCTION__); + if (device == NULL) { + ALOGE("NULL device on open"); + return -EINVAL; + } + vcs_fingerprint_device_t *vdev = (vcs_fingerprint_device_t*)calloc( + 1, sizeof(vcs_fingerprint_device_t)); + + if (vdev == NULL) { + ALOGE("Insufficient memory for fingerprint device"); + return -ENOMEM; + } + + vdev->device.common.tag = HARDWARE_DEVICE_TAG; + vdev->device.common.version = HARDWARE_MODULE_API_VERSION(2, 0); + vdev->device.common.module = (struct hw_module_t*)module; + vdev->device.common.close = fingerprint_close; + + vdev->device.pre_enroll = fingerprint_pre_enroll; + vdev->device.enroll = fingerprint_enroll; + vdev->device.post_enroll = fingerprint_post_enroll; + vdev->device.get_authenticator_id = fingerprint_get_auth_id; + vdev->device.set_active_group = fingerprint_set_active_group; + vdev->device.authenticate = fingerprint_authenticate; + vdev->device.cancel = fingerprint_cancel; + vdev->device.enumerate = fingerprint_enumerate; + vdev->device.remove = fingerprint_remove; + vdev->device.set_notify = set_notify_callback; + vdev->device.notify = NULL; + + vdev->active_gid = 0; + vdev->init = false; + + pthread_mutex_init(&vdev->lock, NULL); + if (pthread_create(&vdev->listener.thread, NULL, listenerSocket, vdev) != + 0) + return -1; + + *device = &vdev->device.common; + + return 0; +} + +static struct hw_module_methods_t fingerprint_module_methods = { + .open = fingerprint_open, +}; + +fingerprint_module_t HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .id = FINGERPRINT_HARDWARE_MODULE_ID, + .name = "KLTE Fingerprint HAL", + .author = "ljzyal(ljzyal@gmail.com)", + .methods = &fingerprint_module_methods, + }, +}; diff --git a/fingerprint/fp_klte.h b/fingerprint/fp_klte.h new file mode 100644 index 0000000..ae0463c --- /dev/null +++ b/fingerprint/fp_klte.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2016 The CyanogenMod Project + * Copyright (C) 2016 The Mokee Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#define CALL_BASE 0 + +#define CALL_INITSERVICE 1 +#define CALL_ENROLL 2 +//userId ,fingerIndex +#define CALL_CANCEL 3 +#define CALL_REMOVE 4 +//userId ,fingerIndex +#define CALL_IDENTIFY 5 +//userId +#define CALL_GET_ENROLLED_FINGER_LIST 6 +//userId +#define CALL_CLEANUP 7 + +typedef enum worker_state_t { + STATE_IDLE = 0, + STATE_ENROLL, + STATE_SCAN, + STATE_EXIT +} worker_state_t; + +typedef struct worker_thread_t { + pthread_t thread; + worker_state_t state; +} worker_thread_t; + +typedef struct vcs_fingerprint_device_t { + fingerprint_device_t device; // "inheritance" + worker_thread_t listener; + uint64_t op_id; + uint64_t challenge; + uint64_t user_id; + uint64_t group_id; + uint64_t secure_user_id; + uint64_t authenticator_id; + uint32_t active_gid; + int send_fd; //send to validity service + int receive_fd; //recevie from validity service + bool init; + pthread_mutex_t lock; +} vcs_fingerprint_device_t; + +static __inline__ int fd_write(int fd, const void* buff, int len){ + int len2; + do { + len2 = write(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} +static __inline__ int fd_read(int fd, void* buff, int len){ + int len2; + do { + len2 = read(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static void checkinit(vcs_fingerprint_device_t* vdev); +static int sendcommand(vcs_fingerprint_device_t* vdev, uint8_t* command, int num); +static int getfingermask(vcs_fingerprint_device_t* vdev); +static int initService(vcs_fingerprint_device_t* vdev); + +static void send_error_notice(vcs_fingerprint_device_t* vdev, fingerprint_error_t error_info); +static void send_acquired_notice(vcs_fingerprint_device_t* vdev, fingerprint_acquired_info_t acquired_info); +static void send_enroll_notice(vcs_fingerprint_device_t* vdev, int fid, int remaining); +static void send_authenticated_notice(vcs_fingerprint_device_t* vdev, int fid); +static void send_remove_notice(vcs_fingerprint_device_t* vdev, int fid); + +static uint64_t get_64bit_rand(); +static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device); +static int fingerprint_set_active_group(struct fingerprint_device *device, uint32_t gid, + const char __unused *path); +static int fingerprint_authenticate(struct fingerprint_device *device, + uint64_t operation_id, __unused uint32_t gid); +static int fingerprint_enroll(struct fingerprint_device *device, + const hw_auth_token_t *hat, + uint32_t __unused gid, + uint32_t __unused timeout_sec); +static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device); +static int fingerprint_post_enroll(struct fingerprint_device* device); +static int fingerprint_cancel(struct fingerprint_device *device); +static int fingerprint_enumerate(struct fingerprint_device *device, + fingerprint_finger_id_t *results, uint32_t *max_size); +static int fingerprint_remove(struct fingerprint_device *device, + uint32_t __unused gid, uint32_t fid); +static int set_notify_callback(struct fingerprint_device *device, + fingerprint_notify_t notify); + +static worker_state_t getListenerState(vcs_fingerprint_device_t* dev); +static void* listenerSocket(void* data); + +static int fingerprint_close(hw_device_t* device); +static int fingerprint_open(const hw_module_t* module, const char __unused *id, + hw_device_t** device); + diff --git a/klte.mk b/klte.mk index 653ab6a..77b4154 100644 --- a/klte.mk +++ b/klte.mk @@ -41,6 +41,7 @@ $(call inherit-product-if-exists, frameworks/native/build/phone-xxhdpi-2048-hwui PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.audio.low_latency.xml:system/etc/permissions/android.hardware.audio.low_latency.xml \ frameworks/native/data/etc/android.hardware.consumerir.xml:system/etc/permissions/android.hardware.consumerir.xml \ + frameworks/native/data/etc/android.hardware.fingerprint.xml:system/etc/permissions/android.hardware.fingerprint.xml \ frameworks/native/data/etc/android.hardware.nfc.xml:system/etc/permissions/android.hardware.nfc.xml \ frameworks/native/data/etc/android.hardware.nfc.hce.xml:system/etc/permissions/android.hardware.nfc.hce.xml \ frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:system/etc/permissions/android.hardware.sensor.stepcounter.xml \ @@ -72,6 +73,12 @@ PRODUCT_PACKAGES += \ PRODUCT_PACKAGES += \ SamsungDoze +# Fingerprint +PRODUCT_PACKAGES += \ + fingerprintd \ + fingerprint.msm8974 \ + ValidityService + # IPv6 tethering PRODUCT_PACKAGES += \ ebtables \ diff --git a/proprietary-files.txt b/proprietary-files.txt index 27be124..820bc27 100644 --- a/proprietary-files.txt +++ b/proprietary-files.txt @@ -221,6 +221,14 @@ vendor/lib/libwvm.so vendor/lib/libWVStreamControlAPI_L1.so vendor/lib/mediadrm/libwvdrmengine.so +# Fingerprint +bin/vcsFPService +lib/libfpasmtztransport.so +lib/libvalAuth.so +lib/libvcsfp.so +lib/libvfmClient.so +lib/libvfmtztransport.so + # Graphics vendor/lib/egl/eglsubAndroid.so vendor/lib/egl/libEGL_adreno.so diff --git a/rootdir/etc/init.qcom.rc b/rootdir/etc/init.qcom.rc index a99bf28..13c27a4 100644 --- a/rootdir/etc/init.qcom.rc +++ b/rootdir/etc/init.qcom.rc @@ -438,7 +438,11 @@ on boot chown system system /sys/class/input/input0/enabled # Fingerprint - mkdir /dev/validity 0775 system system + mkdir /dev/validity 0770 system system + mkdir /data/validity 0770 system system + + # Fingerprint_sensor + chown system radio /sys/class/fingerprint/fingerprint/type_check # SEC DVFS sysfs node chown radio system /sys/power/cpufreq_max_limit @@ -929,6 +933,11 @@ service adsprpcd /system/bin/adsprpcd user media group media +service fingerprintd /system/bin/fingerprintd + class late_start + user system + group input + service qcamerasvr /system/bin/mm-qcamera-daemon class main user camera @@ -1164,6 +1173,12 @@ service sec-sh /system/bin/sh /system/etc/init.sec.boot.sh user root oneshot +# SENSOR FRAMEWORK : starts fingerprintService +service vcsFPService /system/bin/vcsFPService + class late_start + user system + group system + on property:persist.sys.ssr.restart_level=1 write /sys/module/subsystem_restart/parameters/restart_level 1 diff --git a/rootdir/etc/ueventd.qcom.rc b/rootdir/etc/ueventd.qcom.rc index cc345f0..6047d66 100644 --- a/rootdir/etc/ueventd.qcom.rc +++ b/rootdir/etc/ueventd.qcom.rc @@ -147,6 +147,9 @@ /dev/ttyGS0 0660 system system /dev/i2c-5 0660 media media +# Fingerprint +/dev/vfsspi 0660 system system + # DVB devices /dev/dvb/adapter0/demux* 0440 media media /dev/dvb/adapter0/dvr* 0660 media media diff --git a/sepolicy/file.te b/sepolicy/file.te index 1cef9ce..3d00a1e 100644 --- a/sepolicy/file.te +++ b/sepolicy/file.te @@ -3,4 +3,5 @@ type sysfs_camera, fs_type, sysfs_type; type sysfs_display, fs_type, sysfs_type; type sysfs_sec, fs_type, sysfs_type; type sysfs_vibeamp, fs_type, sysfs_type; +type vcs_data_file, file_type, data_file_type; type wifi_efs_file, file_type; diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts index 2f9da6e..142eceb 100644 --- a/sepolicy/file_contexts +++ b/sepolicy/file_contexts @@ -19,6 +19,12 @@ # EFS /dev/block/bootdevice/by-name/efs u:object_r:modem_efs_partition_device:s0 +# Fingerprint +/system/bin/vcsFPService u:object_r:vcs_exec:s0 +/data/validity(/.*)? u:object_r:vcs_data_file:s0 +/dev/validity(/.*)? u:object_r:vcs_device:s0 +/dev/vfsspi u:object_r:vcs_device:s0 + # Macloader /system/bin/macloader u:object_r:macloader_exec:s0 diff --git a/sepolicy/fingerprintd.te b/sepolicy/fingerprintd.te new file mode 100644 index 0000000..0844bf1 --- /dev/null +++ b/sepolicy/fingerprintd.te @@ -0,0 +1 @@ +allow fingerprintd system_app:unix_stream_socket { connectto read write setopt }; diff --git a/sepolicy/system_app.te b/sepolicy/system_app.te new file mode 100644 index 0000000..027926f --- /dev/null +++ b/sepolicy/system_app.te @@ -0,0 +1,7 @@ +# For com.validity.fingerprint +allow system_app vcs:process signull; +allow system_app vcs_data_file:dir r_dir_perms; +allow system_app vcs_data_file:file r_file_perms; +allow system_app vcs_device:dir r_dir_perms; +allow system_app vcs_device:file r_file_perms; +allow system_app vcs_device:fifo_file create_file_perms; diff --git a/sepolicy/tee.te b/sepolicy/tee.te new file mode 100644 index 0000000..02eeef6 --- /dev/null +++ b/sepolicy/tee.te @@ -0,0 +1,2 @@ +allow tee vcs_data_file:dir create_dir_perms; +allow tee vcs_data_file:file create_file_perms; diff --git a/sepolicy/ueventd.te b/sepolicy/ueventd.te index b224fc3..e9dd599 100644 --- a/sepolicy/ueventd.te +++ b/sepolicy/ueventd.te @@ -1,3 +1,4 @@ allow ueventd sysfs_camera:file rw_file_perms; allow ueventd sysfs_sec:file rw_file_perms; allow ueventd sysfs_vibeamp:file rw_file_perms; +allow ueventd vcs_device:chr_file create_file_perms; diff --git a/sepolicy/vcs.te b/sepolicy/vcs.te new file mode 100644 index 0000000..dcc28f1 --- /dev/null +++ b/sepolicy/vcs.te @@ -0,0 +1,22 @@ +type vcs, domain; +type vcs_exec, exec_type, file_type; + +# vcs +init_daemon_domain(vcs) +binder_use(vcs) + +allow vcs system_app:process signull; + +allow vcs vcs_data_file:dir create_dir_perms; +allow vcs vcs_data_file:file create_file_perms; + +allow vcs vcs_device:dir create_dir_perms; +allow vcs vcs_device:file create_file_perms; +allow vcs vcs_device:fifo_file create_file_perms; +allow vcs vcs_device:chr_file create_file_perms; + +allow vcs tee_device:chr_file rw_file_perms; + +allow vcs firmware_file:dir r_dir_perms; +allow vcs firmware_file:file r_file_perms; + diff --git a/validityservice/Android.mk b/validityservice/Android.mk new file mode 100644 index 0000000..eb55cac --- /dev/null +++ b/validityservice/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_PACKAGE_NAME := ValidityService + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res +LOCAL_AAPT_FLAGS := --auto-add-overlay + +LOCAL_PROGUARD_FLAG_FILES := proguard.flags + +LOCAL_CERTIFICATE := platform +LOCAL_PRIVILEGED_MODULE := true + +LOCAL_JACK_ENABLED := disabled + +include $(BUILD_PACKAGE) diff --git a/validityservice/AndroidManifest.xml b/validityservice/AndroidManifest.xml new file mode 100644 index 0000000..50d1d79 --- /dev/null +++ b/validityservice/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + diff --git a/validityservice/proguard.flags b/validityservice/proguard.flags new file mode 100644 index 0000000..47c2f15 --- /dev/null +++ b/validityservice/proguard.flags @@ -0,0 +1,2 @@ +-verbose +-keep class com.validity.fingerprint.* {*;} diff --git a/validityservice/res/drawable/icon.png b/validityservice/res/drawable/icon.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/validityservice/res/drawable/icon.png differ diff --git a/validityservice/res/values/strings.xml b/validityservice/res/values/strings.xml new file mode 100644 index 0000000..3617dc1 --- /dev/null +++ b/validityservice/res/values/strings.xml @@ -0,0 +1,20 @@ + + + + Validity service + diff --git a/validityservice/src/com/validity/fingerprint/ConsumerInfo.java b/validityservice/src/com/validity/fingerprint/ConsumerInfo.java new file mode 100644 index 0000000..c81267d --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/ConsumerInfo.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + + +public class ConsumerInfo { + public Object info; + public int type; + + public ConsumerInfo() { + } + + public ConsumerInfo(int type) { + this.type = type; + } +} diff --git a/validityservice/src/com/validity/fingerprint/EnrollCaptureStatus.java b/validityservice/src/com/validity/fingerprint/EnrollCaptureStatus.java new file mode 100644 index 0000000..94d87d0 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/EnrollCaptureStatus.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class EnrollCaptureStatus { + + public int badSwipes; + public int cumulativeCoverageMap; + public int currentCoverageMap; + public int imageQuality; + public int positionFeedback; + public int progress; + public int templateResult; + public int totalSwipes; + +} diff --git a/validityservice/src/com/validity/fingerprint/EnrollUser.java b/validityservice/src/com/validity/fingerprint/EnrollUser.java new file mode 100644 index 0000000..2710f52 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/EnrollUser.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class EnrollUser { + public int fingerIndex; + public int mode; + public String userId; + + public EnrollUser() { + mode = 1; + } + +} diff --git a/validityservice/src/com/validity/fingerprint/Fingerprint.java b/validityservice/src/com/validity/fingerprint/Fingerprint.java new file mode 100644 index 0000000..50a5bdd --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/Fingerprint.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +import android.content.Context; +import android.util.Log; + +public class Fingerprint extends FingerprintCore { + + public static final int VCS_ENROLL_MODE_DEFAULT = 1; + public static final int VCS_ENROLL_MODE_REENROLL = 2; + public static final int VCS_ENROLL_MODE_SECONDARY = 3; + + public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_MIDDLE = 11; + public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_MIDDLE_FULL = 12; + public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_LEFT = 21; + public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_RIGHT = 31; + public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_ANY = 41; + + public static final int VCS_NOTIFY_SNSR_TEST_CONTINUE = 1; + public static final int VCS_NOTIFY_SNSR_TEST_STOP = 2; + public static final int VCS_NOTIFY_ENROLL_BEGIN = 3; + public static final int VCS_NOTIFY_ENROLL_END = 4; + + public static final int VCS_REQUEST_PROCESS_FIDO = 1; + public static final int VCS_REQUEST_PROCESS_ALIPAY = 2; + public static final int VCS_REQUEST_COMMAND_SENSOR_TEST = 11; + public static final int VCS_REQUEST_GET_SENSOR_INFO = 12; + public static final int VCS_REQUEST_GET_ENROLL_REPEAT_COUNT = 13; + private static final int VCS_REQUEST_ENABLE_WOF = 21; + private static final int VCS_REQUEST_GET_WOF_STATE = 22; + + public static final int VCS_SENSOR_STATUS_OK = 0; + public static final int VCS_SENSOR_STATUS_WORKING = 46; + public static final int VCS_SENSOR_STATUS_INITIALISING = 358; + public static final int VCS_SENSOR_STATUS_INITIALIZING = 358; + public static final int VCS_SENSOR_STATUS_OUT_OF_ORDER = 360; + public static final int VCS_SENSOR_STATUS_MALFUNCTIONED = 534; + public static final int VCS_SENSOR_STATUS_FAILURE = 535; + + public static final int VCS_WOF_STATE_INACTIVE = 0; + public static final int VCS_WOF_STATE_ACTIVE = 1; + + private native int jniEnableSensorDevice(int enable); + private native int jniEnrollUser(Object enrollInfo); + private native int jniEnrollUser(String userId, int fingerIndex, int mode); + private native int jniEnrollUser(String userId, String appData, int fingerIndex); + private native int jniGetSensorStatus(); + private native int jniNotify(int code, Object data); + private native int jniProcessFIDO(byte requestData[], VcsByteArray responseData); + private native int jniReEnrollUser(String userId, String appData, int fingerIndex, int mode); + private native int jniRemoveEnrolledFinger(Object enrollInfo); + private native int jniRemoveEnrolledFinger(String userId, int fingerIndex); + private native int jniRequest(int command, Object data); + private native int jniSetPassword(String userId, byte abyte0[], byte newPwdHash[]); // What is abyte0 means? + private native int jniVerifyPassword(String userId, byte pwdHash[]); + + public Fingerprint(Context ctx) { + super(ctx); + } + + public Fingerprint(Context ctx, FingerprintCore.EventListener listener) { + super(ctx, listener); + } + + public int enableSensorDevice(boolean enable) { + if (mOperation != 150) + return VCS_RESULT_ALREADY_INPROGRESS; + return jniEnableSensorDevice((enable? 1: 0)); + } + + public int enableWakeOnFinger() { + return jniRequest(VCS_REQUEST_ENABLE_WOF, null); + } + + public int enroll(EnrollUser enrollInfo) { + int ret = VCS_RESULT_FAILED; + if (mOperation != 150) + return ret; + ret = jniEnrollUser(enrollInfo); + if (ret == VCS_RESULT_OK) + mOperation = 151; + return ret; + } + + public int enroll(String userId, int fingerIndex) { + int ret = VCS_RESULT_FAILED; + if (mOperation != 150) + return ret; + if (null == userId) + userId = ""; + ret = jniEnrollUser(userId, fingerIndex, VCS_ENROLL_MODE_DEFAULT); + if (ret == VCS_RESULT_OK) + mOperation = 151; + return ret; + } + + public int enroll(String userId, int fingerIndex, int mode) { + int ret = VCS_RESULT_FAILED; + if (mOperation != 150) + return ret; + if (null == userId) + userId = ""; + ret = jniEnrollUser(userId, fingerIndex, mode); + if (ret == VCS_RESULT_OK) + mOperation = 151; + return ret; + } + + public int enroll(String userId, String appData, int fingerIndex) { + int ret = VCS_RESULT_FAILED; + if (mOperation != 150) + return ret; + if (null == userId) + userId = ""; + if (null == appData) + appData = ""; + ret = jniEnrollUser(userId, appData, fingerIndex); + if (ret == VCS_RESULT_OK) + mOperation = 151; + return ret; + } + + public int enroll(String userId, String appData, int fingerIndex, int mode) { + int ret = VCS_RESULT_FAILED; + if (mOperation != 150) + return ret; + if (null == userId) + userId = ""; + if (null == appData) + appData = ""; + ret = jniReEnrollUser(userId, appData, fingerIndex, mode); + if (ret == VCS_RESULT_OK) + mOperation = 151; + return ret; + } + + public int getSensorStatus() { + if (mOperation != 150) + return VCS_RESULT_ALREADY_INPROGRESS; + return jniGetSensorStatus(); + } + + public int getWakeOnFingerState(VcsInt wofState) { + if (wofState == null) + return VCS_RESULT_INVALID_ARGUMENT; + return jniRequest(VCS_REQUEST_GET_WOF_STATE, wofState); + } + + public int notify(int code, Object data) { + return jniNotify(code, data); + } + + public int processFIDO(byte requestData[], VcsByteArray responseData) { + if ((requestData == null) || (responseData == null)) + return VCS_RESULT_INVALID_ARGUMENT; + return jniProcessFIDO(requestData, responseData); + } + + public int removeEnrolledFinger(RemoveEnroll enrollInfo) { + return jniRemoveEnrolledFinger(enrollInfo); + } + + public int removeEnrolledFinger(String userId, int fingerIndex) { + if (mOperation != 150) + return VCS_RESULT_ALREADY_INPROGRESS; + if (null == userId) + userId = ""; + return jniRemoveEnrolledFinger(userId, fingerIndex); + } + + public int removeEnrolledUser(String userId) { + if (mOperation != 150) + return VCS_RESULT_ALREADY_INPROGRESS; + if (null == userId) + userId = ""; + return jniRemoveEnrolledFinger(userId, FINGER_INDEX_LEFT_THUMB_SECOND); + } + + public int request(int command, Object data) { + return jniRequest(command, data); + } + + public int setPassword(String userId, byte newPwdHash[]) { + if (userId == null || newPwdHash == null) + return VCS_RESULT_INVALID_ARGUMENT; + return jniSetPassword(userId, "".getBytes(), newPwdHash); + } + + public int verifyPassword(String userId, byte pwdHash[]) { + if (userId == null || pwdHash == null) + return VCS_RESULT_INVALID_ARGUMENT; + return jniVerifyPassword(userId, pwdHash); + } +} diff --git a/validityservice/src/com/validity/fingerprint/FingerprintBitmap.java b/validityservice/src/com/validity/fingerprint/FingerprintBitmap.java new file mode 100644 index 0000000..9b4d1cc --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/FingerprintBitmap.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +import android.graphics.Bitmap; + +public class FingerprintBitmap { + public Bitmap fingerprint; + public int quality; +} diff --git a/validityservice/src/com/validity/fingerprint/FingerprintCore.java b/validityservice/src/com/validity/fingerprint/FingerprintCore.java new file mode 100644 index 0000000..d83b246 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/FingerprintCore.java @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +import android.content.Context; +import android.util.Log; + +public class FingerprintCore extends VcsEvents { + public static interface EventListener { + public abstract void onEvent(FingerprintEvent fingerprintevent); + } + public static final String API_VERSION = "0.7"; + public static final String VCS_POLICY_VERSION = "0.1"; + protected static final boolean DBG = false; + protected static final int IDLE = 150; + protected static final int ENROLL = 151; + protected static final int IDENTIFY = 152; + protected static final int STOREDATATOUSER = 153; + protected static final int GETDATAFROMUSER = 154; + protected static final int REMOVEDATAFROMUSER = 155; + protected static final int GETPRINT = 156; + protected static final String TAG = "Fingerprint"; + protected static final String USER_ID = "android"; + protected int mOperation; + private EventListener mEventListener; + private String mAppId; + private String mUserId; + private String mAppKey; + private String mKeyData; + + private native int jniCancelOp(); + private native int jniCleanupVcs(); + private native int jniGetEnrolledFingerList(String userId, VcsInt fingermask); + private native int jniGetFingerprintImage(); + private native int jniGetFingerprintImageEx(Object info); + private native String[] jniGetUserList(VcsInt retCode); + private native String jniGetVersion(); + private native int jniIdentify(String userId); + private native int jniInitVcs(); + private native int jniInitVcs(FingerprintCore fingerprintcore); + private native int jniProtect(byte toProtect[], VcsAddInfo addInfo, VcsByteArray protectedData); + private native int jniRegisterEventsCB(FingerprintCore fingerprintcore); + private native int jniSetDetectFinger(int timeout); + private native int jniSetSecurityLevel(int level); + private native int jniUnprotect(byte protectedData[], VcsAddInfo addInfo, VcsByteArray unProtectedData); + + static { + try { + System.loadLibrary("vcsfp"); + } + catch (Throwable e) { + Log.e("Fingerprint", "Error loading library libvcsfp: " + e); + } + } + + public FingerprintCore(Context ctx) { + mOperation = IDLE; + mEventListener = null; + mAppId = ""; + mUserId = ""; + mAppKey = ""; + mKeyData = ""; + jniInitVcs(this); + } + + public FingerprintCore(Context ctx, EventListener listener) { + mOperation = IDLE; + mEventListener = null; + mAppId = ""; + mUserId = ""; + mAppKey = ""; + mKeyData = ""; + VLog.i("init ret="+jniInitVcs(this)); + mEventListener = listener; + } + + private boolean isOperationComplete(int eventId) { + if (eventId == VCS_EVT_ENROLL_SUCCESS || eventId == VCS_EVT_IDENTIFY_SUCCESS || + eventId == VCS_EVT_VERIFY_SUCCESS || eventId == VCS_EVT_ENROLL_FAILED || + eventId == VCS_EVT_IDENTIFY_FAILED || eventId == VCS_EVT_VERIFY_FAILED || + eventId == VCS_EVT_GESTURE) + return true; + return false; + } + + public synchronized void FingerprintEventCallback(FingerprintEvent event) { + if (event == null) { + Log.e("Fingerprint", "FP - EventsCB()::Invalid event data!"); + return; + } + if (isOperationComplete(event.eventId)) { + Log.i("Fingerprint", "Operation complete, setting to IDLE"); + this.mOperation = IDLE; + } + if ((this.mOperation == GETPRINT) && ((event.eventId == VCS_EVT_EIV_FINGERPRINT_CAPTURED) || + (event.eventId == VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_FAILED))) { + this.mOperation = IDLE; + } + if (this.mEventListener != null) { + this.mEventListener.onEvent(event); + } + } + + public int cancel() { + int ret = VCS_RESULT_FAILED; + if (mOperation == IDLE) + return ret; + ret = jniCancelOp(); + mOperation = IDLE; + return ret; + } + + public int cleanUp() { + int ret = VCS_RESULT_FAILED; + mEventListener = null; + ret = jniCleanupVcs(); + return ret; + } + + public int getEnrolledFingerList(String userId, VcsInt fingermask) { + if (null == userId) + userId = ""; + int ret = jniGetEnrolledFingerList(userId, fingermask);; + return ret; + } + + public int getFingerprintImage(){ + int ret = VCS_RESULT_FAILED; + if (mOperation != IDLE) + return ret; + ret = jniGetFingerprintImage(); + if (ret == VCS_RESULT_OK) + mOperation = GETPRINT; + return ret; + } + + public int getFingerprintImage(ConsumerInfo info) { + int ret = VCS_RESULT_FAILED; + if (mOperation != IDLE) + return ret; + if (info == null) + Log.i("Fingerprint", "ConsumerInfo is null"); + ret = jniGetFingerprintImageEx(info); + if (ret == VCS_RESULT_OK) + mOperation = GETPRINT; + return ret; + } + + public int getUserList(VcsStringArray userList) { + VcsInt retCode = new VcsInt(); + userList.strlist = jniGetUserList(retCode); + if (userList.strlist == null) + return retCode.num; + return VCS_RESULT_OK; + } + + public String getVersion() { + if (mOperation != IDLE) { + Log.e("Fingerprint", "Other operation is in progress, cancelling request"); + return null; + } + return jniGetVersion(); + } + + public int identify(String userId) { + int ret = VCS_RESULT_FAILED; + if (mOperation == IDENTIFY) + return VCS_RESULT_ALREADY_INPROGRESS; + if (mOperation != IDLE) { + return ret; + } else { + if (null == userId) + userId = ""; + ret = jniIdentify(userId); + if (ret == VCS_RESULT_OK) + mOperation = IDENTIFY; + } + return ret; + } + + public int protect(byte toProtect[], VcsAddInfo addInfo, VcsByteArray protectedData) { + if (toProtect == null || addInfo == null || protectedData == null) + return VCS_RESULT_INVALID_ARGUMENT; + return jniProtect(toProtect, addInfo, protectedData); + } + + public int registerListener(EventListener listener) { + if (mOperation != IDLE) + return VCS_RESULT_FAILED; + mEventListener = listener; + return VCS_RESULT_OK; + } + + public int setDetectFinger(int timeout) { + return jniSetDetectFinger(timeout); + } + + public int setSecurityLevel(int level) { + if (mOperation != IDLE) + return VCS_RESULT_FAILED; + if (level == VCS_SECURITY_LEVEL_LOW || level == VCS_SECURITY_LEVEL_REGULAR || + level == VCS_SECURITY_LEVEL_HIGH || level == VCS_SECURITY_LEVEL_VERY_HIGH) + return jniSetSecurityLevel(level); + return VCS_RESULT_INVALID_ARGUMENT; + } + + public int unProtect(byte protectedData[], VcsAddInfo addInfo, VcsByteArray unProtectedData) { + if (protectedData == null || unProtectedData == null) + return VCS_RESULT_INVALID_ARGUMENT; + if (null == addInfo) + addInfo = new VcsAddInfo(); + return jniUnprotect(protectedData, addInfo, unProtectedData); + } +} diff --git a/validityservice/src/com/validity/fingerprint/FingerprintEvent.java b/validityservice/src/com/validity/fingerprint/FingerprintEvent.java new file mode 100644 index 0000000..905fda5 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/FingerprintEvent.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class FingerprintEvent { + public Object eventData; + public int eventId; +} diff --git a/validityservice/src/com/validity/fingerprint/IdentifyResult.java b/validityservice/src/com/validity/fingerprint/IdentifyResult.java new file mode 100644 index 0000000..504a5d0 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/IdentifyResult.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class IdentifyResult { + public byte templateId[] = new byte[16]; + public int matchedFingerIndexes[] = new int[20]; + public int corrMinuCount[] = new int[4]; + public int vMinuCount[] = new int[4]; + public String appData; + public int fMinuCount; + public int fingerIndex; + public float matchRate; + public int matchScore; + public int templateUpdated; + public String userId; +} diff --git a/validityservice/src/com/validity/fingerprint/RemoveEnroll.java b/validityservice/src/com/validity/fingerprint/RemoveEnroll.java new file mode 100644 index 0000000..f6681d9 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/RemoveEnroll.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class RemoveEnroll { + public int fingerIndex; + public String userId; +} diff --git a/validityservice/src/com/validity/fingerprint/SensorInfo.java b/validityservice/src/com/validity/fingerprint/SensorInfo.java new file mode 100644 index 0000000..0af01f1 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/SensorInfo.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class SensorInfo { + public int flexId; + public String fwVersion; + public int productId; +} diff --git a/validityservice/src/com/validity/fingerprint/VLog.java b/validityservice/src/com/validity/fingerprint/VLog.java new file mode 100644 index 0000000..7d65d0b --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/VLog.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +import android.util.Log; + +public class VLog { + private static final String TAG = "ValidityService"; + private static final boolean DEBUG = false; + + public static void i(final String message) { + Log.i(TAG, message); + } + + public static void d(final String message) { + if (DEBUG) { + Log.d(TAG, message); + } + } + + public static void v(final String message) { + if (DEBUG) { + Log.v(TAG, message); + } + } + + public static void e(final String message, final Throwable t) { + Log.e(TAG, message, t); + } + + public static void e(final String message) { + Log.e(TAG, message); + } + + public static void w(final String message, final Throwable t) { + Log.w(TAG, message, t); + } + + public static void w(final String message) { + Log.w(TAG, message); + } +} diff --git a/validityservice/src/com/validity/fingerprint/ValidityService.java b/validityservice/src/com/validity/fingerprint/ValidityService.java new file mode 100644 index 0000000..b827e9c --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/ValidityService.java @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.LocalServerSocket; +import android.net.LocalSocket; +import android.os.Bundle; +import android.os.IBinder; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +public class ValidityService extends Service implements FingerprintCore.EventListener { + public static final String SOCKET_NAME = "validityservice"; + public static final String SOCKET_NAME_CB = "validityservice_callback"; + private LocalServerSocket mServerSocket = null; + private LocalServerSocket mServerSocketCB = null; + private LocalSocket mSocketCB = null; + + public static final int CALL_BASE = 0; + + public static final int CALL_INITSERVICE = CALL_BASE + 1; + public static final int CALL_ENROLL = CALL_BASE + 2; // userId ,fingerIndex + public static final int CALL_CANCEL = CALL_BASE + 3; + public static final int CALL_REMOVE = CALL_BASE + 4; // userId ,fingerIndex + public static final int CALL_IDENTIFY = CALL_BASE + 5; // userId + public static final int CALL_GET_ENROLLED_FINGER_LIST = CALL_BASE + 6; // userId + public static final int CALL_CLEANUP = CALL_BASE + 7; + + public static final int CB_ERROR = 1; + public static final int CB_ENROLL = 2; + public static final int CB_REMOVED = 3; + public static final int CB_ACQUIRED = 4; + public static final int CB_AUTHENTICATED = 5; + + private boolean mIsIdentify = false; + private int mLastEnrollFingerindex = 0; + private IdentifyResult mIdresult = null; + private boolean mEnrollBad = false; + private int mEnrollRepeatCount = 0; + private int mActiveGid = 0; + private boolean mIsNeedIdentify = false; + private int mIdentifyImage = 0; + + Fingerprint fp = new Fingerprint(this, this); + + /** We should set a password after we enroll one finger. This password is "123456q" + * The password hash method is SHA-1. + */ + public static final byte[] pwdhash = "bfff2dd4f1b310eb0dbf593bd83f94dd8d34077e".getBytes(); + + public int initService() { + int ret = fp.getSensorStatus(); + VLog.i("init: ret=" + ret); + VLog.i("init: version=" + fp.getVersion()); + notify_start(); + if (ret != 0 && ret != 1004) return -1; + return 0; + } + + public void notify_start() { + fp.cancel(); + fp.notify(Fingerprint.VCS_NOTIFY_ENROLL_BEGIN, null); + } + + public void notify_end() { + fp.cancel(); + fp.notify(Fingerprint.VCS_NOTIFY_ENROLL_END, null); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); + VLog.v("onCreate"); + try { + mServerSocket = new LocalServerSocket(SOCKET_NAME); + mServerSocketCB = new LocalServerSocket(SOCKET_NAME_CB); + } catch (IOException e) { + VLog.v("in onCreate, making server socket: " + e); + return; + } + Thread t_server = new Thread() { + @Override + public void run() { + LocalSocket socket = null; + while (true) { + try { + VLog.v("Waiting for connection..."); + socket = mServerSocket.accept(); + VLog.v(".....Got socket: " + socket); + if (socket != null) { + startService(socket); + } else { + return; + } + } catch (IOException e) { + VLog.v("in accept: " + e); + } + } + } + }; + Thread t_server_cb = new Thread() { + @Override + public void run() { + while (true) { + try { + VLog.v("Waiting for connection..."); + mSocketCB = mServerSocketCB.accept(); + VLog.v(".....Got socket: " + mSocketCB); + if (mSocketCB == null) { + return; + } + } catch (IOException e) { + VLog.v("in accept: " + e); + } + } + } + }; + t_server.start(); + t_server_cb.start(); + + ScreenReceiver receiver = new ScreenReceiver(); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + registerReceiver(receiver, filter); + } + + private void startService(final LocalSocket socket) { + Thread t = new Thread() { + @Override + public void run() { + try { + InputStream is = socket.getInputStream(); + OutputStream os = socket.getOutputStream(); + InputStreamReader isr = new InputStreamReader(is); + OutputStreamWriter osr = new OutputStreamWriter(os); + while (true) { + byte[] data = new byte[128]; + int count = is.read(data); + int ret = -1; + String userId; + int fingerIndex; + for (int i = 0;i < count;i++){ + VLog.d("data["+i+"]="+data[i]); + } + switch (data[0]) { + case CALL_INITSERVICE: + ret = initService(); + break; + case CALL_ENROLL: + userId = "User_" + data[1]; + fingerIndex = data[2]; + mLastEnrollFingerindex = fingerIndex; + mEnrollBad = false; + mEnrollRepeatCount = 8; + fp.verifyPassword(userId, pwdhash); + ret = fp.enroll(userId, "", fingerIndex, Fingerprint.VCS_ENROLL_MODE_DEFAULT); + break; + case CALL_CANCEL: + ret = fp.cancel(); + break; + case CALL_REMOVE: + userId = "User_" + data[1]; + fingerIndex = data[2]; + ret = fp.removeEnrolledFinger(userId, fingerIndex); + if (fingerIndex == VcsEvents.FINGER_INDEX_ALL) { + notify_end(); + notify_start(); + } + break; + case CALL_IDENTIFY: + userId = "User_" + data[1]; + mIsIdentify = true; + fp.setSecurityLevel(VcsEvents.VCS_SECURITY_LEVEL_HIGH); + mIdresult = null; + mActiveGid = data[1]; + ret = fp.identify(userId); + break; + case CALL_GET_ENROLLED_FINGER_LIST: + userId = "User_" + data[1]; + VcsInt fingermask = new VcsInt(); + fp.getEnrolledFingerList(userId, fingermask); + ret = fingermask.num; + break; + case CALL_CLEANUP: + notify_end(); + ret = fp.cleanUp(); + break; + default: + VLog.e("unknown function:" + data[0]); + } + String str = ret + ""; + osr.write(str); + osr.flush(); + } + } catch (IOException e) { + VLog.e("in startService loop: " + e.getMessage()); + try { + socket.close(); + } catch (IOException es) { + VLog.e("Cannot close socket: " + es.getMessage()); + } + return; + } + } + }; + t.start(); + } + + public int convertImageQuality(int imageQuality) { + switch (imageQuality) { + case VcsEvents.VCS_IMAGE_QUALITY_GOOD: + return 0; // FINGERPRINT_ACQUIRED_GOOD + case VcsEvents.VCS_IMAGE_QUALITY_REVERSE_MOTION: + case VcsEvents.VCS_IMAGE_QUALITY_TOO_SHORT: + case VcsEvents.VCS_IMAGE_QUALITY_WET_FINGER: + return 1; // FINGERPRINT_ACQUIRED_PARTIAL + case VcsEvents.VCS_IMAGE_QUALITY_STICTION: + case VcsEvents.VCS_IMAGE_QUALITY_SOMETHING_ON_THE_SENSOR: + return 3; // FINGERPRINT_ACQUIRED_IMAGER_DIRTY + case VcsEvents.VCS_IMAGE_QUALITY_TOO_SLOW: + return 4; // FINGERPRINT_ACQUIRED_TOO_SLOW + case VcsEvents.VCS_IMAGE_QUALITY_TOO_FAST: + return 5; // FINGERPRINT_ACQUIRED_TOO_FAST + default: + VLog.d("imageQuality="+imageQuality); + return 2; // FINGERPRINT_ACQUIRED_INSUFFICIENT + } + } + + /** Get which finger we detected. */ + public int getIdentifyFid() { + if (mIdresult == null) return 1; + return mIdresult.fingerIndex; + } + + public void onEvent(final FingerprintEvent event) { + VLog.v("identify onEvent: receive event :" + event.eventId); + OutputStreamWriter osr = null; + try { + OutputStream os = mSocketCB.getOutputStream(); + osr = new OutputStreamWriter(os); + String str = null; + switch (event.eventId) { + case VcsEvents.VCS_EVT_EIV_FINGERPRINT_CAPTURE_REDUNDANT: + str = CB_ACQUIRED + ":" + 1; + mEnrollBad = true; + break; + case VcsEvents.VCS_EVT_ENROLL_CAPTURE_STATUS: + EnrollCaptureStatus data_status = (EnrollCaptureStatus)event.eventData; + if (mEnrollBad) mEnrollBad = false; + else mEnrollRepeatCount = mEnrollRepeatCount - 1; + if (mEnrollRepeatCount != 0) { + str = CB_ENROLL + ":" + mLastEnrollFingerindex + ":" + mEnrollRepeatCount; + } + break; + case VcsEvents.VCS_EVT_EIV_FINGERPRINT_CAPTURED_BAD: + str = CB_ACQUIRED + ":" + convertImageQuality((int)event.eventData); + mEnrollBad = true; + break; + case VcsEvents.VCS_EVT_ENROLL_SUCCESS: + str = CB_ENROLL + ":" + mLastEnrollFingerindex + ":" + 0; + fp.setPassword("User_0", pwdhash); + break; + case VcsEvents.VCS_EVT_ENROLL_FAILED: + str = CB_ERROR + ":" + 2; //FINGERPRINT_ERROR_UNABLE_TO_PROCESS + VLog.e("enroll onEvent: enroll error, result=" + (int)event.eventData); + break; + case VcsEvents.VCS_EVT_VERIFY_COMPLETED: + case VcsEvents.VCS_EVT_IDENTIFY_COMPLETED: + mIdresult = (IdentifyResult)event.eventData; + break; + case VcsEvents.VCS_EVT_EIV_FINGERPRINT_CAPTURED: + FingerprintBitmap data_map = (FingerprintBitmap)event.eventData; + mIdentifyImage = convertImageQuality(data_map.quality); + break; + case VcsEvents.VCS_EVT_VERIFY_SUCCESS: + case VcsEvents.VCS_EVT_IDENTIFY_SUCCESS: + mIsIdentify = false; + str = CB_AUTHENTICATED + ":" + getIdentifyFid(); + break; + case VcsEvents.VCS_EVT_SENSOR_REMOVED: + mIsIdentify = false; + str = CB_ERROR + ":" + 1; //FINGERPRINT_ERROR_HW_UNAVAILABLE + VLog.e("identify onEvent: identify error, result=" + (int)event.eventData); + break; + case VcsEvents.VCS_EVT_VERIFY_FAILED: + case VcsEvents.VCS_EVT_IDENTIFY_FAILED: + mIsIdentify = false; + VLog.e("identify onEvent: identify error, result=" + (int)event.eventData); + switch ((int)event.eventData) { + case VcsEvents.VCS_RESULT_BAD_QUALITY_IMAGE: + str = CB_ACQUIRED + ":" + mIdentifyImage; + case VcsEvents.VCS_RESULT_USER_DOESNT_EXIST: + fp.setSecurityLevel(VcsEvents.VCS_SECURITY_LEVEL_HIGH); + mIdresult = null; + mIsIdentify = true; + fp.identify("User_" + mActiveGid); + if (str == null) { + str = CB_ACQUIRED + ":" + 1; // FINGERPRINT_ACQUIRED_PARTIAL + } + break; + case VcsEvents.VCS_RESULT_OPERATION_CANCELED: + break; + default: + str = CB_ERROR + ":" + 2; //FINGERPRINT_ERROR_UNABLE_TO_PROCESS + } + break; + default: + VLog.v("identify onEvent: No need to process event :" + event.eventId); + } + if (str != null) { + osr.write(str); + osr.flush(); + } + } catch (IOException e) { + VLog.e("in onEvent: " + e.getMessage()); + try { + osr.close(); + mSocketCB.close(); + } catch (IOException es) { + VLog.e("Cannot close socket: " + es.getMessage()); + } + return; + } + } + + /** Our Keyguard will not call identify when turn on screen, so we need call it. */ + public void onScreenOn() { + if (mIsNeedIdentify) { + mIsNeedIdentify = false; + fp.setSecurityLevel(VcsEvents.VCS_SECURITY_LEVEL_HIGH); + mIdresult = null; + mIsIdentify = true; + fp.identify("User_" + mActiveGid); + } + } + + public void onScreenOff() { + if (mIsIdentify) { + mIsNeedIdentify = true; + } + } + + public class ScreenReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { + onScreenOn(); + } + else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { + onScreenOff(); + } + else VLog.e("Unknown intent:" + intent.getAction()); + } + } + +} diff --git a/validityservice/src/com/validity/fingerprint/ValidityServiceStarter.java b/validityservice/src/com/validity/fingerprint/ValidityServiceStarter.java new file mode 100644 index 0000000..9552e7e --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/ValidityServiceStarter.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class ValidityServiceStarter extends Application { + + @Override + public void onCreate() { + super.onCreate(); + VLog.v("onCreate"); + Intent serviceintent = new Intent(this, ValidityService.class); + startService(serviceintent); + } + +} diff --git a/validityservice/src/com/validity/fingerprint/VcsAddInfo.java b/validityservice/src/com/validity/fingerprint/VcsAddInfo.java new file mode 100644 index 0000000..ae6522c --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/VcsAddInfo.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class VcsAddInfo { + public int algID; + public byte data[]; + + public VcsAddInfo() { + } + + public VcsAddInfo(int algorithmID) { + algID = algorithmID; + } +} diff --git a/validityservice/src/com/validity/fingerprint/VcsByteArray.java b/validityservice/src/com/validity/fingerprint/VcsByteArray.java new file mode 100644 index 0000000..d0225e5 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/VcsByteArray.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class VcsByteArray { + public byte data[]; +} diff --git a/validityservice/src/com/validity/fingerprint/VcsEvents.java b/validityservice/src/com/validity/fingerprint/VcsEvents.java new file mode 100644 index 0000000..44ace90 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/VcsEvents.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class VcsEvents { + + public static final int FINGER_INDEX_LEFT_THUMB = 1; + public static final int FINGER_INDEX_LEFT_INDEX = 2; + public static final int FINGER_INDEX_LEFT_MIDDLE = 3; + public static final int FINGER_INDEX_LEFT_RING = 4; + public static final int FINGER_INDEX_LEFT_LITTLE = 5; + public static final int FINGER_INDEX_RIGHT_THUMB = 6; + public static final int FINGER_INDEX_RIGHT_INDEX = 7; + public static final int FINGER_INDEX_RIGHT_MIDDLE = 8; + public static final int FINGER_INDEX_RIGHT_RING = 9; + public static final int FINGER_INDEX_RIGHT_LITTLE = 10; + public static final int FINGER_INDEX_LEFT_THUMB_SECOND = 11; + public static final int FINGER_INDEX_LEFT_INDEX_SECOND = 12; + public static final int FINGER_INDEX_LEFT_MIDDLE_SECOND = 13; + public static final int FINGER_INDEX_LEFT_RING_SECOND = 14; + public static final int FINGER_INDEX_LEFT_LITTLE_SECOND = 15; + public static final int FINGER_INDEX_RIGHT_THUMB_SECOND = 16; + public static final int FINGER_INDEX_RIGHT_INDEX_SECOND = 17; + public static final int FINGER_INDEX_RIGHT_MIDDLE_SECOND = 18; + public static final int FINGER_INDEX_RIGHT_RING_SECOND = 19; + public static final int FINGER_INDEX_RIGHT_LITTLE_SECOND = 20; + public static final int FINGER_INDEX_ALL = 21; + + public static final int VCS_EVT_SENSOR_REMOVED = 1; + public static final int VCS_EVT_SENSOR_DETECTED = 2; + public static final int VCS_EVT_SENSOR_READY_FOR_USE = 3; + public static final int VCS_EVT_SENSOR_FAILED_INITIALIZATION = 4; + public static final int VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_COMPLETE = 5; + public static final int VCS_EVT_SENSOR_RAW_FINGERPRINT_CAPTURE_COMPLETE = 6; + public static final int VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_FAILED = 7; + public static final int VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_START = 8; + public static final int VCS_EVT_ALL_SENSORS_INITIALIZED = 9; + public static final int VCS_EVT_SENSOR_FINGERPRINT_FAILED_SWIPE_RETRY = 10; + public static final int VCS_EVT_FINGER_DETECTED = 11; + public static final int VCS_EVT_ENROLL_COMPLETED = 13; + public static final int VCS_EVT_VERIFY_COMPLETED = 14; + public static final int VCS_EVT_IDENTIFY_COMPLETED = 15; + public static final int VCS_EVT_ENROLL_NEXT_CAPTURE_START = 16; + public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURED = 17; + public static final int VCS_EVT_FINGER_REMOVED = 20; + public static final int VCS_EVT_ENROLL_CAPTURE_STATUS = 32; + public static final int VCS_EVT_FINGER_SETTLED = 33; + public static final int VCS_EVT_SET_IR_FLAGS = 37; + public static final int VCS_EVT_SWIPE_DIRECTION = 41; + public static final int VCS_EVT_SWIPE_SPEED_UPDATE = 42; + public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURED_BAD = 45; + public static final int VCS_EVT_SENSOR_NON_RECOVERABLE = 46; + public static final int VCS_EVT_ENVIRONMENT_NOISE_DETECTED = 47; + public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURE_REDUNDANT = 49; + public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURE_EARLY = 50; + + public static final int VCS_EVT_ENROLL_SUCCESS = 421; + public static final int VCS_EVT_VERIFY_SUCCESS = 422; + public static final int VCS_EVT_IDENTIFY_SUCCESS = 423; + public static final int VCS_EVT_ENROLL_FAILED = 424; + public static final int VCS_EVT_VERIFY_FAILED = 425; + public static final int VCS_EVT_IDENTIFY_FAILED = 426; + public static final int VCS_EVT_GESTURE = 427; + public static final int VCS_EVT_SENSOR_INFO = 428; + + public static final int VCS_IMAGE_QUALITY_GOOD = 0; + public static final int VCS_IMAGE_QUALITY_STICTION = 1; + public static final int VCS_IMAGE_QUALITY_TOO_FAST = 2; + public static final int VCS_IMAGE_QUALITY_TOO_SHORT = 4; + public static final int VCS_IMAGE_QUALITY_REVERSE_MOTION = 8; + public static final int VCS_IMAGE_QUALITY_TOO_SLOW = 16; + public static final int VCS_IMAGE_QUALITY_SOMETHING_ON_THE_SENSOR = 512; + public static final int VCS_IMAGE_QUALITY_ONE_HAND_SWIPE = 1024; + public static final int VCS_IMAGE_QUALITY_FINGER_OFFSET = 4096; + public static final int VCS_IMAGE_QUALITY_BAD_SWIPE = 8192; + public static final int VCS_IMAGE_QUALITY_SKEW_TOO_LARGE = 32768; + public static final int VCS_IMAGE_QUALITY_PRESSURE_TOO_LIGHT = 0x10000; + public static final int VCS_IMAGE_QUALITY_FINGER_OFFSET_TOO_FAR_LEFT = 0x20000; + public static final int VCS_IMAGE_QUALITY_FINGER_OFFSET_TOO_FAR_RIGHT = 0x40000; + public static final int VCS_IMAGE_QUALITY_PRESSURE_TOO_HARD = 0x80000; + public static final int VCS_IMAGE_QUALITY_ASP_DATA_INVALID = 0x100000; + public static final int VCS_IMAGE_QUALITY_NOT_A_FINGER_SWIPE = 0x200000; + public static final int VCS_IMAGE_QUALITY_BASELINE_DATA_INVALID = 0x400000; + public static final int VCS_IMAGE_QUALITY_WET_FINGER = 0x1000000; + public static final int VCS_IMAGE_QUALITY_FINGER_TOO_THIN = 0x2000000; + public static final int VCS_IMAGE_QUALITY_PARTIAL_TOUCH = 0x8000000; + public static final int VCS_IMAGE_QUALITY_EMPTY_TOUCH = 0x10000000; + public static final int VCS_IMAGE_QUALITY_GESTURE = 0x20000000; + public static final int VCS_IMAGE_QUALITY_PROCESS_FAILED = 0x40000000; + public static final int VCS_IMAGE_QUALITY_PROCESS_FAILED_FATAL = 0x80000000; + + public static final int VCS_NOTIFY_AUTH_SESSION_BEGIN = 5; + public static final int VCS_NOTIFY_AUTH_SESSION_END = 6; + + public static final int VCS_POLICY_AUTHENTICATE_ALWAYS = 1; + public static final int VCS_POLICY_AUTHENTICATE_ON_SCREEN_UNLOCK_TIMEOUT = 2; + public static final int VCS_POLICY_AUTHENTICATE_ON_PREVIOUS_IDENTIFY_TIMEOUT = 3; + + public static final int VCS_PROTECT_ALG_SIMPLE_USER_DATA = 1; + public static final int VCS_PROTECT_ALG_SIMPLE_APP_DATA = 2; + + public static final int VCS_RESULT_FAILED = -1; + public static final int VCS_RESULT_OK = 0; + public static final int VCS_RESULT_CANCEL = 1; + public static final int VCS_RESULT_OUT_OF_MEMORY = 2; + public static final int VCS_RESULT_NO_MORE_ENTRIES = 3; + public static final int VCS_RESULT_BAD_PARAM = 17; + public static final int VCS_RESULT_SENSOR_NOT_FOUND = 19; + public static final int VCS_RESULT_SENSOR_OPEN_FAILED = 22; + public static final int VCS_RESULT_TIMEOUT = 34; + public static final int VCS_RESULT_NULL_POINTER = 40; + public static final int VCS_RESULT_SENSOR_BUSY = 46; + public static final int VCS_RESULT_ERROR = 54; + public static final int VCS_RESULT_TEMPLATE_FILE_CREATION_FAILED = 64; + public static final int VCS_RESULT_USER_DOESNT_EXIST = 65; + public static final int VCS_RESULT_TEMPLATE_DOESNT_EXIST = 66; + public static final int VCS_RESULT_INVALID_USER_HANDLE = 70; + public static final int VCS_RESULT_TEMPLATE_CORRUPTED = 87; + public static final int VCS_RESULT_USER_FINGER_ALREADY_ENROLLED = 88; + public static final int VCS_RESULT_USER_DATA_CORRUPTED = 91; + public static final int VCS_RESULT_MATCHER_OPEN_FAILED = 300; + public static final int VCS_RESULT_MATCHER_CLOSE_FAILED = 301; + public static final int VCS_RESULT_MATCHER_MATCH_FAILED = 302; + public static final int VCS_RESULT_MATCHER_EXTRACT_FAILED = 303; + public static final int VCS_RESULT_MATCHER_ENROLL_FAILED = 304; + public static final int VCS_RESULT_MATCHER_VERIFY_FAILED = 305; + public static final int VCS_RESULT_MATCHER_ADD_IMAGE_FAILED = 306; + public static final int VCS_RESULT_MATCHER_MATCH_IMAGE_FAILED = 307; + public static final int VCS_RESULT_MATCHER_CHECK_QUALITY_FAILED = 308; + public static final int VCS_RESULT_SERVICE_NOT_RUNNING = 321; + public static final int VCS_RESULT_SENSOR_NOT_READY_FOR_USE = 358; + public static final int VCS_RESULT_SENSOR_IS_REMOVED = 360; + public static final int VCS_RESULT_OPERATION_CANCELED = 361; + public static final int VCS_RESULT_USER_IDENTIFICATION_FAILED = 362; + public static final int VCS_RESULT_USER_VERIFICATION_FAILED = 363; + public static final int VCS_RESULT_MATCH_FAILED = 367; + public static final int VCS_RESULT_SERVICE_STOPPED = 500; + public static final int VCS_RESULT_GET_PRINT_STOPPED = 501; + public static final int VCS_RESULT_OPERATION_DENIED = 510; + public static final int VCS_RESULT_PIPE_ERROR = 511; + public static final int VCS_RESULT_SENSOR_KEYS_NOT_READY = 512; + public static final int VCS_RESULT_BAD_DEVICE = 513; + public static final int VCS_RESULT_TOO_MANY_BAD_SWIPES = 515; + public static final int VCS_RESULT_BAD_QUALITY_IMAGE = 601; + public static final int VCS_RESULT_KEYDATA_NOT_FOUND = 777; + public static final int VCS_RESULT_DATA_STORE_FAILED = 1001; + public static final int VCS_RESULT_DATA_RETRIEVE_FAILED = 1002; + public static final int VCS_RESULT_DATA_REMOVE_FAILED = 1003; + public static final int VCS_RESULT_ALREADY_INPROGRESS = 1004; + public static final int VCS_RESULT_NOT_IMPLEMENTED = 1005; + public static final int VCS_RESULT_INVALID_ARGUMENT = 1006; + + public static final int VCS_SECURITY_LEVEL_LOW = 0; + public static final int VCS_SECURITY_LEVEL_REGULAR = 1; + public static final int VCS_SECURITY_LEVEL_HIGH = 2; + public static final int VCS_SECURITY_LEVEL_VERY_HIGH = 3; + + public static final int VCS_SWIPE_DIRECTION_UP = 0; + public static final int VCS_SWIPE_DIRECTION_DOWN = 1; + public static final int VCS_SWIPE_DIRECTION_LEFT = 3; + public static final int VCS_SWIPE_DIRECTION_RIGHT = 4; + public static final int VCS_SWIPE_DIRECTION_REST = 5; +} diff --git a/validityservice/src/com/validity/fingerprint/VcsInt.java b/validityservice/src/com/validity/fingerprint/VcsInt.java new file mode 100644 index 0000000..bd4bb56 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/VcsInt.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class VcsInt { + public int num; +} diff --git a/validityservice/src/com/validity/fingerprint/VcsStringArray.java b/validityservice/src/com/validity/fingerprint/VcsStringArray.java new file mode 100644 index 0000000..e250496 --- /dev/null +++ b/validityservice/src/com/validity/fingerprint/VcsStringArray.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2016 The Mokee Project + * Copyright (C) 2016 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.validity.fingerprint; + +public class VcsStringArray { + public String strlist[]; +}