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