1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <ftl/flags.h> 20 #include <gui/WindowInfo.h> 21 #include <ui/Transform.h> 22 #include <utils/BitSet.h> 23 #include <bitset> 24 #include "Connection.h" 25 #include "InputTargetFlags.h" 26 27 namespace android::inputdispatcher { 28 29 /* 30 * An input target specifies how an input event is to be dispatched to a particular window 31 * including the window's input channel, control flags, a timeout, and an X / Y offset to 32 * be added to input event coordinates to compensate for the absolute position of the 33 * window area. 34 */ 35 class InputTarget { 36 public: 37 using Flags = InputTargetFlags; 38 39 enum class DispatchMode { 40 /* This flag indicates that the event should be sent as is. 41 * Should always be set unless the event is to be transmuted. */ 42 AS_IS, 43 /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside 44 * of the area of this target and so should instead be delivered as an 45 * AMOTION_EVENT_ACTION_OUTSIDE to this target. */ 46 OUTSIDE, 47 /* This flag indicates that a hover sequence is starting in the given window. 48 * The event is transmuted into ACTION_HOVER_ENTER. */ 49 HOVER_ENTER, 50 /* This flag indicates that a hover event happened outside of a window which handled 51 * previous hover events, signifying the end of the current hover sequence for that 52 * window. 53 * The event is transmuted into ACTION_HOVER_ENTER. */ 54 HOVER_EXIT, 55 /* This flag indicates that the event should be canceled. 56 * It is used to transmute ACTION_MOVE into ACTION_CANCEL when a touch slips 57 * outside of a window. */ 58 SLIPPERY_EXIT, 59 /* This flag indicates that the event should be dispatched as an initial down. 60 * It is used to transmute ACTION_MOVE into ACTION_DOWN when a touch slips 61 * into a new window. */ 62 SLIPPERY_ENTER, 63 64 ftl_last = SLIPPERY_ENTER, 65 }; 66 67 // The input connection to be targeted. 68 std::shared_ptr<Connection> connection; 69 70 // Flags for the input target. 71 ftl::Flags<Flags> flags; 72 73 // The dispatch mode that should be used for this target. 74 DispatchMode dispatchMode = DispatchMode::AS_IS; 75 76 // Scaling factor to apply to MotionEvent as it is delivered. 77 // (ignored for KeyEvents) 78 float globalScaleFactor = 1.0f; 79 80 // Current display transform. Used for compatibility for raw coordinates. 81 ui::Transform displayTransform; 82 83 // Event time for the first motion event (ACTION_DOWN) dispatched to this input target if 84 // FLAG_SPLIT is set. 85 std::optional<nsecs_t> firstDownTimeInTarget; 86 87 // The window that this input target is being dispatched to. It is possible for this to be 88 // null for cases like global monitors. 89 sp<gui::WindowInfoHandle> windowHandle; 90 91 InputTarget() = default; 92 InputTarget(const std::shared_ptr<Connection>&, ftl::Flags<Flags> = {}); 93 94 android::base::Result<void> addPointers(std::bitset<MAX_POINTER_ID + 1> pointerIds, 95 const ui::Transform& transform); 96 void setDefaultPointerTransform(const ui::Transform& transform); 97 98 /** 99 * Returns whether the default pointer information should be used. This will be true when the 100 * InputTarget doesn't have any bits set in the pointerIds bitset. This can happen for monitors 101 * and non splittable windows since we want all pointers for the EventEntry to go to this 102 * target. 103 */ 104 bool useDefaultPointerTransform() const; 105 106 /** 107 * Returns the default Transform object. This should be used when useDefaultPointerTransform is 108 * true. 109 */ 110 const ui::Transform& getDefaultPointerTransform() const; 111 112 const ui::Transform& getTransformForPointer(int32_t pointerId) const; 113 114 std::bitset<MAX_POINTER_ID + 1> getPointerIds() const; 115 116 std::string getPointerInfoString() const; 117 118 private: 119 template <typename K, typename V> 120 using ArrayMap = std::vector<std::pair<K, V>>; 121 using PointerIds = std::bitset<MAX_POINTER_ID + 1>; 122 // The mapping of pointer IDs to the transform that should be used for that collection of IDs. 123 // Each of the pointer IDs are mutually disjoint, and their union makes up pointer IDs to 124 // include in the motion events dispatched to this target. We use an ArrayMap to store this to 125 // avoid having to define hash or comparison functions for ui::Transform, which would be needed 126 // to use std::unordered_map or std::map respectively. 127 ArrayMap<ui::Transform, PointerIds> mPointerTransforms; 128 }; 129 130 std::ostream& operator<<(std::ostream& out, const InputTarget& target); 131 132 } // namespace android::inputdispatcher 133