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