blob: 52ac23bd5982f07e331a736fbf5e3ac8914f4118 [file] [log] [blame]
Jeff Pua3c57362024-06-10 15:03:50 +00001/*
2 * Copyright (C) 2024 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 <unordered_map>
18
19#include "VirtualHal.h"
20
21#include <android-base/logging.h>
22
23#include "util/CancellationSignal.h"
24
25#undef LOG_TAG
26#define LOG_TAG "FaceVirtualHalAidl"
27
28namespace aidl::android::hardware::biometrics::face {
29using AcquiredInfoAndVendorCode = virtualhal::AcquiredInfoAndVendorCode;
30using Tag = AcquiredInfoAndVendorCode::Tag;
31
32::ndk::ScopedAStatus VirtualHal::setEnrollments(const std::vector<int32_t>& enrollments) {
33 Face::cfg().sourcedFromAidl();
34 Face::cfg().setopt<OptIntVec>("enrollments", intVec2OptIntVec(enrollments));
35 return ndk::ScopedAStatus::ok();
36}
37
38::ndk::ScopedAStatus VirtualHal::setEnrollmentHit(int32_t enrollment_hit) {
39 Face::cfg().sourcedFromAidl();
40 Face::cfg().set<std::int32_t>("enrollment_hit", enrollment_hit);
41 return ndk::ScopedAStatus::ok();
42}
43
44::ndk::ScopedAStatus VirtualHal::setNextEnrollment(
45 const ::aidl::android::hardware::biometrics::face::NextEnrollment& next_enrollment) {
46 Face::cfg().sourcedFromAidl();
47 std::ostringstream os;
48 os << next_enrollment.id << ":";
49
50 int stepSize = next_enrollment.progressSteps.size();
51 for (int i = 0; i < stepSize; i++) {
52 auto& step = next_enrollment.progressSteps[i];
53 os << step.durationMs;
54 int acSize = step.acquiredInfoAndVendorCodes.size();
55 for (int j = 0; j < acSize; j++) {
56 if (j == 0) os << "-[";
57 auto& acquiredInfoAndVendorCode = step.acquiredInfoAndVendorCodes[j];
58 if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::vendorCode)
59 os << acquiredInfoAndVendorCode.get<Tag::vendorCode>();
60 else if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
61 os << (int)acquiredInfoAndVendorCode.get<Tag::acquiredInfo>();
62 else
63 LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode union tag";
64 if (j == acSize - 1)
65 os << "]";
66 else
67 os << ",";
68 }
69 if (i == stepSize - 1)
70 os << ":";
71 else
72 os << ",";
73 }
74
75 os << (next_enrollment.result ? "true" : "false");
76 Face::cfg().set<std::string>("next_enrollment", os.str());
77 return ndk::ScopedAStatus::ok();
78}
79
80::ndk::ScopedAStatus VirtualHal::setAuthenticatorId(int64_t in_id) {
81 Face::cfg().sourcedFromAidl();
82 Face::cfg().set<int64_t>("authenticator_id", in_id);
83 return ndk::ScopedAStatus::ok();
84}
85
86::ndk::ScopedAStatus VirtualHal::setChallenge(int64_t in_challenge) {
87 Face::cfg().sourcedFromAidl();
88 Face::cfg().set<int64_t>("challenge", in_challenge);
89 return ndk::ScopedAStatus::ok();
90}
91
92::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateFails(bool in_fail) {
93 Face::cfg().sourcedFromAidl();
94 Face::cfg().set<bool>("operation_authenticate_fails", in_fail);
95 return ndk::ScopedAStatus::ok();
96}
97
98::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateLatency(
99 const std::vector<int32_t>& in_latency) {
100 ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
101 if (!status.isOk()) {
102 return status;
103 }
104
105 Face::cfg().sourcedFromAidl();
106 Face::cfg().setopt<OptIntVec>("operation_authenticate_latency", intVec2OptIntVec(in_latency));
107 return ndk::ScopedAStatus::ok();
108}
109
110::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateDuration(int32_t in_duration) {
111 if (in_duration < 0) {
112 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
113 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
114 }
115 Face::cfg().sourcedFromAidl();
116 Face::cfg().set<int32_t>("operation_authenticate_duration", in_duration);
117 return ndk::ScopedAStatus::ok();
118}
119
120::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateError(int32_t in_error) {
121 Face::cfg().sourcedFromAidl();
122 Face::cfg().set<int32_t>("operation_authenticate_error", in_error);
123 return ndk::ScopedAStatus::ok();
124}
125
126::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateAcquired(
127 const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
128 Face::cfg().sourcedFromAidl();
129 Face::cfg().setopt<OptIntVec>("operation_authenticate_acquired",
130 acquiredInfoVec2OptIntVec(in_acquired));
131 return ndk::ScopedAStatus::ok();
132}
133
134::ndk::ScopedAStatus VirtualHal::setOperationEnrollLatency(const std::vector<int32_t>& in_latency) {
135 ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
136 if (!status.isOk()) {
137 return status;
138 }
139 Face::cfg().sourcedFromAidl();
140 Face::cfg().setopt<OptIntVec>("operation_enroll_latency", intVec2OptIntVec(in_latency));
141 return ndk::ScopedAStatus::ok();
142}
143
144::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionLatency(
145 const std::vector<int32_t>& in_latency) {
146 ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
147 if (!status.isOk()) {
148 return status;
149 }
150 Face::cfg().sourcedFromAidl();
151 Face::cfg().setopt<OptIntVec>("operation_detect_interact_latency",
152 intVec2OptIntVec(in_latency));
153 return ndk::ScopedAStatus::ok();
154}
155
156::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionFails(bool in_fails) {
157 Face::cfg().sourcedFromAidl();
158 Face::cfg().set<bool>("operation_detect_interaction_fails", in_fails);
159 return ndk::ScopedAStatus::ok();
160}
161
162::ndk::ScopedAStatus VirtualHal::setLockout(bool in_lockout) {
163 Face::cfg().sourcedFromAidl();
164 Face::cfg().set<bool>("lockout", in_lockout);
165 return ndk::ScopedAStatus::ok();
166}
167
168::ndk::ScopedAStatus VirtualHal::setLockoutEnable(bool in_enable) {
169 Face::cfg().sourcedFromAidl();
170 Face::cfg().set<bool>("lockout_enable", in_enable);
171 return ndk::ScopedAStatus::ok();
172}
173
174::ndk::ScopedAStatus VirtualHal::setLockoutTimedEnable(bool in_enable) {
175 Face::cfg().sourcedFromAidl();
176 Face::cfg().set<bool>("lockout_timed_enable", in_enable);
177 return ndk::ScopedAStatus::ok();
178}
179
180::ndk::ScopedAStatus VirtualHal::setLockoutTimedThreshold(int32_t in_threshold) {
181 if (in_threshold < 0) {
182 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
183 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
184 }
185 Face::cfg().sourcedFromAidl();
186 Face::cfg().set<int32_t>("lockout_timed_threshold", in_threshold);
187 return ndk::ScopedAStatus::ok();
188}
189
190::ndk::ScopedAStatus VirtualHal::setLockoutTimedDuration(int32_t in_duration) {
191 if (in_duration < 0) {
192 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
193 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
194 }
195 Face::cfg().sourcedFromAidl();
196 Face::cfg().set<int32_t>("lockout_timed_duration", in_duration);
197 return ndk::ScopedAStatus::ok();
198}
199
200::ndk::ScopedAStatus VirtualHal::setLockoutPermanentThreshold(int32_t in_threshold) {
201 if (in_threshold < 0) {
202 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
203 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
204 }
205 Face::cfg().sourcedFromAidl();
206 Face::cfg().set<int32_t>("lockout_permanent_threshold", in_threshold);
207 return ndk::ScopedAStatus::ok();
208}
209
210::ndk::ScopedAStatus VirtualHal::resetConfigurations() {
211 Face::cfg().sourcedFromAidl();
212 Face::cfg().init();
213 return ndk::ScopedAStatus::ok();
214}
215
216::ndk::ScopedAStatus VirtualHal::setType(
217 ::aidl::android::hardware::biometrics::face::FaceSensorType in_type) {
218 Face::cfg().sourcedFromAidl();
219 Face::cfg().set<std::string>("type", Face::type2String(in_type));
220 return ndk::ScopedAStatus::ok();
221}
222
223::ndk::ScopedAStatus VirtualHal::setSensorStrength(common::SensorStrength in_strength) {
224 Face::cfg().sourcedFromAidl();
225 Face::cfg().set<std::string>("strength", Face::strength2String(in_strength));
226 return ndk::ScopedAStatus::ok();
227}
228
229OptIntVec VirtualHal::intVec2OptIntVec(const std::vector<int32_t>& in_vec) {
230 OptIntVec optIntVec;
231 std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
232 [](int value) { return std::optional<int>(value); });
233 return optIntVec;
234}
235
236OptIntVec VirtualHal::acquiredInfoVec2OptIntVec(
237 const std::vector<AcquiredInfoAndVendorCode>& in_vec) {
238 OptIntVec optIntVec;
239 std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
240 [](AcquiredInfoAndVendorCode ac) {
241 int value;
242 if (ac.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
243 value = (int)ac.get<Tag::acquiredInfo>();
244 else if (ac.getTag() == AcquiredInfoAndVendorCode::vendorCode)
245 value = ac.get<Tag::vendorCode>();
246 else
247 LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode tag";
248 return std::optional<int>(value);
249 });
250 return optIntVec;
251}
252
253::ndk::ScopedAStatus VirtualHal::sanityCheckLatency(const std::vector<int32_t>& in_latency) {
254 if (in_latency.size() == 0 || in_latency.size() > 2) {
255 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
256 IVirtualHal::STATUS_INVALID_PARAMETER,
257 "Error: input input array must contain 1 or 2 elements"));
258 }
259
260 for (auto x : in_latency) {
261 if (x < 0) {
262 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
263 IVirtualHal::STATUS_INVALID_PARAMETER,
264 "Error: input data must not be negative"));
265 }
266 }
267
268 return ndk::ScopedAStatus::ok();
269}
270
271::ndk::ScopedAStatus VirtualHal::getFaceHal(std::shared_ptr<IFace>* pFace) {
272 *pFace = mFp;
273 return ndk::ScopedAStatus::ok();
274}
275} // namespace aidl::android::hardware::biometrics::face