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 <gui/WindowInfo.h>
20 #include <input/Input.h>
21 #include <utils/BitSet.h>
22 #include <bitset>
23 #include <ostream>
24 #include <set>
25 #include "InputTarget.h"
26 
27 namespace android {
28 
29 namespace inputdispatcher {
30 
31 // Focus tracking for touch.
32 struct TouchedWindow {
33     sp<gui::WindowInfoHandle> windowHandle;
34     InputTarget::DispatchMode dispatchMode = InputTarget::DispatchMode::AS_IS;
35     ftl::Flags<InputTarget::Flags> targetFlags;
36 
37     // Hovering
38     bool hasHoveringPointers() const;
39     bool hasHoveringPointers(DeviceId deviceId) const;
40     bool hasHoveringPointer(DeviceId deviceId, int32_t pointerId) const;
41     void addHoveringPointer(DeviceId deviceId, const PointerProperties& pointer);
42     void removeHoveringPointer(DeviceId deviceId, int32_t pointerId);
43 
44     // Touching
45     bool hasTouchingPointer(DeviceId deviceId, int32_t pointerId) const;
46     bool hasTouchingPointers() const;
47     bool hasTouchingPointers(DeviceId deviceId) const;
48     std::vector<PointerProperties> getTouchingPointers(DeviceId deviceId) const;
49     android::base::Result<void> addTouchingPointers(DeviceId deviceId,
50                                                     const std::vector<PointerProperties>& pointers);
51     void removeTouchingPointer(DeviceId deviceId, int32_t pointerId);
52     void removeTouchingPointers(DeviceId deviceId, std::bitset<MAX_POINTER_ID + 1> pointers);
53     bool hasActiveStylus() const;
54     std::set<DeviceId> getTouchingDeviceIds() const;
55 
56     // Pilfering pointers
57     bool hasPilferingPointers(DeviceId deviceId) const;
58     void addPilferingPointers(DeviceId deviceId, std::bitset<MAX_POINTER_ID + 1> pointerIds);
59     void addPilferingPointer(DeviceId deviceId, int32_t pointerId);
60     std::bitset<MAX_POINTER_ID + 1> getPilferingPointers(DeviceId deviceId) const;
61     std::map<DeviceId, std::bitset<MAX_POINTER_ID + 1>> getPilferingPointers() const;
62 
63     // Down time
64     std::optional<nsecs_t> getDownTimeInTarget(DeviceId deviceId) const;
65     void trySetDownTimeInTarget(DeviceId deviceId, nsecs_t downTime);
66 
67     void removeAllTouchingPointersForDevice(DeviceId deviceId);
68     void removeAllHoveringPointersForDevice(DeviceId deviceId);
69     void clearHoveringPointers(DeviceId deviceId);
70     std::string dump() const;
71 
72 private:
73     struct DeviceState {
74         std::vector<PointerProperties> touchingPointers;
75         // The pointer ids of the pointers that this window is currently pilfering, by device
76         std::bitset<MAX_POINTER_ID + 1> pilferingPointerIds;
77         // Time at which the first action down occurred on this window, for each device
78         // NOTE: This is not initialized in case of HOVER entry/exit and DISPATCH_AS_OUTSIDE
79         // scenario.
80         std::optional<nsecs_t> downTimeInTarget;
81         std::vector<PointerProperties> hoveringPointers;
82 
hasPointersTouchedWindow::DeviceState83         bool hasPointers() const { return !touchingPointers.empty() || !hoveringPointers.empty(); };
84     };
85 
86     std::map<DeviceId, DeviceState> mDeviceStates;
87 
88     static std::string deviceStateToString(const TouchedWindow::DeviceState& state);
89 };
90 
91 std::ostream& operator<<(std::ostream& out, const TouchedWindow& window);
92 
93 } // namespace inputdispatcher
94 } // namespace android
95