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 #include "InputTarget.h"
18 
19 #include <android-base/stringprintf.h>
20 #include <inttypes.h>
21 #include <string>
22 
23 using android::base::StringPrintf;
24 
25 namespace android::inputdispatcher {
26 
dispatchModeToString(int32_t dispatchMode)27 std::string dispatchModeToString(int32_t dispatchMode) {
28     switch (dispatchMode) {
29         case InputTarget::FLAG_DISPATCH_AS_IS:
30             return "DISPATCH_AS_IS";
31         case InputTarget::FLAG_DISPATCH_AS_OUTSIDE:
32             return "DISPATCH_AS_OUTSIDE";
33         case InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER:
34             return "DISPATCH_AS_HOVER_ENTER";
35         case InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT:
36             return "DISPATCH_AS_HOVER_EXIT";
37         case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT:
38             return "DISPATCH_AS_SLIPPERY_EXIT";
39         case InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER:
40             return "DISPATCH_AS_SLIPPERY_ENTER";
41     }
42     return StringPrintf("%" PRId32, dispatchMode);
43 }
44 
addPointers(BitSet32 newPointerIds,float xOffset,float yOffset,float windowXScale,float windowYScale)45 void InputTarget::addPointers(BitSet32 newPointerIds, float xOffset, float yOffset,
46                               float windowXScale, float windowYScale) {
47     // The pointerIds can be empty, but still a valid InputTarget. This can happen for Monitors
48     // and non splittable windows since we will just use all the pointers from the input event.
49     if (newPointerIds.isEmpty()) {
50         setDefaultPointerInfo(xOffset, yOffset, windowXScale, windowYScale);
51         return;
52     }
53 
54     // Ensure that the new set of pointers doesn't overlap with the current set of pointers.
55     ALOG_ASSERT((pointerIds & newPointerIds) == 0);
56 
57     pointerIds |= newPointerIds;
58     while (!newPointerIds.isEmpty()) {
59         int32_t pointerId = newPointerIds.clearFirstMarkedBit();
60         pointerInfos[pointerId].xOffset = xOffset;
61         pointerInfos[pointerId].yOffset = yOffset;
62         pointerInfos[pointerId].windowXScale = windowXScale;
63         pointerInfos[pointerId].windowYScale = windowYScale;
64     }
65 }
66 
setDefaultPointerInfo(float xOffset,float yOffset,float windowXScale,float windowYScale)67 void InputTarget::setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
68                                         float windowYScale) {
69     pointerIds.clear();
70     pointerInfos[0].xOffset = xOffset;
71     pointerInfos[0].yOffset = yOffset;
72     pointerInfos[0].windowXScale = windowXScale;
73     pointerInfos[0].windowYScale = windowYScale;
74 }
75 
useDefaultPointerInfo() const76 bool InputTarget::useDefaultPointerInfo() const {
77     return pointerIds.isEmpty();
78 }
79 
getDefaultPointerInfo() const80 const PointerInfo& InputTarget::getDefaultPointerInfo() const {
81     return pointerInfos[0];
82 }
83 
getPointerInfoString() const84 std::string InputTarget::getPointerInfoString() const {
85     if (useDefaultPointerInfo()) {
86         const PointerInfo& pointerInfo = getDefaultPointerInfo();
87         return StringPrintf("xOffset=%.1f, yOffset=%.1f windowScaleFactor=(%.1f, %.1f)",
88                             pointerInfo.xOffset, pointerInfo.yOffset, pointerInfo.windowXScale,
89                             pointerInfo.windowYScale);
90     }
91 
92     std::string out;
93     for (uint32_t i = pointerIds.firstMarkedBit(); i <= pointerIds.lastMarkedBit(); i++) {
94         if (!pointerIds.hasBit(i)) {
95             continue;
96         }
97         out += StringPrintf("\n  pointerId %d: xOffset=%.1f, yOffset=%.1f "
98                             "windowScaleFactor=(%.1f, %.1f)",
99                             i, pointerInfos[i].xOffset, pointerInfos[i].yOffset,
100                             pointerInfos[i].windowXScale, pointerInfos[i].windowYScale);
101     }
102     return out;
103 }
104 } // namespace android::inputdispatcher
105