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