• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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