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