blob: 4f04934d34776ced04d640ced4de4167805ffaaf [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/LayerDebugInfo.h>
25#include <gui/Surface.h>
26#include <gui/SurfaceComposerClient.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000027#include <private/android_filesystem_config.h>
Huihong Luo05539a12022-02-23 10:29:40 -080028#include <private/gui/ComposerServiceAIDL.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010029#include <ui/DisplayMode.h>
Marin Shalamanov228f46b2021-01-28 21:11:45 +010030#include <ui/DynamicDisplayInfo.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000031#include <utils/String8.h>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080032#include <functional>
chaviw8ffc7b82020-08-18 11:25:37 -070033#include "utils/ScreenshotUtils.h"
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080034
Ana Krulec13be8ad2018-08-21 02:43:56 +000035namespace android {
36
37using Transaction = SurfaceComposerClient::Transaction;
Huihong Luo05539a12022-02-23 10:29:40 -080038using gui::LayerDebugInfo;
Huihong Luo3bdef862022-03-03 11:57:19 -080039using gui::aidl_utils::statusTFromBinderStatus;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -080040using ui::ColorMode;
Ana Krulec13be8ad2018-08-21 02:43:56 +000041
42namespace {
43const String8 DISPLAY_NAME("Credentials Display Test");
44const String8 SURFACE_NAME("Test Surface Name");
Ana Krulec13be8ad2018-08-21 02:43:56 +000045} // namespace
46
47/**
48 * This class tests the CheckCredentials method in SurfaceFlinger.
49 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
50 * return anything meaningful.
51 */
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080052
53// TODO(b/129481165): remove the #pragma below and fix conversion issues
54#pragma clang diagnostic push
55#pragma clang diagnostic ignored "-Wconversion"
Ana Krulec13be8ad2018-08-21 02:43:56 +000056class CredentialsTest : public ::testing::Test {
57protected:
Chavi Weingartenc73be482022-08-31 16:55:07 +000058 void SetUp() override { ASSERT_NO_FATAL_FAILURE(initClient()); }
Ana Krulec13be8ad2018-08-21 02:43:56 +000059
60 void TearDown() override {
61 mComposerClient->dispose();
62 mBGSurfaceControl.clear();
63 mComposerClient.clear();
Ana Krulec13be8ad2018-08-21 02:43:56 +000064 }
65
66 sp<IBinder> mDisplay;
67 sp<IBinder> mVirtualDisplay;
68 sp<SurfaceComposerClient> mComposerClient;
69 sp<SurfaceControl> mBGSurfaceControl;
70 sp<SurfaceControl> mVirtualSurfaceControl;
71
72 void initClient() {
Ady Abrahamd11bade2022-08-01 16:18:03 -070073 mComposerClient = sp<SurfaceComposerClient>::make();
Ana Krulec13be8ad2018-08-21 02:43:56 +000074 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
75 }
76
Huihong Luo31b5ac22022-08-15 20:38:10 -070077 static sp<IBinder> getFirstDisplayToken() {
78 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
79 if (ids.empty()) {
80 return nullptr;
81 }
82
83 return SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
84 }
85
Ana Krulec13be8ad2018-08-21 02:43:56 +000086 void setupBackgroundSurface() {
Huihong Luo31b5ac22022-08-15 20:38:10 -070087 mDisplay = getFirstDisplayToken();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080088 ASSERT_FALSE(mDisplay == nullptr);
89
Marin Shalamanova7fe3042021-01-29 21:02:08 +010090 ui::DisplayMode mode;
91 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +000092
93 // Background surface
Marin Shalamanova7fe3042021-01-29 21:02:08 +010094 mBGSurfaceControl = mComposerClient->createSurface(SURFACE_NAME, mode.resolution.getWidth(),
95 mode.resolution.getHeight(),
96 PIXEL_FORMAT_RGBA_8888, 0);
Ana Krulec13be8ad2018-08-21 02:43:56 +000097 ASSERT_TRUE(mBGSurfaceControl != nullptr);
98 ASSERT_TRUE(mBGSurfaceControl->isValid());
99
100 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700101 t.setDisplayLayerStack(mDisplay, ui::DEFAULT_LAYER_STACK);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000102 ASSERT_EQ(NO_ERROR,
103 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
104 }
105
Ana Krulec13be8ad2018-08-21 02:43:56 +0000106 /**
Ana Krulec13be8ad2018-08-21 02:43:56 +0000107 * Template function the check a condition for different types of users: root
108 * graphics, system, and non-supported user. Root, graphics, and system should
109 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
110 */
111 template <typename T>
112 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
113 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000114 {
115 UIDFaker f(AID_SYSTEM);
116 ASSERT_EQ(privilegedValue, condition());
117 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000118
119 // Check as a Graphics user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000120 {
121 UIDFaker f(AID_GRAPHICS);
122 ASSERT_EQ(privilegedValue, condition());
123 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000124
125 // Check as a system user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000126 {
127 UIDFaker f(AID_SYSTEM);
128 ASSERT_EQ(privilegedValue, condition());
129 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000130
131 // Check as a non-supported user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000132 {
133 UIDFaker f(AID_BIN);
134 ASSERT_EQ(unprivilegedValue, condition());
135 }
chaviwd4a61642020-09-01 14:53:46 -0700136
137 // Check as shell since shell has some additional permissions
Chavi Weingartenc73be482022-08-31 16:55:07 +0000138 {
139 UIDFaker f(AID_SHELL);
140 ASSERT_EQ(privilegedValue, condition());
141 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000142 }
143};
144
145TEST_F(CredentialsTest, ClientInitTest) {
146 // Root can init can init the client.
147 ASSERT_NO_FATAL_FAILURE(initClient());
148
149 // Graphics can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000150 {
151 UIDFaker f(AID_GRAPHICS);
152 ASSERT_NO_FATAL_FAILURE(initClient());
153 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000154
155 // System can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000156 {
157 UIDFaker f(AID_SYSTEM);
158 ASSERT_NO_FATAL_FAILURE(initClient());
159 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000160
Robert Carrb89ea9d2018-12-10 13:01:14 -0800161 // Anyone else can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000162 {
163 UIDFaker f(AID_BIN);
164 mComposerClient = sp<SurfaceComposerClient>::make();
165 ASSERT_NO_FATAL_FAILURE(initClient());
166 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000167}
168
169TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700170 std::function<bool()> condition = [] { return getFirstDisplayToken() != nullptr; };
Ana Krulec13be8ad2018-08-21 02:43:56 +0000171 // Anyone can access display information.
172 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
173}
174
175TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
176 // The following methods are tested with a UID that is not root, graphics,
177 // or system, to show that anyone can access them.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000178 UIDFaker f(AID_BIN);
Huihong Luo31b5ac22022-08-15 20:38:10 -0700179 const auto display = getFirstDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000180 ASSERT_TRUE(display != nullptr);
181
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100182 ui::DisplayMode mode;
183 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000184
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100185 Vector<ui::DisplayMode> modes;
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100186 ui::DynamicDisplayInfo info;
187 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000188}
189
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100190TEST_F(CredentialsTest, GetDynamicDisplayInfoTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700191 const auto display = getFirstDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000192 std::function<status_t()> condition = [=]() {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100193 ui::DynamicDisplayInfo info;
194 return SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000195 };
196 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
197}
198
Daniel Solomon42d04562019-01-20 21:03:19 -0800199TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700200 const auto display = getFirstDisplayToken();
Daniel Solomon42d04562019-01-20 21:03:19 -0800201 std::function<status_t()> condition = [=]() {
202 ui::DisplayPrimaries primaries;
203 return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries);
204 };
205 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
206}
207
Steven Thomasa87ed452020-01-03 16:10:05 -0800208TEST_F(CredentialsTest, SetDesiredDisplayConfigsTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700209 const auto display = getFirstDisplayToken();
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100210 ui::DisplayModeId defaultMode;
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200211 bool allowGroupSwitching;
Steven Thomasf734df42020-04-13 21:09:28 -0700212 float primaryFpsMin;
213 float primaryFpsMax;
214 float appRequestFpsMin;
215 float appRequestFpsMax;
216 status_t res =
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100217 SurfaceComposerClient::getDesiredDisplayModeSpecs(display, &defaultMode,
218 &allowGroupSwitching, &primaryFpsMin,
219 &primaryFpsMax, &appRequestFpsMin,
220 &appRequestFpsMax);
Steven Thomasa87ed452020-01-03 16:10:05 -0800221 ASSERT_EQ(res, NO_ERROR);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000222 std::function<status_t()> condition = [=]() {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100223 return SurfaceComposerClient::setDesiredDisplayModeSpecs(display, defaultMode,
224 allowGroupSwitching, primaryFpsMin,
225 primaryFpsMax, appRequestFpsMin,
226 appRequestFpsMax);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000227 };
228 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
229}
230
231TEST_F(CredentialsTest, SetActiveColorModeTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700232 const auto display = getFirstDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000233 std::function<status_t()> condition = [=]() {
234 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
235 };
236 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
237}
238
Ana Krulec13be8ad2018-08-21 02:43:56 +0000239TEST_F(CredentialsTest, CreateDisplayTest) {
chaviwd4a61642020-09-01 14:53:46 -0700240 // Only graphics and system processes can create a secure display.
Ana Krulec13be8ad2018-08-21 02:43:56 +0000241 std::function<bool()> condition = [=]() {
242 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
243 return testDisplay.get() != nullptr;
244 };
chaviwd4a61642020-09-01 14:53:46 -0700245
246 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000247 {
248 UIDFaker f(AID_ROOT);
249 ASSERT_FALSE(condition());
250 }
chaviwd4a61642020-09-01 14:53:46 -0700251
252 // Check as a Graphics user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000253 {
254 UIDFaker f(AID_GRAPHICS);
255 ASSERT_TRUE(condition());
256 }
chaviwd4a61642020-09-01 14:53:46 -0700257
258 // Check as a system user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000259 {
260 UIDFaker f(AID_SYSTEM);
261 ASSERT_TRUE(condition());
262 }
chaviwd4a61642020-09-01 14:53:46 -0700263
264 // Check as a non-supported user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000265 {
266 UIDFaker f(AID_BIN);
267 ASSERT_FALSE(condition());
268 }
chaviwd4a61642020-09-01 14:53:46 -0700269
270 // Check as shell since shell has some additional permissions
Chavi Weingartenc73be482022-08-31 16:55:07 +0000271 {
272 UIDFaker f(AID_SHELL);
273 ASSERT_FALSE(condition());
274 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000275
276 condition = [=]() {
277 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
278 return testDisplay.get() != nullptr;
279 };
280 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
281}
282
Ana Krulec13be8ad2018-08-21 02:43:56 +0000283TEST_F(CredentialsTest, CaptureTest) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700284 const auto display = getFirstDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000285 std::function<status_t()> condition = [=]() {
286 sp<GraphicBuffer> outBuffer;
chaviw690db382020-07-27 16:46:46 -0700287 DisplayCaptureArgs captureArgs;
288 captureArgs.displayToken = display;
289 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700290 return ScreenCapture::captureDisplay(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000291 };
292 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
293}
294
295TEST_F(CredentialsTest, CaptureLayersTest) {
296 setupBackgroundSurface();
297 sp<GraphicBuffer> outBuffer;
298 std::function<status_t()> condition = [=]() {
chaviw26c52482020-07-28 16:25:52 -0700299 LayerCaptureArgs captureArgs;
300 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
301 captureArgs.sourceCrop = {0, 0, 1, 1};
302
303 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700304 return ScreenCapture::captureLayers(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000305 };
306 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
307}
308
309/**
310 * The following tests are for methods accessible directly through SurfaceFlinger.
311 */
Ana Krulec13be8ad2018-08-21 02:43:56 +0000312TEST_F(CredentialsTest, GetLayerDebugInfo) {
313 setupBackgroundSurface();
Huihong Luo05539a12022-02-23 10:29:40 -0800314 sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
Ana Krulec13be8ad2018-08-21 02:43:56 +0000315
316 // Historically, only root and shell can access the getLayerDebugInfo which
317 // is called when we call dumpsys. I don't see a reason why we should change this.
318 std::vector<LayerDebugInfo> outLayers;
Chavi Weingartenc73be482022-08-31 16:55:07 +0000319 binder::Status status = binder::Status::ok();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000320 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000321 {
322 UIDFaker f(AID_ROOT);
323 status = sf->getLayerDebugInfo(&outLayers);
324 ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
325 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000326
327 // Check as a shell.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000328 {
329 UIDFaker f(AID_SHELL);
330 status = sf->getLayerDebugInfo(&outLayers);
331 ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
332 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000333
334 // Check as anyone else.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000335 {
336 UIDFaker f(AID_BIN);
337 status = sf->getLayerDebugInfo(&outLayers);
338 ASSERT_EQ(PERMISSION_DENIED, statusTFromBinderStatus(status));
339 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000340}
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800341
342TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700343 const auto display = getFirstDisplayToken();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800344 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800345 bool result = false;
346 status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result);
347 ASSERT_EQ(NO_ERROR, error);
348 bool hasWideColorMode = false;
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100349 ui::DynamicDisplayInfo info;
350 SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
351 const auto& colorModes = info.supportedColorModes;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800352 for (ColorMode colorMode : colorModes) {
353 switch (colorMode) {
354 case ColorMode::DISPLAY_P3:
355 case ColorMode::ADOBE_RGB:
356 case ColorMode::DCI_P3:
357 hasWideColorMode = true;
358 break;
359 default:
360 break;
361 }
362 }
363 ASSERT_EQ(hasWideColorMode, result);
364}
365
366TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700367 const auto display = getFirstDisplayToken();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800368 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800369 std::function<status_t()> condition = [=]() {
370 bool result = false;
371 return SurfaceComposerClient::isWideColorDisplay(display, &result);
372 };
373 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
374}
375
Peiyong Lind1fedb42019-03-11 17:48:41 -0700376TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
Huihong Luo31b5ac22022-08-15 20:38:10 -0700377 const auto display = getFirstDisplayToken();
Peiyong Lind1fedb42019-03-11 17:48:41 -0700378 ASSERT_FALSE(display == nullptr);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100379 ui::DynamicDisplayInfo info;
380 SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
381 ColorMode colorMode = info.activeColorMode;
Peiyong Lind1fedb42019-03-11 17:48:41 -0700382 ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
383}
384
Ana Krulec13be8ad2018-08-21 02:43:56 +0000385} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800386
387// TODO(b/129481165): remove the #pragma below and fix conversion issues
388#pragma clang diagnostic pop // ignored "-Wconversion"