blob: c1ef48ec97963b0f880a6260b55cb446cb464ea8 [file] [log] [blame]
chaviw8ffc7b82020-08-18 11:25:37 -07001/*
2 * Copyright (C) 2020 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// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Huihong Luo05539a12022-02-23 10:29:40 -080021#include <android/gui/ISurfaceComposer.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000022#include <gtest/gtest.h>
Huihong Luo3bdef862022-03-03 11:57:19 -080023#include <gui/AidlStatusUtil.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000024#include <gui/Surface.h>
25#include <gui/SurfaceComposerClient.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000026#include <private/android_filesystem_config.h>
Huihong Luo05539a12022-02-23 10:29:40 -080027#include <private/gui/ComposerServiceAIDL.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010028#include <ui/DisplayMode.h>
Marin Shalamanov228f46b2021-01-28 21:11:45 +010029#include <ui/DynamicDisplayInfo.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000030#include <utils/String8.h>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080031#include <functional>
chaviw8ffc7b82020-08-18 11:25:37 -070032#include "utils/ScreenshotUtils.h"
Chavi Weingartenc78f53c2023-04-14 18:50:53 +000033#include "utils/WindowInfosListenerUtils.h"
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080034
Ana Krulec13be8ad2018-08-21 02:43:56 +000035namespace android {
36
37using Transaction = SurfaceComposerClient::Transaction;
Huihong Luo3bdef862022-03-03 11:57:19 -080038using gui::aidl_utils::statusTFromBinderStatus;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -080039using ui::ColorMode;
Ana Krulec13be8ad2018-08-21 02:43:56 +000040
41namespace {
42const String8 DISPLAY_NAME("Credentials Display Test");
43const String8 SURFACE_NAME("Test Surface Name");
Ana Krulec13be8ad2018-08-21 02:43:56 +000044} // namespace
45
46/**
47 * This class tests the CheckCredentials method in SurfaceFlinger.
48 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
49 * return anything meaningful.
50 */
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080051
52// TODO(b/129481165): remove the #pragma below and fix conversion issues
53#pragma clang diagnostic push
54#pragma clang diagnostic ignored "-Wconversion"
Ana Krulec13be8ad2018-08-21 02:43:56 +000055class CredentialsTest : public ::testing::Test {
56protected:
Chavi Weingartenc73be482022-08-31 16:55:07 +000057 void SetUp() override { ASSERT_NO_FATAL_FAILURE(initClient()); }
Ana Krulec13be8ad2018-08-21 02:43:56 +000058
59 void TearDown() override {
60 mComposerClient->dispose();
61 mBGSurfaceControl.clear();
62 mComposerClient.clear();
Ana Krulec13be8ad2018-08-21 02:43:56 +000063 }
64
65 sp<IBinder> mDisplay;
66 sp<IBinder> mVirtualDisplay;
67 sp<SurfaceComposerClient> mComposerClient;
68 sp<SurfaceControl> mBGSurfaceControl;
69 sp<SurfaceControl> mVirtualSurfaceControl;
70
71 void initClient() {
Ady Abrahamd11bade2022-08-01 16:18:03 -070072 mComposerClient = sp<SurfaceComposerClient>::make();
Ana Krulec13be8ad2018-08-21 02:43:56 +000073 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
74 }
75
Huihong Luo31b5ac22022-08-15 20:38:10 -070076 static sp<IBinder> getFirstDisplayToken() {
77 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
78 if (ids.empty()) {
79 return nullptr;
80 }
81
82 return SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
83 }
84
Sally Qi6bb12822022-10-05 11:42:30 -070085 static std::optional<uint64_t> getFirstDisplayId() {
86 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
87 if (ids.empty()) {
88 return std::nullopt;
89 }
90
91 return ids.front().value;
92 }
93
Ana Krulec13be8ad2018-08-21 02:43:56 +000094 void setupBackgroundSurface() {
Huihong Luo31b5ac22022-08-15 20:38:10 -070095 mDisplay = getFirstDisplayToken();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080096 ASSERT_FALSE(mDisplay == nullptr);
97
Marin Shalamanova7fe3042021-01-29 21:02:08 +010098 ui::DisplayMode mode;
99 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000100
101 // Background surface
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100102 mBGSurfaceControl = mComposerClient->createSurface(SURFACE_NAME, mode.resolution.getWidth(),
103 mode.resolution.getHeight(),
104 PIXEL_FORMAT_RGBA_8888, 0);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000105 ASSERT_TRUE(mBGSurfaceControl != nullptr);
106 ASSERT_TRUE(mBGSurfaceControl->isValid());
107
108 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700109 t.setDisplayLayerStack(mDisplay, ui::DEFAULT_LAYER_STACK);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000110 ASSERT_EQ(NO_ERROR,
111 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
112 }
113
Ana Krulec13be8ad2018-08-21 02:43:56 +0000114 /**
Ana Krulec13be8ad2018-08-21 02:43:56 +0000115 * Template function the check a condition for different types of users: root
116 * graphics, system, and non-supported user. Root, graphics, and system should
117 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
118 */
119 template <typename T>
120 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
121 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000122 {
123 UIDFaker f(AID_SYSTEM);
124 ASSERT_EQ(privilegedValue, condition());
125 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000126
127 // Check as a Graphics user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000128 {
129 UIDFaker f(AID_GRAPHICS);
130 ASSERT_EQ(privilegedValue, condition());
131 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000132
133 // Check as a system user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000134 {
135 UIDFaker f(AID_SYSTEM);
136 ASSERT_EQ(privilegedValue, condition());
137 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000138
139 // Check as a non-supported user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000140 {
141 UIDFaker f(AID_BIN);
142 ASSERT_EQ(unprivilegedValue, condition());
143 }
chaviwd4a61642020-09-01 14:53:46 -0700144
145 // Check as shell since shell has some additional permissions
Chavi Weingartenc73be482022-08-31 16:55:07 +0000146 {
147 UIDFaker f(AID_SHELL);
148 ASSERT_EQ(privilegedValue, condition());
149 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000150 }
151};
152
153TEST_F(CredentialsTest, ClientInitTest) {
154 // Root can init can init the client.
155 ASSERT_NO_FATAL_FAILURE(initClient());
156
157 // Graphics can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000158 {
159 UIDFaker f(AID_GRAPHICS);
160 ASSERT_NO_FATAL_FAILURE(initClient());
161 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000162
163 // System can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000164 {
165 UIDFaker f(AID_SYSTEM);
166 ASSERT_NO_FATAL_FAILURE(initClient());
167 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000168
Robert Carrb89ea9d2018-12-10 13:01:14 -0800169 // Anyone else can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000170 {
171 UIDFaker f(AID_BIN);
172 mComposerClient = sp<SurfaceComposerClient>::make();
173 ASSERT_NO_FATAL_FAILURE(initClient());
174 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000175}
176
177TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700178 std::function<bool()> condition = [] { return getFirstDisplayToken() != nullptr; };
Ana Krulec13be8ad2018-08-21 02:43:56 +0000179 // Anyone can access display information.
Sally Qi6bb12822022-10-05 11:42:30 -0700180 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000181}
182
183TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
184 // The following methods are tested with a UID that is not root, graphics,
185 // or system, to show that anyone can access them.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000186 UIDFaker f(AID_BIN);
Sally Qi6bb12822022-10-05 11:42:30 -0700187 const auto id = getFirstDisplayId();
188 ASSERT_TRUE(id);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100189 ui::DynamicDisplayInfo info;
Sally Qi6bb12822022-10-05 11:42:30 -0700190 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfoFromId(*id, &info));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000191}
192
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100193TEST_F(CredentialsTest, GetDynamicDisplayInfoTest) {
Sally Qi6bb12822022-10-05 11:42:30 -0700194 const auto id = getFirstDisplayId();
195 ASSERT_TRUE(id);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000196 std::function<status_t()> condition = [=]() {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100197 ui::DynamicDisplayInfo info;
Sally Qi6bb12822022-10-05 11:42:30 -0700198 return SurfaceComposerClient::getDynamicDisplayInfoFromId(*id, &info);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000199 };
200 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
201}
202
Daniel Solomon42d04562019-01-20 21:03:19 -0800203TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700204 const auto display = getFirstDisplayToken();
Daniel Solomon42d04562019-01-20 21:03:19 -0800205 std::function<status_t()> condition = [=]() {
206 ui::DisplayPrimaries primaries;
207 return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries);
208 };
209 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
210}
211
Steven Thomasa87ed452020-01-03 16:10:05 -0800212TEST_F(CredentialsTest, SetDesiredDisplayConfigsTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700213 const auto display = getFirstDisplayToken();
Ady Abraham285f8c12022-10-11 17:12:14 -0700214 gui::DisplayModeSpecs specs;
215 status_t res = SurfaceComposerClient::getDesiredDisplayModeSpecs(display, &specs);
Steven Thomasa87ed452020-01-03 16:10:05 -0800216 ASSERT_EQ(res, NO_ERROR);
Ady Abraham285f8c12022-10-11 17:12:14 -0700217 gui::DisplayModeSpecs setSpecs;
Ana Krulec13be8ad2018-08-21 02:43:56 +0000218 std::function<status_t()> condition = [=]() {
Ady Abraham285f8c12022-10-11 17:12:14 -0700219 return SurfaceComposerClient::setDesiredDisplayModeSpecs(display, specs);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000220 };
221 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
222}
223
224TEST_F(CredentialsTest, SetActiveColorModeTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700225 const auto display = getFirstDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000226 std::function<status_t()> condition = [=]() {
227 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
228 };
229 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
230}
231
Ana Krulec13be8ad2018-08-21 02:43:56 +0000232TEST_F(CredentialsTest, CreateDisplayTest) {
chaviwd4a61642020-09-01 14:53:46 -0700233 // Only graphics and system processes can create a secure display.
Ana Krulec13be8ad2018-08-21 02:43:56 +0000234 std::function<bool()> condition = [=]() {
235 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
236 return testDisplay.get() != nullptr;
237 };
chaviwd4a61642020-09-01 14:53:46 -0700238
239 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000240 {
241 UIDFaker f(AID_ROOT);
Patrick Williamse58a92b2024-02-29 14:52:25 -0600242 ASSERT_TRUE(condition());
Chavi Weingartenc73be482022-08-31 16:55:07 +0000243 }
chaviwd4a61642020-09-01 14:53:46 -0700244
245 // Check as a Graphics user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000246 {
247 UIDFaker f(AID_GRAPHICS);
248 ASSERT_TRUE(condition());
249 }
chaviwd4a61642020-09-01 14:53:46 -0700250
251 // Check as a system user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000252 {
253 UIDFaker f(AID_SYSTEM);
254 ASSERT_TRUE(condition());
255 }
chaviwd4a61642020-09-01 14:53:46 -0700256
257 // Check as a non-supported user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000258 {
259 UIDFaker f(AID_BIN);
260 ASSERT_FALSE(condition());
261 }
chaviwd4a61642020-09-01 14:53:46 -0700262
263 // Check as shell since shell has some additional permissions
Chavi Weingartenc73be482022-08-31 16:55:07 +0000264 {
265 UIDFaker f(AID_SHELL);
266 ASSERT_FALSE(condition());
267 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000268
269 condition = [=]() {
270 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
271 return testDisplay.get() != nullptr;
272 };
273 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
274}
275
Ana Krulec13be8ad2018-08-21 02:43:56 +0000276TEST_F(CredentialsTest, CaptureLayersTest) {
277 setupBackgroundSurface();
278 sp<GraphicBuffer> outBuffer;
279 std::function<status_t()> condition = [=]() {
chaviw26c52482020-07-28 16:25:52 -0700280 LayerCaptureArgs captureArgs;
281 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
282 captureArgs.sourceCrop = {0, 0, 1, 1};
283
284 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700285 return ScreenCapture::captureLayers(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000286 };
287 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
288}
289
290/**
291 * The following tests are for methods accessible directly through SurfaceFlinger.
292 */
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800293
294TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700295 const auto display = getFirstDisplayToken();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800296 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800297 bool result = false;
298 status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result);
299 ASSERT_EQ(NO_ERROR, error);
300 bool hasWideColorMode = false;
Sally Qi6bb12822022-10-05 11:42:30 -0700301 const auto id = getFirstDisplayId();
302 ASSERT_TRUE(id);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100303 ui::DynamicDisplayInfo info;
Sally Qi6bb12822022-10-05 11:42:30 -0700304 SurfaceComposerClient::getDynamicDisplayInfoFromId(*id, &info);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100305 const auto& colorModes = info.supportedColorModes;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800306 for (ColorMode colorMode : colorModes) {
307 switch (colorMode) {
308 case ColorMode::DISPLAY_P3:
309 case ColorMode::ADOBE_RGB:
310 case ColorMode::DCI_P3:
311 hasWideColorMode = true;
312 break;
313 default:
314 break;
315 }
316 }
317 ASSERT_EQ(hasWideColorMode, result);
318}
319
320TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700321 const auto display = getFirstDisplayToken();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800322 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800323 std::function<status_t()> condition = [=]() {
324 bool result = false;
325 return SurfaceComposerClient::isWideColorDisplay(display, &result);
326 };
327 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
328}
329
Peiyong Lind1fedb42019-03-11 17:48:41 -0700330TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
Sally Qi6bb12822022-10-05 11:42:30 -0700331 const auto id = getFirstDisplayId();
332 ASSERT_TRUE(id);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100333 ui::DynamicDisplayInfo info;
Sally Qi6bb12822022-10-05 11:42:30 -0700334 SurfaceComposerClient::getDynamicDisplayInfoFromId(*id, &info);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100335 ColorMode colorMode = info.activeColorMode;
Peiyong Lind1fedb42019-03-11 17:48:41 -0700336 ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
337}
338
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000339TEST_F(CredentialsTest, TransactionPermissionTest) {
340 WindowInfosListenerUtils windowInfosListenerUtils;
341 std::string name = "Test Layer";
342 sp<IBinder> token = sp<BBinder>::make();
343 WindowInfo windowInfo;
344 windowInfo.name = name;
345 windowInfo.token = token;
346 sp<SurfaceControl> surfaceControl =
347 mComposerClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
348 ISurfaceComposerClient::eFXSurfaceBufferState);
349 const Rect crop(0, 0, 100, 100);
350 {
351 UIDFaker f(AID_SYSTEM);
352 Transaction()
353 .setLayerStack(surfaceControl, ui::DEFAULT_LAYER_STACK)
354 .show(surfaceControl)
355 .setLayer(surfaceControl, INT32_MAX - 1)
356 .setCrop(surfaceControl, crop)
357 .setInputWindowInfo(surfaceControl, windowInfo)
358 .apply();
359 }
360
Patrick Williams04e41762024-04-23 19:05:38 -0500361 // Attempt to set a trusted overlay from a non-privileged process. This should fail silently.
362 {
363 UIDFaker f{AID_BIN};
364 Transaction().setTrustedOverlay(surfaceControl, true).apply(/*synchronous=*/true);
365 }
366
367 // Verify that the layer was not made a trusted overlay.
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000368 {
369 UIDFaker f(AID_SYSTEM);
370 auto windowIsPresentAndNotTrusted = [&](const std::vector<WindowInfo>& windowInfos) {
371 auto foundWindowInfo =
372 WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos);
373 if (!foundWindowInfo) {
374 return false;
375 }
376 return !foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY);
377 };
Patrick Williams04e41762024-04-23 19:05:38 -0500378 ASSERT_TRUE(
379 windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndNotTrusted));
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000380 }
381
Patrick Williams04e41762024-04-23 19:05:38 -0500382 // Verify that privileged processes are able to set trusted overlays.
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000383 {
384 UIDFaker f(AID_SYSTEM);
Patrick Williams04e41762024-04-23 19:05:38 -0500385 Transaction().setTrustedOverlay(surfaceControl, true).apply(/*synchronous=*/true);
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000386 auto windowIsPresentAndTrusted = [&](const std::vector<WindowInfo>& windowInfos) {
387 auto foundWindowInfo =
388 WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos);
389 if (!foundWindowInfo) {
390 return false;
391 }
392 return foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY);
393 };
Patrick Williams04e41762024-04-23 19:05:38 -0500394 ASSERT_TRUE(
395 windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndTrusted));
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000396 }
397}
398
Ana Krulec13be8ad2018-08-21 02:43:56 +0000399} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800400
401// TODO(b/129481165): remove the #pragma below and fix conversion issues
402#pragma clang diagnostic pop // ignored "-Wconversion"