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 #undef LOG_TAG
18 #define LOG_TAG "FaceVirtualHalSession"
19
20 #include <android-base/logging.h>
21
22 #include "Session.h"
23
24 namespace aidl::android::hardware::biometrics::face {
25
26 constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;
27
onClientDeath(void * cookie)28 void onClientDeath(void* cookie) {
29 LOG(INFO) << "FaceService has died";
30 Session* session = static_cast<Session*>(cookie);
31 if (session && !session->isClosed()) {
32 session->close();
33 }
34 }
35
Session(std::unique_ptr<FakeFaceEngine> engine,std::shared_ptr<ISessionCallback> cb)36 Session::Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb)
37 : mEngine(std::move(engine)),
38 mCb(std::move(cb)),
39 mRandom(std::mt19937::default_seed),
40 mStateClosed(false) {
41 CHECK(mEngine);
42 CHECK(mCb);
43 mThread = std::make_unique<WorkerThread>(MAX_WORKER_QUEUE_SIZE);
44 mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
45 }
46
linkToDeath(AIBinder * binder)47 binder_status_t Session::linkToDeath(AIBinder* binder) {
48 return AIBinder_linkToDeath(binder, mDeathRecipient, this);
49 }
50
generateChallenge()51 ndk::ScopedAStatus Session::generateChallenge() {
52 LOG(INFO) << "generateChallenge";
53 mThread->schedule(Callable::from([this] { mEngine->generateChallengeImpl(mCb.get()); }));
54 return ndk::ScopedAStatus::ok();
55 }
56
revokeChallenge(int64_t challenge)57 ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) {
58 LOG(INFO) << "revokeChallenge";
59 mThread->schedule(Callable::from(
60 [this, challenge] { mEngine->revokeChallengeImpl(mCb.get(), challenge); }));
61 return ndk::ScopedAStatus::ok();
62 }
63
getEnrollmentConfig(EnrollmentType,std::vector<EnrollmentStageConfig> * cancellationSignal)64 ndk::ScopedAStatus Session::getEnrollmentConfig(
65 EnrollmentType /*enrollmentType*/, std::vector<EnrollmentStageConfig>* cancellationSignal) {
66 *cancellationSignal = {};
67 return ndk::ScopedAStatus::ok();
68 }
69
enroll(const keymaster::HardwareAuthToken & hat,EnrollmentType enrollmentType,const std::vector<Feature> & features,const std::optional<NativeHandle> &,std::shared_ptr<biometrics::common::ICancellationSignal> * cancellationSignal)70 ndk::ScopedAStatus Session::enroll(
71 const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType,
72 const std::vector<Feature>& features, const std::optional<NativeHandle>& /*previewSurface*/,
73 std::shared_ptr<biometrics::common::ICancellationSignal>* cancellationSignal) {
74 LOG(INFO) << "enroll";
75 std::promise<void> cancellationPromise;
76 auto cancFuture = cancellationPromise.get_future();
77
78 mThread->schedule(Callable::from(
79 [this, hat, enrollmentType, features, cancFuture = std::move(cancFuture)] {
80 mEngine->enrollImpl(mCb.get(), hat, enrollmentType, features, cancFuture);
81 }));
82
83 *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
84 return ndk::ScopedAStatus::ok();
85 }
86
authenticate(int64_t keystoreOperationId,std::shared_ptr<common::ICancellationSignal> * cancellationSignal)87 ndk::ScopedAStatus Session::authenticate(
88 int64_t keystoreOperationId,
89 std::shared_ptr<common::ICancellationSignal>* cancellationSignal) {
90 LOG(INFO) << "authenticate";
91 std::promise<void> cancellationPromise;
92 auto cancFuture = cancellationPromise.get_future();
93
94 mThread->schedule(
95 Callable::from([this, keystoreOperationId, cancFuture = std::move(cancFuture)] {
96 mEngine->authenticateImpl(mCb.get(), keystoreOperationId, cancFuture);
97 }));
98
99 *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
100 return ndk::ScopedAStatus::ok();
101 }
102
detectInteraction(std::shared_ptr<common::ICancellationSignal> * cancellationSignal)103 ndk::ScopedAStatus Session::detectInteraction(
104 std::shared_ptr<common::ICancellationSignal>* cancellationSignal) {
105 LOG(INFO) << "detectInteraction";
106 std::promise<void> cancellationPromise;
107 auto cancFuture = cancellationPromise.get_future();
108
109 mThread->schedule(Callable::from([this, cancFuture = std::move(cancFuture)] {
110 mEngine->detectInteractionImpl(mCb.get(), cancFuture);
111 }));
112
113 *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
114 return ndk::ScopedAStatus::ok();
115 }
116
enumerateEnrollments()117 ndk::ScopedAStatus Session::enumerateEnrollments() {
118 LOG(INFO) << "enumerateEnrollments";
119 mThread->schedule(Callable::from([this] { mEngine->enumerateEnrollmentsImpl(mCb.get()); }));
120 return ndk::ScopedAStatus::ok();
121 }
122
removeEnrollments(const std::vector<int32_t> & enrollmentIds)123 ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
124 LOG(INFO) << "removeEnrollments";
125 mThread->schedule(Callable::from(
126 [this, enrollmentIds] { mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds); }));
127 return ndk::ScopedAStatus::ok();
128 }
129
getFeatures()130 ndk::ScopedAStatus Session::getFeatures() {
131 LOG(INFO) << "getFeatures";
132 mThread->schedule(Callable::from([this] { mEngine->getFeaturesImpl(mCb.get()); }));
133 return ndk::ScopedAStatus::ok();
134 }
135
setFeature(const keymaster::HardwareAuthToken & hat,Feature feature,bool enabled)136 ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& hat, Feature feature,
137 bool enabled) {
138 LOG(INFO) << "setFeature";
139 mThread->schedule(Callable::from([this, hat, feature, enabled] {
140 mEngine->setFeatureImpl(mCb.get(), hat, feature, enabled);
141 }));
142 return ndk::ScopedAStatus::ok();
143 }
144
getAuthenticatorId()145 ndk::ScopedAStatus Session::getAuthenticatorId() {
146 LOG(INFO) << "getAuthenticatorId";
147 mThread->schedule(Callable::from([this] { mEngine->getAuthenticatorIdImpl(mCb.get()); }));
148 return ndk::ScopedAStatus::ok();
149 }
150
invalidateAuthenticatorId()151 ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
152 LOG(INFO) << "invalidateAuthenticatorId";
153 mThread->schedule(
154 Callable::from([this] { mEngine->invalidateAuthenticatorIdImpl(mCb.get()); }));
155 return ndk::ScopedAStatus::ok();
156 }
157
resetLockout(const keymaster::HardwareAuthToken & hat)158 ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat) {
159 LOG(INFO) << "resetLockout";
160 mThread->schedule(Callable::from([this, hat] { mEngine->resetLockoutImpl(mCb.get(), hat); }));
161 return ndk::ScopedAStatus::ok();
162 }
163
close()164 ndk::ScopedAStatus Session::close() {
165 LOG(INFO) << "close";
166 if (mCb) {
167 mCb->onSessionClosed();
168 }
169 AIBinder_DeathRecipient_delete(mDeathRecipient);
170 mStateClosed = true;
171 return ndk::ScopedAStatus::ok();
172 }
173
authenticateWithContext(int64_t operationId,const common::OperationContext &,std::shared_ptr<common::ICancellationSignal> * out)174 ndk::ScopedAStatus Session::authenticateWithContext(
175 int64_t operationId, const common::OperationContext& /*context*/,
176 std::shared_ptr<common::ICancellationSignal>* out) {
177 return authenticate(operationId, out);
178 }
179
enrollWithContext(const keymaster::HardwareAuthToken & hat,EnrollmentType enrollmentType,const std::vector<Feature> & features,const std::optional<NativeHandle> & previewSurface,const common::OperationContext &,std::shared_ptr<common::ICancellationSignal> * out)180 ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat,
181 EnrollmentType enrollmentType,
182 const std::vector<Feature>& features,
183 const std::optional<NativeHandle>& previewSurface,
184 const common::OperationContext& /*context*/,
185 std::shared_ptr<common::ICancellationSignal>* out) {
186 return enroll(hat, enrollmentType, features, previewSurface, out);
187 }
188
detectInteractionWithContext(const common::OperationContext &,std::shared_ptr<common::ICancellationSignal> * out)189 ndk::ScopedAStatus Session::detectInteractionWithContext(
190 const common::OperationContext& /*context*/,
191 std::shared_ptr<common::ICancellationSignal>* out) {
192 return detectInteraction(out);
193 }
194
onContextChanged(const common::OperationContext &)195 ndk::ScopedAStatus Session::onContextChanged(const common::OperationContext& /*context*/) {
196 return ndk::ScopedAStatus::ok();
197 }
198
enrollWithOptions(const FaceEnrollOptions & options,std::shared_ptr<common::ICancellationSignal> * out)199 ndk::ScopedAStatus Session::enrollWithOptions(const FaceEnrollOptions& options,
200 std::shared_ptr<common::ICancellationSignal>* out) {
201 return enroll(options.hardwareAuthToken, options.enrollmentType, options.features,
202 options.nativeHandlePreview, out);
203 }
204
205 } // namespace aidl::android::hardware::biometrics::face
206