|  | /* | 
|  | * Copyright 2015, 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. | 
|  | */ | 
|  |  | 
|  | #include <inttypes.h> | 
|  |  | 
|  | #include <binder/IPCThreadState.h> | 
|  | #include <binder/IServiceManager.h> | 
|  | #include <binder/PermissionCache.h> | 
|  | #include <utils/String16.h> | 
|  | #include <utils/Looper.h> | 
|  | #include <keystore/IKeystoreService.h> | 
|  | #include <keystore/keystore.h> // for error code | 
|  | #include <hardware/hardware.h> | 
|  | #include <hardware/fingerprint.h> | 
|  | #include <hardware/hw_auth_token.h> | 
|  | #include "IFingerprintDaemon.h" | 
|  | #include "IFingerprintDaemonCallback.h" | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | static const String16 USE_FINGERPRINT_PERMISSION("android.permission.USE_FINGERPRINT"); | 
|  | static const String16 MANAGE_FINGERPRINT_PERMISSION("android.permission.MANAGE_FINGERPRINT"); | 
|  | static const String16 HAL_FINGERPRINT_PERMISSION("android.permission.MANAGE_FINGERPRINT"); // TODO | 
|  | static const String16 DUMP_PERMISSION("android.permission.DUMP"); | 
|  |  | 
|  | const android::String16 | 
|  | IFingerprintDaemon::descriptor("android.hardware.fingerprint.IFingerprintDaemon"); | 
|  |  | 
|  | const android::String16& | 
|  | IFingerprintDaemon::getInterfaceDescriptor() const { | 
|  | return IFingerprintDaemon::descriptor; | 
|  | } | 
|  |  | 
|  | status_t BnFingerprintDaemon::onTransact(uint32_t code, const Parcel& data, Parcel* reply, | 
|  | uint32_t flags) { | 
|  | switch(code) { | 
|  | case AUTHENTICATE: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const uint64_t sessionId = data.readInt64(); | 
|  | const uint32_t groupId = data.readInt32(); | 
|  | const int32_t ret = authenticate(sessionId, groupId); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | }; | 
|  | case CANCEL_AUTHENTICATION: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t ret = stopAuthentication(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case ENROLL: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const ssize_t tokenSize = data.readInt32(); | 
|  | const uint8_t* token = static_cast<const uint8_t *>(data.readInplace(tokenSize)); | 
|  | const int32_t groupId = data.readInt32(); | 
|  | const int32_t timeout = data.readInt32(); | 
|  | const int32_t ret = enroll(token, tokenSize, groupId, timeout); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case CANCEL_ENROLLMENT: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t ret = stopEnrollment(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case PRE_ENROLL: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const uint64_t ret = preEnroll(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt64(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case POST_ENROLL: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t ret = postEnroll(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case REMOVE: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t fingerId = data.readInt32(); | 
|  | const int32_t groupId = data.readInt32(); | 
|  | const int32_t ret = remove(fingerId, groupId); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case ENUMERATE: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t ret = enumerate(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case GET_AUTHENTICATOR_ID: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const uint64_t ret = getAuthenticatorId(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt64(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case SET_ACTIVE_GROUP: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t group = data.readInt32(); | 
|  | const ssize_t pathSize = data.readInt32(); | 
|  | const uint8_t* path = static_cast<const uint8_t *>(data.readInplace(pathSize)); | 
|  | const int32_t ret = setActiveGroup(group, path, pathSize); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case OPEN_HAL: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int64_t ret = openHal(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt64(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case CLOSE_HAL: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | const int32_t ret = closeHal(); | 
|  | reply->writeNoException(); | 
|  | reply->writeInt32(ret); | 
|  | return NO_ERROR; | 
|  | } | 
|  | case INIT: { | 
|  | CHECK_INTERFACE(IFingerprintDaemon, data, reply); | 
|  | if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) { | 
|  | return PERMISSION_DENIED; | 
|  | } | 
|  | sp<IFingerprintDaemonCallback> callback = | 
|  | interface_cast<IFingerprintDaemonCallback>(data.readStrongBinder()); | 
|  | init(callback); | 
|  | reply->writeNoException(); | 
|  | return NO_ERROR; | 
|  | } | 
|  | default: | 
|  | return BBinder::onTransact(code, data, reply, flags); | 
|  | } | 
|  | }; | 
|  |  | 
|  | bool BnFingerprintDaemon::checkPermission(const String16& permission) { | 
|  | const IPCThreadState* ipc = IPCThreadState::self(); | 
|  | const int calling_pid = ipc->getCallingPid(); | 
|  | const int calling_uid = ipc->getCallingUid(); | 
|  | return PermissionCache::checkPermission(permission, calling_pid, calling_uid); | 
|  | } | 
|  |  | 
|  |  | 
|  | }; // namespace android |