blob: 5128394d4e5ed11e4a582007d3dc8025ca6a88bb [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>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080028#include <ui/DisplayConfig.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000029#include <utils/String8.h>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080030#include <functional>
chaviw8ffc7b82020-08-18 11:25:37 -070031#include "utils/ScreenshotUtils.h"
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080032
Ana Krulec13be8ad2018-08-21 02:43:56 +000033namespace android {
34
35using Transaction = SurfaceComposerClient::Transaction;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -080036using ui::ColorMode;
Ana Krulec13be8ad2018-08-21 02:43:56 +000037
38namespace {
39const String8 DISPLAY_NAME("Credentials Display Test");
40const String8 SURFACE_NAME("Test Surface Name");
Ana Krulec13be8ad2018-08-21 02:43:56 +000041} // namespace
42
43/**
44 * This class tests the CheckCredentials method in SurfaceFlinger.
45 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
46 * return anything meaningful.
47 */
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080048
49// TODO(b/129481165): remove the #pragma below and fix conversion issues
50#pragma clang diagnostic push
51#pragma clang diagnostic ignored "-Wconversion"
Ana Krulec13be8ad2018-08-21 02:43:56 +000052class CredentialsTest : public ::testing::Test {
53protected:
54 void SetUp() override {
55 // Start the tests as root.
56 seteuid(AID_ROOT);
57
58 ASSERT_NO_FATAL_FAILURE(initClient());
59 }
60
61 void TearDown() override {
62 mComposerClient->dispose();
63 mBGSurfaceControl.clear();
64 mComposerClient.clear();
65 // Finish the tests as root.
66 seteuid(AID_ROOT);
67 }
68
69 sp<IBinder> mDisplay;
70 sp<IBinder> mVirtualDisplay;
71 sp<SurfaceComposerClient> mComposerClient;
72 sp<SurfaceControl> mBGSurfaceControl;
73 sp<SurfaceControl> mVirtualSurfaceControl;
74
75 void initClient() {
76 mComposerClient = new SurfaceComposerClient;
77 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
78 }
79
80 void setupBackgroundSurface() {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080081 mDisplay = SurfaceComposerClient::getInternalDisplayToken();
82 ASSERT_FALSE(mDisplay == nullptr);
83
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080084 DisplayConfig config;
85 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(mDisplay, &config));
Ana Krulec13be8ad2018-08-21 02:43:56 +000086
87 // Background surface
88 mBGSurfaceControl =
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080089 mComposerClient->createSurface(SURFACE_NAME, config.resolution.getWidth(),
90 config.resolution.getHeight(),
Ana Krulec13be8ad2018-08-21 02:43:56 +000091 PIXEL_FORMAT_RGBA_8888, 0);
92 ASSERT_TRUE(mBGSurfaceControl != nullptr);
93 ASSERT_TRUE(mBGSurfaceControl->isValid());
94
95 Transaction t;
96 t.setDisplayLayerStack(mDisplay, 0);
97 ASSERT_EQ(NO_ERROR,
98 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
99 }
100
101 void setupVirtualDisplay() {
102 mVirtualDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
103 const ssize_t displayWidth = 100;
104 const ssize_t displayHeight = 100;
105
106 // Background surface
107 mVirtualSurfaceControl =
108 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
109 PIXEL_FORMAT_RGBA_8888, 0);
110 ASSERT_TRUE(mVirtualSurfaceControl != nullptr);
111 ASSERT_TRUE(mVirtualSurfaceControl->isValid());
112
113 Transaction t;
114 t.setDisplayLayerStack(mVirtualDisplay, 0);
115 ASSERT_EQ(NO_ERROR,
116 t.setLayer(mVirtualSurfaceControl, INT_MAX - 3)
117 .show(mVirtualSurfaceControl)
118 .apply());
119 }
120
121 /**
122 * Sets UID to imitate Graphic's process.
123 */
124 void setGraphicsUID() {
125 seteuid(AID_ROOT);
126 seteuid(AID_GRAPHICS);
127 }
128
129 /**
130 * Sets UID to imitate System's process.
131 */
132 void setSystemUID() {
133 seteuid(AID_ROOT);
134 seteuid(AID_SYSTEM);
135 }
136
137 /**
138 * Sets UID to imitate a process that doesn't have any special privileges in
139 * our code.
140 */
141 void setBinUID() {
142 seteuid(AID_ROOT);
143 seteuid(AID_BIN);
144 }
145
146 /**
147 * Template function the check a condition for different types of users: root
148 * graphics, system, and non-supported user. Root, graphics, and system should
149 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
150 */
151 template <typename T>
152 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
153 // Check with root.
154 seteuid(AID_ROOT);
155 ASSERT_EQ(privilegedValue, condition());
156
157 // Check as a Graphics user.
158 setGraphicsUID();
159 ASSERT_EQ(privilegedValue, condition());
160
161 // Check as a system user.
162 setSystemUID();
163 ASSERT_EQ(privilegedValue, condition());
164
165 // Check as a non-supported user.
166 setBinUID();
167 ASSERT_EQ(unprivilegedValue, condition());
168 }
169};
170
171TEST_F(CredentialsTest, ClientInitTest) {
172 // Root can init can init the client.
173 ASSERT_NO_FATAL_FAILURE(initClient());
174
175 // Graphics can init the client.
176 setGraphicsUID();
177 ASSERT_NO_FATAL_FAILURE(initClient());
178
179 // System can init the client.
180 setSystemUID();
181 ASSERT_NO_FATAL_FAILURE(initClient());
182
Robert Carrb89ea9d2018-12-10 13:01:14 -0800183 // Anyone else can init the client.
Ana Krulec13be8ad2018-08-21 02:43:56 +0000184 setBinUID();
185 mComposerClient = new SurfaceComposerClient;
Robert Carrb89ea9d2018-12-10 13:01:14 -0800186 ASSERT_NO_FATAL_FAILURE(initClient());
Ana Krulec13be8ad2018-08-21 02:43:56 +0000187}
188
189TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800190 std::function<bool()> condition = [] {
191 return SurfaceComposerClient::getInternalDisplayToken() != nullptr;
Ana Krulec13be8ad2018-08-21 02:43:56 +0000192 };
193 // Anyone can access display information.
194 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
195}
196
197TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
198 // The following methods are tested with a UID that is not root, graphics,
199 // or system, to show that anyone can access them.
200 setBinUID();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800201 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000202 ASSERT_TRUE(display != nullptr);
203
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800204 DisplayConfig config;
205 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
Ana Krulec13be8ad2018-08-21 02:43:56 +0000206
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800207 Vector<DisplayConfig> configs;
Ana Krulec13be8ad2018-08-21 02:43:56 +0000208 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayConfigs(display, &configs));
209
210 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveConfig(display));
211
212 ASSERT_NE(static_cast<ui::ColorMode>(BAD_VALUE),
213 SurfaceComposerClient::getActiveColorMode(display));
214}
215
216TEST_F(CredentialsTest, GetDisplayColorModesTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800217 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000218 std::function<status_t()> condition = [=]() {
219 Vector<ui::ColorMode> outColorModes;
220 return SurfaceComposerClient::getDisplayColorModes(display, &outColorModes);
221 };
222 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
223}
224
Daniel Solomon42d04562019-01-20 21:03:19 -0800225TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800226 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Daniel Solomon42d04562019-01-20 21:03:19 -0800227 std::function<status_t()> condition = [=]() {
228 ui::DisplayPrimaries primaries;
229 return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries);
230 };
231 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
232}
233
Steven Thomasa87ed452020-01-03 16:10:05 -0800234TEST_F(CredentialsTest, SetDesiredDisplayConfigsTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800235 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Steven Thomasa87ed452020-01-03 16:10:05 -0800236 int32_t defaultConfig;
Steven Thomasf734df42020-04-13 21:09:28 -0700237 float primaryFpsMin;
238 float primaryFpsMax;
239 float appRequestFpsMin;
240 float appRequestFpsMax;
241 status_t res =
242 SurfaceComposerClient::getDesiredDisplayConfigSpecs(display, &defaultConfig,
243 &primaryFpsMin, &primaryFpsMax,
244 &appRequestFpsMin,
245 &appRequestFpsMax);
Steven Thomasa87ed452020-01-03 16:10:05 -0800246 ASSERT_EQ(res, NO_ERROR);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000247 std::function<status_t()> condition = [=]() {
Steven Thomasf734df42020-04-13 21:09:28 -0700248 return SurfaceComposerClient::setDesiredDisplayConfigSpecs(display, defaultConfig,
249 primaryFpsMin, primaryFpsMax,
250 appRequestFpsMin,
251 appRequestFpsMax);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000252 };
253 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
254}
255
256TEST_F(CredentialsTest, SetActiveColorModeTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800257 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000258 std::function<status_t()> condition = [=]() {
259 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
260 };
261 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
262}
263
Ana Krulec13be8ad2018-08-21 02:43:56 +0000264TEST_F(CredentialsTest, CreateDisplayTest) {
265 std::function<bool()> condition = [=]() {
266 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
267 return testDisplay.get() != nullptr;
268 };
269 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
270
271 condition = [=]() {
272 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
273 return testDisplay.get() != nullptr;
274 };
275 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
276}
277
Ana Krulec13be8ad2018-08-21 02:43:56 +0000278TEST_F(CredentialsTest, CaptureTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800279 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000280 std::function<status_t()> condition = [=]() {
281 sp<GraphicBuffer> outBuffer;
chaviw690db382020-07-27 16:46:46 -0700282 DisplayCaptureArgs captureArgs;
283 captureArgs.displayToken = display;
284 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700285 return ScreenCapture::captureDisplay(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
290TEST_F(CredentialsTest, CaptureLayersTest) {
291 setupBackgroundSurface();
292 sp<GraphicBuffer> outBuffer;
293 std::function<status_t()> condition = [=]() {
chaviw26c52482020-07-28 16:25:52 -0700294 LayerCaptureArgs captureArgs;
295 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
296 captureArgs.sourceCrop = {0, 0, 1, 1};
297
298 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700299 return ScreenCapture::captureLayers(captureArgs, captureResults);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000300 };
301 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
302}
303
304/**
305 * The following tests are for methods accessible directly through SurfaceFlinger.
306 */
307
308/**
309 * An app can pass a buffer queue to the media server and ask the media server to decode a DRM video
310 * to that buffer queue. The media server is the buffer producer in this case. Because the app may create
311 * its own buffer queue and act as the buffer consumer, the media server wants to be careful to avoid
312 * sending decoded video frames to the app. This is where authenticateSurfaceTexture call comes in, to check
313 * the consumer of a buffer queue is SurfaceFlinger.
314 */
315TEST_F(CredentialsTest, AuthenticateSurfaceTextureTest) {
316 setupBackgroundSurface();
317 sp<IGraphicBufferProducer> producer =
318 mBGSurfaceControl->getSurface()->getIGraphicBufferProducer();
319 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
320
321 std::function<bool()> condition = [=]() { return sf->authenticateSurfaceTexture(producer); };
322 // Anyone should be able to check if the consumer of the buffer queue is SF.
323 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
324}
325
326TEST_F(CredentialsTest, GetLayerDebugInfo) {
327 setupBackgroundSurface();
328 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
329
330 // Historically, only root and shell can access the getLayerDebugInfo which
331 // is called when we call dumpsys. I don't see a reason why we should change this.
332 std::vector<LayerDebugInfo> outLayers;
333 // Check with root.
334 seteuid(AID_ROOT);
335 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
336
337 // Check as a shell.
338 seteuid(AID_SHELL);
339 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
340
341 // Check as anyone else.
342 seteuid(AID_ROOT);
343 seteuid(AID_BIN);
344 ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers));
345}
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800346
347TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800348 const auto display = SurfaceComposerClient::getInternalDisplayToken();
349 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800350 bool result = false;
351 status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result);
352 ASSERT_EQ(NO_ERROR, error);
353 bool hasWideColorMode = false;
354 Vector<ColorMode> colorModes;
355 SurfaceComposerClient::getDisplayColorModes(display, &colorModes);
356 for (ColorMode colorMode : colorModes) {
357 switch (colorMode) {
358 case ColorMode::DISPLAY_P3:
359 case ColorMode::ADOBE_RGB:
360 case ColorMode::DCI_P3:
361 hasWideColorMode = true;
362 break;
363 default:
364 break;
365 }
366 }
367 ASSERT_EQ(hasWideColorMode, result);
368}
369
370TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800371 const auto display = SurfaceComposerClient::getInternalDisplayToken();
372 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800373 std::function<status_t()> condition = [=]() {
374 bool result = false;
375 return SurfaceComposerClient::isWideColorDisplay(display, &result);
376 };
377 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
378}
379
Peiyong Lind1fedb42019-03-11 17:48:41 -0700380TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
381 const auto display = SurfaceComposerClient::getInternalDisplayToken();
382 ASSERT_FALSE(display == nullptr);
383 ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(display);
384 ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
385}
386
Ana Krulec13be8ad2018-08-21 02:43:56 +0000387} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800388
389// TODO(b/129481165): remove the #pragma below and fix conversion issues
390#pragma clang diagnostic pop // ignored "-Wconversion"