blob: 97cba631922547e81991d884e8258b9184f5df01 [file] [log] [blame]
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001/*
2 * Copyright (C) 2019 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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Valerie Hau9cfc6d82019-09-23 13:54:07 -070021#include <private/android_filesystem_config.h>
22#include <thread>
23#include "LayerTransactionTest.h"
24
25namespace android {
26
27using android::hardware::graphics::common::V1_1::BufferUsage;
28
29TEST_F(LayerTransactionTest, SetFlagsSecureEUidSystem) {
30 sp<SurfaceControl> layer;
31 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
32 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
33
34 sp<ISurfaceComposer> composer = ComposerService::getComposerService();
35 sp<GraphicBuffer> outBuffer;
36 Transaction()
37 .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
38 .apply(true);
39 ASSERT_EQ(PERMISSION_DENIED,
40 composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false));
41
42 UIDFaker f(AID_SYSTEM);
43
44 // By default the system can capture screenshots with secure layers but they
45 // will be blacked out
46 ASSERT_EQ(NO_ERROR, composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false));
47
48 {
49 SCOPED_TRACE("as system");
50 auto shot = screenshot();
51 shot->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
52 }
53
54 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
55 // to receive them...we are expected to take care with the results.
56 bool outCapturedSecureLayers;
57 ASSERT_EQ(NO_ERROR,
58 composer->captureScreen(mDisplay, &outBuffer, outCapturedSecureLayers,
59 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), 0,
Dominik Laskowski718f9602019-11-09 20:01:35 -080060 0, false, ui::ROTATION_0, true));
Valerie Hau9cfc6d82019-09-23 13:54:07 -070061 ASSERT_EQ(true, outCapturedSecureLayers);
62 ScreenCapture sc(outBuffer);
63 sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
64}
65
66TEST_F(LayerTransactionTest, SetTransformToDisplayInverse_BufferState) {
67 sp<SurfaceControl> layer;
68 ASSERT_NO_FATAL_FAILURE(
69 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
70
71 Transaction().setTransformToDisplayInverse(layer, false).apply();
72
73 ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::GREEN, 32, 32));
74
75 Transaction().setTransformToDisplayInverse(layer, true).apply();
76}
77
78TEST_F(LayerTransactionTest, SetSidebandStreamNull_BufferState) {
79 sp<SurfaceControl> layer;
80 ASSERT_NO_FATAL_FAILURE(
81 layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
82
83 // verify this doesn't cause a crash
84 Transaction().setSidebandStream(layer, nullptr).apply();
85}
86
87TEST_F(LayerTransactionTest, ReparentToSelf) {
88 sp<SurfaceControl> layer;
89 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
90 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
91 Transaction().reparent(layer, layer->getHandle()).apply();
92
93 {
94 // We expect the transaction to be silently dropped, but for SurfaceFlinger
95 // to still be functioning.
96 SCOPED_TRACE("after reparent to self");
97 const Rect rect(0, 0, 32, 32);
98 auto shot = screenshot();
99 shot->expectColor(rect, Color::RED);
100 shot->expectBorder(rect, Color::BLACK);
101 }
102}
103
104// This test ensures that when we drop an app buffer in SurfaceFlinger, we merge
105// the dropped buffer's damage region into the next buffer's damage region. If
106// we don't do this, we'll report an incorrect damage region to hardware
107// composer, resulting in broken rendering. This test checks the BufferQueue
108// case.
109//
110// Unfortunately, we don't currently have a way to inspect the damage region
111// SurfaceFlinger sends to hardware composer from a test, so this test requires
112// the dev to manually watch the device's screen during the test to spot broken
113// rendering. Because the results can't be automatically verified, this test is
114// marked disabled.
115TEST_F(LayerTransactionTest, DISABLED_BufferQueueLayerMergeDamageRegionWhenDroppingBuffers) {
116 const int width = mDisplayWidth;
117 const int height = mDisplayHeight;
118 sp<SurfaceControl> layer;
119 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height));
120 const auto producer = layer->getIGraphicBufferProducer();
121 const sp<IProducerListener> dummyListener(new DummyProducerListener);
122 IGraphicBufferProducer::QueueBufferOutput queueBufferOutput;
123 ASSERT_EQ(OK,
124 producer->connect(dummyListener, NATIVE_WINDOW_API_CPU, true, &queueBufferOutput));
125
126 std::map<int, sp<GraphicBuffer>> slotMap;
127 auto slotToBuffer = [&](int slot, sp<GraphicBuffer>* buf) {
128 ASSERT_NE(nullptr, buf);
129 const auto iter = slotMap.find(slot);
130 ASSERT_NE(slotMap.end(), iter);
131 *buf = iter->second;
132 };
133
134 auto dequeue = [&](int* outSlot) {
135 ASSERT_NE(nullptr, outSlot);
136 *outSlot = -1;
137 int slot;
138 sp<Fence> fence;
139 uint64_t age;
140 FrameEventHistoryDelta timestamps;
141 const status_t dequeueResult =
142 producer->dequeueBuffer(&slot, &fence, width, height, PIXEL_FORMAT_RGBA_8888,
143 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
144 &age, &timestamps);
145 if (dequeueResult == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
146 sp<GraphicBuffer> newBuf;
147 ASSERT_EQ(OK, producer->requestBuffer(slot, &newBuf));
148 ASSERT_NE(nullptr, newBuf.get());
149 slotMap[slot] = newBuf;
150 } else {
151 ASSERT_EQ(OK, dequeueResult);
152 }
153 *outSlot = slot;
154 };
155
156 auto queue = [&](int slot, const Region& damage, nsecs_t displayTime) {
157 IGraphicBufferProducer::QueueBufferInput input(
158 /*timestamp=*/displayTime, /*isAutoTimestamp=*/false, HAL_DATASPACE_UNKNOWN,
159 /*crop=*/Rect::EMPTY_RECT, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
160 /*transform=*/0, Fence::NO_FENCE);
161 input.setSurfaceDamage(damage);
162 IGraphicBufferProducer::QueueBufferOutput output;
163 ASSERT_EQ(OK, producer->queueBuffer(slot, input, &output));
164 };
165
166 auto fillAndPostBuffers = [&](const Color& color) {
167 int slot1;
168 ASSERT_NO_FATAL_FAILURE(dequeue(&slot1));
169 int slot2;
170 ASSERT_NO_FATAL_FAILURE(dequeue(&slot2));
171
172 sp<GraphicBuffer> buf1;
173 ASSERT_NO_FATAL_FAILURE(slotToBuffer(slot1, &buf1));
174 sp<GraphicBuffer> buf2;
175 ASSERT_NO_FATAL_FAILURE(slotToBuffer(slot2, &buf2));
176 TransactionUtils::fillGraphicBufferColor(buf1, Rect(width, height), color);
177 TransactionUtils::fillGraphicBufferColor(buf2, Rect(width, height), color);
178
179 const auto displayTime = systemTime() + milliseconds_to_nanoseconds(100);
180 ASSERT_NO_FATAL_FAILURE(queue(slot1, Region::INVALID_REGION, displayTime));
181 ASSERT_NO_FATAL_FAILURE(
182 queue(slot2, Region(Rect(width / 3, height / 3, 2 * width / 3, 2 * height / 3)),
183 displayTime));
184 };
185
186 const auto startTime = systemTime();
187 const std::array<Color, 3> colors = {Color::RED, Color::GREEN, Color::BLUE};
188 int colorIndex = 0;
189 while (nanoseconds_to_seconds(systemTime() - startTime) < 10) {
190 ASSERT_NO_FATAL_FAILURE(fillAndPostBuffers(colors[colorIndex++ % colors.size()]));
191 std::this_thread::sleep_for(1s);
192 }
193
194 ASSERT_EQ(OK, producer->disconnect(NATIVE_WINDOW_API_CPU));
195}
196} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800197
198// TODO(b/129481165): remove the #pragma below and fix conversion issues
199#pragma clang diagnostic pop // ignored "-Wconversion"