1/*
2 * Copyright 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#include <inttypes.h>
18
19#include <binder/IPCThreadState.h>
20#include <binder/IServiceManager.h>
21#include <binder/PermissionCache.h>
22#include <utils/String16.h>
23#include <utils/Looper.h>
24#include <keystore/IKeystoreService.h>
25#include <keystore/keystore.h> // for error code
26#include <hardware/hardware.h>
27#include <hardware/fingerprint.h>
28#include <hardware/hw_auth_token.h>
29#include "IFingerprintDaemon.h"
30#include "IFingerprintDaemonCallback.h"
31
32namespace android {
33
34static const String16 USE_FINGERPRINT_PERMISSION("android.permission.USE_FINGERPRINT");
35static const String16 MANAGE_FINGERPRINT_PERMISSION("android.permission.MANAGE_FINGERPRINT");
36static const String16 HAL_FINGERPRINT_PERMISSION("android.permission.MANAGE_FINGERPRINT"); // TODO
37static const String16 DUMP_PERMISSION("android.permission.DUMP");
38
39const android::String16
40IFingerprintDaemon::descriptor("android.hardware.fingerprint.IFingerprintDaemon");
41
42const android::String16&
43IFingerprintDaemon::getInterfaceDescriptor() const {
44    return IFingerprintDaemon::descriptor;
45}
46
47status_t BnFingerprintDaemon::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
48        uint32_t flags) {
49    switch(code) {
50        case AUTHENTICATE: {
51            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
52            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
53                return PERMISSION_DENIED;
54            }
55            const uint64_t sessionId = data.readInt64();
56            const uint32_t groupId = data.readInt32();
57            const int32_t ret = authenticate(sessionId, groupId);
58            reply->writeNoException();
59            reply->writeInt32(ret);
60            return NO_ERROR;
61        };
62        case CANCEL_AUTHENTICATION: {
63            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
64            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
65                return PERMISSION_DENIED;
66            }
67            const int32_t ret = stopAuthentication();
68            reply->writeNoException();
69            reply->writeInt32(ret);
70            return NO_ERROR;
71        }
72        case ENROLL: {
73            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
74            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
75                return PERMISSION_DENIED;
76            }
77            const ssize_t tokenSize = data.readInt32();
78            const uint8_t* token = static_cast<const uint8_t *>(data.readInplace(tokenSize));
79            const int32_t groupId = data.readInt32();
80            const int32_t timeout = data.readInt32();
81            const int32_t ret = enroll(token, tokenSize, groupId, timeout);
82            reply->writeNoException();
83            reply->writeInt32(ret);
84            return NO_ERROR;
85        }
86        case CANCEL_ENROLLMENT: {
87            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
88            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
89                return PERMISSION_DENIED;
90            }
91            const int32_t ret = stopEnrollment();
92            reply->writeNoException();
93            reply->writeInt32(ret);
94            return NO_ERROR;
95        }
96        case PRE_ENROLL: {
97            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
98            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
99                return PERMISSION_DENIED;
100            }
101            const uint64_t ret = preEnroll();
102            reply->writeNoException();
103            reply->writeInt64(ret);
104            return NO_ERROR;
105        }
106        case POST_ENROLL: {
107            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
108            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
109                return PERMISSION_DENIED;
110            }
111            const int32_t ret = postEnroll();
112            reply->writeNoException();
113            reply->writeInt32(ret);
114            return NO_ERROR;
115        }
116        case REMOVE: {
117            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
118            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
119                return PERMISSION_DENIED;
120            }
121            const int32_t fingerId = data.readInt32();
122            const int32_t groupId = data.readInt32();
123            const int32_t ret = remove(fingerId, groupId);
124            reply->writeNoException();
125            reply->writeInt32(ret);
126            return NO_ERROR;
127        }
128        case GET_AUTHENTICATOR_ID: {
129            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
130            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
131                return PERMISSION_DENIED;
132            }
133            const uint64_t ret = getAuthenticatorId();
134            reply->writeNoException();
135            reply->writeInt64(ret);
136            return NO_ERROR;
137        }
138        case SET_ACTIVE_GROUP: {
139            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
140            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
141                return PERMISSION_DENIED;
142            }
143            const int32_t group = data.readInt32();
144            const ssize_t pathSize = data.readInt32();
145            const uint8_t* path = static_cast<const uint8_t *>(data.readInplace(pathSize));
146            const int32_t ret = setActiveGroup(group, path, pathSize);
147            reply->writeNoException();
148            reply->writeInt32(ret);
149            return NO_ERROR;
150        }
151        case OPEN_HAL: {
152            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
153            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
154                return PERMISSION_DENIED;
155            }
156            const int64_t ret = openHal();
157            reply->writeNoException();
158            reply->writeInt64(ret);
159            return NO_ERROR;
160        }
161        case CLOSE_HAL: {
162            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
163            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
164                return PERMISSION_DENIED;
165            }
166            const int32_t ret = closeHal();
167            reply->writeNoException();
168            reply->writeInt32(ret);
169            return NO_ERROR;
170        }
171        case INIT: {
172            CHECK_INTERFACE(IFingerprintDaemon, data, reply);
173            if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
174                return PERMISSION_DENIED;
175            }
176            sp<IFingerprintDaemonCallback> callback =
177                    interface_cast<IFingerprintDaemonCallback>(data.readStrongBinder());
178            init(callback);
179            reply->writeNoException();
180            return NO_ERROR;
181        }
182        default:
183            return BBinder::onTransact(code, data, reply, flags);
184    }
185};
186
187bool BnFingerprintDaemon::checkPermission(const String16& permission) {
188    const IPCThreadState* ipc = IPCThreadState::self();
189    const int calling_pid = ipc->getCallingPid();
190    const int calling_uid = ipc->getCallingUid();
191    return PermissionCache::checkPermission(permission, calling_pid, calling_uid);
192}
193
194
195}; // namespace android
196