xref: /aosp_15_r20/hardware/interfaces/biometrics/fingerprint/aidl/default/VirtualHal.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
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 "FingerprintVirtualHalAidl"
27 
28 namespace aidl::android::hardware::biometrics::fingerprint {
29 using AcquiredInfoAndVendorCode = virtualhal::AcquiredInfoAndVendorCode;
30 using Tag = AcquiredInfoAndVendorCode::Tag;
31 
setEnrollments(const std::vector<int32_t> & enrollments)32 ::ndk::ScopedAStatus VirtualHal::setEnrollments(const std::vector<int32_t>& enrollments) {
33     Fingerprint::cfg().sourcedFromAidl();
34     Fingerprint::cfg().setopt<OptIntVec>("enrollments", intVec2OptIntVec(enrollments));
35     return ndk::ScopedAStatus::ok();
36 }
37 
setEnrollmentHit(int32_t enrollment_hit)38 ::ndk::ScopedAStatus VirtualHal::setEnrollmentHit(int32_t enrollment_hit) {
39     Fingerprint::cfg().sourcedFromAidl();
40     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", enrollment_hit);
41     return ndk::ScopedAStatus::ok();
42 }
43 
setNextEnrollment(const NextEnrollment & next_enrollment)44 ::ndk::ScopedAStatus VirtualHal::setNextEnrollment(const NextEnrollment& next_enrollment) {
45     Fingerprint::cfg().sourcedFromAidl();
46     std::ostringstream os;
47     os << next_enrollment.id << ":";
48 
49     int stepSize = next_enrollment.progressSteps.size();
50     for (int i = 0; i < stepSize; i++) {
51         auto& step = next_enrollment.progressSteps[i];
52         os << step.durationMs;
53         int acSize = step.acquiredInfoAndVendorCodes.size();
54         for (int j = 0; j < acSize; j++) {
55             if (j == 0) os << "-[";
56             auto& acquiredInfoAndVendorCode = step.acquiredInfoAndVendorCodes[j];
57             if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::vendorCode)
58                 os << acquiredInfoAndVendorCode.get<Tag::vendorCode>();
59             else if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
60                 os << (int)acquiredInfoAndVendorCode.get<Tag::acquiredInfo>();
61             else
62                 LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode union tag";
63             if (j == acSize - 1)
64                 os << "]";
65             else
66                 os << ",";
67         }
68         if (i == stepSize - 1)
69             os << ":";
70         else
71             os << ",";
72     }
73 
74     os << (next_enrollment.result ? "true" : "false");
75     Fingerprint::cfg().set<std::string>("next_enrollment", os.str());
76     return ndk::ScopedAStatus::ok();
77 }
78 
setAuthenticatorId(int64_t in_id)79 ::ndk::ScopedAStatus VirtualHal::setAuthenticatorId(int64_t in_id) {
80     Fingerprint::cfg().sourcedFromAidl();
81     Fingerprint::cfg().set<int64_t>("authenticator_id", in_id);
82     return ndk::ScopedAStatus::ok();
83 }
84 
setChallenge(int64_t in_challenge)85 ::ndk::ScopedAStatus VirtualHal::setChallenge(int64_t in_challenge) {
86     Fingerprint::cfg().sourcedFromAidl();
87     Fingerprint::cfg().set<int64_t>("challenge", in_challenge);
88     return ndk::ScopedAStatus::ok();
89 }
90 
setOperationAuthenticateFails(bool in_fail)91 ::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateFails(bool in_fail) {
92     Fingerprint::cfg().sourcedFromAidl();
93     Fingerprint::cfg().set<bool>("operation_authenticate_fails", in_fail);
94     return ndk::ScopedAStatus::ok();
95 }
96 
setOperationAuthenticateLatency(const std::vector<int32_t> & in_latency)97 ::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateLatency(
98         const std::vector<int32_t>& in_latency) {
99     ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
100     if (!status.isOk()) {
101         return status;
102     }
103 
104     Fingerprint::cfg().sourcedFromAidl();
105     Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_latency",
106                                          intVec2OptIntVec(in_latency));
107     return ndk::ScopedAStatus::ok();
108 }
109 
setOperationAuthenticateDuration(int32_t in_duration)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     Fingerprint::cfg().sourcedFromAidl();
116     Fingerprint::cfg().set<int32_t>("operation_authenticate_duration", in_duration);
117     return ndk::ScopedAStatus::ok();
118 }
119 
setOperationAuthenticateError(int32_t in_error)120 ::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateError(int32_t in_error) {
121     Fingerprint::cfg().sourcedFromAidl();
122     Fingerprint::cfg().set<int32_t>("operation_authenticate_error", in_error);
123     return ndk::ScopedAStatus::ok();
124 }
125 
setOperationAuthenticateAcquired(const std::vector<AcquiredInfoAndVendorCode> & in_acquired)126 ::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateAcquired(
127         const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
128     Fingerprint::cfg().sourcedFromAidl();
129     Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_acquired",
130                                          acquiredInfoVec2OptIntVec(in_acquired));
131     return ndk::ScopedAStatus::ok();
132 }
133 
setOperationEnrollError(int32_t in_error)134 ::ndk::ScopedAStatus VirtualHal::setOperationEnrollError(int32_t in_error) {
135     Fingerprint::cfg().sourcedFromAidl();
136     Fingerprint::cfg().set<int32_t>("operation_enroll_error", in_error);
137     return ndk::ScopedAStatus::ok();
138 }
139 
setOperationEnrollLatency(const std::vector<int32_t> & in_latency)140 ::ndk::ScopedAStatus VirtualHal::setOperationEnrollLatency(const std::vector<int32_t>& in_latency) {
141     ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
142     if (!status.isOk()) {
143         return status;
144     }
145     Fingerprint::cfg().sourcedFromAidl();
146     Fingerprint::cfg().setopt<OptIntVec>("operation_enroll_latency", intVec2OptIntVec(in_latency));
147     return ndk::ScopedAStatus::ok();
148 }
149 
setOperationDetectInteractionLatency(const std::vector<int32_t> & in_latency)150 ::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionLatency(
151         const std::vector<int32_t>& in_latency) {
152     ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
153     if (!status.isOk()) {
154         return status;
155     }
156     Fingerprint::cfg().sourcedFromAidl();
157     Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interact_latency",
158                                          intVec2OptIntVec(in_latency));
159     return ndk::ScopedAStatus::ok();
160 }
161 
setOperationDetectInteractionError(int32_t in_error)162 ::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionError(int32_t in_error) {
163     Fingerprint::cfg().sourcedFromAidl();
164     Fingerprint::cfg().set<int32_t>("operation_detect_interaction_error", in_error);
165     return ndk::ScopedAStatus::ok();
166 }
167 
setOperationDetectInteractionDuration(int32_t in_duration)168 ::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionDuration(int32_t in_duration) {
169     if (in_duration < 0) {
170         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
171                 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
172     }
173     Fingerprint::cfg().sourcedFromAidl();
174     Fingerprint::cfg().set<int32_t>("operation_detect_interaction_duration", in_duration);
175     return ndk::ScopedAStatus::ok();
176 }
177 
setOperationDetectInteractionAcquired(const std::vector<AcquiredInfoAndVendorCode> & in_acquired)178 ::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionAcquired(
179         const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
180     Fingerprint::cfg().sourcedFromAidl();
181     Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_acquired",
182                                          acquiredInfoVec2OptIntVec(in_acquired));
183     return ndk::ScopedAStatus::ok();
184 }
185 
setLockout(bool in_lockout)186 ::ndk::ScopedAStatus VirtualHal::setLockout(bool in_lockout) {
187     Fingerprint::cfg().sourcedFromAidl();
188     Fingerprint::cfg().set<bool>("lockout", in_lockout);
189     return ndk::ScopedAStatus::ok();
190 }
191 
setLockoutEnable(bool in_enable)192 ::ndk::ScopedAStatus VirtualHal::setLockoutEnable(bool in_enable) {
193     Fingerprint::cfg().sourcedFromAidl();
194     Fingerprint::cfg().set<bool>("lockout_enable", in_enable);
195     return ndk::ScopedAStatus::ok();
196 }
197 
setLockoutTimedThreshold(int32_t in_threshold)198 ::ndk::ScopedAStatus VirtualHal::setLockoutTimedThreshold(int32_t in_threshold) {
199     if (in_threshold < 0) {
200         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
201                 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
202     }
203     Fingerprint::cfg().sourcedFromAidl();
204     Fingerprint::cfg().set<int32_t>("lockout_timed_threshold", in_threshold);
205     return ndk::ScopedAStatus::ok();
206 }
207 
setLockoutTimedDuration(int32_t in_duration)208 ::ndk::ScopedAStatus VirtualHal::setLockoutTimedDuration(int32_t in_duration) {
209     if (in_duration < 0) {
210         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
211                 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
212     }
213     Fingerprint::cfg().sourcedFromAidl();
214     Fingerprint::cfg().set<int32_t>("lockout_timed_duration", in_duration);
215     return ndk::ScopedAStatus::ok();
216 }
217 
setLockoutPermanentThreshold(int32_t in_threshold)218 ::ndk::ScopedAStatus VirtualHal::setLockoutPermanentThreshold(int32_t in_threshold) {
219     if (in_threshold < 0) {
220         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
221                 IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
222     }
223     Fingerprint::cfg().sourcedFromAidl();
224     Fingerprint::cfg().set<int32_t>("lockout_permanent_threshold", in_threshold);
225     return ndk::ScopedAStatus::ok();
226 }
227 
resetConfigurations()228 ::ndk::ScopedAStatus VirtualHal::resetConfigurations() {
229     Fingerprint::cfg().sourcedFromAidl();
230     Fingerprint::cfg().init();
231     return ndk::ScopedAStatus::ok();
232 }
233 
setType(::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type)234 ::ndk::ScopedAStatus VirtualHal::setType(
235         ::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type) {
236     Fingerprint::cfg().sourcedFromAidl();
237     Fingerprint::cfg().set<std::string>("type", Fingerprint::type2String(in_type));
238     return ndk::ScopedAStatus::ok();
239 }
240 
setSensorId(int32_t in_id)241 ::ndk::ScopedAStatus VirtualHal::setSensorId(int32_t in_id) {
242     Fingerprint::cfg().sourcedFromAidl();
243     Fingerprint::cfg().set<int32_t>("sensor_id", in_id);
244     return ndk::ScopedAStatus::ok();
245 }
246 
setSensorStrength(SensorStrength in_strength)247 ::ndk::ScopedAStatus VirtualHal::setSensorStrength(SensorStrength in_strength) {
248     Fingerprint::cfg().sourcedFromAidl();
249     Fingerprint::cfg().set<int32_t>("sensor_strength", (int32_t)in_strength);
250     return ndk::ScopedAStatus::ok();
251 }
252 
setMaxEnrollmentPerUser(int32_t in_max)253 ::ndk::ScopedAStatus VirtualHal::setMaxEnrollmentPerUser(int32_t in_max) {
254     Fingerprint::cfg().sourcedFromAidl();
255     Fingerprint::cfg().set<int32_t>("max_enrollments", in_max);
256     return ndk::ScopedAStatus::ok();
257 }
258 
setSensorLocation(const SensorLocation & in_loc)259 ::ndk::ScopedAStatus VirtualHal::setSensorLocation(const SensorLocation& in_loc) {
260     std::string str = std::to_string(in_loc.sensorLocationX) + ":" +
261                       std::to_string(in_loc.sensorLocationY) + ":" +
262                       std::to_string(in_loc.sensorRadius);
263     ;
264     Fingerprint::cfg().sourcedFromAidl();
265     Fingerprint::cfg().set<std::string>("sensor_location", str);
266     return ndk::ScopedAStatus::ok();
267 }
268 
setNavigationGuesture(bool in_v)269 ::ndk::ScopedAStatus VirtualHal::setNavigationGuesture(bool in_v) {
270     Fingerprint::cfg().sourcedFromAidl();
271     Fingerprint::cfg().set<bool>("navigation_guesture", in_v);
272     return ndk::ScopedAStatus::ok();
273 }
274 
setDetectInteraction(bool in_v)275 ::ndk::ScopedAStatus VirtualHal::setDetectInteraction(bool in_v) {
276     Fingerprint::cfg().sourcedFromAidl();
277     Fingerprint::cfg().set<bool>("detect_interaction", in_v);
278     return ndk::ScopedAStatus::ok();
279 }
280 
setDisplayTouch(bool in_v)281 ::ndk::ScopedAStatus VirtualHal::setDisplayTouch(bool in_v) {
282     Fingerprint::cfg().sourcedFromAidl();
283     Fingerprint::cfg().set<bool>("display_touch", in_v);
284     return ndk::ScopedAStatus::ok();
285 }
286 
setControlIllumination(bool in_v)287 ::ndk::ScopedAStatus VirtualHal::setControlIllumination(bool in_v) {
288     Fingerprint::cfg().sourcedFromAidl();
289     Fingerprint::cfg().set<bool>("control_illumination", in_v);
290     return ndk::ScopedAStatus::ok();
291 }
292 
intVec2OptIntVec(const std::vector<int32_t> & in_vec)293 OptIntVec VirtualHal::intVec2OptIntVec(const std::vector<int32_t>& in_vec) {
294     OptIntVec optIntVec;
295     std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
296                    [](int value) { return std::optional<int>(value); });
297     return optIntVec;
298 }
299 
acquiredInfoVec2OptIntVec(const std::vector<AcquiredInfoAndVendorCode> & in_vec)300 OptIntVec VirtualHal::acquiredInfoVec2OptIntVec(
301         const std::vector<AcquiredInfoAndVendorCode>& in_vec) {
302     OptIntVec optIntVec;
303     std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
304                    [](AcquiredInfoAndVendorCode ac) {
305                        int value;
306                        if (ac.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
307                            value = (int)ac.get<Tag::acquiredInfo>();
308                        else if (ac.getTag() == AcquiredInfoAndVendorCode::vendorCode)
309                            value = ac.get<Tag::vendorCode>();
310                        else
311                            LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode tag";
312                        return std::optional<int>(value);
313                    });
314     return optIntVec;
315 }
316 
sanityCheckLatency(const std::vector<int32_t> & in_latency)317 ::ndk::ScopedAStatus VirtualHal::sanityCheckLatency(const std::vector<int32_t>& in_latency) {
318     if (in_latency.size() == 0 || in_latency.size() > 2) {
319         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
320                 IVirtualHal::STATUS_INVALID_PARAMETER,
321                 "Error: input input array must contain 1 or 2 elements"));
322     }
323 
324     for (auto x : in_latency) {
325         if (x < 0) {
326             return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
327                     IVirtualHal::STATUS_INVALID_PARAMETER,
328                     "Error: input data must not be negative"));
329         }
330     }
331 
332     return ndk::ScopedAStatus::ok();
333 }
334 
getFingerprintHal(std::shared_ptr<::aidl::android::hardware::biometrics::fingerprint::IFingerprint> * pFp)335 ::ndk::ScopedAStatus VirtualHal::getFingerprintHal(
336         std::shared_ptr<::aidl::android::hardware::biometrics::fingerprint::IFingerprint>* pFp) {
337     LOG(INFO) << " calling getFingerprintHal in VirtualHal.cpp";
338     *pFp = mFp;
339     return ndk::ScopedAStatus::ok();
340 }
341 }  // namespace aidl::android::hardware::biometrics::fingerprint
342