diff --git a/fingerprint/Android.bp b/fingerprint/Android.bp index 382be4d..ed17973 100644 --- a/fingerprint/Android.bp +++ b/fingerprint/Android.bp @@ -1,7 +1,6 @@ -cc_binary { - name: "android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150", +cc_defaults { + name: "xiaomi_sm6150-fingerprint_defaults", defaults: ["hidl_defaults"], - init_rc: ["android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150.rc"], vintf_fragments: ["android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150.xml"], vendor: true, relative_install_path: "hw", @@ -11,6 +10,7 @@ cc_binary { ], shared_libs: [ + "libbase", "libcutils", "liblog", "libhidlbase", @@ -22,3 +22,16 @@ cc_binary { ], } + +cc_binary { + name: "android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150", + defaults: ["xiaomi_sm6150-fingerprint_defaults"], + init_rc: ["android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150.rc"], +} + +cc_binary { + name: "android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150-udfps", + defaults: ["xiaomi_sm6150-fingerprint_defaults"], + init_rc: ["android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150-udfps.rc"], + cflags: ["-DENABLE_UDFPS"], +} diff --git a/fingerprint/BiometricsFingerprint.cpp b/fingerprint/BiometricsFingerprint.cpp index a733e59..65e9850 100644 --- a/fingerprint/BiometricsFingerprint.cpp +++ b/fingerprint/BiometricsFingerprint.cpp @@ -21,6 +21,18 @@ #include "BiometricsFingerprint.h" +#define COMMAND_NIT 10 +#define PARAM_NIT_FOD 1 +#define PARAM_NIT_NONE 0 + +#define FOD_STATUS_ON 1 +#define FOD_STATUS_OFF -1 + +#define TOUCH_DEV_PATH "/dev/xiaomi-touch" +#define Touch_Fod_Enable 10 +#define TOUCH_MAGIC 0x5400 +#define TOUCH_IOC_SETMODE TOUCH_MAGIC + 0 + namespace android { namespace hardware { namespace biometrics { @@ -39,6 +51,10 @@ BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevi if (!mDevice) { ALOGE("Can't open HAL module"); } + +#ifdef ENABLE_UDFPS + touch_fd_ = android::base::unique_fd(open(TOUCH_DEV_PATH, O_RDWR)); +#endif } BiometricsFingerprint::~BiometricsFingerprint() { @@ -378,7 +394,11 @@ void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) { * under-display fingerprint sensor. */ Return BiometricsFingerprint::isUdfps(uint32_t /* sensorId */) { +#ifdef ENABLE_UDFPS + return true; +#else return false; +#endif } /** @@ -402,6 +422,13 @@ Return BiometricsFingerprint::isUdfps(uint32_t /* sensorId */) { */ Return BiometricsFingerprint::onFingerDown(uint32_t /* x */, uint32_t /* y */, float /* minor */, float /* major */) { +#ifdef ENABLE_UDFPS + int arg[2] = {Touch_Fod_Enable, FOD_STATUS_ON}; + ioctl(touch_fd_.get(), TOUCH_IOC_SETMODE, &arg); + + mDevice->extCmd(mDevice, COMMAND_NIT, PARAM_NIT_FOD); +#endif + return Void(); } /** @@ -414,6 +441,13 @@ Return BiometricsFingerprint::onFingerDown(uint32_t /* x */, uint32_t /* y * previously caused a "finger down" event will be reported. */ Return BiometricsFingerprint::onFingerUp() { +#ifdef ENABLE_UDFPS + int arg[2] = {Touch_Fod_Enable, FOD_STATUS_OFF}; + ioctl(touch_fd_.get(), TOUCH_IOC_SETMODE, &arg); + + mDevice->extCmd(mDevice, COMMAND_NIT, PARAM_NIT_NONE); +#endif + return Void(); } diff --git a/fingerprint/BiometricsFingerprint.h b/fingerprint/BiometricsFingerprint.h index 01307ab..203b4a2 100644 --- a/fingerprint/BiometricsFingerprint.h +++ b/fingerprint/BiometricsFingerprint.h @@ -18,7 +18,13 @@ #ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H #define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H + +#ifdef ENABLE_UDFPS +#include +#include "hardware/fingerprint.h" +#else #include +#endif #include @@ -78,6 +84,10 @@ struct BiometricsFingerprint : public IBiometricsFingerprint { std::mutex mClientCallbackMutex; sp mClientCallback; fingerprint_device_t* mDevice; + +#ifdef ENABLE_UDFPS + android::base::unique_fd touch_fd_; +#endif }; } // namespace implementation diff --git a/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150-udfps.rc b/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150-udfps.rc new file mode 100644 index 0000000..993b9b3 --- /dev/null +++ b/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150-udfps.rc @@ -0,0 +1,7 @@ +service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.3-service.xiaomi_sm6150-udfps + # "class hal" causes a race condition on some devices due to files created + # in /data. As a workaround, postpone startup until later in boot once + # /data is mounted. + class late_start + user system + group system input uhid diff --git a/fingerprint/hardware/fingerprint.h b/fingerprint/hardware/fingerprint.h new file mode 100644 index 0000000..b6e455d --- /dev/null +++ b/fingerprint/hardware/fingerprint.h @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2014 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. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H +#define ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H + +#include +#include + +#define FINGERPRINT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define FINGERPRINT_MODULE_API_VERSION_2_0 HARDWARE_MODULE_API_VERSION(2, 0) +#define FINGERPRINT_MODULE_API_VERSION_2_1 HARDWARE_MODULE_API_VERSION(2, 1) +#define FINGERPRINT_MODULE_API_VERSION_3_0 HARDWARE_MODULE_API_VERSION(3, 0) +#define FINGERPRINT_HARDWARE_MODULE_ID "fingerprint" + +typedef enum fingerprint_msg_type { + FINGERPRINT_ERROR = -1, + FINGERPRINT_ACQUIRED = 1, + FINGERPRINT_TEMPLATE_ENROLLING = 3, + FINGERPRINT_TEMPLATE_REMOVED = 4, + FINGERPRINT_AUTHENTICATED = 5, + FINGERPRINT_TEMPLATE_ENUMERATING = 6, +} fingerprint_msg_type_t; + +/* + * Fingerprint errors are meant to tell the framework to terminate the current operation and ask + * for the user to correct the situation. These will almost always result in messaging and user + * interaction to correct the problem. + * + * For example, FINGERPRINT_ERROR_CANCELED should follow any acquisition message that results in + * a situation where the current operation can't continue without user interaction. For example, + * if the sensor is dirty during enrollment and no further enrollment progress can be made, + * send FINGERPRINT_ACQUIRED_IMAGER_DIRTY followed by FINGERPRINT_ERROR_CANCELED. + */ +typedef enum fingerprint_error { + FINGERPRINT_ERROR_HW_UNAVAILABLE = 1, /* The hardware has an error that can't be resolved. */ + FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2, /* Bad data; operation can't continue */ + FINGERPRINT_ERROR_TIMEOUT = 3, /* The operation has timed out waiting for user input. */ + FINGERPRINT_ERROR_NO_SPACE = 4, /* No space available to store a template */ + FINGERPRINT_ERROR_CANCELED = 5, /* The current operation can't proceed. See above. */ + FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6, /* fingerprint with given id can't be removed */ + FINGERPRINT_ERROR_LOCKOUT = + 7, /* the fingerprint hardware is in lockout due to too many attempts */ + FINGERPRINT_ERROR_VENDOR_BASE = 1000 /* vendor-specific error messages start here */ +} fingerprint_error_t; + +/* + * Fingerprint acquisition info is meant as feedback for the current operation. Anything but + * FINGERPRINT_ACQUIRED_GOOD will be shown to the user as feedback on how to take action on the + * current operation. For example, FINGERPRINT_ACQUIRED_IMAGER_DIRTY can be used to tell the user + * to clean the sensor. If this will cause the current operation to fail, an additional + * FINGERPRINT_ERROR_CANCELED can be sent to stop the operation in progress (e.g. enrollment). + * In general, these messages will result in a "Try again" message. + */ +typedef enum fingerprint_acquired_info { + FINGERPRINT_ACQUIRED_GOOD = 0, + FINGERPRINT_ACQUIRED_PARTIAL = 1, /* sensor needs more data, i.e. longer swipe. */ + FINGERPRINT_ACQUIRED_INSUFFICIENT = 2, /* image doesn't contain enough detail for recognition*/ + FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3, /* sensor needs to be cleaned */ + FINGERPRINT_ACQUIRED_TOO_SLOW = 4, /* mostly swipe-type sensors; not enough data collected */ + FINGERPRINT_ACQUIRED_TOO_FAST = 5, /* for swipe and area sensors; tell user to slow down*/ + FINGERPRINT_ACQUIRED_DETECTED = 6, /* when the finger is first detected. Used to optimize + wakeup. Should be followed by one of the above messages */ + FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000 /* vendor-specific acquisition messages start here */ +} fingerprint_acquired_info_t; + +typedef struct fingerprint_finger_id { + uint32_t gid; + uint32_t fid; +} fingerprint_finger_id_t; + +typedef struct fingerprint_enroll { + fingerprint_finger_id_t finger; + /* samples_remaining goes from N (no data collected, but N scans needed) + * to 0 (no more data is needed to build a template). */ + uint32_t samples_remaining; + uint64_t msg; /* Vendor specific message. Used for user guidance */ +} fingerprint_enroll_t; + +typedef struct fingerprint_iterator { + fingerprint_finger_id_t finger; + uint32_t remaining_templates; +} fingerprint_iterator_t; + +typedef fingerprint_iterator_t fingerprint_enumerated_t; +typedef fingerprint_iterator_t fingerprint_removed_t; + +typedef struct fingerprint_acquired { + fingerprint_acquired_info_t acquired_info; /* information about the image */ +} fingerprint_acquired_t; + +typedef struct fingerprint_authenticated { + fingerprint_finger_id_t finger; + hw_auth_token_t hat; +} fingerprint_authenticated_t; + +typedef struct fingerprint_msg { + fingerprint_msg_type_t type; + union { + fingerprint_error_t error; + fingerprint_enroll_t enroll; + fingerprint_enumerated_t enumerated; + fingerprint_removed_t removed; + fingerprint_acquired_t acquired; + fingerprint_authenticated_t authenticated; + } data; +} fingerprint_msg_t; + +/* Callback function type */ +typedef void (*fingerprint_notify_t)(const fingerprint_msg_t* msg); + +/* Synchronous operation */ +typedef struct fingerprint_device { + /** + * Common methods of the fingerprint device. This *must* be the first member + * of fingerprint_device as users of this structure will cast a hw_device_t + * to fingerprint_device pointer in contexts where it's known + * the hw_device_t references a fingerprint_device. + */ + struct hw_device_t common; + + /* + * Client provided callback function to receive notifications. + * Do not set by hand, use the function above instead. + */ + fingerprint_notify_t notify; + + /* + * Set notification callback: + * Registers a user function that would receive notifications from the HAL + * The call will block if the HAL state machine is in busy state until HAL + * leaves the busy state. + * + * Function return: 0 if callback function is successfuly registered + * or a negative number in case of error, generally from the errno.h set. + */ + int (*set_notify)(struct fingerprint_device* dev, fingerprint_notify_t notify); + + /* + * Fingerprint pre-enroll enroll request: + * Generates a unique token to upper layers to indicate the start of an enrollment transaction. + * This token will be wrapped by security for verification and passed to enroll() for + * verification before enrollment will be allowed. This is to ensure adding a new fingerprint + * template was preceded by some kind of credential confirmation (e.g. device password). + * + * Function return: 0 if function failed + * otherwise, a uint64_t of token + */ + uint64_t (*pre_enroll)(struct fingerprint_device* dev); + + /* + * Fingerprint enroll request: + * Switches the HAL state machine to collect and store a new fingerprint + * template. Switches back as soon as enroll is complete + * (fingerprint_msg.type == FINGERPRINT_TEMPLATE_ENROLLING && + * fingerprint_msg.data.enroll.samples_remaining == 0) + * or after timeout_sec seconds. + * The fingerprint template will be assigned to the group gid. User has a choice + * to supply the gid or set it to 0 in which case a unique group id will be generated. + * + * Function return: 0 if enrollment process can be successfully started + * or a negative number in case of error, generally from the errno.h set. + * A notify() function may be called indicating the error condition. + */ + int (*enroll)(struct fingerprint_device* dev, const hw_auth_token_t* hat, uint32_t gid, + uint32_t timeout_sec); + + /* + * Finishes the enroll operation and invalidates the pre_enroll() generated challenge. + * This will be called at the end of a multi-finger enrollment session to indicate + * that no more fingers will be added. + * + * Function return: 0 if the request is accepted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*post_enroll)(struct fingerprint_device* dev); + + /* + * get_authenticator_id: + * Returns a token associated with the current fingerprint set. This value will + * change whenever a new fingerprint is enrolled, thus creating a new fingerprint + * set. + * + * Function return: current authenticator id or 0 if function failed. + */ + uint64_t (*get_authenticator_id)(struct fingerprint_device* dev); + + /* + * Cancel pending enroll or authenticate, sending FINGERPRINT_ERROR_CANCELED + * to all running clients. Switches the HAL state machine back to the idle state. + * Unlike enroll_done() doesn't invalidate the pre_enroll() challenge. + * + * Function return: 0 if cancel request is accepted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*cancel)(struct fingerprint_device* dev); + + /* + * Enumerate all the fingerprint templates found in the directory set by + * set_active_group() + * For each template found a notify() will be called with: + * fingerprint_msg.type == FINGERPRINT_TEMPLATE_ENUMERATED + * fingerprint_msg.data.enumerated.finger indicating a template id + * fingerprint_msg.data.enumerated.remaining_templates indicating how many more + * enumeration messages to expect. + * Note: If there are no fingerprints, then this should return 0 and the first fingerprint + * enumerated should have fingerid=0 and remaining=0 + * Function return: 0 if enumerate request is accepted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*enumerate)(struct fingerprint_device* dev); + + /* + * Fingerprint remove request: + * Deletes a fingerprint template. + * Works only within the path set by set_active_group(). + * The fid parameter can be used as a widcard: + * * fid == 0 -- delete all the templates in the group. + * * fid != 0 -- delete this specific template from the group. + * For each template found a notify() will be called with: + * fingerprint_msg.type == FINGERPRINT_TEMPLATE_REMOVED + * fingerprint_msg.data.removed.finger indicating a template id deleted + * fingerprint_msg.data.removed.remaining_templates indicating how many more + * templates will be deleted by this operation. + * + * Function return: 0 if fingerprint template(s) can be successfully deleted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*remove)(struct fingerprint_device* dev, uint32_t gid, uint32_t fid); + + /* + * Restricts the HAL operation to a set of fingerprints belonging to a + * group provided. + * The caller must provide a path to a storage location within the user's + * data directory. + * + * Function return: 0 on success + * or a negative number in case of error, generally from the errno.h set. + */ + int (*set_active_group)(struct fingerprint_device* dev, uint32_t gid, const char* store_path); + + /* + * Authenticates an operation identifed by operation_id + * + * Function return: 0 on success + * or a negative number in case of error, generally from the errno.h set. + */ + int (*authenticate)(struct fingerprint_device* dev, uint64_t operation_id, uint32_t gid); + + /** + * Call a Xiaomi fingerprint extension command. + */ + int (*extCmd)(struct fingerprint_device* dev, int32_t cmd, int32_t param); + + /* Reserved for backward binary compatibility */ + void* reserved[4]; +} fingerprint_device_t; + +typedef struct fingerprint_module { + /** + * Common methods of the fingerprint module. This *must* be the first member + * of fingerprint_module as users of this structure will cast a hw_module_t + * to fingerprint_module pointer in contexts where it's known + * the hw_module_t references a fingerprint_module. + */ + struct hw_module_t common; +} fingerprint_module_t; + +#endif /* ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H */ diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts index 48547a5..d60a82a 100644 --- a/sepolicy/vendor/file_contexts +++ b/sepolicy/vendor/file_contexts @@ -23,6 +23,7 @@ # HALs /(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.3-service\.xiaomi_sm6150 u:object_r:hal_fingerprint_default_exec:s0 +/(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.3-service\.xiaomi_sm6150-udfps u:object_r:hal_fingerprint_default_exec:s0 /vendor/bin/hw/android\.hardware\.light@2\.0-service\.xiaomi_sm6150 u:object_r:hal_light_default_exec:s0 /vendor/bin/hw/android\.hardware\.power-service\.xiaomi-libperfmgr u:object_r:hal_power_default_exec:s0 /vendor/bin/hw/vendor\.lineage\.livedisplay@2\.1-service\.xiaomi_sm6150 u:object_r:hal_lineage_livedisplay_qti_exec:s0 diff --git a/sepolicy/vendor/hal_fingerprint_default.te b/sepolicy/vendor/hal_fingerprint_default.te index c7e8bf7..3784937 100644 --- a/sepolicy/vendor/hal_fingerprint_default.te +++ b/sepolicy/vendor/hal_fingerprint_default.te @@ -7,10 +7,12 @@ allow hal_fingerprint_default fingerprint_device:chr_file rw_file_perms; allow hal_fingerprint_default fingerprint_data_file:dir create_dir_perms; allow hal_fingerprint_default fingerprint_data_file:file create_file_perms; allow hal_fingerprint_default input_device:chr_file rw_file_perms; -allow hal_fingerprint_default vendor_qdsp_device:chr_file r_file_perms; allow hal_fingerprint_default self:netlink_socket create_socket_perms_no_ioctl; allow hal_fingerprint_default tee_device:chr_file rw_file_perms; +allow hal_fingerprint_default touchfeature_device:chr_file rw_file_perms; allow hal_fingerprint_default uhid_device:chr_file rw_file_perms; +allow hal_fingerprint_default vendor_qdsp_device:chr_file r_file_perms; +allow hal_fingerprint_default vendor_sysfs_graphics:file rw_file_perms; allow hal_fingerprint_default vendor_xdsp_device:chr_file r_file_perms; r_dir_file(hal_fingerprint_default, firmware_file) diff --git a/sm6150.mk b/sm6150.mk index 0bc188d..5f97571 100644 --- a/sm6150.mk +++ b/sm6150.mk @@ -140,9 +140,6 @@ PRODUCT_PACKAGES += \ android.hardware.drm@1.4-service.clearkey # Fingerprint -PRODUCT_PACKAGES += \ - android.hardware.biometrics.fingerprint@2.1-service.xiaomi_sm6150 - PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.fingerprint.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.fingerprint.xml