blob: f6188738b2f8221d95235fa449b777cc5f6061e9 [file] [log] [blame]
Ana Krulec13be8ad2018-08-21 02:43:56 +00001#include <algorithm>
2#include <functional>
3#include <limits>
4#include <ostream>
5
6#include <gtest/gtest.h>
7
8#include <gui/ISurfaceComposer.h>
9#include <gui/LayerDebugInfo.h>
10#include <gui/Surface.h>
11#include <gui/SurfaceComposerClient.h>
12
13#include <private/android_filesystem_config.h>
14#include <private/gui/ComposerService.h>
Ana Krulec13be8ad2018-08-21 02:43:56 +000015#include <ui/DisplayInfo.h>
16#include <utils/String8.h>
17
18namespace android {
19
20using Transaction = SurfaceComposerClient::Transaction;
Peiyong Lin4f3fddf2019-01-24 17:21:24 -080021using ui::ColorMode;
Ana Krulec13be8ad2018-08-21 02:43:56 +000022
23namespace {
24const String8 DISPLAY_NAME("Credentials Display Test");
25const String8 SURFACE_NAME("Test Surface Name");
Ana Krulec13be8ad2018-08-21 02:43:56 +000026const float FRAME_SCALE = 1.0f;
27} // namespace
28
29/**
30 * This class tests the CheckCredentials method in SurfaceFlinger.
31 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
32 * return anything meaningful.
33 */
34class CredentialsTest : public ::testing::Test {
35protected:
36 void SetUp() override {
37 // Start the tests as root.
38 seteuid(AID_ROOT);
39
40 ASSERT_NO_FATAL_FAILURE(initClient());
41 }
42
43 void TearDown() override {
44 mComposerClient->dispose();
45 mBGSurfaceControl.clear();
46 mComposerClient.clear();
47 // Finish the tests as root.
48 seteuid(AID_ROOT);
49 }
50
51 sp<IBinder> mDisplay;
52 sp<IBinder> mVirtualDisplay;
53 sp<SurfaceComposerClient> mComposerClient;
54 sp<SurfaceControl> mBGSurfaceControl;
55 sp<SurfaceControl> mVirtualSurfaceControl;
56
57 void initClient() {
58 mComposerClient = new SurfaceComposerClient;
59 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
60 }
61
62 void setupBackgroundSurface() {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080063 mDisplay = SurfaceComposerClient::getInternalDisplayToken();
64 ASSERT_FALSE(mDisplay == nullptr);
65
Ana Krulec13be8ad2018-08-21 02:43:56 +000066 DisplayInfo info;
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080067 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplay, &info));
Ana Krulec13be8ad2018-08-21 02:43:56 +000068 const ssize_t displayWidth = info.w;
69 const ssize_t displayHeight = info.h;
70
71 // Background surface
72 mBGSurfaceControl =
73 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
74 PIXEL_FORMAT_RGBA_8888, 0);
75 ASSERT_TRUE(mBGSurfaceControl != nullptr);
76 ASSERT_TRUE(mBGSurfaceControl->isValid());
77
78 Transaction t;
79 t.setDisplayLayerStack(mDisplay, 0);
80 ASSERT_EQ(NO_ERROR,
81 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
82 }
83
84 void setupVirtualDisplay() {
85 mVirtualDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
86 const ssize_t displayWidth = 100;
87 const ssize_t displayHeight = 100;
88
89 // Background surface
90 mVirtualSurfaceControl =
91 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
92 PIXEL_FORMAT_RGBA_8888, 0);
93 ASSERT_TRUE(mVirtualSurfaceControl != nullptr);
94 ASSERT_TRUE(mVirtualSurfaceControl->isValid());
95
96 Transaction t;
97 t.setDisplayLayerStack(mVirtualDisplay, 0);
98 ASSERT_EQ(NO_ERROR,
99 t.setLayer(mVirtualSurfaceControl, INT_MAX - 3)
100 .show(mVirtualSurfaceControl)
101 .apply());
102 }
103
104 /**
105 * Sets UID to imitate Graphic's process.
106 */
107 void setGraphicsUID() {
108 seteuid(AID_ROOT);
109 seteuid(AID_GRAPHICS);
110 }
111
112 /**
113 * Sets UID to imitate System's process.
114 */
115 void setSystemUID() {
116 seteuid(AID_ROOT);
117 seteuid(AID_SYSTEM);
118 }
119
120 /**
121 * Sets UID to imitate a process that doesn't have any special privileges in
122 * our code.
123 */
124 void setBinUID() {
125 seteuid(AID_ROOT);
126 seteuid(AID_BIN);
127 }
128
129 /**
130 * Template function the check a condition for different types of users: root
131 * graphics, system, and non-supported user. Root, graphics, and system should
132 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
133 */
134 template <typename T>
135 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
136 // Check with root.
137 seteuid(AID_ROOT);
138 ASSERT_EQ(privilegedValue, condition());
139
140 // Check as a Graphics user.
141 setGraphicsUID();
142 ASSERT_EQ(privilegedValue, condition());
143
144 // Check as a system user.
145 setSystemUID();
146 ASSERT_EQ(privilegedValue, condition());
147
148 // Check as a non-supported user.
149 setBinUID();
150 ASSERT_EQ(unprivilegedValue, condition());
151 }
152};
153
154TEST_F(CredentialsTest, ClientInitTest) {
155 // Root can init can init the client.
156 ASSERT_NO_FATAL_FAILURE(initClient());
157
158 // Graphics can init the client.
159 setGraphicsUID();
160 ASSERT_NO_FATAL_FAILURE(initClient());
161
162 // System can init the client.
163 setSystemUID();
164 ASSERT_NO_FATAL_FAILURE(initClient());
165
Robert Carrb89ea9d2018-12-10 13:01:14 -0800166 // Anyone else can init the client.
Ana Krulec13be8ad2018-08-21 02:43:56 +0000167 setBinUID();
168 mComposerClient = new SurfaceComposerClient;
Robert Carrb89ea9d2018-12-10 13:01:14 -0800169 ASSERT_NO_FATAL_FAILURE(initClient());
Ana Krulec13be8ad2018-08-21 02:43:56 +0000170}
171
172TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800173 std::function<bool()> condition = [] {
174 return SurfaceComposerClient::getInternalDisplayToken() != nullptr;
Ana Krulec13be8ad2018-08-21 02:43:56 +0000175 };
176 // Anyone can access display information.
177 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
178}
179
180TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
181 // The following methods are tested with a UID that is not root, graphics,
182 // or system, to show that anyone can access them.
183 setBinUID();
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800184 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000185 ASSERT_TRUE(display != nullptr);
186
187 DisplayInfo info;
188 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
189
190 Vector<DisplayInfo> configs;
191 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayConfigs(display, &configs));
192
193 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveConfig(display));
194
195 ASSERT_NE(static_cast<ui::ColorMode>(BAD_VALUE),
196 SurfaceComposerClient::getActiveColorMode(display));
197}
198
199TEST_F(CredentialsTest, GetDisplayColorModesTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800200 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000201 std::function<status_t()> condition = [=]() {
202 Vector<ui::ColorMode> outColorModes;
203 return SurfaceComposerClient::getDisplayColorModes(display, &outColorModes);
204 };
205 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
206}
207
Daniel Solomon42d04562019-01-20 21:03:19 -0800208TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800209 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Daniel Solomon42d04562019-01-20 21:03:19 -0800210 std::function<status_t()> condition = [=]() {
211 ui::DisplayPrimaries primaries;
212 return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries);
213 };
214 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
215}
216
Ana Krulec13be8ad2018-08-21 02:43:56 +0000217TEST_F(CredentialsTest, SetActiveConfigTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800218 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000219 std::function<status_t()> condition = [=]() {
220 return SurfaceComposerClient::setActiveConfig(display, 0);
221 };
222 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
223}
224
225TEST_F(CredentialsTest, SetActiveColorModeTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800226 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000227 std::function<status_t()> condition = [=]() {
228 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
229 };
230 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
231}
232
Ana Krulec13be8ad2018-08-21 02:43:56 +0000233TEST_F(CredentialsTest, CreateDisplayTest) {
234 std::function<bool()> condition = [=]() {
235 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
236 return testDisplay.get() != nullptr;
237 };
238 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
239
240 condition = [=]() {
241 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
242 return testDisplay.get() != nullptr;
243 };
244 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
245}
246
247TEST_F(CredentialsTest, DISABLED_DestroyDisplayTest) {
248 setupVirtualDisplay();
249
250 DisplayInfo info;
251 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mVirtualDisplay, &info));
252 SurfaceComposerClient::destroyDisplay(mVirtualDisplay);
253 // This test currently fails. TODO(b/112002626): Find a way to properly create
254 // a display in the test environment, so that destroy display can remove it.
255 ASSERT_EQ(NAME_NOT_FOUND, SurfaceComposerClient::getDisplayInfo(mVirtualDisplay, &info));
256}
257
258TEST_F(CredentialsTest, CaptureTest) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800259 const auto display = SurfaceComposerClient::getInternalDisplayToken();
Ana Krulec13be8ad2018-08-21 02:43:56 +0000260 std::function<status_t()> condition = [=]() {
261 sp<GraphicBuffer> outBuffer;
Peiyong Lin0e003c92018-09-17 11:09:51 -0700262 return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB,
263 ui::PixelFormat::RGBA_8888, Rect(), 0 /*reqWidth*/,
Dominik Laskowski718f9602019-11-09 20:01:35 -0800264 0 /*reqHeight*/, false, ui::ROTATION_0, &outBuffer);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000265 };
266 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
267}
268
269TEST_F(CredentialsTest, CaptureLayersTest) {
270 setupBackgroundSurface();
271 sp<GraphicBuffer> outBuffer;
272 std::function<status_t()> condition = [=]() {
273 sp<GraphicBuffer> outBuffer;
Peiyong Lin0e003c92018-09-17 11:09:51 -0700274 return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(),
275 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
Vishnu Nairefc42e22019-12-03 17:36:12 -0800276 Rect(0, 0, 1, 1), FRAME_SCALE, &outBuffer);
Ana Krulec13be8ad2018-08-21 02:43:56 +0000277 };
278 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
279}
280
281/**
282 * The following tests are for methods accessible directly through SurfaceFlinger.
283 */
284
285/**
286 * An app can pass a buffer queue to the media server and ask the media server to decode a DRM video
287 * to that buffer queue. The media server is the buffer producer in this case. Because the app may create
288 * its own buffer queue and act as the buffer consumer, the media server wants to be careful to avoid
289 * sending decoded video frames to the app. This is where authenticateSurfaceTexture call comes in, to check
290 * the consumer of a buffer queue is SurfaceFlinger.
291 */
292TEST_F(CredentialsTest, AuthenticateSurfaceTextureTest) {
293 setupBackgroundSurface();
294 sp<IGraphicBufferProducer> producer =
295 mBGSurfaceControl->getSurface()->getIGraphicBufferProducer();
296 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
297
298 std::function<bool()> condition = [=]() { return sf->authenticateSurfaceTexture(producer); };
299 // Anyone should be able to check if the consumer of the buffer queue is SF.
300 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
301}
302
303TEST_F(CredentialsTest, GetLayerDebugInfo) {
304 setupBackgroundSurface();
305 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
306
307 // Historically, only root and shell can access the getLayerDebugInfo which
308 // is called when we call dumpsys. I don't see a reason why we should change this.
309 std::vector<LayerDebugInfo> outLayers;
310 // Check with root.
311 seteuid(AID_ROOT);
312 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
313
314 // Check as a shell.
315 seteuid(AID_SHELL);
316 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
317
318 // Check as anyone else.
319 seteuid(AID_ROOT);
320 seteuid(AID_BIN);
321 ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers));
322}
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800323
324TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800325 const auto display = SurfaceComposerClient::getInternalDisplayToken();
326 ASSERT_FALSE(display == nullptr);
Peiyong Lin4f3fddf2019-01-24 17:21:24 -0800327 bool result = false;
328 status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result);
329 ASSERT_EQ(NO_ERROR, error);
330 bool hasWideColorMode = false;
331 Vector<ColorMode> colorModes;
332 SurfaceComposerClient::getDisplayColorModes(display, &colorModes);
333 for (ColorMode colorMode : colorModes) {
334 switch (colorMode) {
335 case ColorMode::DISPLAY_P3:
336 case ColorMode::ADOBE_RGB:
337 case ColorMode::DCI_P3:
338 hasWideColorMode = true;
339 break;
340 default:
341 break;
342 }
343 }
344 ASSERT_EQ(hasWideColorMode, result);
345}
346
347TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) {
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 std::function<status_t()> condition = [=]() {
351 bool result = false;
352 return SurfaceComposerClient::isWideColorDisplay(display, &result);
353 };
354 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
355}
356
Peiyong Lind1fedb42019-03-11 17:48:41 -0700357TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) {
358 const auto display = SurfaceComposerClient::getInternalDisplayToken();
359 ASSERT_FALSE(display == nullptr);
360 ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(display);
361 ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode);
362}
363
Ana Krulec13be8ad2018-08-21 02:43:56 +0000364} // namespace android