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 && info.isClone == isClone;
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 the flags that we use is 32 bits for writing into the parcel.
94 static_assert(sizeof(inputConfig) == 4u);
95
96 // clang-format off
97 status_t status = parcel->writeStrongBinder(token) ?:
98 parcel->writeInt64(dispatchingTimeout.count()) ?:
99 parcel->writeInt32(id) ?:
100 parcel->writeUtf8AsUtf16(name) ?:
101 parcel->writeInt32(layoutParamsFlags.get()) ?:
102 parcel->writeInt32(
103 static_cast<std::underlying_type_t<WindowInfo::Type>>(layoutParamsType)) ?:
104 parcel->writeInt32(frameLeft) ?:
105 parcel->writeInt32(frameTop) ?:
106 parcel->writeInt32(frameRight) ?:
107 parcel->writeInt32(frameBottom) ?:
108 parcel->writeInt32(surfaceInset) ?:
109 parcel->writeFloat(globalScaleFactor) ?:
110 parcel->writeFloat(alpha) ?:
111 parcel->writeFloat(transform.dsdx()) ?:
112 parcel->writeFloat(transform.dtdx()) ?:
113 parcel->writeFloat(transform.tx()) ?:
114 parcel->writeFloat(transform.dtdy()) ?:
115 parcel->writeFloat(transform.dsdy()) ?:
116 parcel->writeFloat(transform.ty()) ?:
117 parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
118 parcel->writeInt32(ownerPid) ?:
119 parcel->writeInt32(ownerUid) ?:
120 parcel->writeUtf8AsUtf16(packageName) ?:
121 parcel->writeInt32(inputConfig.get()) ?:
122 parcel->writeInt32(displayId) ?:
123 applicationInfo.writeToParcel(parcel) ?:
124 parcel->write(touchableRegion) ?:
125 parcel->writeBool(replaceTouchableRegionWithCrop) ?:
126 parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
127 parcel->writeStrongBinder(windowToken) ?:
128 parcel->writeBool(isClone);
129 // clang-format on
130 return status;
131 }
132
readFromParcel(const android::Parcel * parcel)133 status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
134 if (parcel == nullptr) {
135 ALOGE("%s: Null parcel", __func__);
136 return BAD_VALUE;
137 }
138 if (parcel->readInt32() == 0) {
139 return OK;
140 }
141
142 token = parcel->readStrongBinder();
143 dispatchingTimeout = static_cast<decltype(dispatchingTimeout)>(parcel->readInt64());
144 status_t status = parcel->readInt32(&id) ?: parcel->readUtf8FromUtf16(&name);
145 if (status != OK) {
146 return status;
147 }
148
149 float dsdx, dtdx, tx, dtdy, dsdy, ty;
150 int32_t lpFlags, lpType, touchOcclusionModeInt, inputConfigInt;
151 sp<IBinder> touchableRegionCropHandleSp;
152
153 // clang-format off
154 status = parcel->readInt32(&lpFlags) ?:
155 parcel->readInt32(&lpType) ?:
156 parcel->readInt32(&frameLeft) ?:
157 parcel->readInt32(&frameTop) ?:
158 parcel->readInt32(&frameRight) ?:
159 parcel->readInt32(&frameBottom) ?:
160 parcel->readInt32(&surfaceInset) ?:
161 parcel->readFloat(&globalScaleFactor) ?:
162 parcel->readFloat(&alpha) ?:
163 parcel->readFloat(&dsdx) ?:
164 parcel->readFloat(&dtdx) ?:
165 parcel->readFloat(&tx) ?:
166 parcel->readFloat(&dtdy) ?:
167 parcel->readFloat(&dsdy) ?:
168 parcel->readFloat(&ty) ?:
169 parcel->readInt32(&touchOcclusionModeInt) ?:
170 parcel->readInt32(&ownerPid) ?:
171 parcel->readInt32(&ownerUid) ?:
172 parcel->readUtf8FromUtf16(&packageName) ?:
173 parcel->readInt32(&inputConfigInt) ?:
174 parcel->readInt32(&displayId) ?:
175 applicationInfo.readFromParcel(parcel) ?:
176 parcel->read(touchableRegion) ?:
177 parcel->readBool(&replaceTouchableRegionWithCrop) ?:
178 parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
179 parcel->readNullableStrongBinder(&windowToken) ?:
180 parcel->readBool(&isClone);
181 // clang-format on
182
183 if (status != OK) {
184 return status;
185 }
186
187 layoutParamsFlags = ftl::Flags<Flag>(lpFlags);
188 layoutParamsType = static_cast<Type>(lpType);
189 transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
190 touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
191 inputConfig = ftl::Flags<InputConfig>(inputConfigInt);
192 touchableRegionCropHandle = touchableRegionCropHandleSp;
193
194 return OK;
195 }
196
WindowInfoHandle()197 WindowInfoHandle::WindowInfoHandle() {}
198
~WindowInfoHandle()199 WindowInfoHandle::~WindowInfoHandle() {}
200
WindowInfoHandle(const WindowInfoHandle & other)201 WindowInfoHandle::WindowInfoHandle(const WindowInfoHandle& other) : mInfo(other.mInfo) {}
202
WindowInfoHandle(const WindowInfo & other)203 WindowInfoHandle::WindowInfoHandle(const WindowInfo& other) : mInfo(other) {}
204
writeToParcel(android::Parcel * parcel) const205 status_t WindowInfoHandle::writeToParcel(android::Parcel* parcel) const {
206 return mInfo.writeToParcel(parcel);
207 }
208
readFromParcel(const android::Parcel * parcel)209 status_t WindowInfoHandle::readFromParcel(const android::Parcel* parcel) {
210 return mInfo.readFromParcel(parcel);
211 }
212
releaseChannel()213 void WindowInfoHandle::releaseChannel() {
214 mInfo.token.clear();
215 }
216
getToken() const217 sp<IBinder> WindowInfoHandle::getToken() const {
218 return mInfo.token;
219 }
220
updateFrom(sp<WindowInfoHandle> handle)221 void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) {
222 mInfo = handle->mInfo;
223 }
224 } // namespace android::gui
225