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