1 /*
2 * Copyright (C) 2020 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 "Session.h"
18
19 #include <android-base/logging.h>
20
21 #include "CancellationSignal.h"
22
23 namespace aidl::android::hardware::biometrics::fingerprint {
24
Session(int sensorId,int userId,std::shared_ptr<ISessionCallback> cb,FakeFingerprintEngine * engine,WorkerThread * worker)25 Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
26 FakeFingerprintEngine* engine, WorkerThread* worker)
27 : mSensorId(sensorId),
28 mUserId(userId),
29 mCb(std::move(cb)),
30 mEngine(engine),
31 mWorker(worker),
32 mScheduledState(SessionState::IDLING),
33 mCurrentState(SessionState::IDLING) {
34 CHECK_GE(mSensorId, 0);
35 CHECK_GE(mUserId, 0);
36 CHECK(mEngine);
37 CHECK(mWorker);
38 CHECK(mCb);
39 }
40
scheduleStateOrCrash(SessionState state)41 void Session::scheduleStateOrCrash(SessionState state) {
42 // TODO(b/166800618): call enterIdling from the terminal callbacks and restore these checks.
43 // CHECK(mScheduledState == SessionState::IDLING);
44 // CHECK(mCurrentState == SessionState::IDLING);
45 mScheduledState = state;
46 }
47
enterStateOrCrash(SessionState state)48 void Session::enterStateOrCrash(SessionState state) {
49 CHECK(mScheduledState == state);
50 mCurrentState = state;
51 mScheduledState = SessionState::IDLING;
52 }
53
enterIdling()54 void Session::enterIdling() {
55 // TODO(b/166800618): call enterIdling from the terminal callbacks and rethink this conditional.
56 if (mCurrentState != SessionState::CLOSED) {
57 mCurrentState = SessionState::IDLING;
58 }
59 }
60
isClosed()61 bool Session::isClosed() {
62 return mCurrentState == SessionState::CLOSED;
63 }
64
generateChallenge()65 ndk::ScopedAStatus Session::generateChallenge() {
66 LOG(INFO) << "generateChallenge";
67 scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE);
68
69 mWorker->schedule(Callable::from([this] {
70 enterStateOrCrash(SessionState::GENERATING_CHALLENGE);
71 mEngine->generateChallengeImpl(mCb.get());
72 enterIdling();
73 }));
74
75 return ndk::ScopedAStatus::ok();
76 }
77
revokeChallenge(int64_t challenge)78 ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) {
79 LOG(INFO) << "revokeChallenge";
80 scheduleStateOrCrash(SessionState::REVOKING_CHALLENGE);
81
82 mWorker->schedule(Callable::from([this, challenge] {
83 enterStateOrCrash(SessionState::REVOKING_CHALLENGE);
84 mEngine->revokeChallengeImpl(mCb.get(), challenge);
85 enterIdling();
86 }));
87
88 return ndk::ScopedAStatus::ok();
89 }
90
enroll(const keymaster::HardwareAuthToken & hat,std::shared_ptr<common::ICancellationSignal> * out)91 ndk::ScopedAStatus Session::enroll(const keymaster::HardwareAuthToken& hat,
92 std::shared_ptr<common::ICancellationSignal>* out) {
93 LOG(INFO) << "enroll";
94 scheduleStateOrCrash(SessionState::ENROLLING);
95
96 std::promise<void> cancellationPromise;
97 auto cancFuture = cancellationPromise.get_future();
98
99 mWorker->schedule(Callable::from([this, hat, cancFuture = std::move(cancFuture)] {
100 enterStateOrCrash(SessionState::ENROLLING);
101 if (shouldCancel(cancFuture)) {
102 mCb->onError(Error::CANCELED, 0 /* vendorCode */);
103 } else {
104 mEngine->enrollImpl(mCb.get(), hat);
105 }
106 enterIdling();
107 }));
108
109 *out = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
110 return ndk::ScopedAStatus::ok();
111 }
112
authenticate(int64_t operationId,std::shared_ptr<common::ICancellationSignal> * out)113 ndk::ScopedAStatus Session::authenticate(int64_t operationId,
114 std::shared_ptr<common::ICancellationSignal>* out) {
115 LOG(INFO) << "authenticate";
116 scheduleStateOrCrash(SessionState::AUTHENTICATING);
117
118 std::promise<void> cancPromise;
119 auto cancFuture = cancPromise.get_future();
120
121 mWorker->schedule(Callable::from([this, operationId, cancFuture = std::move(cancFuture)] {
122 enterStateOrCrash(SessionState::AUTHENTICATING);
123 if (shouldCancel(cancFuture)) {
124 mCb->onError(Error::CANCELED, 0 /* vendorCode */);
125 } else {
126 mEngine->authenticateImpl(mCb.get(), operationId);
127 }
128 enterIdling();
129 }));
130
131 *out = SharedRefBase::make<CancellationSignal>(std::move(cancPromise));
132 return ndk::ScopedAStatus::ok();
133 }
134
detectInteraction(std::shared_ptr<common::ICancellationSignal> * out)135 ndk::ScopedAStatus Session::detectInteraction(std::shared_ptr<common::ICancellationSignal>* out) {
136 LOG(INFO) << "detectInteraction";
137 scheduleStateOrCrash(SessionState::DETECTING_INTERACTION);
138
139 std::promise<void> cancellationPromise;
140 auto cancFuture = cancellationPromise.get_future();
141
142 mWorker->schedule(Callable::from([this, cancFuture = std::move(cancFuture)] {
143 enterStateOrCrash(SessionState::DETECTING_INTERACTION);
144 if (shouldCancel(cancFuture)) {
145 mCb->onError(Error::CANCELED, 0 /* vendorCode */);
146 } else {
147 mEngine->detectInteractionImpl(mCb.get());
148 }
149 enterIdling();
150 }));
151
152 *out = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
153 return ndk::ScopedAStatus::ok();
154 }
155
enumerateEnrollments()156 ndk::ScopedAStatus Session::enumerateEnrollments() {
157 LOG(INFO) << "enumerateEnrollments";
158 scheduleStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS);
159
160 mWorker->schedule(Callable::from([this] {
161 enterStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS);
162 mEngine->enumerateEnrollmentsImpl(mCb.get());
163 enterIdling();
164 }));
165
166 return ndk::ScopedAStatus::ok();
167 }
168
removeEnrollments(const std::vector<int32_t> & enrollmentIds)169 ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
170 LOG(INFO) << "removeEnrollments";
171 scheduleStateOrCrash(SessionState::REMOVING_ENROLLMENTS);
172
173 mWorker->schedule(Callable::from([this, enrollmentIds] {
174 enterStateOrCrash(SessionState::REMOVING_ENROLLMENTS);
175 mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds);
176 enterIdling();
177 }));
178
179 return ndk::ScopedAStatus::ok();
180 }
181
getAuthenticatorId()182 ndk::ScopedAStatus Session::getAuthenticatorId() {
183 LOG(INFO) << "getAuthenticatorId";
184 scheduleStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID);
185
186 mWorker->schedule(Callable::from([this] {
187 enterStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID);
188 mEngine->getAuthenticatorIdImpl(mCb.get());
189 enterIdling();
190 }));
191
192 return ndk::ScopedAStatus::ok();
193 }
194
invalidateAuthenticatorId()195 ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
196 LOG(INFO) << "invalidateAuthenticatorId";
197 scheduleStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID);
198
199 mWorker->schedule(Callable::from([this] {
200 enterStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID);
201 mEngine->invalidateAuthenticatorIdImpl(mCb.get());
202 enterIdling();
203 }));
204
205 return ndk::ScopedAStatus::ok();
206 }
207
resetLockout(const keymaster::HardwareAuthToken & hat)208 ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat) {
209 LOG(INFO) << "resetLockout";
210 scheduleStateOrCrash(SessionState::RESETTING_LOCKOUT);
211
212 mWorker->schedule(Callable::from([this, hat] {
213 enterStateOrCrash(SessionState::RESETTING_LOCKOUT);
214 mEngine->resetLockoutImpl(mCb.get(), hat);
215 enterIdling();
216 }));
217
218 return ndk::ScopedAStatus::ok();
219 }
220
close()221 ndk::ScopedAStatus Session::close() {
222 LOG(INFO) << "close";
223 // TODO(b/166800618): call enterIdling from the terminal callbacks and restore this check.
224 // CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session.
225 // Crashing.";
226 mCurrentState = SessionState::CLOSED;
227 mCb->onSessionClosed();
228 return ndk::ScopedAStatus::ok();
229 }
230
onPointerDown(int32_t,int32_t,int32_t,float,float)231 ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/,
232 float /*minor*/, float /*major*/) {
233 LOG(INFO) << "onPointerDown";
234 return ndk::ScopedAStatus::ok();
235 }
236
onPointerUp(int32_t)237 ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) {
238 LOG(INFO) << "onPointerUp";
239 return ndk::ScopedAStatus::ok();
240 }
241
onUiReady()242 ndk::ScopedAStatus Session::onUiReady() {
243 LOG(INFO) << "onUiReady";
244 return ndk::ScopedAStatus::ok();
245 }
246
247 } // namespace aidl::android::hardware::biometrics::fingerprint
248