blob: 775de4a8fe7e7a424a5f5b795d2d045f5d78787e [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
77 void setupBackgroundSurface() {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080078 mDisplay = SurfaceComposerClient::getInternalDisplayToken();
79 ASSERT_FALSE(mDisplay == nullptr);
80
Marin Shalamanova7fe3042021-01-29 21:02:08 +010081 ui::DisplayMode mode;
82 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplay, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +000083
84 // Background surface
Marin Shalamanova7fe3042021-01-29 21:02:08 +010085 mBGSurfaceControl = mComposerClient->createSurface(SURFACE_NAME, mode.resolution.getWidth(),
86 mode.resolution.getHeight(),
87 PIXEL_FORMAT_RGBA_8888, 0);
Ana Krulec13be8ad2018-08-21 02:43:56 +000088 ASSERT_TRUE(mBGSurfaceControl != nullptr);
89 ASSERT_TRUE(mBGSurfaceControl->isValid());
90
91 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -070092 t.setDisplayLayerStack(mDisplay, ui::DEFAULT_LAYER_STACK);
Ana Krulec13be8ad2018-08-21 02:43:56 +000093 ASSERT_EQ(NO_ERROR,
94 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
95 }
96
Ana Krulec13be8ad2018-08-21 02:43:56 +000097 /**
Ana Krulec13be8ad2018-08-21 02:43:56 +000098 * Template function the check a condition for different types of users: root
99 * graphics, system, and non-supported user. Root, graphics, and system should
100 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
101 */
102 template <typename T>
103 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
104 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000105 {
106 UIDFaker f(AID_SYSTEM);
107 ASSERT_EQ(privilegedValue, condition());
108 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000109
110 // Check as a Graphics user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000111 {
112 UIDFaker f(AID_GRAPHICS);
113 ASSERT_EQ(privilegedValue, condition());
114 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000115
116 // Check as a system user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000117 {
118 UIDFaker f(AID_SYSTEM);
119 ASSERT_EQ(privilegedValue, condition());
120 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000121
122 // Check as a non-supported user.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000123 {
124 UIDFaker f(AID_BIN);
125 ASSERT_EQ(unprivilegedValue, condition());
126 }
chaviwd4a61642020-09-01 14:53:46 -0700127
128 // Check as shell since shell has some additional permissions
Chavi Weingartenc73be482022-08-31 16:55:07 +0000129 {
130 UIDFaker f(AID_SHELL);
131 ASSERT_EQ(privilegedValue, condition());
132 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000133 }
134};
135
136TEST_F(CredentialsTest, ClientInitTest) {
137 // Root can init can init the client.
138 ASSERT_NO_FATAL_FAILURE(initClient());
139
140 // Graphics can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000141 {
142 UIDFaker f(AID_GRAPHICS);
143 ASSERT_NO_FATAL_FAILURE(initClient());
144 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000145
146 // System can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000147 {
148 UIDFaker f(AID_SYSTEM);
149 ASSERT_NO_FATAL_FAILURE(initClient());
150 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000151
Robert Carrb89ea9d2018-12-10 13:01:14 -0800152 // Anyone else can init the client.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000153 {
154 UIDFaker f(AID_BIN);
155 mComposerClient = sp<SurfaceComposerClient>::make();
156 ASSERT_NO_FATAL_FAILURE(initClient());
157 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000158}
159
160TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800161 std::function<bool()> condition = [] {
162 return SurfaceComposerClient::getInternalDisplayToken() != nullptr;
Ana Krulec13be8ad2018-08-21 02:43:56 +0000163 };
164 // Anyone can access display information.
165 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
166}
167
168TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
169 // The following methods are tested with a UID that is not root, graphics,
170 // or system, to show that anyone can access them.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000171 UIDFaker f(AID_BIN);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800172 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000173 ASSERT_TRUE(display != nullptr);
174
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100175 ui::DisplayMode mode;
176 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000177
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100178 Vector<ui::DisplayMode> modes;
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100179 ui::DynamicDisplayInfo info;
180 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000181}
182
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100183TEST_F(CredentialsTest, GetDynamicDisplayInfoTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800184 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000185 std::function<status_t()> condition = [=]() {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100186 ui::DynamicDisplayInfo info;
187 return SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000188 };
189 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
190}
191
Daniel Solomon42d04562019-01-20 21:03:19 -0800192TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800193 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Daniel Solomon42d04562019-01-20 21:03:19 -0800194 std::function<status_t()> condition = [=]() {
195 ui::DisplayPrimaries primaries;
196 return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries);
197 };
198 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
199}
200
Steven Thomasa87ed452020-01-03 16:10:05 -0800201TEST_F(CredentialsTest, SetDesiredDisplayConfigsTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800202 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100203 ui::DisplayModeId defaultMode;
Marin Shalamanov30b0b3c2020-10-13 19:15:06 +0200204 bool allowGroupSwitching;
Steven Thomasf734df42020-04-13 21:09:28 -0700205 float primaryFpsMin;
206 float primaryFpsMax;
207 float appRequestFpsMin;
208 float appRequestFpsMax;
209 status_t res =
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100210 SurfaceComposerClient::getDesiredDisplayModeSpecs(display, &defaultMode,
211 &allowGroupSwitching, &primaryFpsMin,
212 &primaryFpsMax, &appRequestFpsMin,
213 &appRequestFpsMax);
Steven Thomasa87ed452020-01-03 16:10:05 -0800214 ASSERT_EQ(res, NO_ERROR);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000215 std::function<status_t()> condition = [=]() {
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100216 return SurfaceComposerClient::setDesiredDisplayModeSpecs(display, defaultMode,
217 allowGroupSwitching, primaryFpsMin,
218 primaryFpsMax, appRequestFpsMin,
219 appRequestFpsMax);
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) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800225 const auto display = SurfaceComposerClient::getInternalDisplayToken();
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);
242 ASSERT_FALSE(condition());
243 }
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, CaptureTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800277 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000278 std::function<status_t()> condition = [=]() {
279 sp<GraphicBuffer> outBuffer;
chaviw690db382020-07-27 16:46:46 -0700280 DisplayCaptureArgs captureArgs;
281 captureArgs.displayToken = display;
282 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700283 return ScreenCapture::captureDisplay(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000284 };
285 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
286}
287
288TEST_F(CredentialsTest, CaptureLayersTest) {
289 setupBackgroundSurface();
290 sp<GraphicBuffer> outBuffer;
291 std::function<status_t()> condition = [=]() {
chaviw26c52482020-07-28 16:25:52 -0700292 LayerCaptureArgs captureArgs;
293 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
294 captureArgs.sourceCrop = {0, 0, 1, 1};
295
296 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700297 return ScreenCapture::captureLayers(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000298 };
299 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
300}
301
302/**
303 * The following tests are for methods accessible directly through SurfaceFlinger.
304 */
Ana Krulec13be8ad2018-08-21 02:43:56 +0000305TEST_F(CredentialsTest, GetLayerDebugInfo) {
306 setupBackgroundSurface();
Huihong Luo05539a12022-02-23 10:29:40 -0800307 sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
Ana Krulec13be8ad2018-08-21 02:43:56 +0000308
309 // Historically, only root and shell can access the getLayerDebugInfo which
310 // is called when we call dumpsys. I don't see a reason why we should change this.
311 std::vector<LayerDebugInfo> outLayers;
Chavi Weingartenc73be482022-08-31 16:55:07 +0000312 binder::Status status = binder::Status::ok();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000313 // Check with root.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000314 {
315 UIDFaker f(AID_ROOT);
316 status = sf->getLayerDebugInfo(&outLayers);
317 ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
318 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000319
320 // Check as a shell.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000321 {
322 UIDFaker f(AID_SHELL);
323 status = sf->getLayerDebugInfo(&outLayers);
324 ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
325 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000326
327 // Check as anyone else.
Chavi Weingartenc73be482022-08-31 16:55:07 +0000328 {
329 UIDFaker f(AID_BIN);
330 status = sf->getLayerDebugInfo(&outLayers);
331 ASSERT_EQ(PERMISSION_DENIED, statusTFromBinderStatus(status));
332 }
Ana Krulec13be8ad2018-08-21 02:43:56 +0000333}
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800334
335TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800336 const auto display = SurfaceComposerClient::getInternalDisplayToken();
337 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800338 bool result = false;
339 status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result);
340 ASSERT_EQ(NO_ERROR, error);
341 bool hasWideColorMode = false;
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100342 ui::DynamicDisplayInfo info;
343 SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
344 const auto& colorModes = info.supportedColorModes;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800345 for (ColorMode colorMode : colorModes) {
346 switch (colorMode) {
347 case ColorMode::DISPLAY_P3:
348 case ColorMode::ADOBE_RGB:
349 case ColorMode::DCI_P3:
350 hasWideColorMode = true;
351 break;
352 default:
353 break;
354 }
355 }
356 ASSERT_EQ(hasWideColorMode, result);
357}
358
359TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800360 const auto display = SurfaceComposerClient::getInternalDisplayToken();
361 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800362 std::function<status_t()> condition = [=]() {
363 bool result = false;
364 return SurfaceComposerClient::isWideColorDisplay(display, &result);
365 };
366 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
367}
368
Peiyong Lind1fedb42019-03-11 17:48:41 -0700369TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
370 const auto display = SurfaceComposerClient::getInternalDisplayToken();
371 ASSERT_FALSE(display == nullptr);
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100372 ui::DynamicDisplayInfo info;
373 SurfaceComposerClient::getDynamicDisplayInfo(display, &info);
374 ColorMode colorMode = info.activeColorMode;
Peiyong Lind1fedb42019-03-11 17:48:41 -0700375 ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
376}
377
Ana Krulec13be8ad2018-08-21 02:43:56 +0000378} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800379
380// TODO(b/129481165): remove the #pragma below and fix conversion issues
381#pragma clang diagnostic pop // ignored "-Wconversion"