Home | History | Annotate | Download | only in fingerprintd
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "fingerprintd"
     18 
     19 #include <binder/IServiceManager.h>
     20 #include <hardware/hardware.h>
     21 #include <hardware/fingerprint.h>
     22 #include <hardware/hw_auth_token.h>
     23 #include <keystore/IKeystoreService.h>
     24 #include <keystore/keystore.h> // for error codes
     25 #include <utils/Log.h>
     26 
     27 #include "FingerprintDaemonProxy.h"
     28 
     29 namespace android {
     30 
     31 FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = NULL;
     32 
     33 // Supported fingerprint HAL version
     34 static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0);
     35 
     36 FingerprintDaemonProxy::FingerprintDaemonProxy() : mModule(NULL), mDevice(NULL), mCallback(NULL) {
     37 
     38 }
     39 
     40 FingerprintDaemonProxy::~FingerprintDaemonProxy() {
     41     closeHal();
     42 }
     43 
     44 void FingerprintDaemonProxy::hal_notify_callback(const fingerprint_msg_t *msg) {
     45     FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance();
     46     const sp<IFingerprintDaemonCallback> callback = instance->mCallback;
     47     if (callback == NULL) {
     48         ALOGE("Invalid callback object");
     49         return;
     50     }
     51     const int64_t device = (int64_t) instance->mDevice;
     52     switch (msg->type) {
     53         case FINGERPRINT_ERROR:
     54             ALOGD("onError(%d)", msg->data.error);
     55             callback->onError(device, msg->data.error);
     56             break;
     57         case FINGERPRINT_ACQUIRED:
     58             ALOGD("onAcquired(%d)", msg->data.acquired.acquired_info);
     59             callback->onAcquired(device, msg->data.acquired.acquired_info);
     60             break;
     61         case FINGERPRINT_AUTHENTICATED:
     62             ALOGD("onAuthenticated(fid=%d, gid=%d)",
     63                     msg->data.authenticated.finger.fid,
     64                     msg->data.authenticated.finger.gid);
     65             if (msg->data.authenticated.finger.fid != 0) {
     66                 const uint8_t* hat = reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
     67                 instance->notifyKeystore(hat, sizeof(msg->data.authenticated.hat));
     68             }
     69             callback->onAuthenticated(device,
     70                     msg->data.authenticated.finger.fid,
     71                     msg->data.authenticated.finger.gid);
     72             break;
     73         case FINGERPRINT_TEMPLATE_ENROLLING:
     74             ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)",
     75                     msg->data.enroll.finger.fid,
     76                     msg->data.enroll.finger.gid,
     77                     msg->data.enroll.samples_remaining);
     78             callback->onEnrollResult(device,
     79                     msg->data.enroll.finger.fid,
     80                     msg->data.enroll.finger.gid,
     81                     msg->data.enroll.samples_remaining);
     82             break;
     83         case FINGERPRINT_TEMPLATE_REMOVED:
     84             ALOGD("onRemove(fid=%d, gid=%d)",
     85                     msg->data.removed.finger.fid,
     86                     msg->data.removed.finger.gid);
     87             callback->onRemoved(device,
     88                     msg->data.removed.finger.fid,
     89                     msg->data.removed.finger.gid);
     90             break;
     91         case FINGERPRINT_TEMPLATE_ENUMERATING:
     92             ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)",
     93                     msg->data.enumerated.finger.fid,
     94                     msg->data.enumerated.finger.gid,
     95                     msg->data.enumerated.remaining_templates);
     96             callback->onEnumerate(device,
     97                     msg->data.enumerated.finger.fid,
     98                     msg->data.enumerated.finger.gid,
     99                     msg->data.enumerated.remaining_templates);
    100             break;
    101         default:
    102             ALOGE("invalid msg type: %d", msg->type);
    103             return;
    104     }
    105 }
    106 
    107 void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) {
    108     if (auth_token != NULL && auth_token_length > 0) {
    109         // TODO: cache service?
    110         sp < IServiceManager > sm = defaultServiceManager();
    111         sp < IBinder > binder = sm->getService(String16("android.security.keystore"));
    112         sp < IKeystoreService > service = interface_cast < IKeystoreService > (binder);
    113         if (service != NULL) {
    114             status_t ret = service->addAuthToken(auth_token, auth_token_length);
    115             if (ret != ResponseCode::NO_ERROR) {
    116                 ALOGE("Falure sending auth token to KeyStore: %d", ret);
    117             }
    118         } else {
    119             ALOGE("Unable to communicate with KeyStore");
    120         }
    121     }
    122 }
    123 
    124 void FingerprintDaemonProxy::init(const sp<IFingerprintDaemonCallback>& callback) {
    125     if (mCallback != NULL && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) {
    126         IInterface::asBinder(mCallback)->unlinkToDeath(this);
    127     }
    128     IInterface::asBinder(callback)->linkToDeath(this);
    129     mCallback = callback;
    130 }
    131 
    132 int32_t FingerprintDaemonProxy::enroll(const uint8_t* token, ssize_t tokenSize, int32_t groupId,
    133         int32_t timeout) {
    134     ALOG(LOG_VERBOSE, LOG_TAG, "enroll(gid=%d, timeout=%d)\n", groupId, timeout);
    135     if (tokenSize != sizeof(hw_auth_token_t) ) {
    136         ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zu\n", tokenSize);
    137         return -1;
    138     }
    139     const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(token);
    140     return mDevice->enroll(mDevice, authToken, groupId, timeout);
    141 }
    142 
    143 uint64_t FingerprintDaemonProxy::preEnroll() {
    144     return mDevice->pre_enroll(mDevice);
    145 }
    146 
    147 int32_t FingerprintDaemonProxy::postEnroll() {
    148     return mDevice->post_enroll(mDevice);
    149 }
    150 
    151 int32_t FingerprintDaemonProxy::stopEnrollment() {
    152     ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n");
    153     return mDevice->cancel(mDevice);
    154 }
    155 
    156 int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) {
    157     ALOG(LOG_VERBOSE, LOG_TAG, "authenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId);
    158     return mDevice->authenticate(mDevice, sessionId, groupId);
    159 }
    160 
    161 int32_t FingerprintDaemonProxy::stopAuthentication() {
    162     ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n");
    163     return mDevice->cancel(mDevice);
    164 }
    165 
    166 int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) {
    167     ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId);
    168     return mDevice->remove(mDevice, groupId, fingerId);
    169 }
    170 
    171 int32_t FingerprintDaemonProxy::enumerate() {
    172     ALOG(LOG_VERBOSE, LOG_TAG, "enumerate()\n");
    173     return mDevice->enumerate(mDevice);
    174 }
    175 
    176 uint64_t FingerprintDaemonProxy::getAuthenticatorId() {
    177     return mDevice->get_authenticator_id(mDevice);
    178 }
    179 
    180 int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* path,
    181         ssize_t pathlen) {
    182     if (pathlen >= PATH_MAX || pathlen <= 0) {
    183         ALOGE("Bad path length: %zd", pathlen);
    184         return -1;
    185     }
    186     // Convert to null-terminated string
    187     char path_name[PATH_MAX];
    188     memcpy(path_name, path, pathlen);
    189     path_name[pathlen] = '\0';
    190     ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, path_name, pathlen);
    191     return mDevice->set_active_group(mDevice, groupId, path_name);
    192 }
    193 
    194 int64_t FingerprintDaemonProxy::openHal() {
    195     ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n");
    196     int err;
    197     const hw_module_t *hw_module = NULL;
    198     if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) {
    199         ALOGE("Can't open fingerprint HW Module, error: %d", err);
    200         return 0;
    201     }
    202     if (NULL == hw_module) {
    203         ALOGE("No valid fingerprint module");
    204         return 0;
    205     }
    206 
    207     mModule = reinterpret_cast<const fingerprint_module_t*>(hw_module);
    208 
    209     if (mModule->common.methods->open == NULL) {
    210         ALOGE("No valid open method");
    211         return 0;
    212     }
    213 
    214     hw_device_t *device = NULL;
    215 
    216     if (0 != (err = mModule->common.methods->open(hw_module, NULL, &device))) {
    217         ALOGE("Can't open fingerprint methods, error: %d", err);
    218         return 0;
    219     }
    220 
    221     if (kVersion != device->version) {
    222         ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
    223         // return 0; // FIXME
    224     }
    225 
    226     mDevice = reinterpret_cast<fingerprint_device_t*>(device);
    227     err = mDevice->set_notify(mDevice, hal_notify_callback);
    228     if (err < 0) {
    229         ALOGE("Failed in call to set_notify(), err=%d", err);
    230         return 0;
    231     }
    232 
    233     // Sanity check - remove
    234     if (mDevice->notify != hal_notify_callback) {
    235         ALOGE("NOTIFY not set properly: %p != %p", mDevice->notify, hal_notify_callback);
    236     }
    237 
    238     ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized");
    239     return reinterpret_cast<int64_t>(mDevice); // This is just a handle
    240 }
    241 
    242 int32_t FingerprintDaemonProxy::closeHal() {
    243     ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n");
    244     if (mDevice == NULL) {
    245         ALOGE("No valid device");
    246         return -ENOSYS;
    247     }
    248     int err;
    249     if (0 != (err = mDevice->common.close(reinterpret_cast<hw_device_t*>(mDevice)))) {
    250         ALOGE("Can't close fingerprint module, error: %d", err);
    251         return err;
    252     }
    253     mDevice = NULL;
    254     return 0;
    255 }
    256 
    257 void FingerprintDaemonProxy::binderDied(const wp<IBinder>& who) {
    258     ALOGD("binder died");
    259     int err;
    260     if (0 != (err = closeHal())) {
    261         ALOGE("Can't close fingerprint device, error: %d", err);
    262     }
    263     if (IInterface::asBinder(mCallback) == who) {
    264         mCallback = NULL;
    265     }
    266 }
    267 
    268 }
    269