Merge "Hardware: Fingerprint: Move the HAL to an async model, add some vendor requested functionality."
diff --git a/include/hardware/fingerprint.h b/include/hardware/fingerprint.h
index be2f9e2..acd96e2 100644
--- a/include/hardware/fingerprint.h
+++ b/include/hardware/fingerprint.h
@@ -20,63 +20,98 @@
 #define FINGERPRINT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
 #define FINGERPRINT_HARDWARE_MODULE_ID "fingerprint"
 
-typedef enum fingerprint_msg {
+typedef enum fingerprint_msg_type {
     FINGERPRINT_ERROR = -1,
-    FINGERPRINT_NO_MATCH = 0,
-    FINGERPRINT_MATCH = 1,
+    FINGERPRINT_SCANNED = 1,
     FINGERPRINT_TEMPLATE_COLLECTING = 2,
-    FINGERPRINT_TEMPLATE_REGISTERED = 3,
     FINGERPRINT_TEMPLATE_DELETED = 4
-} fingerprint_msg_t;
+} fingerprint_msg_type_t;
 
 typedef enum fingerprint_error {
     FINGERPRINT_ERROR_HW_UNAVAILABLE = 1,
-    FINGERPRINT_ERROR_BAD_CAPTURE = 2
+    FINGERPRINT_ERROR_BAD_CAPTURE = 2,
+    FINGERPRINT_ERROR_TIMEOUT = 3
 } fingerprint_error_t;
 
+typedef struct fingerprint_enroll {
+    uint32_t id;
+    /* samples_remaining goes form N (no data collected, but N scans needed)
+     * to 0 (no more data is needed to build a template)
+     * If HAL fails to decrement samples_remaining between calls the client
+     * will declare template collection a failure and should abort the operation
+     * by calling fingerprint_close() */
+    uint32_t samples_remaining;
+} fingerprint_enroll_t;
+
+typedef struct fingerprint_scanned {
+    uint32_t id; /* 0 is a special id and means no match */
+    uint32_t confidence; /* Goes form 0 (no match) to 0xffffFFFF (100% sure) */
+} fingerprint_ident_t;
+
+typedef struct fingerprint_msg {
+    fingerprint_msg_type_t type;
+    union {
+        uint64_t raw;
+        fingerprint_error_t error;
+        fingerprint_enroll_t enroll;
+        fingerprint_ident_t ident;
+    } data;
+} fingerprint_msg_t;
+
+/* Callback function type */
+typedef void (*fingerprint_notify_t)(fingerprint_msg_t msg);
+
 /* Synchronous operation */
 typedef struct fingerprint_device {
     struct hw_device_t common;
 
     /*
-     * Figerprint enroll request: records and stores a fingerprint template.
-     * Timeout after temeout_sec seconds.
+     * Figerprint 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_COLLECTING &&
+     *  fingerprint_msg.data.enroll.samples_remaining == 0)
+     * or after temeout_sec seconds.
      *
-     * Function return:
-     *   - Machine state: error, collected or registered.
-     *   - Data is interpreted as error code, collection percentage
-     *     or fingerprint id.
+     * Function return: 0 if enrollment process can be successfully started
+     *                 -1 otherwise.
      */
-    fingerprint_msg_t (*enroll)(unsigned timeout_sec, unsigned *data);
+    int (*enroll)(struct fingerprint_device *dev, unsigned timeout_sec);
 
     /*
-     * Figerprint remove request: deletes a fingerprint template.
+     * Figerprint remove request:
+     * deletes a fingerprint template.
+     * If the fingerprint id is 0 the entire template database will be removed.
      *
-     * Function return:
-     *   - Delete result: error or success.
+     * Function return: 0 if fingerprint template can be successfully deleted
+     *                 -1 otherwise.
      */
-    fingerprint_msg_t (*remove)(unsigned fingerprint_id);
+    int (*remove)(struct fingerprint_device *dev, uint32_t fingerprint_id);
 
     /*
-     * Figerprint match request: Collect a fingerprint and
-     * match against stored template with fingerprint_id.
-     * Timeout after temeout_sec seconds.
+     * 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:
-     *   - Match, no match or error.
+     * Function return: 0 if callback function is successfuly registered
+     *                 -1 otherwise.
      */
-    fingerprint_msg_t (*match)(unsigned fingerprint_id, unsigned timeout_sec);
+    int (*set_notify)(struct fingerprint_device *dev,
+                        fingerprint_notify_t notify);
+
+    /*
+     * Client provided callback function to receive notifications.
+     * Do not set by hand, use the function above instead.
+     */
+    fingerprint_notify_t notify;
 
     /* Reserved for future use. Must be NULL. */
-    void* reserved[8 - 3];
+    void* reserved[8 - 4];
 } fingerprint_device_t;
 
 typedef struct fingerprint_module {
     struct hw_module_t common;
 } fingerprint_module_t;
 
-/* For asyncronous mode - as a possible API model
-typedef void (*fingerprint_callback)(int request_id, fingerprint_msg msg, data);
-*/
-
 #endif  /* ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H */
diff --git a/modules/fingerprint/fingerprint.c b/modules/fingerprint/fingerprint.c
index a7691ed..c2ff169 100644
--- a/modules/fingerprint/fingerprint.c
+++ b/modules/fingerprint/fingerprint.c
@@ -31,30 +31,26 @@
     }
 }
 
-static fingerprint_msg_t fingerprint_enroll(unsigned timeout_sec,
-                                            unsigned *data) {
-    (void)timeout_sec;
-    (void)data;
+static int fingerprint_enroll(struct fingerprint_device __unused *dev,
+                                unsigned __unused timeout_sec) {
     return FINGERPRINT_ERROR;
 }
 
-static fingerprint_msg_t fingerprint_remove(unsigned fingerprint_id) {
-    (void)fingerprint_id;
+static int fingerprint_remove(struct fingerprint_device __unused *dev,
+                                uint16_t __unused fingerprint_id) {
     return FINGERPRINT_ERROR;
 }
 
-static fingerprint_msg_t fingerprint_match(unsigned fingerprint_id,
-                                            unsigned timeout_sec) {
-    (void)fingerprint_id;
-    (void)timeout_sec;
+static int set_notify_callback(struct fingerprint_device *dev,
+                                fingerprint_notify_t notify) {
+    /* Decorate with locks */
+    dev->notify = notify;
     return FINGERPRINT_ERROR;
 }
 
-static int fingerprint_open(const hw_module_t* module, const char* id,
+static int fingerprint_open(const hw_module_t* module, const char __unused *id,
                             hw_device_t** device)
 {
-    (void)id;
-
     if (device == NULL) {
         ALOGE("NULL device on open");
         return -EINVAL;
@@ -70,7 +66,8 @@
 
     dev->enroll = fingerprint_enroll;
     dev->remove = fingerprint_remove;
-    dev->match = fingerprint_match;
+    dev->set_notify = set_notify_callback;
+    dev->notify = NULL;
 
     *device = (hw_device_t*) dev;
     return 0;
diff --git a/tests/fingerprint/fingerprint_tests.cpp b/tests/fingerprint/fingerprint_tests.cpp
index ad6e1dd..4463751 100644
--- a/tests/fingerprint/fingerprint_tests.cpp
+++ b/tests/fingerprint/fingerprint_tests.cpp
@@ -21,17 +21,17 @@
 
 TEST_F(FingerprintDevice, isThereEnroll) {
     ASSERT_TRUE(NULL != fp_device()->enroll)
-        << "Enroll function is not implemented";
+        << "enroll() function is not implemented";
 }
 
 TEST_F(FingerprintDevice, isThereRemove) {
     ASSERT_TRUE(NULL != fp_device()->remove)
-        << "Remove function is not implemented";
+        << "remove() function is not implemented";
 }
 
-TEST_F(FingerprintDevice, isThereMatch) {
-    ASSERT_TRUE(NULL != fp_device()->match)
-        << "Match function is not implemented";
+TEST_F(FingerprintDevice, isThereSetNotify) {
+    ASSERT_TRUE(NULL != fp_device()->set_notify)
+        << "set_notify() function is not implemented";
 }
 
 }  // namespace tests