1 /*
2 * Copyright (C) 2016 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 #include <frameworks/native/cmds/surfacereplayer/proto/src/trace.pb.h>
18 #include <google/protobuf/io/zero_copy_stream_impl.h>
19
20 #include <gtest/gtest.h>
21
22 #include <android/native_window.h>
23
24 #include <gui/ISurfaceComposer.h>
25 #include <gui/LayerState.h>
26 #include <gui/Surface.h>
27 #include <gui/SurfaceComposerClient.h>
28
29 #include <private/gui/ComposerService.h>
30 #include <ui/DisplayInfo.h>
31
32 #include <fstream>
33 #include <random>
34 #include <thread>
35
36 namespace android {
37
38 using Transaction = SurfaceComposerClient::Transaction;
39
40 constexpr int32_t SCALING_UPDATE = 1;
41 constexpr uint32_t BUFFER_UPDATES = 18;
42 constexpr uint32_t LAYER_UPDATE = INT_MAX - 2;
43 constexpr uint32_t SIZE_UPDATE = 134;
44 constexpr uint32_t STACK_UPDATE = 1;
45 constexpr uint64_t DEFERRED_UPDATE = 0;
46 constexpr float ALPHA_UPDATE = 0.29f;
47 constexpr float CORNER_RADIUS_UPDATE = 0.2f;
48 constexpr float POSITION_UPDATE = 121;
49 const Rect CROP_UPDATE(16, 16, 32, 32);
50
51 const String8 DISPLAY_NAME("SurfaceInterceptor Display Test");
52 constexpr auto TEST_SURFACE_NAME = "BG Interceptor Test Surface";
53 constexpr auto UNIQUE_TEST_SURFACE_NAME = "BG Interceptor Test Surface#0";
54 constexpr auto LAYER_NAME = "Layer Create and Delete Test";
55 constexpr auto UNIQUE_LAYER_NAME = "Layer Create and Delete Test#0";
56
57 constexpr auto DEFAULT_FILENAME = "/data/SurfaceTrace.dat";
58
59 // Fill an RGBA_8888 formatted surface with a single color.
fillSurfaceRGBA8(const sp<SurfaceControl> & sc,uint8_t r,uint8_t g,uint8_t b)60 static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, uint8_t r, uint8_t g, uint8_t b) {
61 ANativeWindow_Buffer outBuffer;
62 sp<Surface> s = sc->getSurface();
63 ASSERT_TRUE(s != nullptr);
64 ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
65 uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
66 for (int y = 0; y < outBuffer.height; y++) {
67 for (int x = 0; x < outBuffer.width; x++) {
68 uint8_t* pixel = img + (4 * (y*outBuffer.stride + x));
69 pixel[0] = r;
70 pixel[1] = g;
71 pixel[2] = b;
72 pixel[3] = 255;
73 }
74 }
75 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
76 }
77
readProtoFile(Trace * trace)78 static status_t readProtoFile(Trace* trace) {
79 status_t err = NO_ERROR;
80
81 int fd = open(DEFAULT_FILENAME, O_RDONLY);
82 {
83 google::protobuf::io::FileInputStream f(fd);
84 if (fd && !trace->ParseFromZeroCopyStream(&f)) {
85 err = PERMISSION_DENIED;
86 }
87 }
88 close(fd);
89
90 return err;
91 }
92
enableInterceptor()93 static void enableInterceptor() {
94 system("service call SurfaceFlinger 1020 i32 1 > /dev/null");
95 }
96
disableInterceptor()97 static void disableInterceptor() {
98 system("service call SurfaceFlinger 1020 i32 0 > /dev/null");
99 }
100
getSurfaceId(const Trace & capturedTrace,const std::string & surfaceName)101 int32_t getSurfaceId(const Trace& capturedTrace, const std::string& surfaceName) {
102 int32_t layerId = 0;
103 for (const auto& increment : capturedTrace.increment()) {
104 if (increment.increment_case() == increment.kSurfaceCreation) {
105 if (increment.surface_creation().name() == surfaceName) {
106 layerId = increment.surface_creation().id();
107 }
108 }
109 }
110 return layerId;
111 }
112
getDisplayId(const Trace & capturedTrace,const std::string & displayName)113 int32_t getDisplayId(const Trace& capturedTrace, const std::string& displayName) {
114 int32_t displayId = 0;
115 for (const auto& increment : capturedTrace.increment()) {
116 if (increment.increment_case() == increment.kDisplayCreation) {
117 if (increment.display_creation().name() == displayName) {
118 displayId = increment.display_creation().id();
119 break;
120 }
121 }
122 }
123 return displayId;
124 }
125
126 class SurfaceInterceptorTest : public ::testing::Test {
127 protected:
SetUp()128 void SetUp() override {
129 // Allow SurfaceInterceptor write to /data
130 system("setenforce 0");
131
132 mComposerClient = new SurfaceComposerClient;
133 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
134 }
135
TearDown()136 void TearDown() override {
137 mComposerClient->dispose();
138 mBGSurfaceControl.clear();
139 mComposerClient.clear();
140 }
141
142 sp<SurfaceComposerClient> mComposerClient;
143 sp<SurfaceControl> mBGSurfaceControl;
144 int32_t mBGLayerId;
145
146 public:
147 using TestTransactionAction = void (SurfaceInterceptorTest::*)(Transaction&);
148 using TestAction = void (SurfaceInterceptorTest::*)();
149 using TestBooleanVerification = bool (SurfaceInterceptorTest::*)(const Trace&);
150 using TestVerification = void (SurfaceInterceptorTest::*)(const Trace&);
151
152 void setupBackgroundSurface();
153 void preProcessTrace(const Trace& trace);
154
155 // captureTest will enable SurfaceInterceptor, setup background surface,
156 // disable SurfaceInterceptor, collect the trace and process the trace for
157 // id of background surface before further verification.
158 void captureTest(TestTransactionAction action, TestBooleanVerification verification);
159 void captureTest(TestTransactionAction action, SurfaceChange::SurfaceChangeCase changeCase);
160 void captureTest(TestTransactionAction action, Increment::IncrementCase incrementCase);
161 void captureTest(TestAction action, TestBooleanVerification verification);
162 void captureTest(TestAction action, TestVerification verification);
163 void runInTransaction(TestTransactionAction action);
164
165 // Verification of changes to a surface
166 bool positionUpdateFound(const SurfaceChange& change, bool foundPosition);
167 bool sizeUpdateFound(const SurfaceChange& change, bool foundSize);
168 bool alphaUpdateFound(const SurfaceChange& change, bool foundAlpha);
169 bool layerUpdateFound(const SurfaceChange& change, bool foundLayer);
170 bool cropUpdateFound(const SurfaceChange& change, bool foundCrop);
171 bool cornerRadiusUpdateFound(const SurfaceChange& change, bool foundCornerRadius);
172 bool matrixUpdateFound(const SurfaceChange& change, bool foundMatrix);
173 bool scalingModeUpdateFound(const SurfaceChange& change, bool foundScalingMode);
174 bool transparentRegionHintUpdateFound(const SurfaceChange& change, bool foundTransparentRegion);
175 bool layerStackUpdateFound(const SurfaceChange& change, bool foundLayerStack);
176 bool hiddenFlagUpdateFound(const SurfaceChange& change, bool foundHiddenFlag);
177 bool opaqueFlagUpdateFound(const SurfaceChange& change, bool foundOpaqueFlag);
178 bool secureFlagUpdateFound(const SurfaceChange& change, bool foundSecureFlag);
179 bool deferredTransactionUpdateFound(const SurfaceChange& change, bool foundDeferred);
180 bool surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase);
181
182 // Find all of the updates in the single trace
183 void assertAllUpdatesFound(const Trace& trace);
184
185 // Verification of creation and deletion of a surface
186 bool surfaceCreationFound(const Increment& increment, bool foundSurface);
187 bool surfaceDeletionFound(const Increment& increment, const int32_t targetId,
188 bool foundSurface);
189 bool displayCreationFound(const Increment& increment, bool foundDisplay);
190 bool displayDeletionFound(const Increment& increment, const int32_t targetId,
191 bool foundDisplay);
192 bool singleIncrementFound(const Trace& trace, Increment::IncrementCase incrementCase);
193
194 // Verification of buffer updates
195 bool bufferUpdatesFound(const Trace& trace);
196
197 // Perform each of the possible changes to a surface
198 void positionUpdate(Transaction&);
199 void sizeUpdate(Transaction&);
200 void alphaUpdate(Transaction&);
201 void layerUpdate(Transaction&);
202 void cropUpdate(Transaction&);
203 void cornerRadiusUpdate(Transaction&);
204 void matrixUpdate(Transaction&);
205 void overrideScalingModeUpdate(Transaction&);
206 void transparentRegionHintUpdate(Transaction&);
207 void layerStackUpdate(Transaction&);
208 void hiddenFlagUpdate(Transaction&);
209 void opaqueFlagUpdate(Transaction&);
210 void secureFlagUpdate(Transaction&);
211 void deferredTransactionUpdate(Transaction&);
212 void surfaceCreation(Transaction&);
213 void displayCreation(Transaction&);
214 void displayDeletion(Transaction&);
215
216 void nBufferUpdates();
217 void runAllUpdates();
218
219 private:
220 void captureInTransaction(TestTransactionAction action, Trace*);
221 void capture(TestAction action, Trace*);
222 };
223
captureInTransaction(TestTransactionAction action,Trace * outTrace)224 void SurfaceInterceptorTest::captureInTransaction(TestTransactionAction action, Trace* outTrace) {
225 enableInterceptor();
226 setupBackgroundSurface();
227 runInTransaction(action);
228 disableInterceptor();
229 ASSERT_EQ(NO_ERROR, readProtoFile(outTrace));
230 preProcessTrace(*outTrace);
231 }
232
capture(TestAction action,Trace * outTrace)233 void SurfaceInterceptorTest::capture(TestAction action, Trace* outTrace) {
234 enableInterceptor();
235 setupBackgroundSurface();
236 (this->*action)();
237 disableInterceptor();
238 ASSERT_EQ(NO_ERROR, readProtoFile(outTrace));
239 preProcessTrace(*outTrace);
240 }
241
setupBackgroundSurface()242 void SurfaceInterceptorTest::setupBackgroundSurface() {
243 const auto display = SurfaceComposerClient::getInternalDisplayToken();
244 ASSERT_FALSE(display == nullptr);
245
246 DisplayInfo info;
247 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info));
248
249 ssize_t displayWidth = info.w;
250 ssize_t displayHeight = info.h;
251
252 // Background surface
253 mBGSurfaceControl = mComposerClient->createSurface(
254 String8(TEST_SURFACE_NAME), displayWidth, displayHeight,
255 PIXEL_FORMAT_RGBA_8888, 0);
256 ASSERT_TRUE(mBGSurfaceControl != nullptr);
257 ASSERT_TRUE(mBGSurfaceControl->isValid());
258
259 Transaction t;
260 t.setDisplayLayerStack(display, 0);
261 ASSERT_EQ(NO_ERROR, t.setLayer(mBGSurfaceControl, INT_MAX-3)
262 .show(mBGSurfaceControl)
263 .apply());
264 }
265
preProcessTrace(const Trace & trace)266 void SurfaceInterceptorTest::preProcessTrace(const Trace& trace) {
267 mBGLayerId = getSurfaceId(trace, UNIQUE_TEST_SURFACE_NAME);
268 }
269
captureTest(TestTransactionAction action,TestBooleanVerification verification)270 void SurfaceInterceptorTest::captureTest(TestTransactionAction action,
271 TestBooleanVerification verification) {
272 Trace capturedTrace;
273 captureInTransaction(action, &capturedTrace);
274 ASSERT_TRUE((this->*verification)(capturedTrace));
275 }
276
captureTest(TestTransactionAction action,Increment::IncrementCase incrementCase)277 void SurfaceInterceptorTest::captureTest(TestTransactionAction action,
278 Increment::IncrementCase incrementCase) {
279 Trace capturedTrace;
280 captureInTransaction(action, &capturedTrace);
281 ASSERT_TRUE(singleIncrementFound(capturedTrace, incrementCase));
282 }
283
captureTest(TestTransactionAction action,SurfaceChange::SurfaceChangeCase changeCase)284 void SurfaceInterceptorTest::captureTest(TestTransactionAction action,
285 SurfaceChange::SurfaceChangeCase changeCase) {
286 Trace capturedTrace;
287 captureInTransaction(action, &capturedTrace);
288 ASSERT_TRUE(surfaceUpdateFound(capturedTrace, changeCase));
289 }
290
captureTest(TestAction action,TestBooleanVerification verification)291 void SurfaceInterceptorTest::captureTest(TestAction action, TestBooleanVerification verification) {
292 Trace capturedTrace;
293 capture(action, &capturedTrace);
294 ASSERT_TRUE((this->*verification)(capturedTrace));
295 }
296
captureTest(TestAction action,TestVerification verification)297 void SurfaceInterceptorTest::captureTest(TestAction action, TestVerification verification) {
298 Trace capturedTrace;
299 capture(action, &capturedTrace);
300 (this->*verification)(capturedTrace);
301 }
302
runInTransaction(TestTransactionAction action)303 void SurfaceInterceptorTest::runInTransaction(TestTransactionAction action) {
304 Transaction t;
305 (this->*action)(t);
306 t.apply(true);
307 }
308
positionUpdate(Transaction & t)309 void SurfaceInterceptorTest::positionUpdate(Transaction& t) {
310 t.setPosition(mBGSurfaceControl, POSITION_UPDATE, POSITION_UPDATE);
311 }
312
sizeUpdate(Transaction & t)313 void SurfaceInterceptorTest::sizeUpdate(Transaction& t) {
314 t.setSize(mBGSurfaceControl, SIZE_UPDATE, SIZE_UPDATE);
315 }
316
alphaUpdate(Transaction & t)317 void SurfaceInterceptorTest::alphaUpdate(Transaction& t) {
318 t.setAlpha(mBGSurfaceControl, ALPHA_UPDATE);
319 }
320
cornerRadiusUpdate(Transaction & t)321 void SurfaceInterceptorTest::cornerRadiusUpdate(Transaction& t) {
322 t.setCornerRadius(mBGSurfaceControl, CORNER_RADIUS_UPDATE);
323 }
324
layerUpdate(Transaction & t)325 void SurfaceInterceptorTest::layerUpdate(Transaction& t) {
326 t.setLayer(mBGSurfaceControl, LAYER_UPDATE);
327 }
328
cropUpdate(Transaction & t)329 void SurfaceInterceptorTest::cropUpdate(Transaction& t) {
330 t.setCrop_legacy(mBGSurfaceControl, CROP_UPDATE);
331 }
332
matrixUpdate(Transaction & t)333 void SurfaceInterceptorTest::matrixUpdate(Transaction& t) {
334 t.setMatrix(mBGSurfaceControl, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2);
335 }
336
overrideScalingModeUpdate(Transaction & t)337 void SurfaceInterceptorTest::overrideScalingModeUpdate(Transaction& t) {
338 t.setOverrideScalingMode(mBGSurfaceControl, SCALING_UPDATE);
339 }
340
transparentRegionHintUpdate(Transaction & t)341 void SurfaceInterceptorTest::transparentRegionHintUpdate(Transaction& t) {
342 Region region(CROP_UPDATE);
343 t.setTransparentRegionHint(mBGSurfaceControl, region);
344 }
345
layerStackUpdate(Transaction & t)346 void SurfaceInterceptorTest::layerStackUpdate(Transaction& t) {
347 t.setLayerStack(mBGSurfaceControl, STACK_UPDATE);
348 }
349
hiddenFlagUpdate(Transaction & t)350 void SurfaceInterceptorTest::hiddenFlagUpdate(Transaction& t) {
351 t.setFlags(mBGSurfaceControl, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
352 }
353
opaqueFlagUpdate(Transaction & t)354 void SurfaceInterceptorTest::opaqueFlagUpdate(Transaction& t) {
355 t.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque);
356 }
357
secureFlagUpdate(Transaction & t)358 void SurfaceInterceptorTest::secureFlagUpdate(Transaction& t) {
359 t.setFlags(mBGSurfaceControl, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
360 }
361
deferredTransactionUpdate(Transaction & t)362 void SurfaceInterceptorTest::deferredTransactionUpdate(Transaction& t) {
363 t.deferTransactionUntil_legacy(mBGSurfaceControl, mBGSurfaceControl->getHandle(),
364 DEFERRED_UPDATE);
365 }
366
displayCreation(Transaction &)367 void SurfaceInterceptorTest::displayCreation(Transaction&) {
368 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
369 SurfaceComposerClient::destroyDisplay(testDisplay);
370 }
371
displayDeletion(Transaction &)372 void SurfaceInterceptorTest::displayDeletion(Transaction&) {
373 sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
374 SurfaceComposerClient::destroyDisplay(testDisplay);
375 }
376
runAllUpdates()377 void SurfaceInterceptorTest::runAllUpdates() {
378 runInTransaction(&SurfaceInterceptorTest::positionUpdate);
379 runInTransaction(&SurfaceInterceptorTest::sizeUpdate);
380 runInTransaction(&SurfaceInterceptorTest::alphaUpdate);
381 runInTransaction(&SurfaceInterceptorTest::cornerRadiusUpdate);
382 runInTransaction(&SurfaceInterceptorTest::layerUpdate);
383 runInTransaction(&SurfaceInterceptorTest::cropUpdate);
384 runInTransaction(&SurfaceInterceptorTest::matrixUpdate);
385 runInTransaction(&SurfaceInterceptorTest::overrideScalingModeUpdate);
386 runInTransaction(&SurfaceInterceptorTest::transparentRegionHintUpdate);
387 runInTransaction(&SurfaceInterceptorTest::layerStackUpdate);
388 runInTransaction(&SurfaceInterceptorTest::hiddenFlagUpdate);
389 runInTransaction(&SurfaceInterceptorTest::opaqueFlagUpdate);
390 runInTransaction(&SurfaceInterceptorTest::secureFlagUpdate);
391 runInTransaction(&SurfaceInterceptorTest::deferredTransactionUpdate);
392 }
393
surfaceCreation(Transaction &)394 void SurfaceInterceptorTest::surfaceCreation(Transaction&) {
395 mComposerClient->createSurface(String8(LAYER_NAME), SIZE_UPDATE, SIZE_UPDATE,
396 PIXEL_FORMAT_RGBA_8888, 0);
397 }
398
nBufferUpdates()399 void SurfaceInterceptorTest::nBufferUpdates() {
400 std::random_device rd;
401 std::mt19937_64 gen(rd());
402 // This makes testing fun
403 std::uniform_int_distribution<uint8_t> dis;
404 for (uint32_t i = 0; i < BUFFER_UPDATES; ++i) {
405 fillSurfaceRGBA8(mBGSurfaceControl, dis(gen), dis(gen), dis(gen));
406 }
407 }
408
positionUpdateFound(const SurfaceChange & change,bool foundPosition)409 bool SurfaceInterceptorTest::positionUpdateFound(const SurfaceChange& change, bool foundPosition) {
410 // There should only be one position transaction with x and y = POSITION_UPDATE
411 bool hasX(change.position().x() == POSITION_UPDATE);
412 bool hasY(change.position().y() == POSITION_UPDATE);
413 if (hasX && hasY && !foundPosition) {
414 foundPosition = true;
415 } else if (hasX && hasY && foundPosition) {
416 // Failed because the position update was found a second time
417 [] () { FAIL(); }();
418 }
419 return foundPosition;
420 }
421
sizeUpdateFound(const SurfaceChange & change,bool foundSize)422 bool SurfaceInterceptorTest::sizeUpdateFound(const SurfaceChange& change, bool foundSize) {
423 bool hasWidth(change.size().h() == SIZE_UPDATE);
424 bool hasHeight(change.size().w() == SIZE_UPDATE);
425 if (hasWidth && hasHeight && !foundSize) {
426 foundSize = true;
427 } else if (hasWidth && hasHeight && foundSize) {
428 [] () { FAIL(); }();
429 }
430 return foundSize;
431 }
432
alphaUpdateFound(const SurfaceChange & change,bool foundAlpha)433 bool SurfaceInterceptorTest::alphaUpdateFound(const SurfaceChange& change, bool foundAlpha) {
434 bool hasAlpha(change.alpha().alpha() == ALPHA_UPDATE);
435 if (hasAlpha && !foundAlpha) {
436 foundAlpha = true;
437 } else if (hasAlpha && foundAlpha) {
438 [] () { FAIL(); }();
439 }
440 return foundAlpha;
441 }
442
cornerRadiusUpdateFound(const SurfaceChange & change,bool foundCornerRadius)443 bool SurfaceInterceptorTest::cornerRadiusUpdateFound(const SurfaceChange &change,
444 bool foundCornerRadius) {
445 bool hasCornerRadius(change.corner_radius().corner_radius() == CORNER_RADIUS_UPDATE);
446 if (hasCornerRadius && !foundCornerRadius) {
447 foundCornerRadius = true;
448 } else if (hasCornerRadius && foundCornerRadius) {
449 [] () { FAIL(); }();
450 }
451 return foundCornerRadius;
452 }
453
layerUpdateFound(const SurfaceChange & change,bool foundLayer)454 bool SurfaceInterceptorTest::layerUpdateFound(const SurfaceChange& change, bool foundLayer) {
455 bool hasLayer(change.layer().layer() == LAYER_UPDATE);
456 if (hasLayer && !foundLayer) {
457 foundLayer = true;
458 } else if (hasLayer && foundLayer) {
459 [] () { FAIL(); }();
460 }
461 return foundLayer;
462 }
463
cropUpdateFound(const SurfaceChange & change,bool foundCrop)464 bool SurfaceInterceptorTest::cropUpdateFound(const SurfaceChange& change, bool foundCrop) {
465 bool hasLeft(change.crop().rectangle().left() == CROP_UPDATE.left);
466 bool hasTop(change.crop().rectangle().top() == CROP_UPDATE.top);
467 bool hasRight(change.crop().rectangle().right() == CROP_UPDATE.right);
468 bool hasBottom(change.crop().rectangle().bottom() == CROP_UPDATE.bottom);
469 if (hasLeft && hasRight && hasTop && hasBottom && !foundCrop) {
470 foundCrop = true;
471 } else if (hasLeft && hasRight && hasTop && hasBottom && foundCrop) {
472 [] () { FAIL(); }();
473 }
474 return foundCrop;
475 }
476
matrixUpdateFound(const SurfaceChange & change,bool foundMatrix)477 bool SurfaceInterceptorTest::matrixUpdateFound(const SurfaceChange& change, bool foundMatrix) {
478 bool hasSx((float)change.matrix().dsdx() == (float)M_SQRT1_2);
479 bool hasTx((float)change.matrix().dtdx() == (float)M_SQRT1_2);
480 bool hasSy((float)change.matrix().dsdy() == (float)M_SQRT1_2);
481 bool hasTy((float)change.matrix().dtdy() == (float)-M_SQRT1_2);
482 if (hasSx && hasTx && hasSy && hasTy && !foundMatrix) {
483 foundMatrix = true;
484 } else if (hasSx && hasTx && hasSy && hasTy && foundMatrix) {
485 [] () { FAIL(); }();
486 }
487 return foundMatrix;
488 }
489
scalingModeUpdateFound(const SurfaceChange & change,bool foundScalingMode)490 bool SurfaceInterceptorTest::scalingModeUpdateFound(const SurfaceChange& change,
491 bool foundScalingMode) {
492 bool hasScalingUpdate(change.override_scaling_mode().override_scaling_mode() == SCALING_UPDATE);
493 if (hasScalingUpdate && !foundScalingMode) {
494 foundScalingMode = true;
495 } else if (hasScalingUpdate && foundScalingMode) {
496 [] () { FAIL(); }();
497 }
498 return foundScalingMode;
499 }
500
transparentRegionHintUpdateFound(const SurfaceChange & change,bool foundTransparentRegion)501 bool SurfaceInterceptorTest::transparentRegionHintUpdateFound(const SurfaceChange& change,
502 bool foundTransparentRegion) {
503 auto traceRegion = change.transparent_region_hint().region(0);
504 bool hasLeft(traceRegion.left() == CROP_UPDATE.left);
505 bool hasTop(traceRegion.top() == CROP_UPDATE.top);
506 bool hasRight(traceRegion.right() == CROP_UPDATE.right);
507 bool hasBottom(traceRegion.bottom() == CROP_UPDATE.bottom);
508 if (hasLeft && hasRight && hasTop && hasBottom && !foundTransparentRegion) {
509 foundTransparentRegion = true;
510 } else if (hasLeft && hasRight && hasTop && hasBottom && foundTransparentRegion) {
511 [] () { FAIL(); }();
512 }
513 return foundTransparentRegion;
514 }
515
layerStackUpdateFound(const SurfaceChange & change,bool foundLayerStack)516 bool SurfaceInterceptorTest::layerStackUpdateFound(const SurfaceChange& change,
517 bool foundLayerStack) {
518 bool hasLayerStackUpdate(change.layer_stack().layer_stack() == STACK_UPDATE);
519 if (hasLayerStackUpdate && !foundLayerStack) {
520 foundLayerStack = true;
521 } else if (hasLayerStackUpdate && foundLayerStack) {
522 [] () { FAIL(); }();
523 }
524 return foundLayerStack;
525 }
526
hiddenFlagUpdateFound(const SurfaceChange & change,bool foundHiddenFlag)527 bool SurfaceInterceptorTest::hiddenFlagUpdateFound(const SurfaceChange& change,
528 bool foundHiddenFlag) {
529 bool hasHiddenFlag(change.hidden_flag().hidden_flag());
530 if (hasHiddenFlag && !foundHiddenFlag) {
531 foundHiddenFlag = true;
532 } else if (hasHiddenFlag && foundHiddenFlag) {
533 [] () { FAIL(); }();
534 }
535 return foundHiddenFlag;
536 }
537
opaqueFlagUpdateFound(const SurfaceChange & change,bool foundOpaqueFlag)538 bool SurfaceInterceptorTest::opaqueFlagUpdateFound(const SurfaceChange& change,
539 bool foundOpaqueFlag) {
540 bool hasOpaqueFlag(change.opaque_flag().opaque_flag());
541 if (hasOpaqueFlag && !foundOpaqueFlag) {
542 foundOpaqueFlag = true;
543 } else if (hasOpaqueFlag && foundOpaqueFlag) {
544 [] () { FAIL(); }();
545 }
546 return foundOpaqueFlag;
547 }
548
secureFlagUpdateFound(const SurfaceChange & change,bool foundSecureFlag)549 bool SurfaceInterceptorTest::secureFlagUpdateFound(const SurfaceChange& change,
550 bool foundSecureFlag) {
551 bool hasSecureFlag(change.secure_flag().secure_flag());
552 if (hasSecureFlag && !foundSecureFlag) {
553 foundSecureFlag = true;
554 } else if (hasSecureFlag && foundSecureFlag) {
555 [] () { FAIL(); }();
556 }
557 return foundSecureFlag;
558 }
559
deferredTransactionUpdateFound(const SurfaceChange & change,bool foundDeferred)560 bool SurfaceInterceptorTest::deferredTransactionUpdateFound(const SurfaceChange& change,
561 bool foundDeferred) {
562 bool hasId(change.deferred_transaction().layer_id() == mBGLayerId);
563 bool hasFrameNumber(change.deferred_transaction().frame_number() == DEFERRED_UPDATE);
564 if (hasId && hasFrameNumber && !foundDeferred) {
565 foundDeferred = true;
566 } else if (hasId && hasFrameNumber && foundDeferred) {
567 [] () { FAIL(); }();
568 }
569 return foundDeferred;
570 }
571
surfaceUpdateFound(const Trace & trace,SurfaceChange::SurfaceChangeCase changeCase)572 bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace,
573 SurfaceChange::SurfaceChangeCase changeCase) {
574 bool foundUpdate = false;
575 for (const auto& increment : trace.increment()) {
576 if (increment.increment_case() == increment.kTransaction) {
577 for (const auto& change : increment.transaction().surface_change()) {
578 if (change.id() == mBGLayerId && change.SurfaceChange_case() == changeCase) {
579 switch (changeCase) {
580 case SurfaceChange::SurfaceChangeCase::kPosition:
581 // foundUpdate is sent for the tests to fail on duplicated increments
582 foundUpdate = positionUpdateFound(change, foundUpdate);
583 break;
584 case SurfaceChange::SurfaceChangeCase::kSize:
585 foundUpdate = sizeUpdateFound(change, foundUpdate);
586 break;
587 case SurfaceChange::SurfaceChangeCase::kAlpha:
588 foundUpdate = alphaUpdateFound(change, foundUpdate);
589 break;
590 case SurfaceChange::SurfaceChangeCase::kLayer:
591 foundUpdate = layerUpdateFound(change, foundUpdate);
592 break;
593 case SurfaceChange::SurfaceChangeCase::kCrop:
594 foundUpdate = cropUpdateFound(change, foundUpdate);
595 break;
596 case SurfaceChange::SurfaceChangeCase::kCornerRadius:
597 foundUpdate = cornerRadiusUpdateFound(change, foundUpdate);
598 break;
599 case SurfaceChange::SurfaceChangeCase::kMatrix:
600 foundUpdate = matrixUpdateFound(change, foundUpdate);
601 break;
602 case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode:
603 foundUpdate = scalingModeUpdateFound(change, foundUpdate);
604 break;
605 case SurfaceChange::SurfaceChangeCase::kTransparentRegionHint:
606 foundUpdate = transparentRegionHintUpdateFound(change, foundUpdate);
607 break;
608 case SurfaceChange::SurfaceChangeCase::kLayerStack:
609 foundUpdate = layerStackUpdateFound(change, foundUpdate);
610 break;
611 case SurfaceChange::SurfaceChangeCase::kHiddenFlag:
612 foundUpdate = hiddenFlagUpdateFound(change, foundUpdate);
613 break;
614 case SurfaceChange::SurfaceChangeCase::kOpaqueFlag:
615 foundUpdate = opaqueFlagUpdateFound(change, foundUpdate);
616 break;
617 case SurfaceChange::SurfaceChangeCase::kSecureFlag:
618 foundUpdate = secureFlagUpdateFound(change, foundUpdate);
619 break;
620 case SurfaceChange::SurfaceChangeCase::kDeferredTransaction:
621 foundUpdate = deferredTransactionUpdateFound(change, foundUpdate);
622 break;
623 case SurfaceChange::SurfaceChangeCase::SURFACECHANGE_NOT_SET:
624 break;
625 }
626 }
627 }
628 }
629 }
630 return foundUpdate;
631 }
632
assertAllUpdatesFound(const Trace & trace)633 void SurfaceInterceptorTest::assertAllUpdatesFound(const Trace& trace) {
634 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kPosition));
635 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kSize));
636 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kAlpha));
637 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kLayer));
638 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kCrop));
639 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kMatrix));
640 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kOverrideScalingMode));
641 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kTransparentRegionHint));
642 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kLayerStack));
643 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kHiddenFlag));
644 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kOpaqueFlag));
645 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kSecureFlag));
646 ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kDeferredTransaction));
647 }
648
surfaceCreationFound(const Increment & increment,bool foundSurface)649 bool SurfaceInterceptorTest::surfaceCreationFound(const Increment& increment, bool foundSurface) {
650 bool isMatch(increment.surface_creation().name() == UNIQUE_LAYER_NAME &&
651 increment.surface_creation().w() == SIZE_UPDATE &&
652 increment.surface_creation().h() == SIZE_UPDATE);
653 if (isMatch && !foundSurface) {
654 foundSurface = true;
655 } else if (isMatch && foundSurface) {
656 [] () { FAIL(); }();
657 }
658 return foundSurface;
659 }
660
surfaceDeletionFound(const Increment & increment,const int32_t targetId,bool foundSurface)661 bool SurfaceInterceptorTest::surfaceDeletionFound(const Increment& increment,
662 const int32_t targetId, bool foundSurface) {
663 bool isMatch(increment.surface_deletion().id() == targetId);
664 if (isMatch && !foundSurface) {
665 foundSurface = true;
666 } else if (isMatch && foundSurface) {
667 [] () { FAIL(); }();
668 }
669 return foundSurface;
670 }
671
displayCreationFound(const Increment & increment,bool foundDisplay)672 bool SurfaceInterceptorTest::displayCreationFound(const Increment& increment, bool foundDisplay) {
673 bool isMatch(increment.display_creation().name() == DISPLAY_NAME.string() &&
674 increment.display_creation().is_secure());
675 if (isMatch && !foundDisplay) {
676 foundDisplay = true;
677 } else if (isMatch && foundDisplay) {
678 [] () { FAIL(); }();
679 }
680 return foundDisplay;
681 }
682
displayDeletionFound(const Increment & increment,const int32_t targetId,bool foundDisplay)683 bool SurfaceInterceptorTest::displayDeletionFound(const Increment& increment,
684 const int32_t targetId, bool foundDisplay) {
685 bool isMatch(increment.display_deletion().id() == targetId);
686 if (isMatch && !foundDisplay) {
687 foundDisplay = true;
688 } else if (isMatch && foundDisplay) {
689 [] () { FAIL(); }();
690 }
691 return foundDisplay;
692 }
693
singleIncrementFound(const Trace & trace,Increment::IncrementCase incrementCase)694 bool SurfaceInterceptorTest::singleIncrementFound(const Trace& trace,
695 Increment::IncrementCase incrementCase) {
696 bool foundIncrement = false;
697 for (const auto& increment : trace.increment()) {
698 if (increment.increment_case() == incrementCase) {
699 int32_t targetId = 0;
700 switch (incrementCase) {
701 case Increment::IncrementCase::kSurfaceCreation:
702 foundIncrement = surfaceCreationFound(increment, foundIncrement);
703 break;
704 case Increment::IncrementCase::kSurfaceDeletion:
705 // Find the id of created surface.
706 targetId = getSurfaceId(trace, UNIQUE_LAYER_NAME);
707 foundIncrement = surfaceDeletionFound(increment, targetId, foundIncrement);
708 break;
709 case Increment::IncrementCase::kDisplayCreation:
710 foundIncrement = displayCreationFound(increment, foundIncrement);
711 break;
712 case Increment::IncrementCase::kDisplayDeletion:
713 // Find the id of created display.
714 targetId = getDisplayId(trace, DISPLAY_NAME.string());
715 foundIncrement = displayDeletionFound(increment, targetId, foundIncrement);
716 break;
717 default:
718 /* code */
719 break;
720 }
721 }
722 }
723 return foundIncrement;
724 }
725
bufferUpdatesFound(const Trace & trace)726 bool SurfaceInterceptorTest::bufferUpdatesFound(const Trace& trace) {
727 uint32_t updates = 0;
728 for (const auto& inc : trace.increment()) {
729 if (inc.increment_case() == inc.kBufferUpdate && inc.buffer_update().id() == mBGLayerId) {
730 updates++;
731 }
732 }
733 return updates == BUFFER_UPDATES;
734 }
735
TEST_F(SurfaceInterceptorTest,InterceptPositionUpdateWorks)736 TEST_F(SurfaceInterceptorTest, InterceptPositionUpdateWorks) {
737 captureTest(&SurfaceInterceptorTest::positionUpdate,
738 SurfaceChange::SurfaceChangeCase::kPosition);
739 }
740
TEST_F(SurfaceInterceptorTest,InterceptSizeUpdateWorks)741 TEST_F(SurfaceInterceptorTest, InterceptSizeUpdateWorks) {
742 captureTest(&SurfaceInterceptorTest::sizeUpdate, SurfaceChange::SurfaceChangeCase::kSize);
743 }
744
TEST_F(SurfaceInterceptorTest,InterceptAlphaUpdateWorks)745 TEST_F(SurfaceInterceptorTest, InterceptAlphaUpdateWorks) {
746 captureTest(&SurfaceInterceptorTest::alphaUpdate, SurfaceChange::SurfaceChangeCase::kAlpha);
747 }
748
TEST_F(SurfaceInterceptorTest,InterceptLayerUpdateWorks)749 TEST_F(SurfaceInterceptorTest, InterceptLayerUpdateWorks) {
750 captureTest(&SurfaceInterceptorTest::layerUpdate, SurfaceChange::SurfaceChangeCase::kLayer);
751 }
752
TEST_F(SurfaceInterceptorTest,InterceptCropUpdateWorks)753 TEST_F(SurfaceInterceptorTest, InterceptCropUpdateWorks) {
754 captureTest(&SurfaceInterceptorTest::cropUpdate, SurfaceChange::SurfaceChangeCase::kCrop);
755 }
756
TEST_F(SurfaceInterceptorTest,InterceptCornerRadiusUpdateWorks)757 TEST_F(SurfaceInterceptorTest, InterceptCornerRadiusUpdateWorks) {
758 captureTest(&SurfaceInterceptorTest::cornerRadiusUpdate,
759 SurfaceChange::SurfaceChangeCase::kCornerRadius);
760 }
761
TEST_F(SurfaceInterceptorTest,InterceptMatrixUpdateWorks)762 TEST_F(SurfaceInterceptorTest, InterceptMatrixUpdateWorks) {
763 captureTest(&SurfaceInterceptorTest::matrixUpdate, SurfaceChange::SurfaceChangeCase::kMatrix);
764 }
765
TEST_F(SurfaceInterceptorTest,InterceptOverrideScalingModeUpdateWorks)766 TEST_F(SurfaceInterceptorTest, InterceptOverrideScalingModeUpdateWorks) {
767 captureTest(&SurfaceInterceptorTest::overrideScalingModeUpdate,
768 SurfaceChange::SurfaceChangeCase::kOverrideScalingMode);
769 }
770
TEST_F(SurfaceInterceptorTest,InterceptTransparentRegionHintUpdateWorks)771 TEST_F(SurfaceInterceptorTest, InterceptTransparentRegionHintUpdateWorks) {
772 captureTest(&SurfaceInterceptorTest::transparentRegionHintUpdate,
773 SurfaceChange::SurfaceChangeCase::kTransparentRegionHint);
774 }
775
TEST_F(SurfaceInterceptorTest,InterceptLayerStackUpdateWorks)776 TEST_F(SurfaceInterceptorTest, InterceptLayerStackUpdateWorks) {
777 captureTest(&SurfaceInterceptorTest::layerStackUpdate,
778 SurfaceChange::SurfaceChangeCase::kLayerStack);
779 }
780
TEST_F(SurfaceInterceptorTest,InterceptHiddenFlagUpdateWorks)781 TEST_F(SurfaceInterceptorTest, InterceptHiddenFlagUpdateWorks) {
782 captureTest(&SurfaceInterceptorTest::hiddenFlagUpdate,
783 SurfaceChange::SurfaceChangeCase::kHiddenFlag);
784 }
785
TEST_F(SurfaceInterceptorTest,InterceptOpaqueFlagUpdateWorks)786 TEST_F(SurfaceInterceptorTest, InterceptOpaqueFlagUpdateWorks) {
787 captureTest(&SurfaceInterceptorTest::opaqueFlagUpdate,
788 SurfaceChange::SurfaceChangeCase::kOpaqueFlag);
789 }
790
TEST_F(SurfaceInterceptorTest,InterceptSecureFlagUpdateWorks)791 TEST_F(SurfaceInterceptorTest, InterceptSecureFlagUpdateWorks) {
792 captureTest(&SurfaceInterceptorTest::secureFlagUpdate,
793 SurfaceChange::SurfaceChangeCase::kSecureFlag);
794 }
795
TEST_F(SurfaceInterceptorTest,InterceptDeferredTransactionUpdateWorks)796 TEST_F(SurfaceInterceptorTest, InterceptDeferredTransactionUpdateWorks) {
797 captureTest(&SurfaceInterceptorTest::deferredTransactionUpdate,
798 SurfaceChange::SurfaceChangeCase::kDeferredTransaction);
799 }
800
TEST_F(SurfaceInterceptorTest,InterceptAllUpdatesWorks)801 TEST_F(SurfaceInterceptorTest, InterceptAllUpdatesWorks) {
802 captureTest(&SurfaceInterceptorTest::runAllUpdates,
803 &SurfaceInterceptorTest::assertAllUpdatesFound);
804 }
805
TEST_F(SurfaceInterceptorTest,InterceptSurfaceCreationWorks)806 TEST_F(SurfaceInterceptorTest, InterceptSurfaceCreationWorks) {
807 captureTest(&SurfaceInterceptorTest::surfaceCreation,
808 Increment::IncrementCase::kSurfaceCreation);
809 }
810
TEST_F(SurfaceInterceptorTest,InterceptDisplayCreationWorks)811 TEST_F(SurfaceInterceptorTest, InterceptDisplayCreationWorks) {
812 captureTest(&SurfaceInterceptorTest::displayCreation,
813 Increment::IncrementCase::kDisplayCreation);
814 }
815
TEST_F(SurfaceInterceptorTest,InterceptDisplayDeletionWorks)816 TEST_F(SurfaceInterceptorTest, InterceptDisplayDeletionWorks) {
817 enableInterceptor();
818 runInTransaction(&SurfaceInterceptorTest::displayDeletion);
819 disableInterceptor();
820 Trace capturedTrace;
821 ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace));
822 ASSERT_TRUE(singleIncrementFound(capturedTrace, Increment::IncrementCase::kDisplayDeletion));
823 }
824
TEST_F(SurfaceInterceptorTest,InterceptBufferUpdateWorks)825 TEST_F(SurfaceInterceptorTest, InterceptBufferUpdateWorks) {
826 captureTest(&SurfaceInterceptorTest::nBufferUpdates,
827 &SurfaceInterceptorTest::bufferUpdatesFound);
828 }
829
830 // If the interceptor is enabled while buffer updates are being pushed, the interceptor should
831 // first create a snapshot of the existing displays and surfaces and then start capturing
832 // the buffer updates
TEST_F(SurfaceInterceptorTest,InterceptWhileBufferUpdatesWorks)833 TEST_F(SurfaceInterceptorTest, InterceptWhileBufferUpdatesWorks) {
834 setupBackgroundSurface();
835 std::thread bufferUpdates(&SurfaceInterceptorTest::nBufferUpdates, this);
836 enableInterceptor();
837 disableInterceptor();
838 bufferUpdates.join();
839
840 Trace capturedTrace;
841 ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace));
842 const auto& firstIncrement = capturedTrace.mutable_increment(0);
843 ASSERT_EQ(firstIncrement->increment_case(), Increment::IncrementCase::kDisplayCreation);
844 }
845
TEST_F(SurfaceInterceptorTest,InterceptSimultaneousUpdatesWorks)846 TEST_F(SurfaceInterceptorTest, InterceptSimultaneousUpdatesWorks) {
847 enableInterceptor();
848 setupBackgroundSurface();
849 std::thread bufferUpdates(&SurfaceInterceptorTest::nBufferUpdates, this);
850 std::thread surfaceUpdates(&SurfaceInterceptorTest::runAllUpdates, this);
851 runInTransaction(&SurfaceInterceptorTest::surfaceCreation);
852 bufferUpdates.join();
853 surfaceUpdates.join();
854 disableInterceptor();
855
856 Trace capturedTrace;
857 ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace));
858 preProcessTrace(capturedTrace);
859
860 assertAllUpdatesFound(capturedTrace);
861 ASSERT_TRUE(bufferUpdatesFound(capturedTrace));
862 ASSERT_TRUE(singleIncrementFound(capturedTrace, Increment::IncrementCase::kSurfaceCreation));
863 }
864
865 }
866