• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <functional>
28 #include <list>
29 #include <mutex>
30 #include <string>
31 #include <thread>
32 #include <tuple>
33 #include <vector>
34 
35 namespace secure_input {
36 
37 template <typename Fn> class NonCopyableFunction;
38 
39 template <typename Ret, typename... Args> class NonCopyableFunction<Ret(Args...)> {
40     class NonCopyableFunctionBase {
41       public:
42         NonCopyableFunctionBase() = default;
~NonCopyableFunctionBase()43         virtual ~NonCopyableFunctionBase() {}
44         virtual Ret operator()(Args... args) = 0;
45         NonCopyableFunctionBase(const NonCopyableFunctionBase&) = delete;
46         NonCopyableFunctionBase& operator=(const NonCopyableFunctionBase&) = delete;
47     };
48 
49     template <typename Fn> class NonCopyableFunctionTypeEraser : public NonCopyableFunctionBase {
50       private:
51         Fn f_;
52 
53       public:
54         NonCopyableFunctionTypeEraser() = default;
NonCopyableFunctionTypeEraser(Fn f)55         explicit NonCopyableFunctionTypeEraser(Fn f) : f_(std::move(f)) {}
operator()56         Ret operator()(Args... args) override { return f_(std::move(args)...); }
57     };
58 
59   private:
60     std::unique_ptr<NonCopyableFunctionBase> f_;
61 
62   public:
63     NonCopyableFunction() = default;
NonCopyableFunction(F f)64     template <typename F> NonCopyableFunction(F f) {
65         f_ = std::make_unique<NonCopyableFunctionTypeEraser<F>>(std::move(f));
66     }
67     NonCopyableFunction(NonCopyableFunction&& other) = default;
68     NonCopyableFunction& operator=(NonCopyableFunction&& other) = default;
69     NonCopyableFunction(const NonCopyableFunction& other) = delete;
70     NonCopyableFunction& operator=(const NonCopyableFunction& other) = delete;
71 
operator()72     Ret operator()(Args... args) {
73         if (f_) return (*f_)(std::move(args)...);
74     }
75 };
76 
77 class EventLoop {
78   private:
79     enum class ThreadState : long {
80         STARTING,
81         RUNNING,
82         STOP_REQUESTED,
83         JOINED,
84         TERMINATING,
85     };
86     std::thread thread_;
87     int eventFd_ = -1;
88     volatile ThreadState state_ = ThreadState::JOINED;
89     std::mutex mutex_;
90     std::condition_variable condVar_;
91 
92     struct EventReceiver {
EventReceiverEventReceiver93         EventReceiver(int fd, short flags, NonCopyableFunction<void(short)> handle)
94             : eventFd(fd), eventFlags(flags), handleEvent(std::move(handle)) {}
95         int eventFd;
96         short eventFlags;
97         NonCopyableFunction<void(short)> handleEvent;
98     };
99 
100     std::vector<EventReceiver> receivers_;
101     std::list<EventReceiver> newReceivers_;
102 
103     struct Timer {
TimerTimer104         Timer(std::chrono::steady_clock::time_point _next,
105               std::chrono::steady_clock::duration _duration, NonCopyableFunction<void()> handle,
106               bool _oneShot)
107             : next(_next), duration(_duration), handleTimer(std::move(handle)), oneShot(_oneShot) {}
108 
109         std::chrono::steady_clock::time_point next;
110         std::chrono::steady_clock::duration duration;
111         NonCopyableFunction<void()> handleTimer;
112         bool oneShot;
113     };
114     std::vector<Timer> timers_;
115     std::list<Timer> newTimers_;
116 
117     static bool timerOrder(const Timer& a, const Timer& b);
118 
119     void processNewTimers();
120 
121     int runTimers();
122     void processNewReceivers();
123 
124   public:
125     ~EventLoop();
126     void addEventReceiver(NonCopyableFunction<void(short)> handler, int eventFd,
127                           short flags = POLLIN);
128 
129     void addTimer(NonCopyableFunction<void()> handler, std::chrono::steady_clock::duration duration,
130                   bool oneShot = true);
131 
132     bool start();
133     void stop();
134 };
135 
136 class EventDev {
137   private:
138     int fd_ = -1;
139     std::string path_;
140 
141   public:
142     EventDev();
143     EventDev(const std::string& path);
144     EventDev(const EventDev&) = delete;
145     EventDev(EventDev&& other);
146     EventDev& operator=(EventDev&& other);
~EventDev()147     ~EventDev() { ungrab(); }
148     bool grab();
149     void ungrab();
150     std::tuple<bool, input_event> readEvent() const;
151     int fd() const;
152 };
153 
154 bool grabAllEvDevsAndRegisterCallbacks(EventLoop* eventloop,
155                                        std::function<void(short, const EventDev&)> handler);
156 
157 }  // namespace secure_input
158 
159 #endif  // CONFIRMATIONUI_EVDEV_H_
160