xref: /aosp_15_r20/cts/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ASurfaceControlTest.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright 2018 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 package android.view.surfacecontrol.cts;
18 
19 import static android.server.wm.ActivityManagerTestBase.createFullscreenActivityScenarioRule;
20 import static android.view.cts.surfacevalidator.ASurfaceControlTestActivity.RectChecker;
21 import static android.view.cts.surfacevalidator.ASurfaceControlTestActivity.WAIT_TIMEOUT_S;
22 import static android.view.cts.util.ASurfaceControlTestUtils.BufferReleaseCallback;
23 import static android.view.cts.util.ASurfaceControlTestUtils.applyAndDeleteSurfaceTransaction;
24 import static android.view.cts.util.ASurfaceControlTestUtils.createSurfaceTransaction;
25 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_acquire;
26 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_create;
27 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_createFromWindow;
28 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_fromJava;
29 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_release;
30 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_apply;
31 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_create;
32 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_delete;
33 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_fromJava;
34 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_releaseBuffer;
35 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setBuffer;
36 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDamageRegion;
37 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDataSpace;
38 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDesiredHdrHeadroom;
39 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDesiredPresentTime;
40 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setExtendedRangeBrightness;
41 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setFrameTimeline;
42 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setLuts;
43 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCommitCallback;
44 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCommitCallbackWithoutContext;
45 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCompleteCallback;
46 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCompleteCallbackWithoutContext;
47 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setPosition;
48 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setQuadrantBuffer;
49 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setSolidBuffer;
50 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setSolidBufferWithRelease;
51 import static android.view.cts.util.ASurfaceControlTestUtils.reparent;
52 import static android.view.cts.util.ASurfaceControlTestUtils.setBufferAlpha;
53 import static android.view.cts.util.ASurfaceControlTestUtils.setBufferOpaque;
54 import static android.view.cts.util.ASurfaceControlTestUtils.setBufferTransform;
55 import static android.view.cts.util.ASurfaceControlTestUtils.setColor;
56 import static android.view.cts.util.ASurfaceControlTestUtils.setCrop;
57 import static android.view.cts.util.ASurfaceControlTestUtils.setGeometry;
58 import static android.view.cts.util.ASurfaceControlTestUtils.setPosition;
59 import static android.view.cts.util.ASurfaceControlTestUtils.setScale;
60 import static android.view.cts.util.ASurfaceControlTestUtils.setVisibility;
61 import static android.view.cts.util.ASurfaceControlTestUtils.setZOrder;
62 import static android.view.cts.util.FrameCallbackData.nGetFrameTimelines;
63 
64 import static org.junit.Assert.assertEquals;
65 import static org.junit.Assert.assertFalse;
66 import static org.junit.Assert.assertThrows;
67 import static org.junit.Assert.assertTrue;
68 import static org.junit.Assume.assumeTrue;
69 
70 import android.graphics.Canvas;
71 import android.graphics.Color;
72 import android.graphics.Rect;
73 import android.hardware.DataSpace;
74 import android.os.SystemClock;
75 import android.os.Trace;
76 import android.platform.test.annotations.RequiresDevice;
77 import android.util.Log;
78 import android.view.Display;
79 import android.view.Surface;
80 import android.view.SurfaceControl;
81 import android.view.SurfaceHolder;
82 import android.view.cts.surfacevalidator.ASurfaceControlTestActivity;
83 import android.view.cts.surfacevalidator.ASurfaceControlTestActivity.PixelChecker;
84 import android.view.cts.surfacevalidator.PixelColor;
85 import android.view.cts.util.ASurfaceControlTestUtils;
86 import android.view.cts.util.FrameCallbackData;
87 import android.view.cts.util.FrameCallbackData.FrameTimeline;
88 
89 import androidx.annotation.NonNull;
90 import androidx.test.ext.junit.rules.ActivityScenarioRule;
91 import androidx.test.filters.LargeTest;
92 import androidx.test.runner.AndroidJUnit4;
93 
94 import com.android.compatibility.common.util.DisableAnimationRule;
95 import com.android.compatibility.common.util.WidgetTestUtils;
96 
97 import org.junit.Assert;
98 import org.junit.Before;
99 import org.junit.Rule;
100 import org.junit.Test;
101 import org.junit.rules.TestName;
102 import org.junit.runner.RunWith;
103 
104 import java.lang.ref.Reference;
105 import java.util.ArrayList;
106 import java.util.HashSet;
107 import java.util.List;
108 import java.util.Set;
109 import java.util.concurrent.CountDownLatch;
110 import java.util.concurrent.TimeUnit;
111 import java.util.concurrent.atomic.AtomicLong;
112 import java.util.function.Consumer;
113 
114 @LargeTest
115 @RunWith(AndroidJUnit4.class)
116 public class ASurfaceControlTest {
117     private static final String TAG = ASurfaceControlTest.class.getSimpleName();
118     private static final boolean DEBUG = false;
119 
120     private static final int DEFAULT_LAYOUT_WIDTH = 100;
121     private static final int DEFAULT_LAYOUT_HEIGHT = 100;
122     private static final Rect DEFAULT_RECT = new Rect(1, 1, DEFAULT_LAYOUT_WIDTH - 1,
123             DEFAULT_LAYOUT_HEIGHT - 1);
124 
125     private static final PixelColor RED = new PixelColor(Color.RED);
126     private static final PixelColor BLUE = new PixelColor(Color.BLUE);
127     private static final PixelColor MAGENTA = new PixelColor(Color.MAGENTA);
128     private static final PixelColor GREEN = new PixelColor(Color.GREEN);
129     private static final PixelColor YELLOW = new PixelColor(Color.YELLOW);
130 
131     @Rule
132     public DisableAnimationRule mDisableAnimationRule = new DisableAnimationRule();
133 
134     @Rule
135     public ActivityScenarioRule<ASurfaceControlTestActivity> mActivityRule =
136             createFullscreenActivityScenarioRule(ASurfaceControlTestActivity.class);
137 
138     @Rule
139     public TestName mName = new TestName();
140 
141     private ASurfaceControlTestActivity mActivity;
142 
143     private long mDesiredPresentTime;
144 
145     @Before
setup()146     public void setup() {
147         mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
148     }
149 
150     ///////////////////////////////////////////////////////////////////////////
151     // SurfaceHolder.Callbacks
152     ///////////////////////////////////////////////////////////////////////////
153 
154     private static class SurfaceHolderCallback implements SurfaceHolder.Callback {
155         BasicSurfaceHolderCallback mBasicSurfaceHolderCallback;
156 
SurfaceHolderCallback(BasicSurfaceHolderCallback basicSurfaceHolderCallback)157         SurfaceHolderCallback(BasicSurfaceHolderCallback basicSurfaceHolderCallback) {
158             mBasicSurfaceHolderCallback = basicSurfaceHolderCallback;
159         }
160 
161         @Override
surfaceCreated(@onNull SurfaceHolder holder)162         public void surfaceCreated(@NonNull SurfaceHolder holder) {
163             Canvas canvas = holder.lockCanvas();
164             canvas.drawColor(Color.YELLOW);
165             holder.unlockCanvasAndPost(canvas);
166 
167             mBasicSurfaceHolderCallback.surfaceCreated(holder);
168         }
169 
170         @Override
surfaceChanged(@onNull SurfaceHolder holder, int format, int width, int height)171         public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
172                 int height) {
173         }
174 
175         @Override
surfaceDestroyed(@onNull SurfaceHolder holder)176         public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
177             mBasicSurfaceHolderCallback.surfaceDestroyed();
178         }
179     }
180 
setAndApplySolidBufferWithRelease( long surfaceControl, int width, int height, int color, BufferReleaseCallback callback)181     public long setAndApplySolidBufferWithRelease(
182             long surfaceControl, int width, int height, int color,
183             BufferReleaseCallback callback) {
184         Assert.assertNotNull(callback);
185 
186         SurfaceControl.Transaction jTransaction = new SurfaceControl.Transaction();
187         final long transaction = nSurfaceTransaction_fromJava(jTransaction);
188         assertTrue(transaction != 0);
189 
190         long buffer = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction,
191                 width, height, color, callback);
192         assertTrue("failed to set buffer", buffer != 0);
193         TimedTransactionListener onCommitCallback = new TimedTransactionListener();
194         nSurfaceTransaction_setOnCommitCallback(transaction, onCommitCallback);
195         nSurfaceTransaction_apply(transaction);
196 
197         try {
198             onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
199         } catch (InterruptedException e) {
200         }
201         if (onCommitCallback.mLatch.getCount() > 0) {
202             Log.e(TAG, "Failed to wait for commit callback");
203         }
204         return buffer;
205     }
206 
setSolidBuffer(long surfaceControl, long surfaceTransaction, int width, int height, int color)207     public long setSolidBuffer(long surfaceControl, long surfaceTransaction, int width,
208             int height, int color) {
209         long buffer = nSurfaceTransaction_setSolidBuffer(surfaceControl, surfaceTransaction,
210                 width, height, color);
211         assertTrue("failed to set buffer", buffer != 0);
212         return buffer;
213     }
214 
215     private abstract static class BasicSurfaceHolderCallback {
216         private final Set<Long> mSurfaceControls = new HashSet<>();
217         private final Set<Long> mBuffers = new HashSet<>();
218 
surfaceCreated(SurfaceHolder surfaceHolder)219         public abstract void surfaceCreated(SurfaceHolder surfaceHolder);
220 
surfaceDestroyed()221         public void surfaceDestroyed() {
222             for (Long surfaceControl : mSurfaceControls) {
223                 reparent(surfaceControl, 0);
224                 nSurfaceControl_release(surfaceControl);
225             }
226             mSurfaceControls.clear();
227 
228             for (Long buffer : mBuffers) {
229                 nSurfaceTransaction_releaseBuffer(buffer);
230             }
231             mBuffers.clear();
232         }
233 
createFromWindow(Surface surface)234         public long createFromWindow(Surface surface) {
235             long surfaceControl = nSurfaceControl_createFromWindow(surface);
236             assertTrue("failed to create surface control", surfaceControl != 0);
237 
238             mSurfaceControls.add(surfaceControl);
239             return surfaceControl;
240         }
241 
create(long parentSurfaceControl)242         public long create(long parentSurfaceControl) {
243             long childSurfaceControl = nSurfaceControl_create(parentSurfaceControl);
244             assertTrue("failed to create child surface control", childSurfaceControl != 0);
245 
246             mSurfaceControls.add(childSurfaceControl);
247             return childSurfaceControl;
248         }
249 
setSolidBuffer( long surfaceControl, long surfaceTransaction, int width, int height, int color)250         public long setSolidBuffer(
251                 long surfaceControl, long surfaceTransaction, int width, int height, int color) {
252             long buffer = nSurfaceTransaction_setSolidBuffer(surfaceControl, surfaceTransaction,
253                     width, height, color);
254             assertTrue("failed to set buffer", buffer != 0);
255             mBuffers.add(buffer);
256             return buffer;
257         }
258 
setSolidBuffer(long surfaceControl, int width, int height, int color)259         public long setSolidBuffer(long surfaceControl, int width, int height, int color) {
260             long surfaceTransaction = createSurfaceTransaction();
261             long buffer = setSolidBuffer(surfaceControl, surfaceTransaction, width, height, color);
262             TimedTransactionListener onCommitCallback = new TimedTransactionListener();
263             nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback);
264             applyAndDeleteSurfaceTransaction(surfaceTransaction);
265             try {
266                 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
267             } catch (InterruptedException e) {
268             }
269             if (onCommitCallback.mLatch.getCount() > 0) {
270                 Log.e(TAG, "Failed to wait for commit callback");
271             }
272             return buffer;
273         }
274 
setNullBuffer(long surfaceControl)275         public void setNullBuffer(long surfaceControl) {
276             long surfaceTransaction = createSurfaceTransaction();
277             nSurfaceTransaction_setBuffer(surfaceControl, surfaceTransaction, 0 /* buffer */);
278             TimedTransactionListener onCommitCallback = new TimedTransactionListener();
279             nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback);
280             applyAndDeleteSurfaceTransaction(surfaceTransaction);
281             try {
282                 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
283             } catch (InterruptedException e) {
284             }
285             if (onCommitCallback.mLatch.getCount() > 0) {
286                 Log.e(TAG, "Failed to wait for commit callback");
287             }
288         }
289 
setQuadrantBuffer(long surfaceControl, long surfaceTransaction, int width, int height, int colorTopLeft, int colorTopRight, int colorBottomRight, int colorBottomLeft)290         public void setQuadrantBuffer(long surfaceControl, long surfaceTransaction, int width,
291                 int height, int colorTopLeft, int colorTopRight, int colorBottomRight,
292                 int colorBottomLeft) {
293             long buffer = nSurfaceTransaction_setQuadrantBuffer(surfaceControl, surfaceTransaction,
294                     width, height, colorTopLeft, colorTopRight, colorBottomRight, colorBottomLeft);
295             assertTrue("failed to set buffer", buffer != 0);
296             mBuffers.add(buffer);
297         }
298 
setQuadrantBuffer(long surfaceControl, int width, int height, int colorTopLeft, int colorTopRight, int colorBottomRight, int colorBottomLeft)299         public void setQuadrantBuffer(long surfaceControl, int width, int height, int colorTopLeft,
300                 int colorTopRight, int colorBottomRight, int colorBottomLeft) {
301             long surfaceTransaction = createSurfaceTransaction();
302             setQuadrantBuffer(surfaceControl, surfaceTransaction, width, height, colorTopLeft,
303                     colorTopRight, colorBottomRight, colorBottomLeft);
304             TimedTransactionListener onCommitCallback = new TimedTransactionListener();
305             nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback);
306             applyAndDeleteSurfaceTransaction(surfaceTransaction);
307             try {
308                 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
309             } catch (InterruptedException e) {
310             }
311             if (onCommitCallback.mLatch.getCount() > 0) {
312                 Log.e(TAG, "Failed to wait for commit callback");
313             }
314         }
315     }
316 
317     ///////////////////////////////////////////////////////////////////////////
318     // Tests
319     ///////////////////////////////////////////////////////////////////////////
320 
verifyTest(BasicSurfaceHolderCallback callback, PixelChecker pixelChecker)321     private void verifyTest(BasicSurfaceHolderCallback callback, PixelChecker pixelChecker) {
322         SurfaceHolderCallback surfaceHolderCallback = new SurfaceHolderCallback(callback);
323         mActivity.verifyTest(surfaceHolderCallback, pixelChecker, mName);
324     }
325 
326     // @ApiTest = ASurfaceTransaction_create()
327     @Test
testSurfaceTransaction_create()328     public void testSurfaceTransaction_create() {
329         long surfaceTransaction = nSurfaceTransaction_create();
330         assertTrue("failed to create surface transaction", surfaceTransaction != 0);
331 
332         nSurfaceTransaction_delete(surfaceTransaction);
333     }
334 
335     // @ApiTest = ASurfaceTransaction_apply(ASurfaceTransaction* _Nonnull transaction)
336     @Test
testSurfaceTransaction_apply()337     public void testSurfaceTransaction_apply() {
338         long surfaceTransaction = nSurfaceTransaction_create();
339         assertTrue("failed to create surface transaction", surfaceTransaction != 0);
340 
341         Log.e("Transaction", "created: " + surfaceTransaction);
342 
343         nSurfaceTransaction_apply(surfaceTransaction);
344         nSurfaceTransaction_delete(surfaceTransaction);
345     }
346 
347     // INTRO: The following tests run a series of commands and verify the
348     // output based on the number of pixels with a certain color on the display.
349     //
350     // The interface being tested is a NDK api but the only way to record the display
351     // through public apis is in through the SDK. So the test logic and test verification
352     // is in Java but the hooks that call into the NDK api are jni code.
353     //
354     // The set up is done during the surfaceCreated callback. In most cases, the
355     // test uses the opportunity to create a child layer through createFromWindow and
356     // performs operations on the child layer.
357     //
358     // When there is no visible buffer for the layer(s) the color defaults to black.
359     // The test cases allow a +/- 10% error rate. This is based on the error
360     // rate allowed in the SurfaceViewSyncTests
361     // @ApiTest = ASurfaceControl_createFromWindow(ANativeWindow* _Nonnull parent,
362     //                                                            const char* _Nonnull debug_name)
363     @Test
testSurfaceControl_createFromWindow()364     public void testSurfaceControl_createFromWindow() {
365         verifyTest(
366                 new BasicSurfaceHolderCallback() {
367                     @Override
368                     public void surfaceCreated(SurfaceHolder holder) {
369                         long surfaceControl = createFromWindow(holder.getSurface());
370                     }
371                 },
372                 new PixelChecker(Color.YELLOW) { //10000
373                     @Override
374                     public boolean checkPixels(int pixelCount, int width, int height) {
375                         return pixelCount > 9000 && pixelCount < 11000;
376                     }
377                 });
378     }
379 
380     // @ApiTest = ASurfaceControl_create(ASurfaceControl* _Nonnull parent,
381     //                                                  const char* _Nonnull debug_name)
382     @Test
testSurfaceControl_create()383     public void testSurfaceControl_create() {
384         verifyTest(
385                 new BasicSurfaceHolderCallback() {
386                     @Override
387                     public void surfaceCreated(SurfaceHolder holder) {
388                         long parentSurfaceControl = createFromWindow(holder.getSurface());
389                         long childSurfaceControl = create(parentSurfaceControl);
390                     }
391                 },
392                 new PixelChecker(Color.YELLOW) { //10000
393                     @Override
394                     public boolean checkPixels(int pixelCount, int width, int height) {
395                         return pixelCount > 9000 && pixelCount < 11000;
396                     }
397                 });
398     }
399 
400     // @ApiTest = ASurfaceControl_fromJava(JNIEnv* env, jobject surfaceControlObj)
401     @Test
testSurfaceControl_fromJava()402     public void testSurfaceControl_fromJava() {
403         SurfaceControl.Builder builder = new SurfaceControl.Builder();
404         builder.setName("testSurfaceControl_fromJava");
405         SurfaceControl control = builder.build();
406         final long childSurfaceControl = nSurfaceControl_fromJava(control);
407         assertTrue(childSurfaceControl != 0);
408         verifyTest(
409                 new BasicSurfaceHolderCallback() {
410                     @Override
411                     public void surfaceCreated(SurfaceHolder holder) {
412                         long parentSurfaceControl = createFromWindow(holder.getSurface());
413                         setVisibility(childSurfaceControl, true);
414                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
415                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
416                         reparent(childSurfaceControl, parentSurfaceControl);
417                     }
418                 },
419                 new PixelChecker(Color.RED) { //10000
420                     @Override
421                     public boolean checkPixels(int pixelCount, int width, int height) {
422                         return pixelCount > 9000 && pixelCount < 11000;
423                     }
424                 });
425         nSurfaceControl_release(childSurfaceControl);
426     }
427 
428     // @ApiTest = ASurfaceTransaction_fromJava(JNIEnv* env, jobject transactionObj)
429     @Test
testSurfaceTransaction_fromJava()430     public void testSurfaceTransaction_fromJava() {
431         SurfaceControl.Transaction jTransaction = new SurfaceControl.Transaction();
432         final long transaction = nSurfaceTransaction_fromJava(jTransaction);
433         verifyTest(
434                 new BasicSurfaceHolderCallback() {
435                     @Override
436                     public void surfaceCreated(SurfaceHolder holder) {
437                         long surfaceControl = createFromWindow(holder.getSurface());
438                         setSolidBuffer(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
439                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
440                         nSurfaceTransaction_apply(transaction);
441                     }
442                 },
443                 new PixelChecker(Color.RED) { //10000
444                     @Override
445                     public boolean checkPixels(int pixelCount, int width, int height) {
446                         return pixelCount > 9000 && pixelCount < 11000;
447                     }
448                 });
449         Reference.reachabilityFence(jTransaction);
450     }
451 
452     // @ApiTest = ASurfaceControl_acquire(ASurfaceControl* aSurfaceControl)
453     @Test
testSurfaceControl_acquire()454     public void testSurfaceControl_acquire() {
455         verifyTest(
456                 new BasicSurfaceHolderCallback() {
457                     @Override
458                     public void surfaceCreated(SurfaceHolder holder) {
459                         long surfaceControl = createFromWindow(holder.getSurface());
460                         // increment one refcount
461                         nSurfaceControl_acquire(surfaceControl);
462                         // decrement one refcount incremented from create call
463                         nSurfaceControl_release(surfaceControl);
464                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
465                                 Color.RED);
466                     }
467                 },
468                 new PixelChecker(Color.RED) { //10000
469                     @Override
470                     public boolean checkPixels(int pixelCount, int width, int height) {
471                         return pixelCount > 9000 && pixelCount < 11000;
472                     }
473                 });
474     }
475 
476     // @ApiTest = ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
477     //                                   ASurfaceControl* aSurfaceControl,
478     //                                   AHardwareBuffer* buffer, int acquire_fence_fd)
479     @Test
testSurfaceTransaction_setBuffer()480     public void testSurfaceTransaction_setBuffer() {
481         verifyTest(
482                 new BasicSurfaceHolderCallback() {
483                     @Override
484                     public void surfaceCreated(SurfaceHolder holder) {
485                         long surfaceControl = createFromWindow(holder.getSurface());
486                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
487                                 Color.RED);
488                     }
489                 },
490                 new PixelChecker(Color.RED) { //10000
491                     @Override
492                     public boolean checkPixels(int pixelCount, int width, int height) {
493                         return pixelCount > 9000 && pixelCount < 11000;
494                     }
495                 });
496     }
497 
498     // @ApiTest = ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
499     //                                   ASurfaceControl* aSurfaceControl,
500     //                                   AHardwareBuffer* buffer, int acquire_fence_fd)
501     @Test
testSurfaceTransaction_setNullBuffer()502     public void testSurfaceTransaction_setNullBuffer() {
503         verifyTest(
504                 new BasicSurfaceHolderCallback() {
505                     @Override
506                     public void surfaceCreated(SurfaceHolder holder) {
507                         long surfaceControl = createFromWindow(holder.getSurface());
508                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
509                                 Color.RED);
510                         setNullBuffer(surfaceControl);
511                     }
512                 },
513                 new PixelChecker(Color.YELLOW) { //10000
514                     @Override
515                     public boolean checkPixels(int pixelCount, int width, int height) {
516                         return pixelCount > 9000 && pixelCount < 11000;
517                     }
518                 });
519     }
520 
521     // @ApiTest = ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
522     //                                   ASurfaceControl* aSurfaceControl,
523     //                                   AHardwareBuffer* buffer, int acquire_fence_fd)
524     @Test
testSurfaceTransaction_setBuffer_parentAndChild()525     public void testSurfaceTransaction_setBuffer_parentAndChild() {
526         verifyTest(
527                 new BasicSurfaceHolderCallback() {
528                     @Override
529                     public void surfaceCreated(SurfaceHolder holder) {
530                         long parentSurfaceControl = createFromWindow(holder.getSurface());
531                         long childSurfaceControl = create(parentSurfaceControl);
532 
533                         setSolidBuffer(parentSurfaceControl, DEFAULT_LAYOUT_WIDTH,
534                                 DEFAULT_LAYOUT_HEIGHT, Color.BLUE);
535                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
536                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
537                     }
538                 },
539                 new PixelChecker(Color.RED) { //10000
540                     @Override
541                     public boolean checkPixels(int pixelCount, int width, int height) {
542                         return pixelCount > 9000 && pixelCount < 11000;
543                     }
544                 });
545     }
546 
547     // @ApiTest = ASurfaceTransaction_setBuffer(ASurfaceTransaction* aSurfaceTransaction,
548     //                                   ASurfaceControl* aSurfaceControl,
549     //                                   AHardwareBuffer* buffer, int acquire_fence_fd)
550     @Test
testSurfaceTransaction_setBuffer_childOnly()551     public void testSurfaceTransaction_setBuffer_childOnly() {
552         verifyTest(
553                 new BasicSurfaceHolderCallback() {
554                     @Override
555                     public void surfaceCreated(SurfaceHolder holder) {
556                         long parentSurfaceControl = createFromWindow(holder.getSurface());
557                         long childSurfaceControl = create(parentSurfaceControl);
558 
559                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
560                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
561                     }
562                 },
563                 new PixelChecker(Color.RED) { //10000
564                     @Override
565                     public boolean checkPixels(int pixelCount, int width, int height) {
566                         return pixelCount > 9000 && pixelCount < 11000;
567                     }
568                 });
569     }
570 
571     // @ApiTest = ASurfaceTransaction_setVisibility(ASurfaceTransaction* _Nonnull transaction,
572     //                                       ASurfaceControl* _Nonnull surface_control,
573     //                                       enum ASurfaceTransactionVisibility visibility)
574     @Test
testSurfaceTransaction_setVisibility_show()575     public void testSurfaceTransaction_setVisibility_show() {
576         verifyTest(
577                 new BasicSurfaceHolderCallback() {
578                     @Override
579                     public void surfaceCreated(SurfaceHolder holder) {
580                         long surfaceControl = createFromWindow(holder.getSurface());
581 
582                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
583                                 Color.RED);
584                         setVisibility(surfaceControl, true);
585                     }
586                 },
587                 new PixelChecker(Color.RED) { //10000
588                     @Override
589                     public boolean checkPixels(int pixelCount, int width, int height) {
590                         return pixelCount > 9000 && pixelCount < 11000;
591                     }
592                 });
593     }
594 
595     // @ApiTest = ASurfaceTransaction_setVisibility(ASurfaceTransaction* _Nonnull transaction,
596     //                                       ASurfaceControl* _Nonnull surface_control,
597     //                                       enum ASurfaceTransactionVisibility visibility)
598     @Test
testSurfaceTransaction_setVisibility_hide()599     public void testSurfaceTransaction_setVisibility_hide() {
600         verifyTest(
601                 new BasicSurfaceHolderCallback() {
602                     @Override
603                     public void surfaceCreated(SurfaceHolder holder) {
604                         long surfaceControl = createFromWindow(holder.getSurface());
605 
606                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
607                                 Color.RED);
608                         setVisibility(surfaceControl, false);
609                     }
610                 },
611                 new PixelChecker(Color.YELLOW) { //10000
612                     @Override
613                     public boolean checkPixels(int pixelCount, int width, int height) {
614                         return pixelCount > 9000 && pixelCount < 11000;
615                     }
616                 });
617     }
618 
619     // @ApiTest = ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* _Nonnull,
620     //                                               ASurfaceControl* _Nonnull surface_control,
621     //                                               enum ASurfaceTransactionTransparency)
622     @Test
testSurfaceTransaction_setBufferOpaque_opaque()623     public void testSurfaceTransaction_setBufferOpaque_opaque() {
624         verifyTest(
625                 new BasicSurfaceHolderCallback() {
626                     @Override
627                     public void surfaceCreated(SurfaceHolder holder) {
628                         long surfaceControl = createFromWindow(holder.getSurface());
629 
630                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
631                                 PixelColor.TRANSLUCENT_RED);
632                         setBufferOpaque(surfaceControl, true);
633                     }
634                 },
635                 new PixelChecker(Color.RED) { //10000
636                     @Override
637                     public boolean checkPixels(int pixelCount, int width, int height) {
638                         return pixelCount > 9000 && pixelCount < 11000;
639                     }
640                 });
641     }
642 
643     // @ApiTest = ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* _Nonnull,
644     //                                               ASurfaceControl* _Nonnull surface_control,
645     //                                               enum ASurfaceTransactionTransparency)
646     @Test
testSurfaceTransaction_setBufferOpaque_translucent()647     public void testSurfaceTransaction_setBufferOpaque_translucent() {
648         verifyTest(
649                 new BasicSurfaceHolderCallback() {
650                     @Override
651                     public void surfaceCreated(SurfaceHolder holder) {
652                         long surfaceControl = createFromWindow(holder.getSurface());
653 
654                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
655                                 PixelColor.TRANSLUCENT_RED);
656                         setBufferOpaque(surfaceControl, false);
657                     }
658                 },
659                 // setBufferOpaque is an optimization that can be used by SurfaceFlinger.
660                 // It isn't required to affect SurfaceFlinger's behavior.
661                 //
662                 // Ideally we would check for a specific blending of red with a layer below
663                 // it. Unfortunately we don't know what blending the layer will use and
664                 // we don't know what variation the GPU/DPU/blitter might have. Although
665                 // we don't know what shade of red might be present, we can at least check
666                 // that the optimization doesn't cause the framework to drop the buffer entirely.
667                 new PixelChecker(Color.YELLOW, false /* logWhenNoMatch */) {
668                     @Override
669                     public boolean checkPixels(int pixelCount, int width, int height) {
670                         return pixelCount == 0;
671                     }
672                 });
673     }
674 
675     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
676     //                                     ASurfaceControl* _Nonnull surface_control,
677     //                                     const ARect& source, const ARect& destination,
678     //                                     int32_t transform)
679     @Test
testSurfaceTransaction_setDestinationRect()680     public void testSurfaceTransaction_setDestinationRect() {
681         verifyTest(
682                 new BasicSurfaceHolderCallback() {
683                     @Override
684                     public void surfaceCreated(SurfaceHolder holder) {
685                         long surfaceControl = createFromWindow(holder.getSurface());
686 
687                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
688                                 Color.RED);
689                     }
690                 },
691                 new PixelChecker(Color.RED) { //10000
692                     @Override
693                     public boolean checkPixels(int pixelCount, int width, int height) {
694                         return pixelCount > 9000 && pixelCount < 11000;
695                     }
696                 });
697     }
698 
699     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
700     //                                     ASurfaceControl* _Nonnull surface_control,
701     //                                     const ARect& source, const ARect& destination,
702     //                                     int32_t transform)
703     @Test
testSurfaceTransaction_setDestinationRect_small()704     public void testSurfaceTransaction_setDestinationRect_small() {
705         verifyTest(
706                 new BasicSurfaceHolderCallback() {
707                     @Override
708                     public void surfaceCreated(SurfaceHolder holder) {
709                         long surfaceControl = createFromWindow(holder.getSurface());
710 
711                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
712                                 Color.RED);
713                         setGeometry(surfaceControl, 0, 0, 100, 100, 10, 10, 50, 50, 0);
714                     }
715                 },
716                 new RectChecker(DEFAULT_RECT) {
717                     @Override
718                     public PixelColor getExpectedColor(int x, int y) {
719                         if (x >= 10 && x < 50 && y >= 10 && y < 50) {
720                             return RED;
721                         } else {
722                             return YELLOW;
723                         }
724                     }
725                 });
726     }
727 
728     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
729     //                                     ASurfaceControl* _Nonnull surface_control,
730     //                                     const ARect& source, const ARect& destination,
731     //                                     int32_t transform)
732     @Test
testSurfaceTransaction_setDestinationRect_childSmall()733     public void testSurfaceTransaction_setDestinationRect_childSmall() {
734         verifyTest(
735                 new BasicSurfaceHolderCallback() {
736                     @Override
737                     public void surfaceCreated(SurfaceHolder holder) {
738                         long parentSurfaceControl = createFromWindow(holder.getSurface());
739                         long childSurfaceControl = create(parentSurfaceControl);
740 
741                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
742                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
743                         setGeometry(childSurfaceControl, 0, 0, 100, 100, 10, 10, 50, 50, 0);
744                     }
745                 },
746                 new RectChecker(DEFAULT_RECT) {
747                     @Override
748                     public PixelColor getExpectedColor(int x, int y) {
749                         if (x >= 10 && x < 50 && y >= 10 && y < 50) {
750                             return RED;
751                         } else {
752                             return YELLOW;
753                         }
754                     }
755                 });
756     }
757 
758     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
759     //                                     ASurfaceControl* _Nonnull surface_control,
760     //                                     const ARect& source, const ARect& destination,
761     //                                     int32_t transform)
762     @Test
testSurfaceTransaction_setDestinationRect_extraLarge()763     public void testSurfaceTransaction_setDestinationRect_extraLarge() {
764         verifyTest(
765                 new BasicSurfaceHolderCallback() {
766                     @Override
767                     public void surfaceCreated(SurfaceHolder holder) {
768                         long surfaceControl = createFromWindow(holder.getSurface());
769 
770                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
771                                 Color.RED);
772                         setGeometry(surfaceControl, 0, 0, 100, 100, -100, -100, 200, 200, 0);
773                     }
774                 },
775                 new PixelChecker(Color.RED) { //10000
776                     @Override
777                     public boolean checkPixels(int pixelCount, int width, int height) {
778                         return pixelCount > 9000 && pixelCount < 11000;
779                     }
780                 });
781     }
782 
783     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
784     //                                     ASurfaceControl* _Nonnull surface_control,
785     //                                     const ARect& source, const ARect& destination,
786     //                                     int32_t transform)
787     @Test
testSurfaceTransaction_setDestinationRect_childExtraLarge()788     public void testSurfaceTransaction_setDestinationRect_childExtraLarge() {
789         verifyTest(
790                 new BasicSurfaceHolderCallback() {
791                     @Override
792                     public void surfaceCreated(SurfaceHolder holder) {
793                         long parentSurfaceControl = createFromWindow(holder.getSurface());
794                         long childSurfaceControl = create(parentSurfaceControl);
795 
796                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
797                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
798                         setGeometry(childSurfaceControl, 0, 0, 100, 100, -100, -100, 200, 200, 0);
799                     }
800                 },
801                 new PixelChecker(Color.RED) { //10000
802                     @Override
803                     public boolean checkPixels(int pixelCount, int width, int height) {
804                         return pixelCount > 9000 && pixelCount < 11000;
805                     }
806                 });
807     }
808 
809     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
810     //                                     ASurfaceControl* _Nonnull surface_control,
811     //                                     const ARect& source, const ARect& destination,
812     //                                     int32_t transform)
813     @Test
testSurfaceTransaction_setDestinationRect_negativeOffset()814     public void testSurfaceTransaction_setDestinationRect_negativeOffset() {
815         verifyTest(
816                 new BasicSurfaceHolderCallback() {
817                     @Override
818                     public void surfaceCreated(SurfaceHolder holder) {
819                         long surfaceControl = createFromWindow(holder.getSurface());
820 
821                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
822                                 Color.RED);
823                         setGeometry(surfaceControl, 0, 0, 100, 100, -30, -20, 50, 50, 0);
824                     }
825                 },
826                 new RectChecker(DEFAULT_RECT) {
827                     @Override
828                     public PixelColor getExpectedColor(int x, int y) {
829                         if (x < 80 && y < 70) {
830                             return RED;
831                         } else {
832                             return YELLOW;
833                         }
834                     }
835                 });
836     }
837 
838     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
839     //                                     ASurfaceControl* _Nonnull surface_control,
840     //                                     const ARect& source, const ARect& destination,
841     //                                     int32_t transform)
842     @Test
testSurfaceTransaction_setDestinationRect_outOfParentBounds()843     public void testSurfaceTransaction_setDestinationRect_outOfParentBounds() {
844         verifyTest(
845                 new BasicSurfaceHolderCallback() {
846                     @Override
847                     public void surfaceCreated(SurfaceHolder holder) {
848                         long surfaceControl = createFromWindow(holder.getSurface());
849 
850                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
851                                 Color.RED);
852                         setGeometry(surfaceControl, 0, 0, 100, 100, 50, 50, 110, 105, 0);
853                     }
854                 },
855                 new RectChecker(DEFAULT_RECT) {
856                     @Override
857                     public PixelColor getExpectedColor(int x, int y) {
858                         if (x >= 50 && y >= 50) {
859                             return RED;
860                         } else {
861                             return YELLOW;
862                         }
863                     }
864                 });
865     }
866 
867     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
868     //                                     ASurfaceControl* _Nonnull surface_control,
869     //                                     const ARect& source, const ARect& destination,
870     //                                     int32_t transform)
871     @Test
testSurfaceTransaction_setDestinationRect_twoLayers()872     public void testSurfaceTransaction_setDestinationRect_twoLayers() {
873         verifyTest(
874                 new BasicSurfaceHolderCallback() {
875                     @Override
876                     public void surfaceCreated(SurfaceHolder holder) {
877                         long surfaceControl1 = createFromWindow(holder.getSurface());
878                         long surfaceControl2 = createFromWindow(holder.getSurface());
879 
880                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
881                                 Color.RED);
882                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
883                                 Color.BLUE);
884                         setGeometry(surfaceControl1, 0, 0, 100, 100, 10, 10, 30, 40, 0);
885                         setGeometry(surfaceControl2, 0, 0, 100, 100, 70, 20, 90, 50, 0);
886                     }
887                 },
888                 new RectChecker(DEFAULT_RECT) {
889                     @Override
890                     public PixelColor getExpectedColor(int x, int y) {
891                         if (x >= 10 && x < 30 && y >= 10 && y < 40) {
892                             return RED;
893                         } else if (x >= 70 && x < 90 && y >= 20 && y < 50) {
894                             return BLUE;
895                         } else {
896                             return YELLOW;
897                         }
898                     }
899                 });
900     }
901 
902     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
903     //                                     ASurfaceControl* _Nonnull surface_control,
904     //                                     const ARect& source, const ARect& destination,
905     //                                     int32_t transform)
906     @Test
testSurfaceTransaction_setSourceRect()907     public void testSurfaceTransaction_setSourceRect() {
908         verifyTest(
909                 new BasicSurfaceHolderCallback() {
910                     @Override
911                     public void surfaceCreated(SurfaceHolder holder) {
912                         long surfaceControl = createFromWindow(holder.getSurface());
913 
914                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
915                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
916                                 Color.MAGENTA, Color.GREEN);
917                     }
918                 },
919                 new RectChecker(DEFAULT_RECT) {
920                     @Override
921                     public PixelColor getExpectedColor(int x, int y) {
922                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
923                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
924                         if (x < halfWidth && y < halfHeight) {
925                             return RED;
926                         } else if (x >= halfWidth && y < halfHeight) {
927                             return BLUE;
928                         } else if (x < halfWidth && y >= halfHeight) {
929                             return GREEN;
930                         } else {
931                             return MAGENTA;
932                         }
933                     }
934                 });
935     }
936 
937     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
938     //                                     ASurfaceControl* _Nonnull surface_control,
939     //                                     const ARect& source, const ARect& destination,
940     //                                     int32_t transform)
941     @Test
testSurfaceTransaction_setSourceRect_smallCentered()942     public void testSurfaceTransaction_setSourceRect_smallCentered() {
943         // These rectangles leave two 10px strips unchecked to allow blended pixels due to GL
944         // texture filtering.
945         Rect topLeft = new Rect(0, 0, 45, 45);
946         Rect topRight = new Rect(55, 0, 100, 45);
947         Rect bottomLeft = new Rect(0, 55, 45, 100);
948         Rect bottomRight = new Rect(55, 55, 100, 100);
949         verifyTest(
950                 new BasicSurfaceHolderCallback() {
951                     @Override
952                     public void surfaceCreated(SurfaceHolder holder) {
953                         long surfaceControl = createFromWindow(holder.getSurface());
954 
955                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
956                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
957                                 Color.MAGENTA, Color.GREEN);
958                         setGeometry(surfaceControl, 10, 10, 90, 90, 0, 0, 100, 100, 0);
959                     }
960                 },
961 
962                 new RectChecker(List.of(topLeft, topRight, bottomLeft, bottomRight)) {
963                     @Override
964                     public PixelColor getExpectedColor(int x, int y) {
965                         if (topLeft.contains(x, y)) {
966                             return RED;
967                         } else if (topRight.contains(x, y)) {
968                             return BLUE;
969                         } else if (bottomLeft.contains(x, y)) {
970                             return GREEN;
971                         } else if (bottomRight.contains(x, y)) {
972                             return MAGENTA;
973                         }
974                         throw new AssertionError(String.format("Unexpected pixel (%d, %d)", x, y));
975                     }
976                 });
977     }
978 
979     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
980     //                                     ASurfaceControl* _Nonnull surface_control,
981     //                                     const ARect& source, const ARect& destination,
982     //                                     int32_t transform)
983     @Test
testSurfaceTransaction_setSourceRect_small()984     public void testSurfaceTransaction_setSourceRect_small() {
985         // These rectangles leave a 10px strip unchecked to allow blended pixels due to GL
986         // texture filtering.
987         Rect topHalf = new Rect(0, 0, 100, 45);
988         Rect bottomHalf = new Rect(0, 55, 100, 100);
989         verifyTest(
990                 new BasicSurfaceHolderCallback() {
991                     @Override
992                     public void surfaceCreated(SurfaceHolder holder) {
993                         long surfaceControl = createFromWindow(holder.getSurface());
994 
995                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
996                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
997                                 Color.MAGENTA, Color.GREEN);
998                         setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 100, 100, 0);
999                     }
1000                 },
1001                 new RectChecker(List.of(topHalf, bottomHalf)) {
1002                     @Override
1003                     public PixelColor getExpectedColor(int x, int y) {
1004                         if (topHalf.contains(x, y)) {
1005                             return BLUE;
1006                         } else if (bottomHalf.contains(x, y)) {
1007                             return MAGENTA;
1008                         }
1009                         throw new AssertionError(String.format("Unexpected pixel (%d, %d)", x, y));
1010                     }
1011                 });
1012     }
1013 
1014     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
1015     //                                     ASurfaceControl* _Nonnull surface_control,
1016     //                                     const ARect& source, const ARect& destination,
1017     //                                     int32_t transform)
1018     @Test
testSurfaceTransaction_setSourceRect_extraLarge()1019     public void testSurfaceTransaction_setSourceRect_extraLarge() {
1020         verifyTest(
1021                 new BasicSurfaceHolderCallback() {
1022                     @Override
1023                     public void surfaceCreated(SurfaceHolder holder) {
1024                         long surfaceControl = createFromWindow(holder.getSurface());
1025 
1026                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
1027                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
1028                                 Color.MAGENTA, Color.GREEN);
1029                         setGeometry(surfaceControl, -50, -50, 150, 150, 0, 0, 100, 100, 0);
1030                     }
1031                 },
1032 
1033                 new RectChecker(DEFAULT_RECT) {
1034                     @Override
1035                     public PixelColor getExpectedColor(int x, int y) {
1036                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
1037                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
1038                         if (x < halfWidth && y < halfHeight) {
1039                             return RED;
1040                         } else if (x >= halfWidth && y < halfHeight) {
1041                             return BLUE;
1042                         } else if (x < halfWidth && y >= halfHeight) {
1043                             return GREEN;
1044                         } else {
1045                             return MAGENTA;
1046                         }
1047                     }
1048                 });
1049     }
1050 
1051     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
1052     //                                     ASurfaceControl* _Nonnull surface_control,
1053     //                                     const ARect& source, const ARect& destination,
1054     //                                     int32_t transform)
1055     @Test
testSurfaceTransaction_setSourceRect_badOffset()1056     public void testSurfaceTransaction_setSourceRect_badOffset() {
1057         verifyTest(
1058                 new BasicSurfaceHolderCallback() {
1059                     @Override
1060                     public void surfaceCreated(SurfaceHolder holder) {
1061                         long surfaceControl = createFromWindow(holder.getSurface());
1062 
1063                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
1064                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
1065                                 Color.MAGENTA, Color.GREEN);
1066                         setGeometry(surfaceControl, -50, -50, 50, 50, 0, 0, 100, 100, 0);
1067                     }
1068                 },
1069                 new PixelChecker(Color.RED) { //10000
1070                     @Override
1071                     public boolean checkPixels(int pixelCount, int width, int height) {
1072                         return pixelCount > 9000 && pixelCount < 11000;
1073                     }
1074                 });
1075     }
1076 
1077     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
1078     //                                     ASurfaceControl* _Nonnull surface_control,
1079     //                                     const ARect& source, const ARect& destination,
1080     //                                     int32_t transform)
1081     @Test
testSurfaceTransaction_setTransform_flipH()1082     public void testSurfaceTransaction_setTransform_flipH() {
1083         verifyTest(
1084                 new BasicSurfaceHolderCallback() {
1085                     @Override
1086                     public void surfaceCreated(SurfaceHolder holder) {
1087                         long surfaceControl = createFromWindow(holder.getSurface());
1088 
1089                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
1090                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
1091                                 Color.MAGENTA, Color.GREEN);
1092                         setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 100, 100,
1093                                 /*NATIVE_WINDOW_TRANSFORM_FLIP_H*/ 1);
1094                     }
1095                 },
1096                 new RectChecker(DEFAULT_RECT) {
1097                     @Override
1098                     public PixelColor getExpectedColor(int x, int y) {
1099                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
1100                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
1101                         if (x < halfWidth && y < halfHeight) {
1102                             return BLUE;
1103                         } else if (x >= halfWidth && y < halfHeight) {
1104                             return RED;
1105                         } else if (x < halfWidth && y >= halfHeight) {
1106                             return MAGENTA;
1107                         } else {
1108                             return GREEN;
1109                         }
1110                     }
1111                 });
1112     }
1113 
1114     // @ApiTest = ASurfaceTransaction_setGeometry(ASurfaceTransaction* _Nonnull transaction,
1115     //                                     ASurfaceControl* _Nonnull surface_control,
1116     //                                     const ARect& source, const ARect& destination,
1117     //                                     int32_t transform)
1118     @Test
testSurfaceTransaction_setTransform_rotate180()1119     public void testSurfaceTransaction_setTransform_rotate180() {
1120         verifyTest(
1121                 new BasicSurfaceHolderCallback() {
1122                     @Override
1123                     public void surfaceCreated(SurfaceHolder holder) {
1124                         long surfaceControl = createFromWindow(holder.getSurface());
1125 
1126                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
1127                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
1128                                 Color.MAGENTA, Color.GREEN);
1129                         setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 100, 100,
1130                                 /*NATIVE_WINDOW_TRANSFORM_ROT_180*/ 3);
1131                     }
1132                 },
1133                 new RectChecker(DEFAULT_RECT) {
1134                     @Override
1135                     public PixelColor getExpectedColor(int x, int y) {
1136                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
1137                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
1138                         if (x < halfWidth && y < halfHeight) {
1139                             return MAGENTA;
1140                         } else if (x >= halfWidth && y < halfHeight) {
1141                             return GREEN;
1142                         } else if (x < halfWidth && y >= halfHeight) {
1143                             return BLUE;
1144                         } else {
1145                             return RED;
1146                         }
1147                     }
1148                 });
1149     }
1150 
1151     // @ApiTest = ASurfaceTransaction_setDamageRegion(ASurfaceTransaction* _Nonnull transaction,
1152     //                                         ASurfaceControl* _Nonnull surface_control,
1153     //                                         const ARect* _Nullable rects, uint32_t count)
1154     @Test
testSurfaceTransaction_setDamageRegion_all()1155     public void testSurfaceTransaction_setDamageRegion_all() {
1156         verifyTest(
1157                 new BasicSurfaceHolderCallback() {
1158                     @Override
1159                     public void surfaceCreated(SurfaceHolder holder) {
1160                         long surfaceControl = createFromWindow(holder.getSurface());
1161                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1162                                 Color.RED);
1163 
1164                         long surfaceTransaction = createSurfaceTransaction();
1165                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
1166                                 DEFAULT_LAYOUT_HEIGHT, Color.BLUE);
1167                         nSurfaceTransaction_setDamageRegion(surfaceControl, surfaceTransaction, 0,
1168                                 0, 100, 100);
1169                         applyAndDeleteSurfaceTransaction(surfaceTransaction);
1170                     }
1171                 },
1172                 new PixelChecker(Color.BLUE) { //10000
1173                     @Override
1174                     public boolean checkPixels(int pixelCount, int width, int height) {
1175                         return pixelCount > 9000 && pixelCount < 11000;
1176                     }
1177                 });
1178     }
1179 
1180     // @ApiTest = ASurfaceTransaction_setLuts(ASurfaceTransaction* _Nonnull transaction,
1181     //                                        ASurfaceControl* _Nonnull surface_control,
1182     //                                        ADisplayLuts* _Nullable luts)
1183     @Test
testSurfaceTransaction_setLuts_1DLut()1184     public void testSurfaceTransaction_setLuts_1DLut() {
1185         verifyTest(
1186             new BasicSurfaceHolderCallback() {
1187                 @Override
1188                 public void surfaceCreated(SurfaceHolder holder) {
1189                     long surfaceControl = createFromWindow(holder.getSurface());
1190                     long surfaceTransaction = createSurfaceTransaction();
1191                     setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1192                             Color.MAGENTA);
1193                     nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction,
1194                             DataSpace.DATASPACE_SRGB);
1195                     nSurfaceTransaction_setLuts(surfaceControl, surfaceTransaction,
1196                             new float[]{0.0f, 0f, 0f, 0f, 0.5f, 0.5f, 0.5f, 0.5f},
1197                             new int[]{0} /* offsets */, new int[]{1} /* dimension */,
1198                             new int[]{8} /* sizeForEachDim */, new int[]{0} /* key */);
1199                     nSurfaceTransaction_apply(surfaceTransaction);
1200                     nSurfaceTransaction_delete(surfaceTransaction);
1201                 }
1202             },
1203 
1204             new RectChecker(new Rect(0, 0, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT)) {
1205                 final PixelColor mResult = new PixelColor(0xFFBC00BC);
1206                 @Override
1207                 public PixelColor getExpectedColor(int x, int y) {
1208                     return mResult;
1209                 }
1210             });
1211     }
1212 
1213     // @ApiTest = ASurfaceTransaction_setLuts(ASurfaceTransaction* _Nonnull transaction,
1214     //                                        ASurfaceControl* _Nonnull surface_control,
1215     //                                        ADisplayLuts* _Nullable luts)
1216     @Test
testSurfaceTransaction_setLuts_twoLuts()1217     public void testSurfaceTransaction_setLuts_twoLuts() {
1218         verifyTest(
1219             new BasicSurfaceHolderCallback() {
1220                 @Override
1221                 public void surfaceCreated(SurfaceHolder holder) {
1222                     long surfaceControl = createFromWindow(holder.getSurface());
1223                     long surfaceTransaction = createSurfaceTransaction();
1224                     setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1225                             Color.CYAN);
1226                     nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction,
1227                             DataSpace.DATASPACE_SRGB);
1228                     nSurfaceTransaction_setLuts(surfaceControl, surfaceTransaction,
1229                             new float[]{0.0f, 0f, 0f, 0f, 0.5f, 0.5f, 0.5f, 0.5f,
1230                                         0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1231                                         0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1232                                         0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f},
1233                             new int[]{0, 8} /* offsets */, new int[]{1, 3} /* dimension */,
1234                             new int[]{8, 2} /* sizeForEachDim */, new int[]{0, 0} /* key */);
1235                     nSurfaceTransaction_apply(surfaceTransaction);
1236                     nSurfaceTransaction_delete(surfaceTransaction);
1237                 }
1238             },
1239 
1240             new RectChecker(new Rect(0, 0, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT)) {
1241                 final PixelColor mResult = new PixelColor(0xFFBCBCBC);
1242                 @Override
1243                 public PixelColor getExpectedColor(int x, int y) {
1244                     return mResult;
1245                 }
1246             });
1247     }
1248 
1249     // @ApiTest = ASurfaceTransaction_setLuts(ASurfaceTransaction* _Nonnull transaction,
1250     //                                        ASurfaceControl* _Nonnull surface_control,
1251     //                                        ADisplayLuts* _Nullable luts)
1252     @Test
testSurfaceTransaction_setLuts_3DLut()1253     public void testSurfaceTransaction_setLuts_3DLut() {
1254         verifyTest(
1255             new BasicSurfaceHolderCallback() {
1256                 @Override
1257                 public void surfaceCreated(SurfaceHolder holder) {
1258                     long surfaceControl = createFromWindow(holder.getSurface());
1259                     long surfaceTransaction = createSurfaceTransaction();
1260                     setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1261                             Color.YELLOW);
1262                     nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction,
1263                             DataSpace.DATASPACE_SRGB);
1264                     nSurfaceTransaction_setLuts(surfaceControl, surfaceTransaction,
1265                             new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
1266                                         0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f,
1267                                         1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
1268                             new int[]{0} /* offsets */, new int[]{3} /* dimension */,
1269                             new int[]{2} /* sizeForEachDim */, new int[]{0} /* key */);
1270                     nSurfaceTransaction_apply(surfaceTransaction);
1271                     nSurfaceTransaction_delete(surfaceTransaction);
1272                 }
1273             },
1274 
1275             new RectChecker(new Rect(0, 0, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT)) {
1276                 final PixelColor mResult = new PixelColor(0xFFBC00FF);
1277                 @Override
1278                 public PixelColor getExpectedColor(int x, int y) {
1279                     return mResult;
1280                 }
1281             });
1282     }
1283 
1284     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1285     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1286     @Test
testSurfaceTransaction_setZOrder_zero()1287     public void testSurfaceTransaction_setZOrder_zero() {
1288         verifyTest(
1289                 new BasicSurfaceHolderCallback() {
1290                     @Override
1291                     public void surfaceCreated(SurfaceHolder holder) {
1292                         long surfaceControl1 = createFromWindow(holder.getSurface());
1293                         long surfaceControl2 = createFromWindow(holder.getSurface());
1294                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1295                                 Color.RED);
1296                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1297                                 Color.MAGENTA);
1298 
1299                         setZOrder(surfaceControl1, 1);
1300                         setZOrder(surfaceControl2, 0);
1301                     }
1302                 },
1303                 new RectChecker(DEFAULT_RECT) {
1304                     @Override
1305                     public PixelColor getExpectedColor(int x, int y) {
1306                         return RED;
1307                     }
1308                 });
1309     }
1310 
1311     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1312     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1313     @Test
testSurfaceTransaction_setZOrder_positive()1314     public void testSurfaceTransaction_setZOrder_positive() {
1315         verifyTest(
1316                 new BasicSurfaceHolderCallback() {
1317                     @Override
1318                     public void surfaceCreated(SurfaceHolder holder) {
1319                         long surfaceControl1 = createFromWindow(holder.getSurface());
1320                         long surfaceControl2 = createFromWindow(holder.getSurface());
1321                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1322                                 Color.RED);
1323                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1324                                 Color.MAGENTA);
1325 
1326                         setZOrder(surfaceControl1, 1);
1327                         setZOrder(surfaceControl2, 5);
1328                     }
1329                 },
1330                 new RectChecker(DEFAULT_RECT) {
1331                     @Override
1332                     public PixelColor getExpectedColor(int x, int y) {
1333                         return MAGENTA;
1334                     }
1335                 });
1336     }
1337 
1338     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1339     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1340     @Test
testSurfaceTransaction_setZOrder_negative()1341     public void testSurfaceTransaction_setZOrder_negative() {
1342         verifyTest(
1343                 new BasicSurfaceHolderCallback() {
1344                     @Override
1345                     public void surfaceCreated(SurfaceHolder holder) {
1346                         long surfaceControl1 = createFromWindow(holder.getSurface());
1347                         long surfaceControl2 = createFromWindow(holder.getSurface());
1348                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1349                                 Color.RED);
1350                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1351                                 Color.MAGENTA);
1352 
1353                         setZOrder(surfaceControl1, 1);
1354                         setZOrder(surfaceControl2, -15);
1355                     }
1356                 },
1357                 new RectChecker(DEFAULT_RECT) {
1358                     @Override
1359                     public PixelColor getExpectedColor(int x, int y) {
1360                         return RED;
1361                     }
1362                 });
1363     }
1364 
1365     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1366     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1367     @Test
testSurfaceTransaction_setZOrder_max()1368     public void testSurfaceTransaction_setZOrder_max() {
1369         verifyTest(
1370                 new BasicSurfaceHolderCallback() {
1371                     @Override
1372                     public void surfaceCreated(SurfaceHolder holder) {
1373                         long surfaceControl1 = createFromWindow(holder.getSurface());
1374                         long surfaceControl2 = createFromWindow(holder.getSurface());
1375                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1376                                 Color.RED);
1377                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1378                                 Color.MAGENTA);
1379 
1380                         setZOrder(surfaceControl1, 1);
1381                         setZOrder(surfaceControl2, Integer.MAX_VALUE);
1382                     }
1383                 },
1384                 new RectChecker(DEFAULT_RECT) {
1385                     @Override
1386                     public PixelColor getExpectedColor(int x, int y) {
1387                         return MAGENTA;
1388                     }
1389                 });
1390     }
1391 
1392     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1393     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1394     @Test
testSurfaceTransaction_setZOrder_min()1395     public void testSurfaceTransaction_setZOrder_min() {
1396         verifyTest(
1397                 new BasicSurfaceHolderCallback() {
1398                     @Override
1399                     public void surfaceCreated(SurfaceHolder holder) {
1400                         long surfaceControl1 = createFromWindow(holder.getSurface());
1401                         long surfaceControl2 = createFromWindow(holder.getSurface());
1402                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1403                                 Color.RED);
1404                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1405                                 Color.MAGENTA);
1406 
1407                         setZOrder(surfaceControl1, 1);
1408                         setZOrder(surfaceControl2, Integer.MIN_VALUE);
1409                     }
1410                 },
1411                 new RectChecker(DEFAULT_RECT) {
1412                     @Override
1413                     public PixelColor getExpectedColor(int x, int y) {
1414                         return RED;
1415                     }
1416                 });
1417     }
1418 
1419     // @ApiTest = ASurfaceTransaction_setOnComplete(ASurfaceTransaction* _Nonnull transaction,
1420     //                                       void* _Null_unspecified context,
1421     //                                       ASurfaceTransaction_OnComplete _Nonnull func)
1422     // @ApiTest = ASurfaceTransactionStats_getLatchTime(
1423     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats)
1424     @Test
testSurfaceTransaction_setOnComplete()1425     public void testSurfaceTransaction_setOnComplete() {
1426         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
1427         verifyTest(
1428                 new BasicSurfaceHolderCallback() {
1429                     @Override
1430                     public void surfaceCreated(SurfaceHolder holder) {
1431                         long surfaceControl = createFromWindow(holder.getSurface());
1432 
1433                         long surfaceTransaction = createSurfaceTransaction();
1434                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
1435                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1436                         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
1437                                 false /* waitForFence */, onCompleteCallback);
1438                         applyAndDeleteSurfaceTransaction(surfaceTransaction);
1439 
1440                         // Wait for callbacks to fire.
1441                         try {
1442                             onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
1443                         } catch (InterruptedException e) {
1444                         }
1445                         if (onCompleteCallback.mLatch.getCount() > 0) {
1446                             Log.e(TAG, "Failed to wait for callback");
1447                         }
1448                     }
1449                 },
1450                 new PixelChecker(Color.RED) { //10000
1451                     @Override
1452                     public boolean checkPixels(int pixelCount, int width, int height) {
1453                         return pixelCount > 9000 && pixelCount < 11000;
1454                     }
1455                 });
1456 
1457         // Validate we got callbacks.
1458         assertEquals(0, onCompleteCallback.mLatch.getCount());
1459         assertTrue(onCompleteCallback.mCallbackTime > 0);
1460     }
1461 
1462     // @ApiTest = ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* _Nonnull,
1463     //                                               int64_t desiredPresentTime)
1464     @Test
1465     @RequiresDevice // emulators can't support sync fences
testSurfaceTransaction_setDesiredPresentTime_now()1466     public void testSurfaceTransaction_setDesiredPresentTime_now() {
1467         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
1468         verifyTest(
1469                 new BasicSurfaceHolderCallback() {
1470                     @Override
1471                     public void surfaceCreated(SurfaceHolder holder) {
1472                         long surfaceControl = createFromWindow(holder.getSurface());
1473 
1474                         long surfaceTransaction = createSurfaceTransaction();
1475                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
1476                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1477                         mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
1478                                 surfaceTransaction, 0);
1479                         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
1480                                 true /* waitForFence */, onCompleteCallback);
1481                         applyAndDeleteSurfaceTransaction(surfaceTransaction);
1482                         // Wait for callbacks to fire.
1483                         try {
1484                             onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
1485                         } catch (InterruptedException e) {
1486                         }
1487                         if (onCompleteCallback.mLatch.getCount() > 0) {
1488                             Log.e(TAG, "Failed to wait for callback");
1489                         }
1490                     }
1491                 },
1492                 new PixelChecker(Color.RED) { //10000
1493                     @Override
1494                     public boolean checkPixels(int pixelCount, int width, int height) {
1495                         return pixelCount > 9000 && pixelCount < 11000;
1496                     }
1497                 });
1498 
1499         assertEquals(0, onCompleteCallback.mLatch.getCount());
1500         assertTrue(onCompleteCallback.mCallbackTime > 0);
1501         assertTrue(onCompleteCallback.mLatchTime > 0);
1502 
1503         assertTrue("transaction was presented too early. presentTime="
1504                         + onCompleteCallback.mPresentTime,
1505                 onCompleteCallback.mPresentTime >= mDesiredPresentTime);
1506     }
1507 
1508     // @ApiTest = ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* _Nonnull,
1509     //                                               int64_t desiredPresentTime)
1510     @Test
1511     @RequiresDevice // emulators can't support sync fences
testSurfaceTransaction_setDesiredPresentTime_30ms()1512     public void testSurfaceTransaction_setDesiredPresentTime_30ms() {
1513         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
1514         verifyTest(
1515                 new BasicSurfaceHolderCallback() {
1516                     @Override
1517                     public void surfaceCreated(SurfaceHolder holder) {
1518                         long surfaceControl = createFromWindow(holder.getSurface());
1519 
1520                         long surfaceTransaction = createSurfaceTransaction();
1521                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
1522                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1523                         mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
1524                                 surfaceTransaction, 30000000);
1525                         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
1526                                 true /* waitForFence */, onCompleteCallback);
1527                         applyAndDeleteSurfaceTransaction(surfaceTransaction);
1528                         // Wait for callbacks to fire.
1529                         try {
1530                             onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
1531                         } catch (InterruptedException e) {
1532                         }
1533                         if (onCompleteCallback.mLatch.getCount() > 0) {
1534                             Log.e(TAG, "Failed to wait for callback");
1535                         }
1536                     }
1537                 },
1538                 new PixelChecker(Color.RED) { //10000
1539                     @Override
1540                     public boolean checkPixels(int pixelCount, int width, int height) {
1541                         return pixelCount > 9000 && pixelCount < 11000;
1542                     }
1543                 });
1544 
1545         assertEquals(0, onCompleteCallback.mLatch.getCount());
1546         assertTrue(onCompleteCallback.mCallbackTime > 0);
1547         assertTrue(onCompleteCallback.mLatchTime > 0);
1548 
1549         assertTrue("transaction was presented too early. presentTime="
1550                         + onCompleteCallback.mPresentTime,
1551                 onCompleteCallback.mPresentTime >= mDesiredPresentTime);
1552     }
1553 
1554     // @ApiTest = ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* _Nonnull,
1555     //                                               int64_t desiredPresentTime)
1556     @Test
1557     @RequiresDevice // emulators can't support sync fences
testSurfaceTransaction_setDesiredPresentTime_100ms()1558     public void testSurfaceTransaction_setDesiredPresentTime_100ms() {
1559         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
1560         verifyTest(
1561                 new BasicSurfaceHolderCallback() {
1562                     @Override
1563                     public void surfaceCreated(SurfaceHolder holder) {
1564                         long surfaceControl = createFromWindow(holder.getSurface());
1565 
1566                         long surfaceTransaction = createSurfaceTransaction();
1567                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
1568                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1569                         mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
1570                                 surfaceTransaction, 100000000);
1571                         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
1572                                 true /* waitForFence */, onCompleteCallback);
1573                         applyAndDeleteSurfaceTransaction(surfaceTransaction);
1574                         // Wait for callbacks to fire.
1575                         try {
1576                             onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
1577                         } catch (InterruptedException e) {
1578                         }
1579                         if (onCompleteCallback.mLatch.getCount() > 0) {
1580                             Log.e(TAG, "Failed to wait for callback");
1581                         }
1582                     }
1583                 },
1584                 new PixelChecker(Color.RED) { //10000
1585                     @Override
1586                     public boolean checkPixels(int pixelCount, int width, int height) {
1587                         return pixelCount > 9000 && pixelCount < 11000;
1588                     }
1589                 });
1590 
1591         assertEquals(0, onCompleteCallback.mLatch.getCount());
1592 
1593         assertTrue(onCompleteCallback.mCallbackTime > 0);
1594         assertTrue(onCompleteCallback.mLatchTime > 0);
1595 
1596         assertTrue("transaction was presented too early. presentTime="
1597                         + onCompleteCallback.mPresentTime,
1598                 onCompleteCallback.mPresentTime >= mDesiredPresentTime);
1599     }
1600 
1601     // @ApiTest = ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* _Nonnull transaction,
1602     //                                        ASurfaceControl* _Nonnull, float alpha)
1603     @Test
testSurfaceTransaction_setBufferAlpha_1_0()1604     public void testSurfaceTransaction_setBufferAlpha_1_0() {
1605         verifyTest(
1606                 new BasicSurfaceHolderCallback() {
1607                     @Override
1608                     public void surfaceCreated(SurfaceHolder holder) {
1609                         long surfaceControl = createFromWindow(holder.getSurface());
1610 
1611                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1612                                 Color.RED);
1613                         setBufferAlpha(surfaceControl, 1.0);
1614                     }
1615                 },
1616                 new PixelChecker(Color.RED) { //10000
1617                     @Override
1618                     public boolean checkPixels(int pixelCount, int width, int height) {
1619                         return pixelCount > 9000 && pixelCount < 11000;
1620                     }
1621                 });
1622     }
1623 
1624     // @ApiTest = ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* _Nonnull transaction,
1625     //                                        ASurfaceControl* _Nonnull, float alpha)
1626     @Test
testSurfaceTransaction_setBufferAlpha_0_5()1627     public void testSurfaceTransaction_setBufferAlpha_0_5() {
1628         BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
1629             @Override
1630             public void surfaceCreated(SurfaceHolder holder) {
1631                 long surfaceControl = createFromWindow(holder.getSurface());
1632 
1633                 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1634                         Color.RED);
1635                 setBufferAlpha(surfaceControl, 0.5);
1636             }
1637         };
1638         verifyTest(callback,
1639                 new PixelChecker(Color.YELLOW, false /* logWhenNoMatch */) {
1640                     @Override
1641                     public boolean checkPixels(int pixelCount, int width, int height) {
1642                         return pixelCount == 0;
1643                     }
1644                 });
1645         verifyTest(callback,
1646                 new PixelChecker(Color.RED, false /* logWhenNoMatch */) {
1647                     @Override
1648                     public boolean checkPixels(int pixelCount, int width, int height) {
1649                         return pixelCount == 0;
1650                     }
1651                 });
1652     }
1653 
1654     // @ApiTest = ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* _Nonnull transaction,
1655     //                                        ASurfaceControl* _Nonnull, float alpha)
1656     @Test
testSurfaceTransaction_setBufferAlpha_0_0()1657     public void testSurfaceTransaction_setBufferAlpha_0_0() {
1658         verifyTest(
1659                 new BasicSurfaceHolderCallback() {
1660                     @Override
1661                     public void surfaceCreated(SurfaceHolder holder) {
1662                         long surfaceControl = createFromWindow(holder.getSurface());
1663 
1664                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1665                                 Color.RED);
1666                         setBufferAlpha(surfaceControl, 0.0);
1667                     }
1668                 },
1669                 new PixelChecker(Color.YELLOW) { //10000
1670                     @Override
1671                     public boolean checkPixels(int pixelCount, int width, int height) {
1672                         return pixelCount > 9000 && pixelCount < 11000;
1673                     }
1674                 });
1675     }
1676 
1677     // @ApiTest = ASurfaceTransaction_reparent(ASurfaceTransaction* _Nonnull transaction,
1678     //                                  ASurfaceControl* _Nonnull surface_control,
1679     //                                  ASurfaceControl* _Nullable new_parent)
1680     @Test
testSurfaceTransaction_reparent()1681     public void testSurfaceTransaction_reparent() {
1682         verifyTest(
1683                 new BasicSurfaceHolderCallback() {
1684                     @Override
1685                     public void surfaceCreated(SurfaceHolder holder) {
1686                         long parentSurfaceControl1 = createFromWindow(holder.getSurface());
1687                         long parentSurfaceControl2 = createFromWindow(holder.getSurface());
1688                         long childSurfaceControl = create(parentSurfaceControl1);
1689 
1690                         setGeometry(parentSurfaceControl1, 0, 0, 100, 100, 0, 0, 25, 100, 0);
1691                         setGeometry(parentSurfaceControl2, 0, 0, 100, 100, 25, 0, 100, 100, 0);
1692 
1693                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
1694                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1695 
1696                         reparent(childSurfaceControl, parentSurfaceControl2);
1697                     }
1698                 },
1699                 new RectChecker(DEFAULT_RECT) {
1700                     @Override
1701                     public PixelColor getExpectedColor(int x, int y) {
1702                         if (x >= 25) {
1703                             return RED;
1704                         } else {
1705                             return YELLOW;
1706                         }
1707                     }
1708                 });
1709     }
1710 
1711     // @ApiTest = ASurfaceTransaction_reparent(ASurfaceTransaction* _Nonnull transaction,
1712     //                                  ASurfaceControl* _Nonnull surface_control,
1713     //                                  ASurfaceControl* _Nullable new_parent)
1714     @Test
testSurfaceTransaction_reparent_null()1715     public void testSurfaceTransaction_reparent_null() {
1716         verifyTest(
1717                 new BasicSurfaceHolderCallback() {
1718                     @Override
1719                     public void surfaceCreated(SurfaceHolder holder) {
1720                         long parentSurfaceControl = createFromWindow(holder.getSurface());
1721                         long childSurfaceControl = create(parentSurfaceControl);
1722 
1723                         setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
1724                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1725 
1726                         reparent(childSurfaceControl, 0);
1727                     }
1728                 },
1729                 new PixelChecker(Color.YELLOW) { //10000
1730                     @Override
1731                     public boolean checkPixels(int pixelCount, int width, int height) {
1732                         return pixelCount > 9000 && pixelCount < 11000;
1733                     }
1734                 });
1735     }
1736 
1737     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1738     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1739     //                                  float b, float alpha, enum ADataSpace dataspace)
1740     @Test
testSurfaceTransaction_setColor()1741     public void testSurfaceTransaction_setColor() {
1742         verifyTest(
1743                 new BasicSurfaceHolderCallback() {
1744                     @Override
1745                     public void surfaceCreated(SurfaceHolder holder) {
1746                         long surfaceControl = createFromWindow(holder.getSurface());
1747 
1748                         setColor(surfaceControl, 0, 1.0f, 0, 1.0f);
1749                     }
1750                 },
1751                 new PixelChecker(Color.GREEN) { // 10000
1752                     @Override
1753                     public boolean checkPixels(int pixelCount, int width, int height) {
1754                         return pixelCount > 9000 && pixelCount < 11000;
1755                     }
1756                 });
1757     }
1758 
1759     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1760     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1761     //                                  float b, float alpha, enum ADataSpace dataspace)
1762     @Test
testSurfaceTransaction_noColorNoBuffer()1763     public void testSurfaceTransaction_noColorNoBuffer() {
1764         verifyTest(
1765                 new BasicSurfaceHolderCallback() {
1766                     @Override
1767                     public void surfaceCreated(SurfaceHolder holder) {
1768                         long parentSurfaceControl = createFromWindow(holder.getSurface());
1769                         long childSurfaceControl = create(parentSurfaceControl);
1770 
1771                         setColor(parentSurfaceControl, 0, 1.0f, 0, 1.0f);
1772                     }
1773                 },
1774                 new PixelChecker(Color.GREEN) { // 10000
1775                     @Override
1776                     public boolean checkPixels(int pixelCount, int width, int height) {
1777                         return pixelCount > 9000 && pixelCount < 11000;
1778                     }
1779                 });
1780     }
1781 
1782     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1783     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1784     //                                  float b, float alpha, enum ADataSpace dataspace)
1785     @Test
testSurfaceTransaction_setColorAlpha()1786     public void testSurfaceTransaction_setColorAlpha() {
1787         verifyTest(
1788                 new BasicSurfaceHolderCallback() {
1789                     @Override
1790                     public void surfaceCreated(SurfaceHolder holder) {
1791                         long parentSurfaceControl = createFromWindow(holder.getSurface());
1792                         setColor(parentSurfaceControl, 0, 0, 1.0f, 0);
1793                     }
1794                 },
1795                 new PixelChecker(Color.YELLOW) { // 10000
1796                     @Override
1797                     public boolean checkPixels(int pixelCount, int width, int height) {
1798                         return pixelCount > 9000 && pixelCount < 11000;
1799                     }
1800                 });
1801     }
1802 
1803     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1804     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1805     //                                  float b, float alpha, enum ADataSpace dataspace)
1806     @Test
testSurfaceTransaction_setColorAndBuffer()1807     public void testSurfaceTransaction_setColorAndBuffer() {
1808         verifyTest(
1809                 new BasicSurfaceHolderCallback() {
1810                     @Override
1811                     public void surfaceCreated(SurfaceHolder holder) {
1812                         long surfaceControl = createFromWindow(holder.getSurface());
1813 
1814                         setSolidBuffer(
1815                                 surfaceControl, DEFAULT_LAYOUT_WIDTH,
1816                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1817                         setColor(surfaceControl, 0, 1.0f, 0, 1.0f);
1818                     }
1819                 },
1820                 new PixelChecker(Color.RED) { // 10000
1821                     @Override
1822                     public boolean checkPixels(int pixelCount, int width, int height) {
1823                         return pixelCount > 9000 && pixelCount < 11000;
1824                     }
1825                 });
1826     }
1827 
1828     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1829     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1830     //                                  float b, float alpha, enum ADataSpace dataspace)
1831     @Test
testSurfaceTransaction_setColorAndBuffer_bufferAlpha_0_5()1832     public void testSurfaceTransaction_setColorAndBuffer_bufferAlpha_0_5() {
1833         verifyTest(
1834                 new BasicSurfaceHolderCallback() {
1835                     @Override
1836                     public void surfaceCreated(SurfaceHolder holder) {
1837                         long surfaceControl = createFromWindow(holder.getSurface());
1838 
1839                         setSolidBuffer(
1840                                 surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1841                                 Color.RED);
1842                         setBufferAlpha(surfaceControl, 0.5);
1843                         setColor(surfaceControl, 0, 0, 1.0f, 1.0f);
1844                     }
1845                 },
1846                 new PixelChecker(Color.RED, false /* logWhenNoMatch */) {
1847                     @Override
1848                     public boolean checkPixels(int pixelCount, int width, int height) {
1849                         return pixelCount == 0;
1850                     }
1851                 });
1852     }
1853 
1854     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1855     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1856     //                                  float b, float alpha, enum ADataSpace dataspace)
1857     @Test
testSurfaceTransaction_setBufferNoColor_bufferAlpha_0()1858     public void testSurfaceTransaction_setBufferNoColor_bufferAlpha_0() {
1859         verifyTest(
1860                 new BasicSurfaceHolderCallback() {
1861                     @Override
1862                     public void surfaceCreated(SurfaceHolder holder) {
1863                         long surfaceControlA = createFromWindow(holder.getSurface());
1864                         long surfaceControlB = createFromWindow(holder.getSurface());
1865 
1866                         setColor(surfaceControlA, 1.0f, 0, 0, 1.0f);
1867                         setSolidBuffer(surfaceControlB, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1868                                 Color.TRANSPARENT);
1869 
1870                         setZOrder(surfaceControlA, 1);
1871                         setZOrder(surfaceControlB, 2);
1872                     }
1873                 },
1874                 new PixelChecker(Color.RED) { // 10000
1875                     @Override
1876                     public boolean checkPixels(int pixelCount, int width, int height) {
1877                         return pixelCount > 9000 && pixelCount < 11000;
1878                     }
1879                 });
1880     }
1881 
1882     // @ApiTest = ASurfaceTransaction_setColor(ASurfaceTransaction* _Nonnull transaction,
1883     //                                  ASurfaceControl* _Nonnull surface_control, float r, float g,
1884     //                                  float b, float alpha, enum ADataSpace dataspace)
1885     @Test
testSurfaceTransaction_setColorAndBuffer_hide()1886     public void testSurfaceTransaction_setColorAndBuffer_hide() {
1887         verifyTest(
1888                 new BasicSurfaceHolderCallback() {
1889                     @Override
1890                     public void surfaceCreated(SurfaceHolder holder) {
1891                         long parentSurfaceControl = createFromWindow(holder.getSurface());
1892                         long childSurfaceControl = create(parentSurfaceControl);
1893 
1894                         setColor(parentSurfaceControl, 0, 1.0f, 0, 1.0f);
1895 
1896                         setSolidBuffer(
1897                                 childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
1898                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
1899                         setColor(childSurfaceControl, 0, 0, 1.0f, 1.0f);
1900                         setVisibility(childSurfaceControl, false);
1901                     }
1902                 },
1903                 new PixelChecker(Color.GREEN) { // 10000
1904                     @Override
1905                     public boolean checkPixels(int pixelCount, int width, int height) {
1906                         return pixelCount > 9000 && pixelCount < 11000;
1907                     }
1908                 });
1909     }
1910 
1911     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1912     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1913     @Test
testSurfaceTransaction_zOrderMultipleSurfaces()1914     public void testSurfaceTransaction_zOrderMultipleSurfaces() {
1915         verifyTest(
1916                 new BasicSurfaceHolderCallback() {
1917                     @Override
1918                     public void surfaceCreated(SurfaceHolder holder) {
1919                         long surfaceControlA = createFromWindow(holder.getSurface());
1920                         long surfaceControlB = createFromWindow(holder.getSurface());
1921 
1922                         // blue color layer of A is above the green buffer and red color layer
1923                         // of B
1924                         setColor(surfaceControlA, 0, 0, 1.0f, 1.0f);
1925                         setSolidBuffer(
1926                                 surfaceControlB, DEFAULT_LAYOUT_WIDTH,
1927                                 DEFAULT_LAYOUT_HEIGHT, Color.GREEN);
1928                         setColor(surfaceControlB, 1.0f, 0, 0, 1.0f);
1929                         setZOrder(surfaceControlA, 5);
1930                         setZOrder(surfaceControlB, 4);
1931                     }
1932                 },
1933                 new PixelChecker(Color.BLUE) { // 10000
1934                     @Override
1935                     public boolean checkPixels(int pixelCount, int width, int height) {
1936                         return pixelCount > 9000 && pixelCount < 11000;
1937                     }
1938                 });
1939     }
1940 
1941     // @ApiTest = ASurfaceTransaction_setZOrder(ASurfaceTransaction* _Nonnull transaction,
1942     //                                   ASurfaceControl* _Nonnull surface_control, int32_t z_order)
1943     @Test
testSurfaceTransaction_zOrderMultipleSurfacesWithParent()1944     public void testSurfaceTransaction_zOrderMultipleSurfacesWithParent() {
1945         verifyTest(
1946                 new BasicSurfaceHolderCallback() {
1947                     @Override
1948                     public void surfaceCreated(SurfaceHolder holder) {
1949                         long parentSurfaceControl = createFromWindow(holder.getSurface());
1950                         long surfaceControlA = create(parentSurfaceControl);
1951                         long surfaceControlB = create(parentSurfaceControl);
1952 
1953                         setColor(surfaceControlA, 0, 1.0f, 0, 1.0f);
1954                         setSolidBuffer(
1955                                 surfaceControlA, DEFAULT_LAYOUT_WIDTH,
1956                                 DEFAULT_LAYOUT_HEIGHT, Color.GREEN);
1957                         setColor(surfaceControlB, 1.0f, 0, 0, 1.0f);
1958                         setZOrder(surfaceControlA, 3);
1959                         setZOrder(surfaceControlB, 4);
1960                     }
1961                 },
1962                 new PixelChecker(Color.RED) { // 10000
1963                     @Override
1964                     public boolean checkPixels(int pixelCount, int width, int height) {
1965                         return pixelCount > 9000 && pixelCount < 11000;
1966                     }
1967                 });
1968     }
1969 
1970     // @ApiTest = ASurfaceTransaction_setPosition(ASurfaceTransaction* _Nonnull transaction,
1971     //                                     ASurfaceControl* _Nonnull surface_control, int32_t x,
1972     //                                     int32_t y)
1973     @Test
testSurfaceTransaction_setPosition()1974     public void testSurfaceTransaction_setPosition() {
1975         verifyTest(
1976                 new BasicSurfaceHolderCallback() {
1977                     @Override
1978                     public void surfaceCreated(SurfaceHolder holder) {
1979                         long surfaceControl = createFromWindow(holder.getSurface());
1980 
1981                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
1982                                 Color.RED);
1983                         setPosition(surfaceControl, 20, 10);
1984                     }
1985                 },
1986                 new RectChecker(DEFAULT_RECT) {
1987                     @Override
1988                     public PixelColor getExpectedColor(int x, int y) {
1989                         if (x >= 20 && y >= 10) {
1990                             return RED;
1991                         } else {
1992                             return YELLOW;
1993                         }
1994                     }
1995                 });
1996     }
1997 
1998     // @ApiTest = ASurfaceTransaction_setPosition(ASurfaceTransaction* _Nonnull transaction,
1999     //                                     ASurfaceControl* _Nonnull surface_control, int32_t x,
2000     //                                     int32_t y)
2001     @Test
testSurfaceTransaction_setPositionNegative()2002     public void testSurfaceTransaction_setPositionNegative() {
2003         verifyTest(
2004                 new BasicSurfaceHolderCallback() {
2005                     @Override
2006                     public void surfaceCreated(SurfaceHolder holder) {
2007                         long surfaceControl = createFromWindow(holder.getSurface());
2008 
2009                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
2010                                 Color.RED);
2011                         // Offset -20, -10
2012                         setPosition(surfaceControl, -20, -10);
2013                     }
2014                 },
2015                 new RectChecker(DEFAULT_RECT) {
2016                     @Override
2017                     public PixelColor getExpectedColor(int x, int y) {
2018                         if (x < DEFAULT_LAYOUT_WIDTH - 20 && y < DEFAULT_LAYOUT_HEIGHT - 10) {
2019                             return RED;
2020                         } else {
2021                             return YELLOW;
2022                         }
2023                     }
2024                 });
2025     }
2026 
2027     // @ApiTest = ASurfaceTransaction_setScale(ASurfaceTransaction* _Nonnull transaction,
2028     //                                  ASurfaceControl* _Nonnull surface_control, float xScale,
2029     //                                  float yScale)
2030     @Test
testSurfaceTransaction_setScale()2031     public void testSurfaceTransaction_setScale() {
2032         verifyTest(
2033                 new BasicSurfaceHolderCallback() {
2034                     @Override
2035                     public void surfaceCreated(SurfaceHolder holder) {
2036                         long surfaceControl = createFromWindow(holder.getSurface());
2037 
2038                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
2039                                 Color.RED);
2040                         setScale(surfaceControl, .5f, .5f);
2041                     }
2042                 },
2043                 new RectChecker(DEFAULT_RECT) {
2044                     @Override
2045                     public PixelColor getExpectedColor(int x, int y) {
2046                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2047                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2048                         if (x < halfWidth && y < halfHeight) {
2049                             return RED;
2050                         } else {
2051                             return YELLOW;
2052                         }
2053                     }
2054                 });
2055     }
2056 
2057     // @ApiTest = ASurfaceTransaction_setScale(ASurfaceTransaction* _Nonnull transaction,
2058     //                                  ASurfaceControl* _Nonnull surface_control, float xScale,
2059     //                                  float yScale)
2060     @Test
testSurfaceTransaction_scaleToZero()2061     public void testSurfaceTransaction_scaleToZero() {
2062         verifyTest(
2063                 new BasicSurfaceHolderCallback() {
2064                     @Override
2065                     public void surfaceCreated(SurfaceHolder holder) {
2066                         long parentSurfaceControl = createFromWindow(holder.getSurface());
2067                         long childSurfaceControl = create(parentSurfaceControl);
2068 
2069                         setSolidBuffer(parentSurfaceControl,
2070                                 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.YELLOW);
2071                         setSolidBuffer(childSurfaceControl,
2072                                 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.RED);
2073                         setScale(childSurfaceControl, 0f, 0f);
2074                     }
2075                 },
2076                 new PixelChecker(Color.YELLOW) {
2077                     @Override
2078                     public boolean checkPixels(int matchingPixelCount, int width, int height) {
2079                         return matchingPixelCount > 9000 & matchingPixelCount < 11000;
2080                     }
2081                 });
2082     }
2083 
2084     // @ApiTest = ASurfaceTransaction_setScale(ASurfaceTransaction* _Nonnull transaction,
2085     //                                  ASurfaceControl* _Nonnull surface_control, float xScale,
2086     //                                  float yScale)
2087     @Test
testSurfaceTransaction_setPositionAndScale()2088     public void testSurfaceTransaction_setPositionAndScale() {
2089         verifyTest(
2090                 new BasicSurfaceHolderCallback() {
2091                     @Override
2092                     public void surfaceCreated(SurfaceHolder holder) {
2093                         long surfaceControl = createFromWindow(holder.getSurface());
2094 
2095                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2096                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
2097                                 Color.MAGENTA, Color.GREEN);
2098 
2099                         // Set the position to -50, -50 in parent space then scale 2x in each
2100                         // direction relative to 0,0. The end result should be a -50,-50,150,150
2101                         // buffer coverage or essentially a 2x center-scale
2102 
2103                         setPosition(surfaceControl, -50, -50);
2104                         setScale(surfaceControl, 2, 2);
2105                     }
2106                 },
2107                 new RectChecker(new Rect(0, 0, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT)) {
2108                     @Override
2109                     public PixelColor getExpectedColor(int x, int y) {
2110                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2111                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2112                         if (x < halfWidth && y < halfHeight) {
2113                             return RED;
2114                         } else if (x >= halfWidth && y < halfHeight) {
2115                             return BLUE;
2116                         } else if (x < halfWidth && y >= halfHeight) {
2117                             return GREEN;
2118                         } else {
2119                             return MAGENTA;
2120                         }
2121                     }
2122 
2123                     @Override
2124                     public boolean checkPixels(int matchingPixelCount, int width, int height) {
2125                         // There will be sampling artifacts along the center line, ignore those
2126                         return matchingPixelCount > 9000 && matchingPixelCount < 11000;
2127                     }
2128                 });
2129     }
2130 
2131     // @ApiTest = ASurfaceTransaction_setBufferTransform(ASurfaceTransaction* _Nonnull transaction,
2132     //                                            ASurfaceControl* _Nonnull surface_control,
2133     //                                            int32_t transform)
2134     @Test
testSurfaceTransaction_setBufferTransform90()2135     public void testSurfaceTransaction_setBufferTransform90() {
2136         verifyTest(
2137                 new BasicSurfaceHolderCallback() {
2138                     @Override
2139                     public void surfaceCreated(SurfaceHolder holder) {
2140                         long surfaceControl = createFromWindow(holder.getSurface());
2141 
2142                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2143                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
2144                                 Color.MAGENTA, Color.GREEN);
2145                         setPosition(surfaceControl, -50, -50);
2146                         setBufferTransform(surfaceControl, /* NATIVE_WINDOW_TRANSFORM_ROT_90 */ 4);
2147                     }
2148                 },
2149                 new RectChecker(DEFAULT_RECT) {
2150                     @Override
2151                     public PixelColor getExpectedColor(int x, int y) {
2152                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2153                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2154                         if (x < halfWidth && y < halfHeight) {
2155                             return BLUE;
2156                         } else {
2157                             return YELLOW;
2158                         }
2159                     }
2160                 });
2161     }
2162 
2163     // @ApiTest = ASurfaceTransaction_setCrop(ASurfaceTransaction* _Nonnull transaction,
2164     //                                 ASurfaceControl* _Nonnull surface_control,
2165     //                                 const ARect& crop)
2166     @Test
testSurfaceTransaction_setCropSmall()2167     public void testSurfaceTransaction_setCropSmall() {
2168         verifyTest(
2169                 new BasicSurfaceHolderCallback() {
2170                     @Override
2171                     public void surfaceCreated(SurfaceHolder holder) {
2172                         long surfaceControl = createFromWindow(holder.getSurface());
2173 
2174                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2175                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
2176                                 Color.MAGENTA, Color.GREEN);
2177                         setCrop(surfaceControl, new Rect(0, 0, 50, 50));
2178                     }
2179                 },
2180 
2181                 new RectChecker(DEFAULT_RECT) {
2182                     @Override
2183                     public PixelColor getExpectedColor(int x, int y) {
2184                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2185                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2186                         if (x < halfWidth && y < halfHeight) {
2187                             return RED;
2188                         } else {
2189                             return YELLOW;
2190                         }
2191                     }
2192                 });
2193     }
2194 
2195     // @ApiTest = ASurfaceTransaction_setCrop(ASurfaceTransaction* _Nonnull transaction,
2196     //                                 ASurfaceControl* _Nonnull surface_control,
2197     //                                 const ARect& crop)
2198     @Test
testSurfaceTransaction_setCropLarge()2199     public void testSurfaceTransaction_setCropLarge() {
2200         verifyTest(
2201                 new BasicSurfaceHolderCallback() {
2202                     @Override
2203                     public void surfaceCreated(SurfaceHolder holder) {
2204                         long surfaceControl = createFromWindow(holder.getSurface());
2205 
2206                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2207                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
2208                                 Color.MAGENTA, Color.GREEN);
2209                         setCrop(surfaceControl, new Rect(0, 0, 150, 150));
2210                     }
2211                 },
2212 
2213                 new RectChecker(DEFAULT_RECT) {
2214                     @Override
2215                     public PixelColor getExpectedColor(int x, int y) {
2216                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2217                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2218                         if (x < halfWidth && y < halfHeight) {
2219                             return RED;
2220                         } else if (x >= halfWidth && y < halfHeight) {
2221                             return BLUE;
2222                         } else if (x < halfWidth && y >= halfHeight) {
2223                             return GREEN;
2224                         } else {
2225                             return MAGENTA;
2226                         }
2227                     }
2228                 });
2229     }
2230 
2231     // @ApiTest = ASurfaceTransaction_setCrop(ASurfaceTransaction* _Nonnull transaction,
2232     //                                 ASurfaceControl* _Nonnull surface_control,
2233     //                                 const ARect& crop)
2234     @Test
testSurfaceTransaction_setCropOffset()2235     public void testSurfaceTransaction_setCropOffset() {
2236         verifyTest(
2237                 new BasicSurfaceHolderCallback() {
2238                     @Override
2239                     public void surfaceCreated(SurfaceHolder holder) {
2240                         long surfaceControl = createFromWindow(holder.getSurface());
2241 
2242                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2243                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
2244                                 Color.MAGENTA, Color.GREEN);
2245                         setCrop(surfaceControl, new Rect(50, 50, 100, 100));
2246                     }
2247                 }, new RectChecker(DEFAULT_RECT) {
2248                     @Override
2249                     public PixelColor getExpectedColor(int x, int y) {
2250                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2251                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2252                         // Only Magenta is visible in the lower right quadrant
2253                         if (x >= halfWidth && y >= halfHeight) {
2254                             return MAGENTA;
2255                         } else {
2256                             return YELLOW;
2257                         }
2258                     }
2259                 });
2260     }
2261 
2262     // @ApiTest = ASurfaceTransaction_setCrop(ASurfaceTransaction* _Nonnull transaction,
2263     //                                 ASurfaceControl* _Nonnull surface_control,
2264     //                                 const ARect& crop)
2265     @Test
testSurfaceTransaction_setCropNegative()2266     public void testSurfaceTransaction_setCropNegative() {
2267         verifyTest(
2268                 new BasicSurfaceHolderCallback() {
2269                     @Override
2270                     public void surfaceCreated(SurfaceHolder holder) {
2271                         long surfaceControl = createFromWindow(holder.getSurface());
2272 
2273                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2274                                 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE,
2275                                 Color.MAGENTA, Color.GREEN);
2276                         setCrop(surfaceControl, new Rect(-50, -50, 50, 50));
2277                     }
2278                 }, new RectChecker(DEFAULT_RECT) {
2279                     @Override
2280                     public PixelColor getExpectedColor(int x, int y) {
2281                         int halfWidth = DEFAULT_LAYOUT_WIDTH / 2;
2282                         int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2;
2283                         if (x < halfWidth && y < halfHeight) {
2284                             return RED;
2285                         } else {
2286                             return YELLOW;
2287                         }
2288                     }
2289                 });
2290     }
2291 
2292     // Returns success of the surface transaction to decide whether to continue the test, such as
2293     // additional assertions.
verifySetFrameTimeline(boolean usePreferredIndex, SurfaceHolder holder)2294     private boolean verifySetFrameTimeline(boolean usePreferredIndex, SurfaceHolder holder) {
2295         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
2296         long surfaceControl = nSurfaceControl_createFromWindow(holder.getSurface());
2297         assertTrue("failed to create surface control", surfaceControl != 0);
2298         long surfaceTransaction = createSurfaceTransaction();
2299         long buffer = nSurfaceTransaction_setSolidBuffer(surfaceControl, surfaceTransaction,
2300                 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.RED);
2301         assertTrue("failed to set buffer", buffer != 0);
2302 
2303         // Get choreographer frame timelines.
2304         FrameCallbackData frameCallbackData = nGetFrameTimelines();
2305         FrameTimeline[] frameTimelines = frameCallbackData.getFrameTimelines();
2306 
2307         int timelineIndex = frameCallbackData.getPreferredFrameTimelineIndex();
2308         if (!usePreferredIndex) {
2309             if (frameTimelines.length == 1) {
2310                 // If there is only one frame timeline then it is already the preferred timeline.
2311                 // Thus testing a non-preferred index is impossible.
2312                 Log.i(TAG, "Non-preferred frame timeline does not exist");
2313                 return false;
2314             }
2315             if (timelineIndex == frameTimelines.length - 1) {
2316                 timelineIndex--;
2317             } else {
2318                 timelineIndex++;
2319             }
2320         }
2321         FrameTimeline frameTimeline = frameTimelines[timelineIndex];
2322         long vsyncId = frameTimeline.getVsyncId();
2323         assertTrue("Vsync ID not valid", vsyncId > 0);
2324 
2325         Trace.beginSection("Surface transaction created " + vsyncId);
2326         nSurfaceTransaction_setFrameTimeline(surfaceTransaction, vsyncId);
2327         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
2328                 true /* waitForFence */, onCompleteCallback);
2329         applyAndDeleteSurfaceTransaction(surfaceTransaction);
2330         Trace.endSection();
2331 
2332         Trace.beginSection("Wait for complete callback " + vsyncId);
2333         // Wait for callbacks to fire.
2334         try {
2335             onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
2336         } catch (InterruptedException e) {
2337         }
2338         if (onCompleteCallback.mLatch.getCount() > 0) {
2339             Log.e(TAG, "Failed to wait for callback");
2340         }
2341         Trace.endSection();
2342 
2343         assertEquals(0, onCompleteCallback.mLatch.getCount());
2344         assertTrue(onCompleteCallback.mCallbackTime > 0);
2345         assertTrue(onCompleteCallback.mLatchTime > 0);
2346 
2347         long periodNanos = (long) (1e9 / mActivity.getDisplay().getRefreshRate());
2348         long threshold = periodNanos / 2;
2349         // Check that the frame did not present earlier than the frame timeline chosen from setting
2350         // a vsyncId in the surface transaction; this should be guaranteed as part of the API
2351         // specification. Don't check whether the frame presents on-time since it can be flaky from
2352         // other delays.
2353         assertTrue("Frame presented too early using frame timeline index=" + timelineIndex
2354                         + " (preferred index=" + frameCallbackData.getPreferredFrameTimelineIndex()
2355                         + ", preferred vsyncId="
2356                         + frameTimelines[frameCallbackData.getPreferredFrameTimelineIndex()]
2357                                   .getVsyncId()
2358                         + "), vsyncId=" + frameTimeline.getVsyncId() + ", actual presentation time="
2359                         + onCompleteCallback.mPresentTime + ", expected presentation time="
2360                         + frameTimeline.getExpectedPresentTime() + ", actual - expected diff (ns)="
2361                         + (onCompleteCallback.mPresentTime - frameTimeline.getExpectedPresentTime())
2362                         + ", acceptable diff threshold (ns)= " + threshold,
2363                 onCompleteCallback.mPresentTime
2364                         > frameTimeline.getExpectedPresentTime() - threshold);
2365         return true;
2366     }
2367 
2368     // @ApiTest = ASurfaceTransaction_setFrameTimeline(ASurfaceTransaction* _Nonnull transaction,
2369     //                                          AVsyncId vsyncId)
2370     @Test
2371     @RequiresDevice // emulators can't support sync fences
testSurfaceTransaction_setFrameTimeline_preferredIndex()2372     public void testSurfaceTransaction_setFrameTimeline_preferredIndex() {
2373         Trace.beginSection(
2374                 "testSurfaceTransaction_setFrameTimeline_preferredIndex");
2375         Trace.endSection();
2376 
2377         BasicSurfaceHolderCallback basicSurfaceHolderCallback = new BasicSurfaceHolderCallback() {
2378             @Override
2379             public void surfaceCreated(SurfaceHolder surfaceHolder) {
2380                 // Noop.
2381             }
2382         };
2383         final CountDownLatch readyFence = new CountDownLatch(1);
2384         ASurfaceControlTestActivity.SurfaceHolderCallback surfaceHolderCallback =
2385                 new ASurfaceControlTestActivity.SurfaceHolderCallback(
2386                         new SurfaceHolderCallback(basicSurfaceHolderCallback), readyFence,
2387                         mActivity.getParentFrameLayout().getRootSurfaceControl());
2388         mActivity.createSurface(surfaceHolderCallback);
2389         try {
2390             assertTrue("timeout", readyFence.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS));
2391         } catch (InterruptedException e) {
2392             Assert.fail("interrupted");
2393         }
2394         if (!verifySetFrameTimeline(true, mActivity.getSurfaceView().getHolder())) return;
2395         mActivity.verifyScreenshot(
2396                 new PixelChecker(Color.RED) { //10000
2397                     @Override
2398                     public boolean checkPixels(int pixelCount, int width, int height) {
2399                         return pixelCount > 9000 && pixelCount < 11000;
2400                     }
2401                 }, mName);
2402 
2403     }
2404 
2405     // @ApiTest = ASurfaceTransaction_setFrameTimeline(ASurfaceTransaction* _Nonnull transaction,
2406     //                                          AVsyncId vsyncId)
2407     @Test
2408     @RequiresDevice // emulators can't support sync fences
testSurfaceTransaction_setFrameTimeline_notPreferredIndex()2409     public void testSurfaceTransaction_setFrameTimeline_notPreferredIndex() {
2410         Trace.beginSection(
2411                 "testSurfaceTransaction_setFrameTimeline_notPreferredIndex");
2412         Trace.endSection();
2413 
2414         BasicSurfaceHolderCallback basicSurfaceHolderCallback = new BasicSurfaceHolderCallback() {
2415             @Override
2416             public void surfaceCreated(SurfaceHolder surfaceHolder) {
2417                 // Noop.
2418             }
2419         };
2420         final CountDownLatch readyFence = new CountDownLatch(1);
2421         ASurfaceControlTestActivity.SurfaceHolderCallback surfaceHolderCallback =
2422                 new ASurfaceControlTestActivity.SurfaceHolderCallback(
2423                         new SurfaceHolderCallback(basicSurfaceHolderCallback), readyFence,
2424                         mActivity.getParentFrameLayout().getRootSurfaceControl());
2425         mActivity.createSurface(surfaceHolderCallback);
2426         try {
2427             assertTrue("timeout", readyFence.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS));
2428         } catch (InterruptedException e) {
2429             Assert.fail("interrupted");
2430         }
2431         if (!verifySetFrameTimeline(false, mActivity.getSurfaceView().getHolder())) return;
2432         mActivity.verifyScreenshot(
2433                 new PixelChecker(Color.RED) { //10000
2434                     @Override
2435                     public boolean checkPixels(int pixelCount, int width, int height) {
2436                         return pixelCount > 9000 && pixelCount < 11000;
2437                     }
2438                 }, mName);
2439 
2440     }
2441 
2442     static class TimedTransactionListener implements
2443             ASurfaceControlTestUtils.TransactionCompleteListener {
2444         long mCallbackTime = -1;
2445         long mLatchTime = -1;
2446         long mPresentTime = -1;
2447         CountDownLatch mLatch = new CountDownLatch(1);
2448         long mTargetSurfaceControlPtr;
2449         boolean mSurfaceControlFound;
2450         boolean mAcquireTimeQueried;
2451         boolean mReleaseFenceQueried;
2452 
2453         @Override
onTransactionComplete(long inLatchTime, long presentTime)2454         public void onTransactionComplete(long inLatchTime, long presentTime) {
2455             mCallbackTime = SystemClock.elapsedRealtime();
2456             mLatchTime = inLatchTime;
2457             mPresentTime = presentTime;
2458             mLatch.countDown();
2459         }
2460 
shouldQueryTransactionStats()2461         public long shouldQueryTransactionStats() {
2462             return mTargetSurfaceControlPtr;
2463         }
2464 
onTransactionStatsRead(boolean surfaceControlFound, boolean releaseFenceQueried, boolean acquireTimeQueried)2465         public void onTransactionStatsRead(boolean surfaceControlFound, boolean releaseFenceQueried,
2466                 boolean acquireTimeQueried) {
2467             mSurfaceControlFound = surfaceControlFound;
2468             mReleaseFenceQueried = releaseFenceQueried;
2469             mAcquireTimeQueried = acquireTimeQueried;
2470         }
2471     }
2472 
2473     // @ApiTest = ASurfaceTransaction_setOnCommit(ASurfaceTransaction* _Nonnull transaction,
2474     //                                     void* _Null_unspecified context,
2475     //                                     ASurfaceTransaction_OnCommit _Nonnull func)
2476     @Test
testSurfaceTransactionOnCommitCallback_emptyTransaction()2477     public void testSurfaceTransactionOnCommitCallback_emptyTransaction()
2478             throws InterruptedException {
2479         // Create and send an empty transaction with onCommit and onComplete callbacks.
2480         long surfaceTransaction = nSurfaceTransaction_create();
2481         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
2482         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, false /* waitForFence */,
2483                 onCompleteCallback);
2484         TimedTransactionListener onCommitCallback = new TimedTransactionListener();
2485         nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback);
2486         nSurfaceTransaction_apply(surfaceTransaction);
2487         nSurfaceTransaction_delete(surfaceTransaction);
2488 
2489         // Wait for callbacks to fire.
2490         onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
2491         onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
2492 
2493         // Validate we got callbacks.
2494         assertEquals(0, onCommitCallback.mLatch.getCount());
2495         assertTrue(onCommitCallback.mCallbackTime > 0);
2496         assertEquals(0, onCompleteCallback.mLatch.getCount());
2497         assertTrue(onCompleteCallback.mCallbackTime > 0);
2498 
2499         // Validate we received the callbacks in expected order.
2500         assertTrue(onCommitCallback.mCallbackTime <= onCompleteCallback.mCallbackTime);
2501     }
2502 
2503     // @ApiTest = ASurfaceTransaction_setOnCommit(ASurfaceTransaction* _Nonnull transaction,
2504     //                                     void* _Null_unspecified context,
2505     //                                     ASurfaceTransaction_OnCommit _Nonnull func)
2506     @Test
testSurfaceTransactionOnCommitCallback_bufferTransaction()2507     public void testSurfaceTransactionOnCommitCallback_bufferTransaction()
2508             throws Throwable {
2509         // Create and send a transaction with a buffer update and with onCommit and onComplete
2510         // callbacks.
2511         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
2512         TimedTransactionListener onCommitCallback = new TimedTransactionListener();
2513         verifyTest(
2514                 new BasicSurfaceHolderCallback() {
2515                     @Override
2516                     public void surfaceCreated(SurfaceHolder holder) {
2517                         long surfaceTransaction = nSurfaceTransaction_create();
2518                         long surfaceControl = createFromWindow(holder.getSurface());
2519                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
2520                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
2521                         nSurfaceTransaction_setOnCompleteCallback(
2522                                 surfaceTransaction /* waitForFence */, false,
2523                                 onCompleteCallback);
2524                         nSurfaceTransaction_setOnCommitCallback(surfaceTransaction,
2525                                 onCommitCallback);
2526                         nSurfaceTransaction_apply(surfaceTransaction);
2527                         nSurfaceTransaction_delete(surfaceTransaction);
2528 
2529                         // Wait for callbacks to fire.
2530                         try {
2531                             onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
2532                         } catch (InterruptedException e) {
2533                         }
2534                         if (onCommitCallback.mLatch.getCount() > 0) {
2535                             Log.e(TAG, "Failed to wait for commit callback");
2536                         }
2537                     }
2538                 },
2539                 new PixelChecker(Color.RED) { //10000
2540                     @Override
2541                     public boolean checkPixels(int pixelCount, int width, int height) {
2542                         return pixelCount > 9000 && pixelCount < 11000;
2543                     }
2544                 });
2545 
2546         onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
2547 
2548         // Validate we got callbacks with a valid latch time.
2549         assertEquals(0, onCommitCallback.mLatch.getCount());
2550         assertTrue(onCommitCallback.mCallbackTime > 0);
2551         assertTrue(onCommitCallback.mLatchTime > 0);
2552         assertEquals(0, onCompleteCallback.mLatch.getCount());
2553         assertTrue(onCompleteCallback.mCallbackTime > 0);
2554         assertTrue(onCompleteCallback.mLatchTime > 0);
2555 
2556         // Validate we received the callbacks in expected order and the latch times reported
2557         // matches.
2558         assertTrue(onCommitCallback.mCallbackTime <= onCompleteCallback.mCallbackTime);
2559         assertEquals(onCommitCallback.mLatchTime, onCompleteCallback.mLatchTime);
2560     }
2561 
2562     // @ApiTest = ASurfaceTransaction_setOnCommit(ASurfaceTransaction* _Nonnull transaction,
2563     //                                     void* _Null_unspecified context,
2564     //                                     ASurfaceTransaction_OnCommit _Nonnull func)
2565     @Test
testSurfaceTransactionOnCommitCallback_geometryTransaction()2566     public void testSurfaceTransactionOnCommitCallback_geometryTransaction()
2567             throws Throwable {
2568         // Create and send a transaction with a buffer update and with onCommit and onComplete
2569         // callbacks.
2570         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
2571         TimedTransactionListener onCommitCallback = new TimedTransactionListener();
2572         verifyTest(
2573                 new BasicSurfaceHolderCallback() {
2574                     @Override
2575                     public void surfaceCreated(SurfaceHolder holder) {
2576                         long surfaceTransaction = nSurfaceTransaction_create();
2577                         long surfaceControl = createFromWindow(holder.getSurface());
2578                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
2579                                 DEFAULT_LAYOUT_HEIGHT, Color.RED);
2580                         nSurfaceTransaction_apply(surfaceTransaction);
2581                         nSurfaceTransaction_delete(surfaceTransaction);
2582                         surfaceTransaction = nSurfaceTransaction_create();
2583                         nSurfaceTransaction_setPosition(surfaceControl, surfaceTransaction, 1, 0);
2584                         nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
2585                                 false /* waitForFence */, onCompleteCallback);
2586                         nSurfaceTransaction_setOnCommitCallback(surfaceTransaction,
2587                                 onCommitCallback);
2588                         nSurfaceTransaction_apply(surfaceTransaction);
2589                         nSurfaceTransaction_delete(surfaceTransaction);
2590                     }
2591                 },
2592                 new RectChecker(DEFAULT_RECT) {
2593                     @Override
2594                     public PixelColor getExpectedColor(int x, int y) {
2595                         if (x >= 1) {
2596                             return RED;
2597                         } else {
2598                             return YELLOW;
2599                         }
2600                     }
2601                 });
2602 
2603         // Wait for callbacks to fire.
2604         onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
2605         onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
2606 
2607         // Validate we got callbacks with a valid latch time.
2608         assertTrue(onCommitCallback.mLatch.getCount() == 0);
2609         assertTrue(onCommitCallback.mCallbackTime > 0);
2610         assertTrue(onCommitCallback.mLatchTime > 0);
2611         assertTrue(onCompleteCallback.mLatch.getCount() == 0);
2612         assertTrue(onCompleteCallback.mCallbackTime > 0);
2613         assertTrue(onCompleteCallback.mLatchTime > 0);
2614 
2615         // Validate we received the callbacks in expected order and the latch times reported
2616         // matches.
2617         assertTrue(onCommitCallback.mCallbackTime <= onCompleteCallback.mCallbackTime);
2618         assertTrue(onCommitCallback.mLatchTime == onCompleteCallback.mLatchTime);
2619     }
2620 
2621     // @ApiTest = ASurfaceTransaction_setOnCommit(ASurfaceTransaction* _Nonnull transaction,
2622     //                                     void* _Null_unspecified context,
2623     //                                     ASurfaceTransaction_OnCommit _Nonnull func)
2624     @Test
testSurfaceTransactionOnCommitCallback_withoutContext()2625     public void testSurfaceTransactionOnCommitCallback_withoutContext()
2626             throws InterruptedException {
2627         // Create and send an empty transaction with onCommit callbacks without context.
2628         long surfaceTransaction = nSurfaceTransaction_create();
2629         TimedTransactionListener onCommitCallback = new TimedTransactionListener();
2630         nSurfaceTransaction_setOnCommitCallbackWithoutContext(surfaceTransaction, onCommitCallback);
2631         nSurfaceTransaction_apply(surfaceTransaction);
2632         nSurfaceTransaction_delete(surfaceTransaction);
2633 
2634         // Wait for callbacks to fire.
2635         onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
2636 
2637         // Validate we got callbacks.
2638         assertEquals(0, onCommitCallback.mLatch.getCount());
2639         assertTrue(onCommitCallback.mCallbackTime > 0);
2640     }
2641 
2642     // @ApiTest = ASurfaceTransaction_setOnComplete(ASurfaceTransaction* _Nonnull transaction,
2643     //                                       void* _Null_unspecified context,
2644     //                                       ASurfaceTransaction_OnComplete _Nonnull func)
2645     @Test
testSurfaceTransactionOnCompleteCallback_withoutContext()2646     public void testSurfaceTransactionOnCompleteCallback_withoutContext()
2647             throws InterruptedException {
2648         // Create and send an empty transaction with onComplete callbacks without context.
2649         long surfaceTransaction = nSurfaceTransaction_create();
2650         TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
2651         nSurfaceTransaction_setOnCompleteCallbackWithoutContext(surfaceTransaction,
2652                 false /* waitForFence */, onCompleteCallback);
2653         nSurfaceTransaction_apply(surfaceTransaction);
2654         nSurfaceTransaction_delete(surfaceTransaction);
2655 
2656         // Wait for callbacks to fire.
2657         onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
2658 
2659         // Validate we got callbacks.
2660         assertEquals(0, onCompleteCallback.mLatch.getCount());
2661         assertTrue(onCompleteCallback.mCallbackTime > 0);
2662     }
2663 
2664     // @ApiTest = ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* _Nonnull,
2665     //                                                    ASurfaceControl* _Nonnull surface_control,
2666     //                                                    float currentRatio, float desiredRatio)
2667     @Test
testSetExtendedRangeBrightness()2668     public void testSetExtendedRangeBrightness() throws Exception {
2669         mActivity.awaitReadyState();
2670         Display display = mActivity.getDisplay();
2671         if (!display.isHdrSdrRatioAvailable()) {
2672             assertEquals(1.0f, display.getHdrSdrRatio(), 0.0001f);
2673         }
2674         // Set something super low so that if hdr/sdr ratio is available, we'll get some level
2675         // of HDR probably
2676         mActivity.getWindow().getAttributes().screenBrightness = 0.01f;
2677         // Wait for the screenBrightness to be picked up by VRI
2678         WidgetTestUtils.runOnMainAndDrawSync(mActivity.getParentFrameLayout(), () -> {});
2679         CountDownLatch hdrReady = new CountDownLatch(1);
2680         Exception[] listenerErrors = new Exception[1];
2681         if (display.isHdrSdrRatioAvailable()) {
2682             display.registerHdrSdrRatioChangedListener(Runnable::run, new Consumer<Display>() {
2683                 boolean mIsRegistered = true;
2684 
2685                 @Override
2686                 public void accept(Display updatedDisplay) {
2687                     try {
2688                         assertEquals(display.getDisplayId(), updatedDisplay.getDisplayId());
2689                         assertTrue(mIsRegistered);
2690                         if (display.getHdrSdrRatio() > 2.f) {
2691                             hdrReady.countDown();
2692                             display.unregisterHdrSdrRatioChangedListener(this);
2693                             mIsRegistered = false;
2694                         }
2695                     } catch (Exception e) {
2696                         synchronized (mActivity) {
2697                             listenerErrors[0] = e;
2698                             hdrReady.countDown();
2699                         }
2700                     }
2701                 }
2702             });
2703         } else {
2704             assertThrows(IllegalStateException.class, () ->
2705                     display.registerHdrSdrRatioChangedListener(Runnable::run, ignored -> {}));
2706         }
2707 
2708         final int extendedDataspace = DataSpace.pack(DataSpace.STANDARD_BT709,
2709                 DataSpace.TRANSFER_SRGB, DataSpace.RANGE_EXTENDED);
2710 
2711         verifyTest(
2712                 new BasicSurfaceHolderCallback() {
2713                     @Override
2714                     public void surfaceCreated(SurfaceHolder holder) {
2715                         long surfaceTransaction = nSurfaceTransaction_create();
2716                         long surfaceControl = createFromWindow(holder.getSurface());
2717                         setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
2718                                 DEFAULT_LAYOUT_HEIGHT, Color.WHITE);
2719                         nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction,
2720                                 extendedDataspace);
2721                         nSurfaceTransaction_setExtendedRangeBrightness(surfaceControl,
2722                                 surfaceTransaction, 3.f, 3.f);
2723                         nSurfaceTransaction_apply(surfaceTransaction);
2724                         nSurfaceTransaction_delete(surfaceTransaction);
2725                     }
2726                 },
2727                 new PixelChecker(Color.WHITE) { //10000
2728                     @Override
2729                     public boolean checkPixels(int pixelCount, int width, int height) {
2730                         return pixelCount > 9000 && pixelCount < 11000;
2731                     }
2732                 });
2733 
2734         // This isn't actually an error if it never happens, it's not _required_ that there's HDR
2735         // headroom available...
2736         if (display.isHdrSdrRatioAvailable()) {
2737             hdrReady.await(1, TimeUnit.SECONDS);
2738         }
2739 
2740         if (display.getHdrSdrRatio() > 2.f) {
2741             verifyTest(
2742                     new BasicSurfaceHolderCallback() {
2743                         @Override
2744                         public void surfaceCreated(SurfaceHolder holder) {
2745                             long surfaceTransaction = nSurfaceTransaction_create();
2746                             long surfaceControl = createFromWindow(holder.getSurface());
2747                             setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
2748                                     DEFAULT_LAYOUT_HEIGHT, Color.WHITE);
2749                             nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction,
2750                                     extendedDataspace);
2751                             nSurfaceTransaction_setExtendedRangeBrightness(surfaceControl,
2752                                     surfaceTransaction, 3.f, 3.f);
2753                             nSurfaceTransaction_apply(surfaceTransaction);
2754                             nSurfaceTransaction_delete(surfaceTransaction);
2755                         }
2756                     },
2757                     new PixelChecker(Color.WHITE) { //10000
2758                         @Override
2759                         public boolean checkPixels(int pixelCount, int width, int height) {
2760                             return pixelCount > 9000 && pixelCount < 11000;
2761                         }
2762                     });
2763         }
2764 
2765         synchronized (mActivity) {
2766             if (listenerErrors[0] != null) {
2767                 throw listenerErrors[0];
2768             }
2769         }
2770     }
2771 
getStableHdrSdrRatio(Display display)2772     private float getStableHdrSdrRatio(Display display) {
2773         float ratio = -1f;
2774         float incomingRatio = display.getHdrSdrRatio();
2775         long startMillis = SystemClock.uptimeMillis();
2776         try {
2777             do {
2778                 ratio = incomingRatio;
2779                 TimeUnit.MILLISECONDS.sleep(500);
2780                 incomingRatio = display.getHdrSdrRatio();
2781                 // Bail if the ratio settled or if it's been way too long.
2782             } while (Math.abs(ratio - incomingRatio) > 0.01
2783                     && SystemClock.uptimeMillis() - startMillis < 10000);
2784         } catch (InterruptedException e) {
2785             throw new RuntimeException(e);
2786         }
2787         return ratio;
2788     }
2789 
2790     // @ApiTest = ASurfaceTransaction_setDesiredHdrHeadroom(ASurfaceTransaction* _Nonnull,
2791     //                                               ASurfaceControl* _Nonnull surface_control,
2792     //                                               float desiredHeadroom)
2793     @Test
testSetDesiredHdrHeadroom()2794     public void testSetDesiredHdrHeadroom() throws Exception {
2795         mActivity.awaitReadyState();
2796         Display display = mActivity.getDisplay();
2797         assumeTrue(display.isHdrSdrRatioAvailable());
2798 
2799         final int dataspace = DataSpace.DATASPACE_BT2020_HLG;
2800 
2801         AtomicLong surfaceControlContainer = new AtomicLong();
2802 
2803         final CountDownLatch readyFence = new CountDownLatch(1);
2804         ASurfaceControlTestActivity.SurfaceHolderCallback surfaceHolderCallback =
2805                 new ASurfaceControlTestActivity.SurfaceHolderCallback(
2806                         new SurfaceHolderCallback(new BasicSurfaceHolderCallback() {
2807                             @Override
2808                             public void surfaceCreated(SurfaceHolder holder) {
2809                                 long surfaceTransaction = nSurfaceTransaction_create();
2810                                 long surfaceControl = createFromWindow(holder.getSurface());
2811                                 surfaceControlContainer.set(surfaceControl);
2812                                 setSolidBuffer(surfaceControl, surfaceTransaction,
2813                                         DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.WHITE);
2814                                 nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction,
2815                                         dataspace);
2816                                 nSurfaceTransaction_apply(surfaceTransaction);
2817                                 nSurfaceTransaction_delete(surfaceTransaction);
2818                             }
2819                         }),
2820                         readyFence,
2821                         mActivity.getParentFrameLayout().getRootSurfaceControl());
2822         mActivity.createSurface(surfaceHolderCallback);
2823         try {
2824             assertTrue("timeout", readyFence.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS));
2825         } catch (InterruptedException e) {
2826             Assert.fail("interrupted");
2827         }
2828 
2829         float headroom = getStableHdrSdrRatio(display);
2830         // Require some small threshold for allowable headroom
2831         assumeTrue(headroom > 1.02f);
2832         float targetHeadroom = 1.f + (headroom - 1.f) / 2;
2833 
2834         mActivity.runOnUiThread(() -> {
2835             long surfaceTransaction = nSurfaceTransaction_create();
2836             nSurfaceTransaction_setDesiredHdrHeadroom(
2837                     surfaceControlContainer.get(), surfaceTransaction, targetHeadroom);
2838             nSurfaceTransaction_apply(surfaceTransaction);
2839             nSurfaceTransaction_delete(surfaceTransaction);
2840         });
2841 
2842         assertTrue("Headroom restriction is not respected",
2843                 getStableHdrSdrRatio(display) <= (targetHeadroom + 0.01));
2844 
2845         mActivity.runOnUiThread(() -> {
2846             long surfaceTransaction = nSurfaceTransaction_create();
2847             nSurfaceTransaction_setDesiredHdrHeadroom(
2848                     surfaceControlContainer.get(), surfaceTransaction, 0.f);
2849             nSurfaceTransaction_apply(surfaceTransaction);
2850             nSurfaceTransaction_delete(surfaceTransaction);
2851         });
2852 
2853         assertTrue("Removed headroom restriction is not respected",
2854                 getStableHdrSdrRatio(display) > targetHeadroom);
2855     }
2856 
2857     static class TimedBufferReleaseCallback implements
2858             BufferReleaseCallback {
2859         long mCallbackTime = -1;
2860         CountDownLatch mLatch = new CountDownLatch(1);
2861 
2862         @Override
onBufferRelease()2863         public void onBufferRelease() {
2864             mCallbackTime = SystemClock.elapsedRealtime();
2865             mLatch.countDown();
2866         }
2867 
callbackCalled()2868         boolean callbackCalled() {
2869             return mCallbackTime != -1;
2870         }
2871 
waitForCallback()2872         boolean waitForCallback() {
2873             try {
2874                 return mLatch.await(10, TimeUnit.SECONDS);
2875             } catch (InterruptedException e) {
2876                 throw new RuntimeException(e);
2877             }
2878         }
2879     }
2880 
2881     // @ApiTest = ASurfaceTransaction_setBufferWithRelease(ASurfaceTransaction* _Nonnull,
2882     //                                              ASurfaceControl* _Nonnull surface_control,
2883     //                                              AHardwareBuffer* _Nonnull buffer,
2884     //                                              int acquire_fence_fd,
2885     //                                              void* _Null_unspecified context,
2886     //                                              ASurfaceTransaction_OnBufferRelease _Nonnull)
2887     @Test
testBufferRelease()2888     public void testBufferRelease() {
2889         SurfaceControl.Builder builder = new SurfaceControl.Builder();
2890         builder.setName("testBufferRelease");
2891         SurfaceControl control = builder.build();
2892         final long surfaceControl = nSurfaceControl_fromJava(control);
2893         assertTrue(surfaceControl != 0);
2894 
2895         var buffer1ReleaseCallback = new TimedBufferReleaseCallback();
2896         long buffer1 = setAndApplySolidBufferWithRelease(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2897                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer1ReleaseCallback);
2898         // Buffer should not have been released, so we don't expect the callback to be called.
2899         assertFalse(buffer1ReleaseCallback.callbackCalled());
2900         var buffer2ReleaseCallback = new TimedBufferReleaseCallback();
2901         long buffer2 = setAndApplySolidBufferWithRelease(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2902                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer2ReleaseCallback);
2903 
2904         // Buffer2 should not have been released, so we don't expect the callback to be called.
2905         // Latching buffer2, should release buffer1.
2906         buffer1ReleaseCallback.waitForCallback();
2907         assertTrue(buffer1ReleaseCallback.callbackCalled());
2908         nSurfaceTransaction_releaseBuffer(buffer1);
2909         assertFalse(buffer2ReleaseCallback.callbackCalled());
2910 
2911         var buffer3ReleaseCallback = new TimedBufferReleaseCallback();
2912         long buffer3 = setAndApplySolidBufferWithRelease(surfaceControl, DEFAULT_LAYOUT_WIDTH,
2913                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer3ReleaseCallback);
2914 
2915         buffer2ReleaseCallback.waitForCallback();
2916         assertTrue(buffer2ReleaseCallback.callbackCalled());
2917         nSurfaceTransaction_releaseBuffer(buffer2);
2918         assertFalse(buffer3ReleaseCallback.callbackCalled());
2919 
2920         nSurfaceControl_release(surfaceControl);
2921 
2922         // releasing the surface control should release the last buffer
2923         // buffer3ReleaseCallback.waitForCallback();
2924         // assertTrue(buffer3ReleaseCallback.callbackCalled());
2925         // nSurfaceTransaction_releaseBuffer(buffer3);
2926     }
2927 
2928     // @ApiTest = ASurfaceTransaction_setBufferWithRelease(ASurfaceTransaction* _Nonnull,
2929     //                                              ASurfaceControl* _Nonnull surface_control,
2930     //                                              AHardwareBuffer* _Nonnull buffer,
2931     //                                              int acquire_fence_fd,
2932     //                                              void* _Null_unspecified context,
2933     //                                              ASurfaceTransaction_OnBufferRelease _Nonnull)
2934     @Test
testBufferReleaseOnSetBuffer()2935     public void testBufferReleaseOnSetBuffer() {
2936         SurfaceControl.Builder builder = new SurfaceControl.Builder();
2937         builder.setName("testBufferRelease");
2938         SurfaceControl control = builder.build();
2939         final long surfaceControl = nSurfaceControl_fromJava(control);
2940         assertTrue(surfaceControl != 0);
2941 
2942         SurfaceControl.Transaction jTransaction = new SurfaceControl.Transaction();
2943         final long transaction = nSurfaceTransaction_fromJava(jTransaction);
2944         assertTrue(transaction != 0);
2945 
2946         var buffer1ReleaseCallback = new TimedBufferReleaseCallback();
2947         long buffer1 = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
2948                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer1ReleaseCallback);
2949         assertTrue("failed to set buffer", buffer1 != 0);
2950 
2951         // Buffer should not have been released, since we are not replacing the buffer.
2952         assertFalse(buffer1ReleaseCallback.callbackCalled());
2953 
2954         var buffer2ReleaseCallback = new TimedBufferReleaseCallback();
2955         long buffer2 = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
2956                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer2ReleaseCallback);
2957 
2958         // Buffer2 replaces Buffer1 when we call set buffer on the transaction so should release buffer1.
2959         buffer1ReleaseCallback.waitForCallback();
2960         assertTrue(buffer1ReleaseCallback.callbackCalled());
2961         nSurfaceTransaction_releaseBuffer(buffer1);
2962         assertFalse(buffer2ReleaseCallback.callbackCalled());
2963 
2964         var buffer3ReleaseCallback = new TimedBufferReleaseCallback();
2965         long buffer3 = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
2966                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer3ReleaseCallback);
2967 
2968         buffer2ReleaseCallback.waitForCallback();
2969         assertTrue(buffer2ReleaseCallback.callbackCalled());
2970         nSurfaceTransaction_releaseBuffer(buffer2);
2971         assertFalse(buffer3ReleaseCallback.callbackCalled());
2972 
2973         // setting a null buffer should release the last buffer
2974         nSurfaceTransaction_setBuffer(surfaceControl, transaction, /*null buffer*/ 0);
2975 
2976         buffer3ReleaseCallback.waitForCallback();
2977         assertTrue(buffer3ReleaseCallback.callbackCalled());
2978         nSurfaceTransaction_releaseBuffer(buffer3);
2979 
2980         nSurfaceControl_release(surfaceControl);
2981     }
2982 
2983     // @ApiTest = ASurfaceTransaction_setBufferWithRelease(ASurfaceTransaction* _Nonnull,
2984     //                                              ASurfaceControl* _Nonnull surface_control,
2985     //                                              AHardwareBuffer* _Nonnull buffer,
2986     //                                              int acquire_fence_fd,
2987     //                                              void* _Null_unspecified context,
2988     //                                              ASurfaceTransaction_OnBufferRelease _Nonnull)
2989     @Test
testBufferReleaseOnTransactionMerge()2990     public void testBufferReleaseOnTransactionMerge() {
2991         SurfaceControl.Builder builder = new SurfaceControl.Builder();
2992         builder.setName("testBufferRelease");
2993         SurfaceControl control = builder.build();
2994         final long surfaceControl = nSurfaceControl_fromJava(control);
2995         assertTrue(surfaceControl != 0);
2996 
2997 
2998         SurfaceControl.Transaction jTransaction = new SurfaceControl.Transaction();
2999         final long transaction = nSurfaceTransaction_fromJava(jTransaction);
3000         assertTrue(transaction != 0);
3001 
3002         var buffer1ReleaseCallback = new TimedBufferReleaseCallback();
3003         long buffer1 = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
3004                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer1ReleaseCallback);
3005         assertTrue("failed to set buffer", buffer1 != 0);
3006 
3007         SurfaceControl.Transaction parentTransaction = new SurfaceControl.Transaction();
3008         parentTransaction.merge(jTransaction);
3009         // Buffer should not have been released, since we are not replacing the buffer.
3010         assertFalse(buffer1ReleaseCallback.callbackCalled());
3011 
3012         var buffer2ReleaseCallback = new TimedBufferReleaseCallback();
3013         long buffer2 = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
3014                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer2ReleaseCallback);
3015         parentTransaction.merge(jTransaction);
3016 
3017         // Buffer2 replaces Buffer1 when we merge the transaction so should release buffer1.
3018         buffer1ReleaseCallback.waitForCallback();
3019         assertTrue(buffer1ReleaseCallback.callbackCalled());
3020         nSurfaceTransaction_releaseBuffer(buffer1);
3021         assertFalse(buffer2ReleaseCallback.callbackCalled());
3022 
3023         var buffer3ReleaseCallback = new TimedBufferReleaseCallback();
3024         long buffer3 = nSurfaceTransaction_setSolidBufferWithRelease(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH,
3025                 DEFAULT_LAYOUT_HEIGHT, Color.RED, buffer3ReleaseCallback);
3026         parentTransaction.merge(jTransaction);
3027 
3028         buffer2ReleaseCallback.waitForCallback();
3029         assertTrue(buffer2ReleaseCallback.callbackCalled());
3030         nSurfaceTransaction_releaseBuffer(buffer2);
3031         assertFalse(buffer3ReleaseCallback.callbackCalled());
3032 
3033         // setting a null buffer should release the last buffer
3034         nSurfaceTransaction_setBuffer(surfaceControl, transaction, /*null buffer*/ 0);
3035         parentTransaction.merge(jTransaction);
3036 
3037         buffer3ReleaseCallback.waitForCallback();
3038         assertTrue(buffer3ReleaseCallback.callbackCalled());
3039         nSurfaceTransaction_releaseBuffer(buffer3);
3040 
3041         nSurfaceControl_release(surfaceControl);
3042     }
3043 
3044     // @ApiTest = ASurfaceTransaction_delete(ASurfaceTransaction* _Nullable transaction)
3045     @Test
testSurfaceTransaction_delete()3046     public void testSurfaceTransaction_delete() {
3047         long surfaceTransaction = nSurfaceTransaction_create();
3048         assertTrue("failed to create surface transaction", surfaceTransaction != 0);
3049         nSurfaceTransaction_delete(surfaceTransaction);
3050 
3051         // can pass a nullptr
3052         nSurfaceTransaction_delete(0);
3053     }
3054 
3055     // @ApiTest = ASurfaceTransactionStats_getLatchTime(
3056     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats)
3057     // @ApiTest = ASurfaceTransactionStats_getAcquireTime(
3058     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats,
3059     //        ASurfaceControl* _Nonnull surface_control)
3060     // @ApiTest = ASurfaceTransactionStats_getASurfaceControls(
3061     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats,
3062     //        ASurfaceControl* _Nullable* _Nullable* _Nonnull outASurfaceControls,
3063     //        size_t* _Nonnull outASurfaceControlsSize)
3064     // @ApiTest = ASurfaceTransactionStats_releaseASurfaceControls(
3065     //        ASurfaceControl* _Nonnull* _Nonnull surface_controls)
3066     @Test
3067     @RequiresDevice // emulators can't support sync fences
testOnCommit_ASurfaceTransactionStats()3068     public void testOnCommit_ASurfaceTransactionStats() {
3069         SurfaceControl.Builder builder = new SurfaceControl.Builder();
3070         builder.setName("testOnCommit_ASurfaceTransactionStats");
3071         SurfaceControl control = builder.build();
3072         final long surfaceControl = nSurfaceControl_fromJava(control);
3073         assertTrue(surfaceControl != 0);
3074         final ArrayList<Long> mBuffers = new ArrayList<>();
3075 
3076         for (int i = 0; i < 100; i++) {
3077             TimedTransactionListener onCommitCallback = new TimedTransactionListener();
3078             long surfaceTransaction = createSurfaceTransaction();
3079             mBuffers.add(setSolidBuffer(surfaceControl, surfaceTransaction, 1,
3080                     1, Color.RED));
3081             nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback);
3082             onCommitCallback.mTargetSurfaceControlPtr = surfaceControl;
3083             applyAndDeleteSurfaceTransaction(surfaceTransaction);
3084             try {
3085                 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS);
3086             } catch (InterruptedException e) {
3087             }
3088 
3089             // Validate we got callbacks.
3090             assertEquals(0, onCommitCallback.mLatch.getCount());
3091             assertTrue(onCommitCallback.mCallbackTime > 0);
3092             assertTrue(onCommitCallback.mSurfaceControlFound);
3093             assertTrue(onCommitCallback.mAcquireTimeQueried);
3094         }
3095 
3096         for (Long buffer : mBuffers) {
3097             nSurfaceTransaction_releaseBuffer(buffer);
3098         }
3099         mBuffers.clear();
3100     }
3101 
3102     // @ApiTest = ASurfaceTransactionStats_getLatchTime(
3103     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats)
3104     // @ApiTest = ASurfaceTransactionStats_getAcquireTime(
3105     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats,
3106     //        ASurfaceControl* _Nonnull surface_control)
3107     // @ApiTest = ASurfaceTransactionStats_getPreviousReleaseFenceFd(
3108     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats,
3109     //        ASurfaceControl* _Nonnull surface_control)
3110     // @ApiTest = ASurfaceTransactionStats_getASurfaceControls(
3111     //        ASurfaceTransactionStats* _Nonnull surface_transaction_stats,
3112     //        ASurfaceControl* _Nullable* _Nullable* _Nonnull outASurfaceControls,
3113     //        size_t* _Nonnull outASurfaceControlsSize)
3114     // @ApiTest = ASurfaceTransactionStats_releaseASurfaceControls(
3115     //        ASurfaceControl* _Nonnull* _Nonnull surface_controls)
3116     @Test
3117     @RequiresDevice // emulators can't support sync fences
testOnComplete_ASurfaceTransactionStats()3118     public void testOnComplete_ASurfaceTransactionStats() {
3119         SurfaceControl.Builder builder = new SurfaceControl.Builder();
3120         builder.setName("testOnComplete_ASurfaceTransactionStats");
3121         SurfaceControl control = builder.build();
3122         final long surfaceControl = nSurfaceControl_fromJava(control);
3123         assertTrue(surfaceControl != 0);
3124         final ArrayList<Long> mBuffers = new ArrayList<>();
3125 
3126         for (int i = 0; i < 100; i++) {
3127             TimedTransactionListener onCompleteCallback = new TimedTransactionListener();
3128             long surfaceTransaction = createSurfaceTransaction();
3129             mBuffers.add(setSolidBuffer(surfaceControl, surfaceTransaction, 1,
3130                     1, Color.RED));
3131             nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction,
3132                     true /* waitForFence */, onCompleteCallback);
3133             onCompleteCallback.mTargetSurfaceControlPtr = surfaceControl;
3134             applyAndDeleteSurfaceTransaction(surfaceTransaction);
3135             try {
3136                 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS);
3137             } catch (InterruptedException e) {
3138             }
3139 
3140             // Validate we got callbacks.
3141             assertEquals(0, onCompleteCallback.mLatch.getCount());
3142             assertTrue(onCompleteCallback.mCallbackTime > 0);
3143             assertTrue(onCompleteCallback.mSurfaceControlFound);
3144             assertTrue(onCompleteCallback.mAcquireTimeQueried);
3145             assertTrue(onCompleteCallback.mReleaseFenceQueried);
3146         }
3147 
3148         for (Long buffer : mBuffers) {
3149             nSurfaceTransaction_releaseBuffer(buffer);
3150         }
3151         mBuffers.clear();
3152     }
3153 }
3154