| /* | |
| * 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 |