1 /*
2 * Copyright (C) 2011 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 <type_traits>
18 #define LOG_TAG "InputWindow"
19 #define LOG_NDEBUG 0
20
21 #include <android-base/stringprintf.h>
22 #include <binder/Parcel.h>
23 #include <input/InputTransport.h>
24 #include <input/InputWindow.h>
25
26 #include <log/log.h>
27
28 namespace android {
29
30
31 // --- InputWindowInfo ---
addTouchableRegion(const Rect & region)32 void InputWindowInfo::addTouchableRegion(const Rect& region) {
33 touchableRegion.orSelf(region);
34 }
35
touchableRegionContainsPoint(int32_t x,int32_t y) const36 bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
37 return touchableRegion.contains(x,y);
38 }
39
frameContainsPoint(int32_t x,int32_t y) const40 bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
41 return x >= frameLeft && x < frameRight
42 && y >= frameTop && y < frameBottom;
43 }
44
supportsSplitTouch() const45 bool InputWindowInfo::supportsSplitTouch() const {
46 return flags.test(Flag::SPLIT_TOUCH);
47 }
48
overlaps(const InputWindowInfo * other) const49 bool InputWindowInfo::overlaps(const InputWindowInfo* other) const {
50 return frameLeft < other->frameRight && frameRight > other->frameLeft
51 && frameTop < other->frameBottom && frameBottom > other->frameTop;
52 }
53
operator ==(const InputWindowInfo & info) const54 bool InputWindowInfo::operator==(const InputWindowInfo& info) const {
55 return info.token == token && info.id == id && info.name == name && info.flags == flags &&
56 info.type == type && info.dispatchingTimeout == dispatchingTimeout &&
57 info.frameLeft == frameLeft && info.frameTop == frameTop &&
58 info.frameRight == frameRight && info.frameBottom == frameBottom &&
59 info.surfaceInset == surfaceInset && info.globalScaleFactor == globalScaleFactor &&
60 info.transform == transform && info.displayWidth == displayWidth &&
61 info.displayHeight == displayHeight &&
62 info.touchableRegion.hasSameRects(touchableRegion) && info.visible == visible &&
63 info.trustedOverlay == trustedOverlay && info.focusable == focusable &&
64 info.touchOcclusionMode == touchOcclusionMode && info.hasWallpaper == hasWallpaper &&
65 info.paused == paused && info.ownerPid == ownerPid && info.ownerUid == ownerUid &&
66 info.packageName == packageName && info.inputFeatures == inputFeatures &&
67 info.displayId == displayId && info.portalToDisplayId == portalToDisplayId &&
68 info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
69 info.applicationInfo == applicationInfo;
70 }
71
writeToParcel(android::Parcel * parcel) const72 status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const {
73 if (parcel == nullptr) {
74 ALOGE("%s: Null parcel", __func__);
75 return BAD_VALUE;
76 }
77 if (name.empty()) {
78 parcel->writeInt32(0);
79 return OK;
80 }
81 parcel->writeInt32(1);
82
83 // clang-format off
84 status_t status = parcel->writeStrongBinder(token) ?:
85 parcel->writeInt64(dispatchingTimeout.count()) ?:
86 parcel->writeInt32(id) ?:
87 parcel->writeUtf8AsUtf16(name) ?:
88 parcel->writeInt32(flags.get()) ?:
89 parcel->writeInt32(static_cast<std::underlying_type_t<InputWindowInfo::Type>>(type)) ?:
90 parcel->writeInt32(frameLeft) ?:
91 parcel->writeInt32(frameTop) ?:
92 parcel->writeInt32(frameRight) ?:
93 parcel->writeInt32(frameBottom) ?:
94 parcel->writeInt32(surfaceInset) ?:
95 parcel->writeFloat(globalScaleFactor) ?:
96 parcel->writeFloat(alpha) ?:
97 parcel->writeFloat(transform.dsdx()) ?:
98 parcel->writeFloat(transform.dtdx()) ?:
99 parcel->writeFloat(transform.tx()) ?:
100 parcel->writeFloat(transform.dtdy()) ?:
101 parcel->writeFloat(transform.dsdy()) ?:
102 parcel->writeFloat(transform.ty()) ?:
103 parcel->writeInt32(displayWidth) ?:
104 parcel->writeInt32(displayHeight) ?:
105 parcel->writeBool(visible) ?:
106 parcel->writeBool(focusable) ?:
107 parcel->writeBool(hasWallpaper) ?:
108 parcel->writeBool(paused) ?:
109 parcel->writeBool(trustedOverlay) ?:
110 parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
111 parcel->writeInt32(ownerPid) ?:
112 parcel->writeInt32(ownerUid) ?:
113 parcel->writeUtf8AsUtf16(packageName) ?:
114 parcel->writeInt32(inputFeatures.get()) ?:
115 parcel->writeInt32(displayId) ?:
116 parcel->writeInt32(portalToDisplayId) ?:
117 applicationInfo.writeToParcel(parcel) ?:
118 parcel->write(touchableRegion) ?:
119 parcel->writeBool(replaceTouchableRegionWithCrop) ?:
120 parcel->writeStrongBinder(touchableRegionCropHandle.promote());
121 // clang-format on
122 return status;
123 }
124
readFromParcel(const android::Parcel * parcel)125 status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) {
126 if (parcel == nullptr) {
127 ALOGE("%s: Null parcel", __func__);
128 return BAD_VALUE;
129 }
130 if (parcel->readInt32() == 0) {
131 return OK;
132 }
133
134 token = parcel->readStrongBinder();
135 dispatchingTimeout = static_cast<decltype(dispatchingTimeout)>(parcel->readInt64());
136 status_t status = parcel->readInt32(&id) ?: parcel->readUtf8FromUtf16(&name);
137 if (status != OK) {
138 return status;
139 }
140
141 flags = Flags<Flag>(parcel->readInt32());
142 type = static_cast<Type>(parcel->readInt32());
143 float dsdx, dtdx, tx, dtdy, dsdy, ty;
144 int32_t touchOcclusionModeInt;
145 // clang-format off
146 status = parcel->readInt32(&frameLeft) ?:
147 parcel->readInt32(&frameTop) ?:
148 parcel->readInt32(&frameRight) ?:
149 parcel->readInt32(&frameBottom) ?:
150 parcel->readInt32(&surfaceInset) ?:
151 parcel->readFloat(&globalScaleFactor) ?:
152 parcel->readFloat(&alpha) ?:
153 parcel->readFloat(&dsdx) ?:
154 parcel->readFloat(&dtdx) ?:
155 parcel->readFloat(&tx) ?:
156 parcel->readFloat(&dtdy) ?:
157 parcel->readFloat(&dsdy) ?:
158 parcel->readFloat(&ty) ?:
159 parcel->readInt32(&displayWidth) ?:
160 parcel->readInt32(&displayHeight) ?:
161 parcel->readBool(&visible) ?:
162 parcel->readBool(&focusable) ?:
163 parcel->readBool(&hasWallpaper) ?:
164 parcel->readBool(&paused) ?:
165 parcel->readBool(&trustedOverlay) ?:
166 parcel->readInt32(&touchOcclusionModeInt) ?:
167 parcel->readInt32(&ownerPid) ?:
168 parcel->readInt32(&ownerUid) ?:
169 parcel->readUtf8FromUtf16(&packageName);
170 // clang-format on
171
172 if (status != OK) {
173 return status;
174 }
175
176 touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
177
178 inputFeatures = Flags<Feature>(parcel->readInt32());
179 status = parcel->readInt32(&displayId) ?:
180 parcel->readInt32(&portalToDisplayId) ?:
181 applicationInfo.readFromParcel(parcel) ?:
182 parcel->read(touchableRegion) ?:
183 parcel->readBool(&replaceTouchableRegionWithCrop);
184
185 if (status != OK) {
186 return status;
187 }
188
189 touchableRegionCropHandle = parcel->readStrongBinder();
190 transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
191
192 return OK;
193 }
194
195 // --- InputWindowHandle ---
196
InputWindowHandle()197 InputWindowHandle::InputWindowHandle() {}
198
~InputWindowHandle()199 InputWindowHandle::~InputWindowHandle() {}
200
InputWindowHandle(const InputWindowHandle & other)201 InputWindowHandle::InputWindowHandle(const InputWindowHandle& other) : mInfo(other.mInfo) {}
202
InputWindowHandle(const InputWindowInfo & other)203 InputWindowHandle::InputWindowHandle(const InputWindowInfo& other) : mInfo(other) {}
204
writeToParcel(android::Parcel * parcel) const205 status_t InputWindowHandle::writeToParcel(android::Parcel* parcel) const {
206 return mInfo.writeToParcel(parcel);
207 }
208
readFromParcel(const android::Parcel * parcel)209 status_t InputWindowHandle::readFromParcel(const android::Parcel* parcel) {
210 return mInfo.readFromParcel(parcel);
211 }
212
releaseChannel()213 void InputWindowHandle::releaseChannel() {
214 mInfo.token.clear();
215 }
216
getToken() const217 sp<IBinder> InputWindowHandle::getToken() const {
218 return mInfo.token;
219 }
220
updateFrom(sp<InputWindowHandle> handle)221 void InputWindowHandle::updateFrom(sp<InputWindowHandle> handle) {
222 mInfo = handle->mInfo;
223 }
224 } // namespace android
225