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 #pragma once
18 
19 #include <aidl/android/hardware/biometrics/fingerprint/BnSession.h>
20 #include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
21 
22 #include "FakeFingerprintEngine.h"
23 #include "WorkerThread.h"
24 
25 namespace aidl::android::hardware::biometrics::fingerprint {
26 
27 namespace common = aidl::android::hardware::biometrics::common;
28 namespace keymaster = aidl::android::hardware::keymaster;
29 
30 enum class SessionState {
31     IDLING,
32     CLOSED,
33     GENERATING_CHALLENGE,
34     REVOKING_CHALLENGE,
35     ENROLLING,
36     AUTHENTICATING,
37     DETECTING_INTERACTION,
38     ENUMERATING_ENROLLMENTS,
39     REMOVING_ENROLLMENTS,
40     GETTING_AUTHENTICATOR_ID,
41     INVALIDATING_AUTHENTICATOR_ID,
42     RESETTING_LOCKOUT,
43 };
44 
45 class Session : public BnSession {
46   public:
47     Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
48             FakeFingerprintEngine* engine, WorkerThread* worker);
49 
50     ndk::ScopedAStatus generateChallenge() override;
51 
52     ndk::ScopedAStatus revokeChallenge(int64_t challenge) override;
53 
54     ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat,
55                               std::shared_ptr<common::ICancellationSignal>* out) override;
56 
57     ndk::ScopedAStatus authenticate(int64_t operationId,
58                                     std::shared_ptr<common::ICancellationSignal>* out) override;
59 
60     ndk::ScopedAStatus detectInteraction(
61             std::shared_ptr<common::ICancellationSignal>* out) override;
62 
63     ndk::ScopedAStatus enumerateEnrollments() override;
64 
65     ndk::ScopedAStatus removeEnrollments(const std::vector<int32_t>& enrollmentIds) override;
66 
67     ndk::ScopedAStatus getAuthenticatorId() override;
68 
69     ndk::ScopedAStatus invalidateAuthenticatorId() override;
70 
71     ndk::ScopedAStatus resetLockout(const keymaster::HardwareAuthToken& hat) override;
72 
73     ndk::ScopedAStatus close() override;
74 
75     ndk::ScopedAStatus onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor,
76                                      float major) override;
77 
78     ndk::ScopedAStatus onPointerUp(int32_t pointerId) override;
79 
80     ndk::ScopedAStatus onUiReady() override;
81 
82     bool isClosed();
83 
84   private:
85     // Crashes the HAL if it's not currently idling because that would be an invalid state machine
86     // transition. Otherwise, sets the scheduled state to the given state.
87     void scheduleStateOrCrash(SessionState state);
88 
89     // Crashes the HAL if the provided state doesn't match the previously scheduled state.
90     // Otherwise, transitions into the provided state, clears the scheduled state, and notifies
91     // the client about the transition by calling ISessionCallback#onStateChanged.
92     void enterStateOrCrash(SessionState state);
93 
94     // Sets the current state to SessionState::IDLING and notifies the client about the transition
95     // by calling ISessionCallback#onStateChanged.
96     void enterIdling();
97 
98     // The sensor and user IDs for which this session was created.
99     int32_t mSensorId;
100     int32_t mUserId;
101 
102     // Callback for talking to the framework. This callback must only be called from non-binder
103     // threads to prevent nested binder calls and consequently a binder thread exhaustion.
104     // Practically, it means that this callback should always be called from the worker thread.
105     std::shared_ptr<ISessionCallback> mCb;
106 
107     // Module that communicates to the actual fingerprint hardware, keystore, TEE, etc. In real
108     // life such modules typically consume a lot of memory and are slow to initialize. This is here
109     // to showcase how such a module can be used within a Session without incurring the high
110     // initialization costs every time a Session is constructed.
111     FakeFingerprintEngine* mEngine;
112 
113     // Worker thread that allows to schedule tasks for asynchronous execution.
114     WorkerThread* mWorker;
115 
116     // Simple representation of the session's state machine. These are atomic because they can be
117     // modified from both the main and the worker threads.
118     std::atomic<SessionState> mScheduledState;
119     std::atomic<SessionState> mCurrentState;
120 };
121 
122 }  // namespace aidl::android::hardware::biometrics::fingerprint
123