• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 
21 #include <gui/BufferItemConsumer.h>
22 #include <ui/Transform.h>
23 #include <thread>
24 #include "TransactionTestHarnesses.h"
25 
26 namespace android {
27 struct PresentationCallbackHelper {
callbackArrivedandroid::PresentationCallbackHelper28     void callbackArrived(bool state) {
29         std::unique_lock l(mMutex);
30         mGotCallback = true;
31         mState = state;
32         mCondition.notify_all();
33     }
awaitCallbackandroid::PresentationCallbackHelper34     bool awaitCallback() {
35         std::unique_lock l(mMutex);
36         mGotCallback = false;
37         mCondition.wait_for(l, 5000ms);
38         EXPECT_TRUE(mGotCallback);
39         return mState;
40     }
41 
42     bool mState;
43     bool mGotCallback;
44     std::mutex mMutex;
45     std::condition_variable mCondition;
46 };
47 
thresh()48 TrustedPresentationThresholds thresh() {
49     TrustedPresentationThresholds thresholds;
50     thresholds.minAlpha = 1.0;
51     thresholds.minFractionRendered = 1.0;
52     thresholds.stabilityRequirementMs = 100;
53     return thresholds;
54 }
55 
56 class LayerTrustedPresentationListenerTest : public LayerTransactionTest {
57 public:
SetUp()58     void SetUp() override {
59         LayerTransactionTest::SetUp();
60         mainLayer = makeLayer();
61         thresholds = thresh();
62     }
63 
TearDown()64     void TearDown() override {
65         LayerTransactionTest::TearDown();
66         mCallback = nullptr;
67         t.reparent(mainLayer, nullptr).apply();
68         mainLayer = nullptr;
69     }
70 
thresholdsPrepared()71     void thresholdsPrepared() {
72         t.show(mainLayer)
73                 .setLayer(mainLayer, INT32_MAX)
74                 .setTrustedPresentationCallback(
75                         mainLayer,
76                         [&](void* context, bool state) {
77                             PresentationCallbackHelper* helper =
78                                     (PresentationCallbackHelper*)context;
79                             helper->callbackArrived(state);
80                         },
81                         thresholds, &pch, mCallback)
82                 .setPosition(mainLayer, 100, 100)
83                 .apply();
84     }
85 
makeLayer()86     sp<SurfaceControl> makeLayer() {
87         sp<SurfaceControl> layer =
88                 createLayer("test", 100, 100, ISurfaceComposerClient::eFXSurfaceBufferState,
89                             mBlackBgSurface.get());
90         fillBufferLayerColor(layer, Color::RED, 100, 100);
91         return layer;
92     }
93     sp<SurfaceControl> mainLayer;
94     PresentationCallbackHelper pch;
95     SurfaceComposerClient::Transaction t;
96     TrustedPresentationThresholds thresholds;
97     sp<SurfaceComposerClient::PresentationCallbackRAII> mCallback;
98 };
99 
100 // The layer is fully presented with the default test setup.
TEST_F(LayerTrustedPresentationListenerTest,callback_arrives)101 TEST_F(LayerTrustedPresentationListenerTest, callback_arrives) {
102     thresholdsPrepared();
103     EXPECT_TRUE(pch.awaitCallback());
104 }
105 
106 // A hidden layer can't be considered presented!
TEST_F(LayerTrustedPresentationListenerTest,hiding_layer_clears_state)107 TEST_F(LayerTrustedPresentationListenerTest, hiding_layer_clears_state) {
108     thresholdsPrepared();
109     EXPECT_TRUE(pch.awaitCallback());
110     t.hide(mainLayer).apply();
111     EXPECT_FALSE(pch.awaitCallback());
112 }
113 
114 // A fully obscured layer can't be considered presented!
TEST_F(LayerTrustedPresentationListenerTest,obscuring_clears_state)115 TEST_F(LayerTrustedPresentationListenerTest, obscuring_clears_state) {
116     thresholdsPrepared();
117     EXPECT_TRUE(pch.awaitCallback());
118 
119     auto otherLayer = makeLayer();
120     t.show(otherLayer)
121             .setPosition(otherLayer, 100, 100)
122             .setLayer(otherLayer, INT32_MAX)
123             .setLayer(mainLayer, INT32_MAX - 1)
124             .apply();
125     EXPECT_FALSE(pch.awaitCallback());
126 }
127 
128 // Even if the layer obscuring us has an Alpha channel, we are still considered
129 // obscured.
TEST_F(LayerTrustedPresentationListenerTest,obscuring_with_transparency_clears_state)130 TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_transparency_clears_state) {
131     thresholdsPrepared();
132     EXPECT_TRUE(pch.awaitCallback());
133 
134     auto otherLayer = makeLayer();
135     t.show(otherLayer)
136             .setPosition(otherLayer, 100, 100)
137             .setLayer(otherLayer, INT32_MAX)
138             .setFlags(otherLayer, 0, layer_state_t::eLayerOpaque)
139             .setLayer(mainLayer, INT32_MAX - 1)
140             .apply();
141     EXPECT_FALSE(pch.awaitCallback());
142 }
143 
144 // We can't be presented if our alpha is below the threshold.
TEST_F(LayerTrustedPresentationListenerTest,alpha_below_threshold)145 TEST_F(LayerTrustedPresentationListenerTest, alpha_below_threshold) {
146     thresholdsPrepared();
147     EXPECT_TRUE(pch.awaitCallback());
148     t.setAlpha(mainLayer, 0.9).apply();
149     EXPECT_FALSE(pch.awaitCallback());
150     t.setAlpha(mainLayer, 1.0).apply();
151     EXPECT_TRUE(pch.awaitCallback());
152 }
153 
154 // Verify that the passed in threshold is actually respected!
TEST_F(LayerTrustedPresentationListenerTest,alpha_below_other_threshold)155 TEST_F(LayerTrustedPresentationListenerTest, alpha_below_other_threshold) {
156     thresholds.minAlpha = 0.8;
157     thresholdsPrepared();
158     EXPECT_TRUE(pch.awaitCallback());
159     t.setAlpha(mainLayer, 0.8).apply();
160     EXPECT_FALSE(pch.awaitCallback());
161     t.setAlpha(mainLayer, 0.9).apply();
162     EXPECT_TRUE(pch.awaitCallback());
163 }
164 
165 // (86*86)/(100*100) = 0.73...so a crop of 86x86 is below the threshold
166 // (87*87)/(100*100) = 0.76...so a crop of 87x87 is above the threshold!
TEST_F(LayerTrustedPresentationListenerTest,crop_below_threshold)167 TEST_F(LayerTrustedPresentationListenerTest, crop_below_threshold) {
168     thresholds.minFractionRendered = 0.75;
169     thresholdsPrepared();
170     EXPECT_TRUE(pch.awaitCallback());
171     t.setCrop(mainLayer, Rect(0, 0, 86, 86)).apply();
172     EXPECT_FALSE(pch.awaitCallback());
173     t.setCrop(mainLayer, Rect(0, 0, 87, 87)).apply();
174     EXPECT_TRUE(pch.awaitCallback());
175 }
176 
TEST_F(LayerTrustedPresentationListenerTest,scale_below_threshold)177 TEST_F(LayerTrustedPresentationListenerTest, scale_below_threshold) {
178     thresholds.minFractionRendered = 0.64;
179     thresholdsPrepared();
180     EXPECT_TRUE(pch.awaitCallback());
181     // 0.8 = sqrt(0.64)
182     t.setMatrix(mainLayer, 0.79, 0, 0, 0.79).apply();
183     EXPECT_FALSE(pch.awaitCallback());
184     t.setMatrix(mainLayer, 0.81, 0, 0, 0.81).apply();
185     EXPECT_TRUE(pch.awaitCallback());
186 }
187 
TEST_F(LayerTrustedPresentationListenerTest,obscuring_with_threshold_1)188 TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_threshold_1) {
189     thresholds.minFractionRendered = 0.75;
190     thresholdsPrepared();
191     EXPECT_TRUE(pch.awaitCallback());
192 
193     auto otherLayer = makeLayer();
194     t.show(otherLayer)
195             .setPosition(otherLayer, 100, 100)
196             .setLayer(otherLayer, INT32_MAX)
197             .setLayer(mainLayer, INT32_MAX - 1)
198             .apply();
199     EXPECT_FALSE(pch.awaitCallback());
200     t.setMatrix(otherLayer, 0.49, 0, 0, 0.49).apply();
201     EXPECT_TRUE(pch.awaitCallback());
202     t.setMatrix(otherLayer, 0.51, 0, 0, 0.51).apply();
203     EXPECT_FALSE(pch.awaitCallback());
204 }
205 
TEST_F(LayerTrustedPresentationListenerTest,obscuring_with_threshold_2)206 TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_threshold_2) {
207     thresholds.minFractionRendered = 0.9;
208     thresholdsPrepared();
209     EXPECT_TRUE(pch.awaitCallback());
210 
211     auto otherLayer = makeLayer();
212     t.show(otherLayer)
213             .setPosition(otherLayer, 100, 100)
214             .setLayer(otherLayer, INT32_MAX)
215             .setLayer(mainLayer, INT32_MAX - 1)
216             .apply();
217     EXPECT_FALSE(pch.awaitCallback());
218     t.setMatrix(otherLayer, 0.3, 0, 0, 0.3).apply();
219     EXPECT_TRUE(pch.awaitCallback());
220     t.setMatrix(otherLayer, 0.33, 0, 0, 0.33).apply();
221     EXPECT_FALSE(pch.awaitCallback());
222 }
223 
TEST_F(LayerTrustedPresentationListenerTest,obscuring_with_alpha)224 TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_alpha) {
225     thresholds.minFractionRendered = 0.9;
226     thresholdsPrepared();
227     EXPECT_TRUE(pch.awaitCallback());
228 
229     auto otherLayer = makeLayer();
230     t.show(otherLayer)
231             .setPosition(otherLayer, 100, 100)
232             .setLayer(otherLayer, INT32_MAX)
233             .setLayer(mainLayer, INT32_MAX - 1)
234             .setAlpha(otherLayer, 0.01)
235             .apply();
236     EXPECT_FALSE(pch.awaitCallback());
237     t.setAlpha(otherLayer, 0.0).apply();
238     EXPECT_TRUE(pch.awaitCallback());
239 }
240 
TEST_F(LayerTrustedPresentationListenerTest,obscuring_with_display_overlay)241 TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_display_overlay) {
242     auto otherLayer = makeLayer();
243     t.show(otherLayer)
244             .setPosition(otherLayer, 100, 100)
245             .setLayer(otherLayer, INT32_MAX)
246             .setFlags(otherLayer, layer_state_t::eLayerSkipScreenshot,
247                       layer_state_t::eLayerSkipScreenshot)
248             .setLayer(mainLayer, INT32_MAX - 1)
249             .show(mainLayer)
250             .setPosition(mainLayer, 100, 100)
251             .setTrustedPresentationCallback(
252                     mainLayer,
253                     [&](void* context, bool state) {
254                         PresentationCallbackHelper* helper = (PresentationCallbackHelper*)context;
255                         helper->callbackArrived(state);
256                     },
257                     thresholds, &pch, mCallback)
258             .apply();
259     EXPECT_TRUE(pch.awaitCallback());
260 }
261 
TEST_F(LayerTrustedPresentationListenerTest,obscuring_with_non_overlapping_bounds)262 TEST_F(LayerTrustedPresentationListenerTest, obscuring_with_non_overlapping_bounds) {
263     thresholds.minFractionRendered = 0.5;
264     auto otherLayer1 = makeLayer();
265     auto otherLayer2 = makeLayer();
266     t.show(otherLayer1)
267             .show(otherLayer2)
268             .setPosition(otherLayer1, 100, 25)
269             .setLayer(otherLayer1, INT32_MAX)
270             .setPosition(otherLayer2, 100, 175)
271             .setLayer(otherLayer2, INT32_MAX)
272             .setLayer(mainLayer, INT32_MAX - 1)
273             .show(mainLayer)
274             .setPosition(mainLayer, 100, 100)
275             .setTrustedPresentationCallback(
276                     mainLayer,
277                     [&](void* context, bool state) {
278                         PresentationCallbackHelper* helper = (PresentationCallbackHelper*)context;
279                         helper->callbackArrived(state);
280                     },
281                     thresholds, &pch, mCallback)
282             .apply();
283 
284     EXPECT_TRUE(pch.awaitCallback());
285 }
286 
287 } // namespace android
288