blob: cd57411761153060610e7c50e27292b6bdeeba1b [file] [log] [blame]
Ana Krulecfbe2c002018-08-09 22:32:45 +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>
15
16#include <ui/DisplayInfo.h>
17#include <utils/String8.h>
18
19namespace android {
20
21using Transaction = SurfaceComposerClient::Transaction;
22
23namespace {
24const String8 DISPLAY_NAME("Credentials Display Test");
25const String8 SURFACE_NAME("Test Surface Name");
26const int32_t MIN_LAYER_Z = 0;
27const int32_t MAX_LAYER_Z = std::numeric_limits<int32_t>::max();
28const uint32_t ROTATION = 0;
29const float FRAME_SCALE = 1.0f;
30} // namespace
31
32/**
33 * This class tests the CheckCredentials method in SurfaceFlinger.
34 * Methods like EnableVsyncInjections and InjectVsync are not tested since they do not
35 * return anything meaningful.
36 */
37class CredentialsTest : public ::testing::Test {
38protected:
39 void SetUp() override {
40 // Start the tests as root.
41 seteuid(AID_ROOT);
42
43 ASSERT_NO_FATAL_FAILURE(initClient());
44 }
45
46 void TearDown() override {
47 mComposerClient->dispose();
48 mBGSurfaceControl.clear();
49 mComposerClient.clear();
50 // Finish the tests as root.
51 seteuid(AID_ROOT);
52 }
53
54 sp<IBinder> mDisplay;
55 sp<IBinder> mVirtualDisplay;
56 sp<SurfaceComposerClient> mComposerClient;
57 sp<SurfaceControl> mBGSurfaceControl;
58 sp<SurfaceControl> mVirtualSurfaceControl;
59
60 void initClient() {
61 mComposerClient = new SurfaceComposerClient;
62 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
63 }
64
65 void setupBackgroundSurface() {
66 mDisplay = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
67 DisplayInfo info;
68 SurfaceComposerClient::getDisplayInfo(mDisplay, &info);
69 const ssize_t displayWidth = info.w;
70 const ssize_t displayHeight = info.h;
71
72 // Background surface
73 mBGSurfaceControl =
74 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
75 PIXEL_FORMAT_RGBA_8888, 0);
76 ASSERT_TRUE(mBGSurfaceControl != nullptr);
77 ASSERT_TRUE(mBGSurfaceControl->isValid());
78
79 Transaction t;
80 t.setDisplayLayerStack(mDisplay, 0);
81 ASSERT_EQ(NO_ERROR,
82 t.setLayer(mBGSurfaceControl, INT_MAX - 3).show(mBGSurfaceControl).apply());
83 }
84
85 void setupVirtualDisplay() {
86 mVirtualDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
87 const ssize_t displayWidth = 100;
88 const ssize_t displayHeight = 100;
89
90 // Background surface
91 mVirtualSurfaceControl =
92 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
93 PIXEL_FORMAT_RGBA_8888, 0);
94 ASSERT_TRUE(mVirtualSurfaceControl != nullptr);
95 ASSERT_TRUE(mVirtualSurfaceControl->isValid());
96
97 Transaction t;
98 t.setDisplayLayerStack(mVirtualDisplay, 0);
99 ASSERT_EQ(NO_ERROR,
100 t.setLayer(mVirtualSurfaceControl, INT_MAX - 3)
101 .show(mVirtualSurfaceControl)
102 .apply());
103 }
104
105 /**
106 * Sets UID to imitate Graphic's process.
107 */
108 void setGraphicsUID() {
109 seteuid(AID_ROOT);
110 seteuid(AID_GRAPHICS);
111 }
112
113 /**
114 * Sets UID to imitate System's process.
115 */
116 void setSystemUID() {
117 seteuid(AID_ROOT);
118 seteuid(AID_SYSTEM);
119 }
120
121 /**
122 * Sets UID to imitate a process that doesn't have any special privileges in
123 * our code.
124 */
125 void setBinUID() {
126 seteuid(AID_ROOT);
127 seteuid(AID_BIN);
128 }
129
130 /**
131 * Template function the check a condition for different types of users: root
132 * graphics, system, and non-supported user. Root, graphics, and system should
133 * always equal privilegedValue, and non-supported user should equal unprivilegedValue.
134 */
135 template <typename T>
136 void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) {
137 // Check with root.
138 seteuid(AID_ROOT);
139 ASSERT_EQ(privilegedValue, condition());
140
141 // Check as a Graphics user.
142 setGraphicsUID();
143 ASSERT_EQ(privilegedValue, condition());
144
145 // Check as a system user.
146 setSystemUID();
147 ASSERT_EQ(privilegedValue, condition());
148
149 // Check as a non-supported user.
150 setBinUID();
151 ASSERT_EQ(unprivilegedValue, condition());
152 }
153};
154
155TEST_F(CredentialsTest, ClientInitTest) {
156 // Root can init can init the client.
157 ASSERT_NO_FATAL_FAILURE(initClient());
158
159 // Graphics can init the client.
160 setGraphicsUID();
161 ASSERT_NO_FATAL_FAILURE(initClient());
162
163 // System can init the client.
164 setSystemUID();
165 ASSERT_NO_FATAL_FAILURE(initClient());
166
167 // No one else can init the client.
168 setBinUID();
169 mComposerClient = new SurfaceComposerClient;
170 ASSERT_EQ(NO_INIT, mComposerClient->initCheck());
171}
172
173TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
174 std::function<bool()> condition = [=]() {
175 sp<IBinder> display(
176 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
177 return (display != nullptr);
178 };
179 // Anyone can access display information.
180 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
181}
182
183TEST_F(CredentialsTest, AllowedGetterMethodsTest) {
184 // The following methods are tested with a UID that is not root, graphics,
185 // or system, to show that anyone can access them.
186 setBinUID();
187 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
188 ASSERT_TRUE(display != nullptr);
189
190 DisplayInfo info;
191 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
192
193 Vector<DisplayInfo> configs;
194 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayConfigs(display, &configs));
195
196 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveConfig(display));
197
198 ASSERT_NE(static_cast<ui::ColorMode>(BAD_VALUE),
199 SurfaceComposerClient::getActiveColorMode(display));
200}
201
202TEST_F(CredentialsTest, GetDisplayColorModesTest) {
203 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
204 std::function<status_t()> condition = [=]() {
205 Vector<ui::ColorMode> outColorModes;
206 return SurfaceComposerClient::getDisplayColorModes(display, &outColorModes);
207 };
208 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, NO_ERROR));
209}
210
211TEST_F(CredentialsTest, SetActiveConfigTest) {
212 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
213 std::function<status_t()> condition = [=]() {
214 return SurfaceComposerClient::setActiveConfig(display, 0);
215 };
216 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
217}
218
219TEST_F(CredentialsTest, SetActiveColorModeTest) {
220 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
221 std::function<status_t()> condition = [=]() {
222 return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE);
223 };
224 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
225}
226
227TEST_F(CredentialsTest, CreateSurfaceTest) {
228 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
229 DisplayInfo info;
230 SurfaceComposerClient::getDisplayInfo(display, &info);
231 const ssize_t displayWidth = info.w;
232 const ssize_t displayHeight = info.h;
233
234 std::function<bool()> condition = [=]() {
235 mBGSurfaceControl =
236 mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
237 PIXEL_FORMAT_RGBA_8888, 0);
238 return mBGSurfaceControl != nullptr && mBGSurfaceControl->isValid();
239 };
240 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
241}
242
243TEST_F(CredentialsTest, CreateDisplayTest) {
244 std::function<bool()> condition = [=]() {
245 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
246 return testDisplay.get() != nullptr;
247 };
248 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
249
250 condition = [=]() {
251 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
252 return testDisplay.get() != nullptr;
253 };
254 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
255}
256
257TEST_F(CredentialsTest, DISABLED_DestroyDisplayTest) {
258 setupVirtualDisplay();
259
260 DisplayInfo info;
261 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mVirtualDisplay, &info));
262 SurfaceComposerClient::destroyDisplay(mVirtualDisplay);
263 // This test currently fails. TODO(b/112002626): Find a way to properly create
264 // a display in the test environment, so that destroy display can remove it.
265 ASSERT_EQ(NAME_NOT_FOUND, SurfaceComposerClient::getDisplayInfo(mVirtualDisplay, &info));
266}
267
268TEST_F(CredentialsTest, CaptureTest) {
269 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
270 std::function<status_t()> condition = [=]() {
271 sp<GraphicBuffer> outBuffer;
272 return ScreenshotClient::capture(display, Rect(), 0 /*reqWidth*/, 0 /*reqHeight*/,
273 MIN_LAYER_Z, MAX_LAYER_Z, false, ROTATION, &outBuffer);
274 };
275 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
276}
277
278TEST_F(CredentialsTest, CaptureLayersTest) {
279 setupBackgroundSurface();
280 sp<GraphicBuffer> outBuffer;
281 std::function<status_t()> condition = [=]() {
282 sp<GraphicBuffer> outBuffer;
283 return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(), Rect(), FRAME_SCALE,
284 &outBuffer);
285 };
286 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
287}
288
289/**
290 * Test for methods accessible directly through 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 ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
300}
301
302TEST_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.
310 seteuid(AID_ROOT);
311 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
312
313 // Check as a shell.
314 seteuid(AID_SHELL);
315 ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers));
316
317 // Check as anyone else.
318 seteuid(AID_ROOT);
319 seteuid(AID_BIN);
320 ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers));
321}
322} // namespace android