xref: /aosp_15_r20/system/teeui/libteeui/include/secure_input/evdev.h (revision 20bfefbe1966c142a35ae1ab84a8af250b3fd403)
1*20bfefbeSAndroid Build Coastguard Worker /*
2*20bfefbeSAndroid Build Coastguard Worker  *
3*20bfefbeSAndroid Build Coastguard Worker  * Copyright 2018, The Android Open Source Project
4*20bfefbeSAndroid Build Coastguard Worker  *
5*20bfefbeSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*20bfefbeSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*20bfefbeSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*20bfefbeSAndroid Build Coastguard Worker  *
9*20bfefbeSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
10*20bfefbeSAndroid Build Coastguard Worker  *
11*20bfefbeSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*20bfefbeSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*20bfefbeSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*20bfefbeSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*20bfefbeSAndroid Build Coastguard Worker  * limitations under the License.
16*20bfefbeSAndroid Build Coastguard Worker  */
17*20bfefbeSAndroid Build Coastguard Worker 
18*20bfefbeSAndroid Build Coastguard Worker #ifndef CONFIRMATIONUI_EVDEV_H_
19*20bfefbeSAndroid Build Coastguard Worker #define CONFIRMATIONUI_EVDEV_H_
20*20bfefbeSAndroid Build Coastguard Worker 
21*20bfefbeSAndroid Build Coastguard Worker #include <linux/input.h>
22*20bfefbeSAndroid Build Coastguard Worker #include <poll.h>
23*20bfefbeSAndroid Build Coastguard Worker 
24*20bfefbeSAndroid Build Coastguard Worker #include <atomic>
25*20bfefbeSAndroid Build Coastguard Worker #include <chrono>
26*20bfefbeSAndroid Build Coastguard Worker #include <condition_variable>
27*20bfefbeSAndroid Build Coastguard Worker #include <list>
28*20bfefbeSAndroid Build Coastguard Worker #include <mutex>
29*20bfefbeSAndroid Build Coastguard Worker #include <string>
30*20bfefbeSAndroid Build Coastguard Worker #include <thread>
31*20bfefbeSAndroid Build Coastguard Worker #include <tuple>
32*20bfefbeSAndroid Build Coastguard Worker #include <vector>
33*20bfefbeSAndroid Build Coastguard Worker 
34*20bfefbeSAndroid Build Coastguard Worker namespace secure_input {
35*20bfefbeSAndroid Build Coastguard Worker 
36*20bfefbeSAndroid Build Coastguard Worker template <typename Fn> class NonCopyableFunction;
37*20bfefbeSAndroid Build Coastguard Worker 
38*20bfefbeSAndroid Build Coastguard Worker template <typename Ret, typename... Args> class NonCopyableFunction<Ret(Args...)> {
39*20bfefbeSAndroid Build Coastguard Worker     class NonCopyableFunctionBase {
40*20bfefbeSAndroid Build Coastguard Worker       public:
41*20bfefbeSAndroid Build Coastguard Worker         NonCopyableFunctionBase() = default;
~NonCopyableFunctionBase()42*20bfefbeSAndroid Build Coastguard Worker         virtual ~NonCopyableFunctionBase() {}
43*20bfefbeSAndroid Build Coastguard Worker         virtual Ret operator()(Args... args) = 0;
44*20bfefbeSAndroid Build Coastguard Worker         NonCopyableFunctionBase(const NonCopyableFunctionBase&) = delete;
45*20bfefbeSAndroid Build Coastguard Worker         NonCopyableFunctionBase& operator=(const NonCopyableFunctionBase&) = delete;
46*20bfefbeSAndroid Build Coastguard Worker     };
47*20bfefbeSAndroid Build Coastguard Worker 
48*20bfefbeSAndroid Build Coastguard Worker     template <typename Fn> class NonCopyableFunctionTypeEraser : public NonCopyableFunctionBase {
49*20bfefbeSAndroid Build Coastguard Worker       private:
50*20bfefbeSAndroid Build Coastguard Worker         Fn f_;
51*20bfefbeSAndroid Build Coastguard Worker 
52*20bfefbeSAndroid Build Coastguard Worker       public:
53*20bfefbeSAndroid Build Coastguard Worker         NonCopyableFunctionTypeEraser() = default;
NonCopyableFunctionTypeEraser(Fn f)54*20bfefbeSAndroid Build Coastguard Worker         explicit NonCopyableFunctionTypeEraser(Fn f) : f_(std::move(f)) {}
operator()55*20bfefbeSAndroid Build Coastguard Worker         Ret operator()(Args... args) override { return f_(std::move(args)...); }
56*20bfefbeSAndroid Build Coastguard Worker     };
57*20bfefbeSAndroid Build Coastguard Worker 
58*20bfefbeSAndroid Build Coastguard Worker   private:
59*20bfefbeSAndroid Build Coastguard Worker     std::unique_ptr<NonCopyableFunctionBase> f_;
60*20bfefbeSAndroid Build Coastguard Worker 
61*20bfefbeSAndroid Build Coastguard Worker   public:
62*20bfefbeSAndroid Build Coastguard Worker     NonCopyableFunction() = default;
NonCopyableFunction(F f)63*20bfefbeSAndroid Build Coastguard Worker     template <typename F> NonCopyableFunction(F f) {
64*20bfefbeSAndroid Build Coastguard Worker         f_ = std::make_unique<NonCopyableFunctionTypeEraser<F>>(std::move(f));
65*20bfefbeSAndroid Build Coastguard Worker     }
66*20bfefbeSAndroid Build Coastguard Worker     NonCopyableFunction(NonCopyableFunction&& other) = default;
67*20bfefbeSAndroid Build Coastguard Worker     NonCopyableFunction& operator=(NonCopyableFunction&& other) = default;
68*20bfefbeSAndroid Build Coastguard Worker     NonCopyableFunction(const NonCopyableFunction& other) = delete;
69*20bfefbeSAndroid Build Coastguard Worker     NonCopyableFunction& operator=(const NonCopyableFunction& other) = delete;
70*20bfefbeSAndroid Build Coastguard Worker 
operator()71*20bfefbeSAndroid Build Coastguard Worker     Ret operator()(Args... args) {
72*20bfefbeSAndroid Build Coastguard Worker         if (f_) return (*f_)(std::move(args)...);
73*20bfefbeSAndroid Build Coastguard Worker     }
74*20bfefbeSAndroid Build Coastguard Worker };
75*20bfefbeSAndroid Build Coastguard Worker 
76*20bfefbeSAndroid Build Coastguard Worker class EventLoop {
77*20bfefbeSAndroid Build Coastguard Worker   private:
78*20bfefbeSAndroid Build Coastguard Worker     enum class ThreadState : long {
79*20bfefbeSAndroid Build Coastguard Worker         STARTING,
80*20bfefbeSAndroid Build Coastguard Worker         RUNNING,
81*20bfefbeSAndroid Build Coastguard Worker         STOP_REQUESTED,
82*20bfefbeSAndroid Build Coastguard Worker         JOINED,
83*20bfefbeSAndroid Build Coastguard Worker         TERMINATING,
84*20bfefbeSAndroid Build Coastguard Worker     };
85*20bfefbeSAndroid Build Coastguard Worker     std::thread thread_;
86*20bfefbeSAndroid Build Coastguard Worker     int eventFd_ = -1;
87*20bfefbeSAndroid Build Coastguard Worker     volatile ThreadState state_ = ThreadState::JOINED;
88*20bfefbeSAndroid Build Coastguard Worker     std::mutex mutex_;
89*20bfefbeSAndroid Build Coastguard Worker     std::condition_variable condVar_;
90*20bfefbeSAndroid Build Coastguard Worker 
91*20bfefbeSAndroid Build Coastguard Worker     struct EventReceiver {
EventReceiverEventReceiver92*20bfefbeSAndroid Build Coastguard Worker         EventReceiver(int fd, short flags, NonCopyableFunction<void(short)> handle)
93*20bfefbeSAndroid Build Coastguard Worker             : eventFd(fd), eventFlags(flags), handleEvent(std::move(handle)) {}
94*20bfefbeSAndroid Build Coastguard Worker         int eventFd;
95*20bfefbeSAndroid Build Coastguard Worker         short eventFlags;
96*20bfefbeSAndroid Build Coastguard Worker         NonCopyableFunction<void(short)> handleEvent;
97*20bfefbeSAndroid Build Coastguard Worker     };
98*20bfefbeSAndroid Build Coastguard Worker 
99*20bfefbeSAndroid Build Coastguard Worker     std::vector<EventReceiver> receivers_;
100*20bfefbeSAndroid Build Coastguard Worker     std::list<EventReceiver> newReceivers_;
101*20bfefbeSAndroid Build Coastguard Worker 
102*20bfefbeSAndroid Build Coastguard Worker     struct Timer {
TimerTimer103*20bfefbeSAndroid Build Coastguard Worker         Timer(std::chrono::steady_clock::time_point _next,
104*20bfefbeSAndroid Build Coastguard Worker               std::chrono::steady_clock::duration _duration, NonCopyableFunction<void()> handle,
105*20bfefbeSAndroid Build Coastguard Worker               bool _oneShot)
106*20bfefbeSAndroid Build Coastguard Worker             : next(_next), duration(_duration), handleTimer(std::move(handle)), oneShot(_oneShot) {}
107*20bfefbeSAndroid Build Coastguard Worker 
108*20bfefbeSAndroid Build Coastguard Worker         std::chrono::steady_clock::time_point next;
109*20bfefbeSAndroid Build Coastguard Worker         std::chrono::steady_clock::duration duration;
110*20bfefbeSAndroid Build Coastguard Worker         NonCopyableFunction<void()> handleTimer;
111*20bfefbeSAndroid Build Coastguard Worker         bool oneShot;
112*20bfefbeSAndroid Build Coastguard Worker     };
113*20bfefbeSAndroid Build Coastguard Worker     std::vector<Timer> timers_;
114*20bfefbeSAndroid Build Coastguard Worker     std::list<Timer> newTimers_;
115*20bfefbeSAndroid Build Coastguard Worker 
116*20bfefbeSAndroid Build Coastguard Worker     static bool timerOrder(const Timer& a, const Timer& b);
117*20bfefbeSAndroid Build Coastguard Worker 
118*20bfefbeSAndroid Build Coastguard Worker     void processNewTimers();
119*20bfefbeSAndroid Build Coastguard Worker 
120*20bfefbeSAndroid Build Coastguard Worker     int runTimers();
121*20bfefbeSAndroid Build Coastguard Worker     void processNewReceivers();
122*20bfefbeSAndroid Build Coastguard Worker 
123*20bfefbeSAndroid Build Coastguard Worker   public:
124*20bfefbeSAndroid Build Coastguard Worker     ~EventLoop();
125*20bfefbeSAndroid Build Coastguard Worker     void addEventReceiver(NonCopyableFunction<void(short)> handler, int eventFd,
126*20bfefbeSAndroid Build Coastguard Worker                           short flags = POLLIN);
127*20bfefbeSAndroid Build Coastguard Worker 
128*20bfefbeSAndroid Build Coastguard Worker     void addTimer(NonCopyableFunction<void()> handler, std::chrono::steady_clock::duration duration,
129*20bfefbeSAndroid Build Coastguard Worker                   bool oneShot = true);
130*20bfefbeSAndroid Build Coastguard Worker 
131*20bfefbeSAndroid Build Coastguard Worker     bool start();
132*20bfefbeSAndroid Build Coastguard Worker     void stop();
133*20bfefbeSAndroid Build Coastguard Worker };
134*20bfefbeSAndroid Build Coastguard Worker 
135*20bfefbeSAndroid Build Coastguard Worker class EventDev {
136*20bfefbeSAndroid Build Coastguard Worker   private:
137*20bfefbeSAndroid Build Coastguard Worker     int fd_ = -1;
138*20bfefbeSAndroid Build Coastguard Worker     std::string path_;
139*20bfefbeSAndroid Build Coastguard Worker 
140*20bfefbeSAndroid Build Coastguard Worker   public:
141*20bfefbeSAndroid Build Coastguard Worker     EventDev();
142*20bfefbeSAndroid Build Coastguard Worker     EventDev(const std::string& path);
143*20bfefbeSAndroid Build Coastguard Worker     EventDev(const EventDev&) = delete;
144*20bfefbeSAndroid Build Coastguard Worker     EventDev(EventDev&& other);
145*20bfefbeSAndroid Build Coastguard Worker     EventDev& operator=(EventDev&& other);
~EventDev()146*20bfefbeSAndroid Build Coastguard Worker     ~EventDev() { ungrab(); }
147*20bfefbeSAndroid Build Coastguard Worker     bool grab();
148*20bfefbeSAndroid Build Coastguard Worker     void ungrab();
149*20bfefbeSAndroid Build Coastguard Worker     std::tuple<bool, input_event> readEvent() const;
150*20bfefbeSAndroid Build Coastguard Worker     int fd() const;
151*20bfefbeSAndroid Build Coastguard Worker };
152*20bfefbeSAndroid Build Coastguard Worker 
153*20bfefbeSAndroid Build Coastguard Worker bool grabAllEvDevsAndRegisterCallbacks(EventLoop* eventloop,
154*20bfefbeSAndroid Build Coastguard Worker                                        std::function<void(short, const EventDev&)> handler);
155*20bfefbeSAndroid Build Coastguard Worker 
156*20bfefbeSAndroid Build Coastguard Worker }  // namespace secure_input
157*20bfefbeSAndroid Build Coastguard Worker 
158*20bfefbeSAndroid Build Coastguard Worker #endif  // CONFIRMATIONUI_EVDEV_H_
159