am 948dfb6e: emulator-fingerprint: Exit listener thread on HAL close

* commit '948dfb6e500f11106f68671d77f85bb633e678ce':
  emulator-fingerprint: Exit listener thread on HAL close
diff --git a/fingerprint/fingerprint.c b/fingerprint/fingerprint.c
index 30ef4b7..baa7ad6 100644
--- a/fingerprint/fingerprint.c
+++ b/fingerprint/fingerprint.c
@@ -14,6 +14,17 @@
  * limitations under the License.
  */
 
+/**
+ * This is a very basic implementation of fingerprint to allow testing on the emulator. It
+ * is *not* meant to be the final implementation on real devices.  For example,  it does *not*
+ * implement all of the required features, such as secure template storage and recognition
+ * inside a Trusted Execution Environment (TEE). However, this file is a reasonable starting
+ * point as developers add fingerprint support to their platform.  See inline comments and
+ * recommendations for details.
+ *
+ * Please see the Android Compatibility Definition Document (CDD) for a full list of requirements
+ * and suggestions.
+ */
 #define LOG_TAG "FingerprintHal"
 
 #include <errno.h>
@@ -33,9 +44,20 @@
     "/data/system/users/0/fpdata/emulator_fingerprint_storage.bin"
 #define MAX_COMM_CHARS 128
 #define MAX_COMM_ERRORS 8
+// Typical devices will allow up to 5 fingerprints per user to maintain performance of
+// t < 500ms for recognition.  This is the total number of fingerprints we'll store.
 #define MAX_NUM_FINGERS 20
 #define MAX_FID_VALUE 0x7FFFFFFF  // Arbitrary limit
 
+/**
+ * Most devices will have an internal state machine resembling this. There are 3 basic states, as
+ * shown below. When device is not authenticating or enrolling, it is expected to be in
+ * the idle state.
+ *
+ * Note that this is completely independent of device wake state.  If the hardware device was in
+ * the "scan" state when the device drops into power collapse, it should resume scanning when power
+ * is restored.  This is to facilitate rapid touch-to-unlock from keyguard.
+ */
 typedef enum worker_state_t {
     STATE_IDLE = 0,
     STATE_ENROLL,
@@ -135,12 +157,18 @@
 /******************************************************************************/
 
 static uint64_t get_64bit_rand() {
+    // This should use a cryptographically-secure random number generator like arc4random().
+    // It should be generated inside of the TEE where possible. Here we just use something
+    // very simple.
     ALOGD("----------------> %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) {
+    // This should return the authentication_id generated when the fingerprint template database
+    // was created.  Though this isn't expected to be secret, it is reasonable to expect it to be
+    // cryptographically generated to avoid replay attacks.
     qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
     ALOGD("----------------> %s ----------------->", __FUNCTION__);
     uint64_t authenticator_id = 0;
@@ -153,10 +181,20 @@
 
 static int fingerprint_set_active_group(struct fingerprint_device __unused *device, uint32_t gid,
         const char *path) {
+    // Groups are a future feature.  For now, the framework sends the profile owner's id (userid)
+    // as the primary group id for the user.  This code should create a tuple (groupId, fingerId)
+    // that represents a single fingerprint entity in the database.  For now we just generate
+    // globally unique ids.
     ALOGW("Setting active finger group not implemented");
     return 0;
 }
 
+/**
+ * If fingerprints are enrolled, then this function is expected to put the sensor into a
+ * "scanning" state where it's actively scanning and recognizing fingerprint features.
+ * Actual authentication must happen in TEE and should be monitored in a separate thread
+ * since this function is expected to return immediately.
+ */
 static int fingerprint_authenticate(struct fingerprint_device *device,
     uint64_t operation_id, __unused uint32_t gid)
 {
@@ -170,6 +208,15 @@
     return 0;
 }
 
+/**
+ * This is expected to put the sensor into an "enroll" state where it's actively scanning and
+ * working towards a finished fingerprint database entry. Authentication must happen in
+ * a separate thread since this function is expected to return immediately.
+ *
+ * Note: This method should always generate a new random authenticator_id.
+ *
+ * Note: As with fingerprint_authenticate(), this would run in TEE on a real device.
+ */
 static int fingerprint_enroll(struct fingerprint_device *device,
         const hw_auth_token_t *hat,
         uint32_t __unused gid,
@@ -181,6 +228,9 @@
         return -EPROTONOSUPPORT;
     }
     if (hat->challenge == dev->challenge) {
+        // The secure_user_id retrieved from the auth token should be stored
+        // with the enrolled fingerprint template and returned in the auth result
+        // for a successful authentication with that finger.
         dev->secure_user_id = hat->user_id;
     } else {
         ALOGW("%s: invalid auth token", __func__);
@@ -206,11 +256,20 @@
 
 }
 
+/**
+ * The pre-enrollment step is simply to get an authentication token that can be wrapped and
+ * verified at a later step.  The primary purpose is to return a token that protects against
+ * spoofing and replay attacks. It is passed to password authentication where it is wrapped and
+ * propagated to the enroll step.
+ */
 static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device) {
     ALOGD("----------------> %s ----------------->", __FUNCTION__);
     uint64_t challenge = 0;
     qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
 
+    // The challenge will typically be a cryptographically-secure key
+    // coming from the TEE so it can be verified at a later step. For now we just generate a
+    // random value.
     challenge = get_64bit_rand();
 
     pthread_mutex_lock(&qdev->lock);
@@ -231,6 +290,10 @@
     return 0;
 }
 
+/**
+ * Cancel is called by the framework to cancel an outstanding event.  This should *not* be called
+ * by the driver since it will cause the framework to stop listening for fingerprints.
+ */
 static int fingerprint_cancel(struct fingerprint_device *device) {
     ALOGD("----------------> %s ----------------->", __FUNCTION__);
     qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
@@ -458,6 +521,29 @@
     return state;
 }
 
+/**
+ * This a very simple event loop for the fingerprint sensor. For a given state (enroll, scan),
+ * this would receive events from the sensor and forward them to fingerprintd using the
+ * notify() method.
+ *
+ * In this simple example, we open a qemu channel (a pipe) where the developer can inject events to
+ * exercise the API and test application code.
+ *
+ * The scanner should remain in the scanning state until either an error occurs or the operation
+ * completes.
+ *
+ * Recoverable errors such as EINTR should be handled locally;  they should not
+ * be propagated unless there's something the user can do about it (e.g. "clean sensor"). Such
+ * messages should go through the onAcquired() interface.
+ *
+ * If an unrecoverable error occurs, an acquired message (e.g. ACQUIRED_PARTIAL) should be sent,
+ * followed by an error message (e.g. FINGERPRINT_ERROR_UNABLE_TO_PROCESS).
+ *
+ * Note that this event loop would typically run in TEE since it must interact with the sensor
+ * hardware and handle raw fingerprint data and encrypted templates.  It is expected that
+ * this code monitors the TEE for resulting events, such as enrollment and authentication status.
+ * Here we just have a very simple event loop that monitors a qemu channel for pseudo events.
+ */
 static void* listenerFunction(void* data) {
     ALOGD("----------------> %s ----------------->", __FUNCTION__);
     qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)data;