1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include "CancelationOptions.h" 20*38e8c45fSAndroid Build Coastguard Worker #include "Entry.h" 21*38e8c45fSAndroid Build Coastguard Worker 22*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h> 23*38e8c45fSAndroid Build Coastguard Worker #include <bitset> 24*38e8c45fSAndroid Build Coastguard Worker 25*38e8c45fSAndroid Build Coastguard Worker namespace android { 26*38e8c45fSAndroid Build Coastguard Worker namespace inputdispatcher { 27*38e8c45fSAndroid Build Coastguard Worker 28*38e8c45fSAndroid Build Coastguard Worker static constexpr int32_t INVALID_POINTER_INDEX = -1; 29*38e8c45fSAndroid Build Coastguard Worker 30*38e8c45fSAndroid Build Coastguard Worker /* Tracks dispatched key and motion event state so that cancellation events can be 31*38e8c45fSAndroid Build Coastguard Worker * synthesized when events are dropped. */ 32*38e8c45fSAndroid Build Coastguard Worker class InputState { 33*38e8c45fSAndroid Build Coastguard Worker public: 34*38e8c45fSAndroid Build Coastguard Worker explicit InputState(const IdGenerator& idGenerator); 35*38e8c45fSAndroid Build Coastguard Worker ~InputState(); 36*38e8c45fSAndroid Build Coastguard Worker 37*38e8c45fSAndroid Build Coastguard Worker // Returns true if the specified source is known to have received a hover enter 38*38e8c45fSAndroid Build Coastguard Worker // motion event. 39*38e8c45fSAndroid Build Coastguard Worker bool isHovering(DeviceId deviceId, uint32_t source, ui::LogicalDisplayId displayId) const; 40*38e8c45fSAndroid Build Coastguard Worker 41*38e8c45fSAndroid Build Coastguard Worker // Records tracking information for a key event that has just been published. 42*38e8c45fSAndroid Build Coastguard Worker // Returns true if the event should be delivered, false if it is inconsistent 43*38e8c45fSAndroid Build Coastguard Worker // and should be skipped. 44*38e8c45fSAndroid Build Coastguard Worker bool trackKey(const KeyEntry& entry, int32_t flags); 45*38e8c45fSAndroid Build Coastguard Worker 46*38e8c45fSAndroid Build Coastguard Worker // Records tracking information for a motion event that has just been published. 47*38e8c45fSAndroid Build Coastguard Worker // Returns true if the event should be delivered, false if it is inconsistent 48*38e8c45fSAndroid Build Coastguard Worker // and should be skipped. 49*38e8c45fSAndroid Build Coastguard Worker bool trackMotion(const MotionEntry& entry, int32_t flags); 50*38e8c45fSAndroid Build Coastguard Worker 51*38e8c45fSAndroid Build Coastguard Worker /** 52*38e8c45fSAndroid Build Coastguard Worker * Return the PointerProperties and the PointerCoords for the last event, if found. Return 53*38e8c45fSAndroid Build Coastguard Worker * std::nullopt if not found. We should not return std::vector<PointerCoords> in isolation, 54*38e8c45fSAndroid Build Coastguard Worker * because the pointers can technically be stored in the vector in any order, so the 55*38e8c45fSAndroid Build Coastguard Worker * PointerProperties are needed to specify the order in which the pointer coords are stored. 56*38e8c45fSAndroid Build Coastguard Worker */ 57*38e8c45fSAndroid Build Coastguard Worker std::optional<std::pair<std::vector<PointerProperties>, std::vector<PointerCoords>>> 58*38e8c45fSAndroid Build Coastguard Worker getPointersOfLastEvent(const MotionEntry& entry, bool hovering) const; 59*38e8c45fSAndroid Build Coastguard Worker 60*38e8c45fSAndroid Build Coastguard Worker // Create cancel events for the previous stream if the current motionEntry requires it. 61*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<EventEntry> cancelConflictingInputStream(const MotionEntry& motionEntry); 62*38e8c45fSAndroid Build Coastguard Worker 63*38e8c45fSAndroid Build Coastguard Worker // Synthesizes cancelation events for the current state and resets the tracked state. 64*38e8c45fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<EventEntry>> synthesizeCancelationEvents( 65*38e8c45fSAndroid Build Coastguard Worker nsecs_t currentTime, const CancelationOptions& options); 66*38e8c45fSAndroid Build Coastguard Worker 67*38e8c45fSAndroid Build Coastguard Worker // Synthesizes down events for the current state. 68*38e8c45fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<EventEntry>> synthesizePointerDownEvents(nsecs_t currentTime); 69*38e8c45fSAndroid Build Coastguard Worker 70*38e8c45fSAndroid Build Coastguard Worker // Clears the current state. 71*38e8c45fSAndroid Build Coastguard Worker void clear(); 72*38e8c45fSAndroid Build Coastguard Worker 73*38e8c45fSAndroid Build Coastguard Worker // Merges pointer-related parts of the input state into another instance. 74*38e8c45fSAndroid Build Coastguard Worker void mergePointerStateTo(InputState& other); 75*38e8c45fSAndroid Build Coastguard Worker 76*38e8c45fSAndroid Build Coastguard Worker // Gets the fallback key associated with a keycode. 77*38e8c45fSAndroid Build Coastguard Worker // Returns std::nullopt if none. 78*38e8c45fSAndroid Build Coastguard Worker // Returns AKEYCODE_UNKNOWN if we are only dispatching the unhandled key to the policy. 79*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> getFallbackKey(int32_t originalKeyCode); 80*38e8c45fSAndroid Build Coastguard Worker 81*38e8c45fSAndroid Build Coastguard Worker // Sets the fallback key for a particular keycode. 82*38e8c45fSAndroid Build Coastguard Worker void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode); 83*38e8c45fSAndroid Build Coastguard Worker 84*38e8c45fSAndroid Build Coastguard Worker // Removes the fallback key for a particular keycode. 85*38e8c45fSAndroid Build Coastguard Worker void removeFallbackKey(int32_t originalKeyCode); 86*38e8c45fSAndroid Build Coastguard Worker getFallbackKeys()87*38e8c45fSAndroid Build Coastguard Worker inline const std::map<int32_t, int32_t>& getFallbackKeys() const { return mFallbackKeys; } 88*38e8c45fSAndroid Build Coastguard Worker 89*38e8c45fSAndroid Build Coastguard Worker private: 90*38e8c45fSAndroid Build Coastguard Worker struct KeyMemento { 91*38e8c45fSAndroid Build Coastguard Worker DeviceId deviceId; 92*38e8c45fSAndroid Build Coastguard Worker uint32_t source; 93*38e8c45fSAndroid Build Coastguard Worker ui::LogicalDisplayId displayId{ui::LogicalDisplayId::INVALID}; 94*38e8c45fSAndroid Build Coastguard Worker int32_t keyCode; 95*38e8c45fSAndroid Build Coastguard Worker int32_t scanCode; 96*38e8c45fSAndroid Build Coastguard Worker int32_t metaState; 97*38e8c45fSAndroid Build Coastguard Worker int32_t flags; 98*38e8c45fSAndroid Build Coastguard Worker nsecs_t downTime; 99*38e8c45fSAndroid Build Coastguard Worker uint32_t policyFlags; 100*38e8c45fSAndroid Build Coastguard Worker }; 101*38e8c45fSAndroid Build Coastguard Worker 102*38e8c45fSAndroid Build Coastguard Worker struct MotionMemento { 103*38e8c45fSAndroid Build Coastguard Worker DeviceId deviceId; 104*38e8c45fSAndroid Build Coastguard Worker uint32_t source; 105*38e8c45fSAndroid Build Coastguard Worker ui::LogicalDisplayId displayId{ui::LogicalDisplayId::INVALID}; 106*38e8c45fSAndroid Build Coastguard Worker int32_t flags; 107*38e8c45fSAndroid Build Coastguard Worker float xPrecision; 108*38e8c45fSAndroid Build Coastguard Worker float yPrecision; 109*38e8c45fSAndroid Build Coastguard Worker float xCursorPosition; 110*38e8c45fSAndroid Build Coastguard Worker float yCursorPosition; 111*38e8c45fSAndroid Build Coastguard Worker nsecs_t downTime; 112*38e8c45fSAndroid Build Coastguard Worker std::vector<PointerProperties> pointerProperties; 113*38e8c45fSAndroid Build Coastguard Worker std::vector<PointerCoords> pointerCoords; 114*38e8c45fSAndroid Build Coastguard Worker // Track for which pointers the target doesn't know about. 115*38e8c45fSAndroid Build Coastguard Worker int32_t firstNewPointerIdx = INVALID_POINTER_INDEX; 116*38e8c45fSAndroid Build Coastguard Worker bool hovering; 117*38e8c45fSAndroid Build Coastguard Worker uint32_t policyFlags; 118*38e8c45fSAndroid Build Coastguard Worker 119*38e8c45fSAndroid Build Coastguard Worker void setPointers(const MotionEntry& entry); 120*38e8c45fSAndroid Build Coastguard Worker void mergePointerStateTo(MotionMemento& other) const; 121*38e8c45fSAndroid Build Coastguard Worker size_t getPointerCount() const; 122*38e8c45fSAndroid Build Coastguard Worker }; 123*38e8c45fSAndroid Build Coastguard Worker 124*38e8c45fSAndroid Build Coastguard Worker const IdGenerator& mIdGenerator; // InputDispatcher owns it so we won't have dangling reference. 125*38e8c45fSAndroid Build Coastguard Worker 126*38e8c45fSAndroid Build Coastguard Worker std::vector<KeyMemento> mKeyMementos; 127*38e8c45fSAndroid Build Coastguard Worker std::vector<MotionMemento> mMotionMementos; 128*38e8c45fSAndroid Build Coastguard Worker std::map</*originalKeyCode*/int32_t, /*fallbackKeyCode*/int32_t> mFallbackKeys; 129*38e8c45fSAndroid Build Coastguard Worker 130*38e8c45fSAndroid Build Coastguard Worker ssize_t findKeyMemento(const KeyEntry& entry) const; 131*38e8c45fSAndroid Build Coastguard Worker ssize_t findMotionMemento(const MotionEntry& entry, bool hovering) const; 132*38e8c45fSAndroid Build Coastguard Worker 133*38e8c45fSAndroid Build Coastguard Worker void addKeyMemento(const KeyEntry& entry, int32_t flags); 134*38e8c45fSAndroid Build Coastguard Worker void addMotionMemento(const MotionEntry& entry, int32_t flags, bool hovering); 135*38e8c45fSAndroid Build Coastguard Worker 136*38e8c45fSAndroid Build Coastguard Worker static bool shouldCancelKey(const KeyMemento& memento, const CancelationOptions& options); 137*38e8c45fSAndroid Build Coastguard Worker static bool shouldCancelMotion(const MotionMemento& memento, const CancelationOptions& options); 138*38e8c45fSAndroid Build Coastguard Worker bool shouldCancelPreviousStream(const MotionEntry& motionEntry) const; 139*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<MotionEntry> createCancelEntryForMemento(const MotionMemento& memento, 140*38e8c45fSAndroid Build Coastguard Worker nsecs_t eventTime) const; 141*38e8c45fSAndroid Build Coastguard Worker 142*38e8c45fSAndroid Build Coastguard Worker // Synthesizes pointer cancel events for a particular set of pointers. 143*38e8c45fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<MotionEntry>> synthesizeCancelationEventsForPointers( 144*38e8c45fSAndroid Build Coastguard Worker const MotionMemento& memento, std::bitset<MAX_POINTER_ID + 1> pointerIds, 145*38e8c45fSAndroid Build Coastguard Worker nsecs_t currentTime); 146*38e8c45fSAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream& out, const InputState& state); 147*38e8c45fSAndroid Build Coastguard Worker }; 148*38e8c45fSAndroid Build Coastguard Worker 149*38e8c45fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const InputState& state); 150*38e8c45fSAndroid Build Coastguard Worker 151*38e8c45fSAndroid Build Coastguard Worker } // namespace inputdispatcher 152*38e8c45fSAndroid Build Coastguard Worker } // namespace android 153