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 #define LOG_TAG "WindowInfo"
18 #define LOG_NDEBUG 0
19
20 #include <type_traits>
21
22 #include <binder/Parcel.h>
23 #include <gui/WindowInfo.h>
24
25 #include <log/log.h>
26
27 namespace android::gui {
28
setInputConfig(ftl::Flags<InputConfig> config,bool value)29 void WindowInfo::setInputConfig(ftl::Flags<InputConfig> config, bool value) {
30 if (value) {
31 inputConfig |= config;
32 return;
33 }
34 inputConfig &= ~config;
35 }
36
addTouchableRegion(const Rect & region)37 void WindowInfo::addTouchableRegion(const Rect& region) {
38 touchableRegion.orSelf(region);
39 }
40
touchableRegionContainsPoint(int32_t x,int32_t y) const41 bool WindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
42 return touchableRegion.contains(x, y);
43 }
44
frameContainsPoint(int32_t x,int32_t y) const45 bool WindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
46 return x >= frameLeft && x < frameRight && y >= frameTop && y < frameBottom;
47 }
48
supportsSplitTouch() const49 bool WindowInfo::supportsSplitTouch() const {
50 return !inputConfig.test(InputConfig::PREVENT_SPLITTING);
51 }
52
isSpy() const53 bool WindowInfo::isSpy() const {
54 return inputConfig.test(InputConfig::SPY);
55 }
56
interceptsStylus() const57 bool WindowInfo::interceptsStylus() const {
58 return inputConfig.test(InputConfig::INTERCEPTS_STYLUS);
59 }
60
overlaps(const WindowInfo * other) const61 bool WindowInfo::overlaps(const WindowInfo* other) const {
62 const bool nonEmpty = (frameRight - frameLeft > 0) || (frameBottom - frameTop > 0);
63 return nonEmpty && frameLeft < other->frameRight && frameRight > other->frameLeft &&
64 frameTop < other->frameBottom && frameBottom > other->frameTop;
65 }
66
operator ==(const WindowInfo & info) const67 bool WindowInfo::operator==(const WindowInfo& info) const {
68 return info.token == token && info.id == id && info.name == name &&
69 info.dispatchingTimeout == dispatchingTimeout && info.frameLeft == frameLeft &&
70 info.frameTop == frameTop && info.frameRight == frameRight &&
71 info.frameBottom == frameBottom && info.surfaceInset == surfaceInset &&
72 info.globalScaleFactor == globalScaleFactor && info.transform == transform &&
73 info.touchableRegion.hasSameRects(touchableRegion) &&
74 info.touchOcclusionMode == touchOcclusionMode && info.ownerPid == ownerPid &&
75 info.ownerUid == ownerUid && info.packageName == packageName &&
76 info.inputConfig == inputConfig && info.displayId == displayId &&
77 info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
78 info.applicationInfo == applicationInfo && info.layoutParamsType == layoutParamsType &&
79 info.layoutParamsFlags == layoutParamsFlags;
80 }
81
writeToParcel(android::Parcel * parcel) const82 status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
83 if (parcel == nullptr) {
84 ALOGE("%s: Null parcel", __func__);
85 return BAD_VALUE;
86 }
87 if (name.empty()) {
88 parcel->writeInt32(0);
89 return OK;
90 }
91 parcel->writeInt32(1);
92
93 // Ensure that the size of custom types are what we expect for writing into the parcel.
94 static_assert(sizeof(inputConfig) == 4u);
95 static_assert(sizeof(ownerPid.val()) == 4u);
96 static_assert(sizeof(ownerUid.val()) == 4u);
97
98 // clang-format off
99 status_t status = parcel->writeStrongBinder(token) ?:
100 parcel->writeInt64(dispatchingTimeout.count()) ?:
101 parcel->writeInt32(id) ?:
102 parcel->writeUtf8AsUtf16(name) ?:
103 parcel->writeInt32(layoutParamsFlags.get()) ?:
104 parcel->writeInt32(
105 static_cast<std::underlying_type_t<WindowInfo::Type>>(layoutParamsType)) ?:
106 parcel->writeInt32(frameLeft) ?:
107 parcel->writeInt32(frameTop) ?:
108 parcel->writeInt32(frameRight) ?:
109 parcel->writeInt32(frameBottom) ?:
110 parcel->writeInt32(surfaceInset) ?:
111 parcel->writeFloat(globalScaleFactor) ?:
112 parcel->writeFloat(alpha) ?:
113 parcel->writeFloat(transform.dsdx()) ?:
114 parcel->writeFloat(transform.dtdx()) ?:
115 parcel->writeFloat(transform.tx()) ?:
116 parcel->writeFloat(transform.dtdy()) ?:
117 parcel->writeFloat(transform.dsdy()) ?:
118 parcel->writeFloat(transform.ty()) ?:
119 parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
120 parcel->writeInt32(ownerPid.val()) ?:
121 parcel->writeInt32(ownerUid.val()) ?:
122 parcel->writeUtf8AsUtf16(packageName) ?:
123 parcel->writeInt32(inputConfig.get()) ?:
124 parcel->writeInt32(displayId) ?:
125 applicationInfo.writeToParcel(parcel) ?:
126 parcel->write(touchableRegion) ?:
127 parcel->writeBool(replaceTouchableRegionWithCrop) ?:
128 parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
129 parcel->writeStrongBinder(windowToken);
130 parcel->writeStrongBinder(focusTransferTarget);
131 // clang-format on
132 return status;
133 }
134
readFromParcel(const android::Parcel * parcel)135 status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
136 if (parcel == nullptr) {
137 ALOGE("%s: Null parcel", __func__);
138 return BAD_VALUE;
139 }
140 if (parcel->readInt32() == 0) {
141 return OK;
142 }
143
144 token = parcel->readStrongBinder();
145 dispatchingTimeout = static_cast<decltype(dispatchingTimeout)>(parcel->readInt64());
146 status_t status = parcel->readInt32(&id) ?: parcel->readUtf8FromUtf16(&name);
147 if (status != OK) {
148 return status;
149 }
150
151 float dsdx, dtdx, tx, dtdy, dsdy, ty;
152 int32_t lpFlags, lpType, touchOcclusionModeInt, inputConfigInt, ownerPidInt, ownerUidInt;
153 sp<IBinder> touchableRegionCropHandleSp;
154
155 // clang-format off
156 status = parcel->readInt32(&lpFlags) ?:
157 parcel->readInt32(&lpType) ?:
158 parcel->readInt32(&frameLeft) ?:
159 parcel->readInt32(&frameTop) ?:
160 parcel->readInt32(&frameRight) ?:
161 parcel->readInt32(&frameBottom) ?:
162 parcel->readInt32(&surfaceInset) ?:
163 parcel->readFloat(&globalScaleFactor) ?:
164 parcel->readFloat(&alpha) ?:
165 parcel->readFloat(&dsdx) ?:
166 parcel->readFloat(&dtdx) ?:
167 parcel->readFloat(&tx) ?:
168 parcel->readFloat(&dtdy) ?:
169 parcel->readFloat(&dsdy) ?:
170 parcel->readFloat(&ty) ?:
171 parcel->readInt32(&touchOcclusionModeInt) ?:
172 parcel->readInt32(&ownerPidInt) ?:
173 parcel->readInt32(&ownerUidInt) ?:
174 parcel->readUtf8FromUtf16(&packageName) ?:
175 parcel->readInt32(&inputConfigInt) ?:
176 parcel->readInt32(&displayId) ?:
177 applicationInfo.readFromParcel(parcel) ?:
178 parcel->read(touchableRegion) ?:
179 parcel->readBool(&replaceTouchableRegionWithCrop) ?:
180 parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
181 parcel->readNullableStrongBinder(&windowToken) ?:
182 parcel->readNullableStrongBinder(&focusTransferTarget);
183
184 // clang-format on
185
186 if (status != OK) {
187 return status;
188 }
189
190 layoutParamsFlags = ftl::Flags<Flag>(lpFlags);
191 layoutParamsType = static_cast<Type>(lpType);
192 transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
193 touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
194 inputConfig = ftl::Flags<InputConfig>(inputConfigInt);
195 ownerPid = Pid{ownerPidInt};
196 ownerUid = Uid{static_cast<uid_t>(ownerUidInt)};
197 touchableRegionCropHandle = touchableRegionCropHandleSp;
198
199 return OK;
200 }
201
WindowInfoHandle()202 WindowInfoHandle::WindowInfoHandle() {}
203
~WindowInfoHandle()204 WindowInfoHandle::~WindowInfoHandle() {}
205
WindowInfoHandle(const WindowInfoHandle & other)206 WindowInfoHandle::WindowInfoHandle(const WindowInfoHandle& other) : mInfo(other.mInfo) {}
207
WindowInfoHandle(const WindowInfo & other)208 WindowInfoHandle::WindowInfoHandle(const WindowInfo& other) : mInfo(other) {}
209
writeToParcel(android::Parcel * parcel) const210 status_t WindowInfoHandle::writeToParcel(android::Parcel* parcel) const {
211 return mInfo.writeToParcel(parcel);
212 }
213
readFromParcel(const android::Parcel * parcel)214 status_t WindowInfoHandle::readFromParcel(const android::Parcel* parcel) {
215 return mInfo.readFromParcel(parcel);
216 }
217
releaseChannel()218 void WindowInfoHandle::releaseChannel() {
219 mInfo.token.clear();
220 }
221
getToken() const222 sp<IBinder> WindowInfoHandle::getToken() const {
223 return mInfo.token;
224 }
225
updateFrom(sp<WindowInfoHandle> handle)226 void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) {
227 mInfo = handle->mInfo;
228 }
229 } // namespace android::gui
230