blob: 434c297cc978d9210d258ff63591c0c8d5008df4 [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
Ana Krulec13be8ad2018-08-21 02:43:56 +000021#include <gtest/gtest.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000022#include <gui/ISurfaceComposer.h>
23#include <gui/LayerDebugInfo.h>
24#include <gui/Surface.h>
25#include <gui/SurfaceComposerClient.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000026#include <private/android_filesystem_config.h>
27#include <private/gui/ComposerService.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"
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080033
Ana Krulec13be8ad2018-08-21 02:43:56 +000034namespace android {
35
36using Transaction = SurfaceComposerClient::Transaction;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -080037using ui::ColorMode;
Ana Krulec13be8ad2018-08-21 02:43:56 +000038
39namespace {
40const String8 DISPLAY_NAME("Credentials Display Test");
41const String8 SURFACE_NAME("Test Surface Name");
Ana Krulec13be8ad2018-08-21 02:43:56 +000042} // namespace
43
44/**
45 * This class tests the CheckCredentials method in SurfaceFlinger.
46 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
47 * return anything meaningful.
48 */
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080049
50// TODO(b/129481165): remove the #pragma below and fix conversion issues
51#pragma clang diagnostic push
52#pragma clang diagnostic ignored "-Wconversion"
Ana Krulec13be8ad2018-08-21 02:43:56 +000053class CredentialsTest : public ::testing::Test {
54protected:
Chavi Weingarten69c69b62022-08-31 16:55:07 +000055 void SetUp() override { ASSERT_NO_FATAL_FAILURE(initClient()); }
Ana Krulec13be8ad2018-08-21 02:43:56 +000056
57 void TearDown() override {
58 mComposerClient->dispose();
59 mBGSurfaceControl.clear();
60 mComposerClient.clear();
Ana Krulec13be8ad2018-08-21 02:43:56 +000061 }
62
63 sp<IBinder> mDisplay;
64 sp<IBinder> mVirtualDisplay;
65 sp<SurfaceComposerClient> mComposerClient;
66 sp<SurfaceControl> mBGSurfaceControl;
67 sp<SurfaceControl> mVirtualSurfaceControl;
68
69 void initClient() {
70 mComposerClient = new SurfaceComposerClient;
71 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
72 }
73
74 void setupBackgroundSurface() {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080075 mDisplay = SurfaceComposerClient::getInternalDisplayToken();
76 ASSERT_FALSE(mDisplay == nullptr);
77
Marin Shalamanova7fe3042021-01-29 21:02:08 +010078 ui::DisplayMode mode;
79 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +000080
81 // Background surface
Marin Shalamanova7fe3042021-01-29 21:02:08 +010082 mBGSurfaceControl = mComposerClient->createSurface(SURFACE_NAME, mode.resolution.getWidth(),
83 mode.resolution.getHeight(),
84 PIXEL_FORMAT_RGBA_8888, 0);
Ana Krulec13be8ad2018-08-21 02:43:56 +000085 ASSERT_TRUE(mBGSurfaceControl != nullptr);
86 ASSERT_TRUE(mBGSurfaceControl->isValid());
87
88 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -070089 t.setDisplayLayerStack(mDisplay, ui::DEFAULT_LAYER_STACK);
Ana Krulec13be8ad2018-08-21 02:43:56 +000090 ASSERT_EQ(NO_ERROR,
91 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
92 }
93
Ana Krulec13be8ad2018-08-21 02:43:56 +000094 /**
Ana Krulec13be8ad2018-08-21 02:43:56 +000095 * Template function the check a condition for different types of users: root
96 * graphics, system, and non-supported user. Root, graphics, and system should
97 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
98 */
99 template <typename T>
100 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
101 // Check with root.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000102 {
103 UIDFaker f(AID_SYSTEM);
104 ASSERT_EQ(privilegedValue, condition());
105 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000106
107 // Check as a Graphics user.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000108 {
109 UIDFaker f(AID_GRAPHICS);
110 ASSERT_EQ(privilegedValue, condition());
111 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000112
113 // Check as a system user.
Chavi Weingarten69c69b62022-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 non-supported user.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000120 {
121 UIDFaker f(AID_BIN);
122 ASSERT_EQ(unprivilegedValue, condition());
123 }
chaviwd4a61642020-09-01 14:53:46 -0700124
125 // Check as shell since shell has some additional permissions
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000126 {
127 UIDFaker f(AID_SHELL);
128 ASSERT_EQ(privilegedValue, condition());
129 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000130 }
131};
132
133TEST_F(CredentialsTest, ClientInitTest) {
134 // Root can init can init the client.
135 ASSERT_NO_FATAL_FAILURE(initClient());
136
137 // Graphics can init the client.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000138 {
139 UIDFaker f(AID_GRAPHICS);
140 ASSERT_NO_FATAL_FAILURE(initClient());
141 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000142
143 // System can init the client.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000144 {
145 UIDFaker f(AID_SYSTEM);
146 ASSERT_NO_FATAL_FAILURE(initClient());
147 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000148
Robert Carrb89ea9d2018-12-10 13:01:14 -0800149 // Anyone else can init the client.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000150 {
151 UIDFaker f(AID_BIN);
152 mComposerClient = new SurfaceComposerClient;
153 ASSERT_NO_FATAL_FAILURE(initClient());
154 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000155}
156
157TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800158 std::function<bool()> condition = [] {
159 return SurfaceComposerClient::getInternalDisplayToken() != nullptr;
Ana Krulec13be8ad2018-08-21 02:43:56 +0000160 };
161 // Anyone can access display information.
162 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
163}
164
165TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
166 // The following methods are tested with a UID that is not root, graphics,
167 // or system, to show that anyone can access them.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000168 UIDFaker f(AID_BIN);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800169 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000170 ASSERT_TRUE(display != nullptr);
171
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100172 ui::DisplayMode mode;
173 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000174
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100175 Vector<ui::DisplayMode> modes;
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100176 ui::DynamicDisplayInfo info;
177 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000178}
179
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100180TEST_F(CredentialsTest, GetDynamicDisplayInfoTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800181 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000182 std::function<status_t()> condition = [=]() {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100183 ui::DynamicDisplayInfo info;
184 return SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000185 };
186 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
187}
188
Daniel Solomon42d04562019-01-20 21:03:19 -0800189TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800190 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Daniel Solomon42d04562019-01-20 21:03:19 -0800191 std::function<status_t()> condition = [=]() {
192 ui::DisplayPrimaries primaries;
193 return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries);
194 };
195 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
196}
197
Steven Thomasa87ed452020-01-03 16:10:05 -0800198TEST_F(CredentialsTest, SetDesiredDisplayConfigsTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800199 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100200 ui::DisplayModeId defaultMode;
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200201 bool allowGroupSwitching;
Steven Thomasf734df42020-04-13 21:09:28 -0700202 float primaryFpsMin;
203 float primaryFpsMax;
204 float appRequestFpsMin;
205 float appRequestFpsMax;
206 status_t res =
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100207 SurfaceComposerClient::getDesiredDisplayModeSpecs(display, &defaultMode,
208 &allowGroupSwitching, &primaryFpsMin,
209 &primaryFpsMax, &appRequestFpsMin,
210 &appRequestFpsMax);
Steven Thomasa87ed452020-01-03 16:10:05 -0800211 ASSERT_EQ(res, NO_ERROR);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000212 std::function<status_t()> condition = [=]() {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100213 return SurfaceComposerClient::setDesiredDisplayModeSpecs(display, defaultMode,
214 allowGroupSwitching, primaryFpsMin,
215 primaryFpsMax, appRequestFpsMin,
216 appRequestFpsMax);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000217 };
218 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
219}
220
221TEST_F(CredentialsTest, SetActiveColorModeTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800222 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000223 std::function<status_t()> condition = [=]() {
224 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
225 };
226 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
227}
228
Ana Krulec13be8ad2018-08-21 02:43:56 +0000229TEST_F(CredentialsTest, CreateDisplayTest) {
chaviwd4a61642020-09-01 14:53:46 -0700230 // Only graphics and system processes can create a secure display.
Ana Krulec13be8ad2018-08-21 02:43:56 +0000231 std::function<bool()> condition = [=]() {
232 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
233 return testDisplay.get() != nullptr;
234 };
chaviwd4a61642020-09-01 14:53:46 -0700235
236 // Check with root.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000237 {
238 UIDFaker f(AID_ROOT);
239 ASSERT_FALSE(condition());
240 }
chaviwd4a61642020-09-01 14:53:46 -0700241
242 // Check as a Graphics user.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000243 {
244 UIDFaker f(AID_GRAPHICS);
245 ASSERT_TRUE(condition());
246 }
chaviwd4a61642020-09-01 14:53:46 -0700247
248 // Check as a system user.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000249 {
250 UIDFaker f(AID_SYSTEM);
251 ASSERT_TRUE(condition());
252 }
chaviwd4a61642020-09-01 14:53:46 -0700253
254 // Check as a non-supported user.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000255 {
256 UIDFaker f(AID_BIN);
257 ASSERT_FALSE(condition());
258 }
chaviwd4a61642020-09-01 14:53:46 -0700259
260 // Check as shell since shell has some additional permissions
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000261 {
262 UIDFaker f(AID_SHELL);
263 ASSERT_FALSE(condition());
264 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000265
266 condition = [=]() {
267 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
268 return testDisplay.get() != nullptr;
269 };
270 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
271}
272
Ana Krulec13be8ad2018-08-21 02:43:56 +0000273TEST_F(CredentialsTest, CaptureTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800274 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000275 std::function<status_t()> condition = [=]() {
276 sp<GraphicBuffer> outBuffer;
chaviw690db382020-07-27 16:46:46 -0700277 DisplayCaptureArgs captureArgs;
278 captureArgs.displayToken = display;
279 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700280 return ScreenCapture::captureDisplay(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000281 };
282 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
283}
284
285TEST_F(CredentialsTest, CaptureLayersTest) {
286 setupBackgroundSurface();
287 sp<GraphicBuffer> outBuffer;
288 std::function<status_t()> condition = [=]() {
chaviw26c52482020-07-28 16:25:52 -0700289 LayerCaptureArgs captureArgs;
290 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
291 captureArgs.sourceCrop = {0, 0, 1, 1};
292
293 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700294 return ScreenCapture::captureLayers(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000295 };
296 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
297}
298
299/**
300 * The following tests are for methods accessible directly through SurfaceFlinger.
301 */
Ana Krulec13be8ad2018-08-21 02:43:56 +0000302TEST_F(CredentialsTest, GetLayerDebugInfo) {
303 setupBackgroundSurface();
304 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
305
306 // Historically, only root and shell can access the getLayerDebugInfo which
307 // is called when we call dumpsys. I don't see a reason why we should change this.
308 std::vector<LayerDebugInfo> outLayers;
309 // Check with root.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000310 {
311 UIDFaker f(AID_ROOT);
312 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
313 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000314
315 // Check as a shell.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000316 {
317 UIDFaker f(AID_SHELL);
318 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
319 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000320
321 // Check as anyone else.
Chavi Weingarten69c69b62022-08-31 16:55:07 +0000322 {
323 UIDFaker f(AID_BIN);
324 ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers));
325 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000326}
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800327
328TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800329 const auto display = SurfaceComposerClient::getInternalDisplayToken();
330 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800331 bool result = false;
332 status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result);
333 ASSERT_EQ(NO_ERROR, error);
334 bool hasWideColorMode = false;
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100335 ui::DynamicDisplayInfo info;
336 SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
337 const auto& colorModes = info.supportedColorModes;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800338 for (ColorMode colorMode : colorModes) {
339 switch (colorMode) {
340 case ColorMode::DISPLAY_P3:
341 case ColorMode::ADOBE_RGB:
342 case ColorMode::DCI_P3:
343 hasWideColorMode = true;
344 break;
345 default:
346 break;
347 }
348 }
349 ASSERT_EQ(hasWideColorMode, result);
350}
351
352TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800353 const auto display = SurfaceComposerClient::getInternalDisplayToken();
354 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800355 std::function<status_t()> condition = [=]() {
356 bool result = false;
357 return SurfaceComposerClient::isWideColorDisplay(display, &result);
358 };
359 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
360}
361
Peiyong Lind1fedb42019-03-11 17:48:41 -0700362TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
363 const auto display = SurfaceComposerClient::getInternalDisplayToken();
364 ASSERT_FALSE(display == nullptr);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100365 ui::DynamicDisplayInfo info;
366 SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
367 ColorMode colorMode = info.activeColorMode;
Peiyong Lind1fedb42019-03-11 17:48:41 -0700368 ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
369}
370
Ana Krulec13be8ad2018-08-21 02:43:56 +0000371} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800372
373// TODO(b/129481165): remove the #pragma below and fix conversion issues
374#pragma clang diagnostic pop // ignored "-Wconversion"