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.applyAndDeleteSurfaceTransaction; 23 import static android.view.cts.util.ASurfaceControlTestUtils.createSurfaceTransaction; 24 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_acquire; 25 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_create; 26 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_createFromWindow; 27 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_fromJava; 28 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_release; 29 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_apply; 30 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_create; 31 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_delete; 32 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_fromJava; 33 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_releaseBuffer; 34 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setBuffer; 35 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDamageRegion; 36 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDataSpace; 37 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDesiredHdrHeadroom; 38 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setDesiredPresentTime; 39 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setExtendedRangeBrightness; 40 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setFrameTimeline; 41 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCommitCallback; 42 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCommitCallbackWithoutContext; 43 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCompleteCallback; 44 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setOnCompleteCallbackWithoutContext; 45 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setPosition; 46 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setQuadrantBuffer; 47 import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceTransaction_setSolidBuffer; 48 import static android.view.cts.util.ASurfaceControlTestUtils.reparent; 49 import static android.view.cts.util.ASurfaceControlTestUtils.setBufferAlpha; 50 import static android.view.cts.util.ASurfaceControlTestUtils.setBufferOpaque; 51 import static android.view.cts.util.ASurfaceControlTestUtils.setBufferTransform; 52 import static android.view.cts.util.ASurfaceControlTestUtils.setColor; 53 import static android.view.cts.util.ASurfaceControlTestUtils.setCrop; 54 import static android.view.cts.util.ASurfaceControlTestUtils.setGeometry; 55 import static android.view.cts.util.ASurfaceControlTestUtils.setPosition; 56 import static android.view.cts.util.ASurfaceControlTestUtils.setScale; 57 import static android.view.cts.util.ASurfaceControlTestUtils.setVisibility; 58 import static android.view.cts.util.ASurfaceControlTestUtils.setZOrder; 59 import static android.view.cts.util.FrameCallbackData.nGetFrameTimelines; 60 61 import static org.junit.Assert.assertEquals; 62 import static org.junit.Assert.assertThrows; 63 import static org.junit.Assert.assertTrue; 64 import static org.junit.Assume.assumeTrue; 65 66 import android.graphics.Canvas; 67 import android.graphics.Color; 68 import android.graphics.Rect; 69 import android.hardware.DataSpace; 70 import android.os.SystemClock; 71 import android.os.Trace; 72 import android.platform.test.annotations.RequiresDevice; 73 import android.util.Log; 74 import android.view.Display; 75 import android.view.Surface; 76 import android.view.SurfaceControl; 77 import android.view.SurfaceHolder; 78 import android.view.cts.surfacevalidator.ASurfaceControlTestActivity; 79 import android.view.cts.surfacevalidator.ASurfaceControlTestActivity.PixelChecker; 80 import android.view.cts.surfacevalidator.PixelColor; 81 import android.view.cts.util.ASurfaceControlTestUtils; 82 import android.view.cts.util.FrameCallbackData; 83 import android.view.cts.util.FrameCallbackData.FrameTimeline; 84 85 import androidx.annotation.NonNull; 86 import androidx.test.ext.junit.rules.ActivityScenarioRule; 87 import androidx.test.filters.LargeTest; 88 import androidx.test.runner.AndroidJUnit4; 89 90 import com.android.compatibility.common.util.DisableAnimationRule; 91 import com.android.compatibility.common.util.WidgetTestUtils; 92 93 import org.junit.Assert; 94 import org.junit.Before; 95 import org.junit.Rule; 96 import org.junit.Test; 97 import org.junit.rules.TestName; 98 import org.junit.runner.RunWith; 99 100 import java.lang.ref.Reference; 101 import java.util.HashSet; 102 import java.util.List; 103 import java.util.Set; 104 import java.util.concurrent.CountDownLatch; 105 import java.util.concurrent.TimeUnit; 106 import java.util.concurrent.atomic.AtomicLong; 107 import java.util.function.Consumer; 108 109 @LargeTest 110 @RunWith(AndroidJUnit4.class) 111 public class ASurfaceControlTest { 112 private static final String TAG = ASurfaceControlTest.class.getSimpleName(); 113 private static final boolean DEBUG = false; 114 115 private static final int DEFAULT_LAYOUT_WIDTH = 100; 116 private static final int DEFAULT_LAYOUT_HEIGHT = 100; 117 private static final Rect DEFAULT_RECT = new Rect(1, 1, DEFAULT_LAYOUT_WIDTH - 1, 118 DEFAULT_LAYOUT_HEIGHT - 1); 119 120 private static final PixelColor RED = new PixelColor(Color.RED); 121 private static final PixelColor BLUE = new PixelColor(Color.BLUE); 122 private static final PixelColor MAGENTA = new PixelColor(Color.MAGENTA); 123 private static final PixelColor GREEN = new PixelColor(Color.GREEN); 124 private static final PixelColor YELLOW = new PixelColor(Color.YELLOW); 125 126 @Rule 127 public DisableAnimationRule mDisableAnimationRule = new DisableAnimationRule(); 128 129 @Rule 130 public ActivityScenarioRule<ASurfaceControlTestActivity> mActivityRule = 131 createFullscreenActivityScenarioRule(ASurfaceControlTestActivity.class); 132 133 @Rule 134 public TestName mName = new TestName(); 135 136 private ASurfaceControlTestActivity mActivity; 137 138 private long mDesiredPresentTime; 139 140 @Before setup()141 public void setup() { 142 mActivityRule.getScenario().onActivity(activity -> mActivity = activity); 143 } 144 145 /////////////////////////////////////////////////////////////////////////// 146 // SurfaceHolder.Callbacks 147 /////////////////////////////////////////////////////////////////////////// 148 149 private static class SurfaceHolderCallback implements SurfaceHolder.Callback { 150 BasicSurfaceHolderCallback mBasicSurfaceHolderCallback; 151 SurfaceHolderCallback(BasicSurfaceHolderCallback basicSurfaceHolderCallback)152 SurfaceHolderCallback(BasicSurfaceHolderCallback basicSurfaceHolderCallback) { 153 mBasicSurfaceHolderCallback = basicSurfaceHolderCallback; 154 } 155 156 @Override surfaceCreated(@onNull SurfaceHolder holder)157 public void surfaceCreated(@NonNull SurfaceHolder holder) { 158 Canvas canvas = holder.lockCanvas(); 159 canvas.drawColor(Color.YELLOW); 160 holder.unlockCanvasAndPost(canvas); 161 162 mBasicSurfaceHolderCallback.surfaceCreated(holder); 163 } 164 165 @Override surfaceChanged(@onNull SurfaceHolder holder, int format, int width, int height)166 public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, 167 int height) { 168 } 169 170 @Override surfaceDestroyed(@onNull SurfaceHolder holder)171 public void surfaceDestroyed(@NonNull SurfaceHolder holder) { 172 mBasicSurfaceHolderCallback.surfaceDestroyed(); 173 } 174 } 175 176 private abstract static class BasicSurfaceHolderCallback { 177 private final Set<Long> mSurfaceControls = new HashSet<>(); 178 private final Set<Long> mBuffers = new HashSet<>(); 179 surfaceCreated(SurfaceHolder surfaceHolder)180 public abstract void surfaceCreated(SurfaceHolder surfaceHolder); 181 surfaceDestroyed()182 public void surfaceDestroyed() { 183 for (Long surfaceControl : mSurfaceControls) { 184 reparent(surfaceControl, 0); 185 nSurfaceControl_release(surfaceControl); 186 } 187 mSurfaceControls.clear(); 188 189 for (Long buffer : mBuffers) { 190 nSurfaceTransaction_releaseBuffer(buffer); 191 } 192 mBuffers.clear(); 193 } 194 createFromWindow(Surface surface)195 public long createFromWindow(Surface surface) { 196 long surfaceControl = nSurfaceControl_createFromWindow(surface); 197 assertTrue("failed to create surface control", surfaceControl != 0); 198 199 mSurfaceControls.add(surfaceControl); 200 return surfaceControl; 201 } 202 create(long parentSurfaceControl)203 public long create(long parentSurfaceControl) { 204 long childSurfaceControl = nSurfaceControl_create(parentSurfaceControl); 205 assertTrue("failed to create child surface control", childSurfaceControl != 0); 206 207 mSurfaceControls.add(childSurfaceControl); 208 return childSurfaceControl; 209 } 210 setSolidBuffer( long surfaceControl, long surfaceTransaction, int width, int height, int color)211 public long setSolidBuffer( 212 long surfaceControl, long surfaceTransaction, int width, int height, int color) { 213 long buffer = nSurfaceTransaction_setSolidBuffer(surfaceControl, surfaceTransaction, 214 width, height, color); 215 assertTrue("failed to set buffer", buffer != 0); 216 mBuffers.add(buffer); 217 return buffer; 218 } 219 setSolidBuffer(long surfaceControl, int width, int height, int color)220 public long setSolidBuffer(long surfaceControl, int width, int height, int color) { 221 long surfaceTransaction = createSurfaceTransaction(); 222 long buffer = setSolidBuffer(surfaceControl, surfaceTransaction, width, height, color); 223 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 224 nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback); 225 applyAndDeleteSurfaceTransaction(surfaceTransaction); 226 try { 227 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 228 } catch (InterruptedException e) { 229 } 230 if (onCommitCallback.mLatch.getCount() > 0) { 231 Log.e(TAG, "Failed to wait for commit callback"); 232 } 233 return buffer; 234 } 235 setNullBuffer(long surfaceControl)236 public void setNullBuffer(long surfaceControl) { 237 long surfaceTransaction = createSurfaceTransaction(); 238 nSurfaceTransaction_setBuffer(surfaceControl, surfaceTransaction, 0 /* buffer */); 239 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 240 nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback); 241 applyAndDeleteSurfaceTransaction(surfaceTransaction); 242 try { 243 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 244 } catch (InterruptedException e) { 245 } 246 if (onCommitCallback.mLatch.getCount() > 0) { 247 Log.e(TAG, "Failed to wait for commit callback"); 248 } 249 } 250 setQuadrantBuffer(long surfaceControl, long surfaceTransaction, int width, int height, int colorTopLeft, int colorTopRight, int colorBottomRight, int colorBottomLeft)251 public void setQuadrantBuffer(long surfaceControl, long surfaceTransaction, int width, 252 int height, int colorTopLeft, int colorTopRight, int colorBottomRight, 253 int colorBottomLeft) { 254 long buffer = nSurfaceTransaction_setQuadrantBuffer(surfaceControl, surfaceTransaction, 255 width, height, colorTopLeft, colorTopRight, colorBottomRight, colorBottomLeft); 256 assertTrue("failed to set buffer", buffer != 0); 257 mBuffers.add(buffer); 258 } 259 setQuadrantBuffer(long surfaceControl, int width, int height, int colorTopLeft, int colorTopRight, int colorBottomRight, int colorBottomLeft)260 public void setQuadrantBuffer(long surfaceControl, int width, int height, int colorTopLeft, 261 int colorTopRight, int colorBottomRight, int colorBottomLeft) { 262 long surfaceTransaction = createSurfaceTransaction(); 263 setQuadrantBuffer(surfaceControl, surfaceTransaction, width, height, colorTopLeft, 264 colorTopRight, colorBottomRight, colorBottomLeft); 265 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 266 nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback); 267 applyAndDeleteSurfaceTransaction(surfaceTransaction); 268 try { 269 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 270 } catch (InterruptedException e) { 271 } 272 if (onCommitCallback.mLatch.getCount() > 0) { 273 Log.e(TAG, "Failed to wait for commit callback"); 274 } 275 } 276 } 277 278 /////////////////////////////////////////////////////////////////////////// 279 // Tests 280 /////////////////////////////////////////////////////////////////////////// 281 verifyTest(BasicSurfaceHolderCallback callback, PixelChecker pixelChecker)282 private void verifyTest(BasicSurfaceHolderCallback callback, PixelChecker pixelChecker) { 283 SurfaceHolderCallback surfaceHolderCallback = new SurfaceHolderCallback(callback); 284 mActivity.verifyTest(surfaceHolderCallback, pixelChecker, mName); 285 } 286 287 @Test testSurfaceTransaction_create()288 public void testSurfaceTransaction_create() { 289 long surfaceTransaction = nSurfaceTransaction_create(); 290 assertTrue("failed to create surface transaction", surfaceTransaction != 0); 291 292 nSurfaceTransaction_delete(surfaceTransaction); 293 } 294 295 @Test testSurfaceTransaction_apply()296 public void testSurfaceTransaction_apply() { 297 long surfaceTransaction = nSurfaceTransaction_create(); 298 assertTrue("failed to create surface transaction", surfaceTransaction != 0); 299 300 Log.e("Transaction", "created: " + surfaceTransaction); 301 302 nSurfaceTransaction_apply(surfaceTransaction); 303 nSurfaceTransaction_delete(surfaceTransaction); 304 } 305 306 // INTRO: The following tests run a series of commands and verify the 307 // output based on the number of pixels with a certain color on the display. 308 // 309 // The interface being tested is a NDK api but the only way to record the display 310 // through public apis is in through the SDK. So the test logic and test verification 311 // is in Java but the hooks that call into the NDK api are jni code. 312 // 313 // The set up is done during the surfaceCreated callback. In most cases, the 314 // test uses the opportunity to create a child layer through createFromWindow and 315 // performs operations on the child layer. 316 // 317 // When there is no visible buffer for the layer(s) the color defaults to black. 318 // The test cases allow a +/- 10% error rate. This is based on the error 319 // rate allowed in the SurfaceViewSyncTests 320 321 @Test testSurfaceControl_createFromWindow()322 public void testSurfaceControl_createFromWindow() { 323 verifyTest( 324 new BasicSurfaceHolderCallback() { 325 @Override 326 public void surfaceCreated(SurfaceHolder holder) { 327 long surfaceControl = createFromWindow(holder.getSurface()); 328 } 329 }, 330 new PixelChecker(Color.YELLOW) { //10000 331 @Override 332 public boolean checkPixels(int pixelCount, int width, int height) { 333 return pixelCount > 9000 && pixelCount < 11000; 334 } 335 }); 336 } 337 338 @Test testSurfaceControl_create()339 public void testSurfaceControl_create() { 340 verifyTest( 341 new BasicSurfaceHolderCallback() { 342 @Override 343 public void surfaceCreated(SurfaceHolder holder) { 344 long parentSurfaceControl = createFromWindow(holder.getSurface()); 345 long childSurfaceControl = create(parentSurfaceControl); 346 } 347 }, 348 new PixelChecker(Color.YELLOW) { //10000 349 @Override 350 public boolean checkPixels(int pixelCount, int width, int height) { 351 return pixelCount > 9000 && pixelCount < 11000; 352 } 353 }); 354 } 355 356 @Test testSurfaceControl_fromJava()357 public void testSurfaceControl_fromJava() { 358 SurfaceControl.Builder builder = new SurfaceControl.Builder(); 359 builder.setName("testSurfaceControl_fromJava"); 360 SurfaceControl control = builder.build(); 361 final long childSurfaceControl = nSurfaceControl_fromJava(control); 362 assertTrue(childSurfaceControl != 0); 363 verifyTest( 364 new BasicSurfaceHolderCallback() { 365 @Override 366 public void surfaceCreated(SurfaceHolder holder) { 367 long parentSurfaceControl = createFromWindow(holder.getSurface()); 368 setVisibility(childSurfaceControl, true); 369 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 370 DEFAULT_LAYOUT_HEIGHT, Color.RED); 371 reparent(childSurfaceControl, parentSurfaceControl); 372 } 373 }, 374 new PixelChecker(Color.RED) { //10000 375 @Override 376 public boolean checkPixels(int pixelCount, int width, int height) { 377 return pixelCount > 9000 && pixelCount < 11000; 378 } 379 }); 380 nSurfaceControl_release(childSurfaceControl); 381 } 382 383 @Test testSurfaceTransaction_fromJava()384 public void testSurfaceTransaction_fromJava() { 385 SurfaceControl.Transaction jTransaction = new SurfaceControl.Transaction(); 386 final long transaction = nSurfaceTransaction_fromJava(jTransaction); 387 verifyTest( 388 new BasicSurfaceHolderCallback() { 389 @Override 390 public void surfaceCreated(SurfaceHolder holder) { 391 long surfaceControl = createFromWindow(holder.getSurface()); 392 setSolidBuffer(surfaceControl, transaction, DEFAULT_LAYOUT_WIDTH, 393 DEFAULT_LAYOUT_HEIGHT, Color.RED); 394 nSurfaceTransaction_apply(transaction); 395 } 396 }, 397 new PixelChecker(Color.RED) { //10000 398 @Override 399 public boolean checkPixels(int pixelCount, int width, int height) { 400 return pixelCount > 9000 && pixelCount < 11000; 401 } 402 }); 403 Reference.reachabilityFence(jTransaction); 404 } 405 406 @Test testSurfaceControl_acquire()407 public void testSurfaceControl_acquire() { 408 verifyTest( 409 new BasicSurfaceHolderCallback() { 410 @Override 411 public void surfaceCreated(SurfaceHolder holder) { 412 long surfaceControl = createFromWindow(holder.getSurface()); 413 // increment one refcount 414 nSurfaceControl_acquire(surfaceControl); 415 // decrement one refcount incremented from create call 416 nSurfaceControl_release(surfaceControl); 417 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 418 Color.RED); 419 } 420 }, 421 new PixelChecker(Color.RED) { //10000 422 @Override 423 public boolean checkPixels(int pixelCount, int width, int height) { 424 return pixelCount > 9000 && pixelCount < 11000; 425 } 426 }); 427 } 428 429 @Test testSurfaceTransaction_setBuffer()430 public void testSurfaceTransaction_setBuffer() { 431 verifyTest( 432 new BasicSurfaceHolderCallback() { 433 @Override 434 public void surfaceCreated(SurfaceHolder holder) { 435 long surfaceControl = createFromWindow(holder.getSurface()); 436 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 437 Color.RED); 438 } 439 }, 440 new PixelChecker(Color.RED) { //10000 441 @Override 442 public boolean checkPixels(int pixelCount, int width, int height) { 443 return pixelCount > 9000 && pixelCount < 11000; 444 } 445 }); 446 } 447 448 @Test testSurfaceTransaction_setNullBuffer()449 public void testSurfaceTransaction_setNullBuffer() { 450 verifyTest( 451 new BasicSurfaceHolderCallback() { 452 @Override 453 public void surfaceCreated(SurfaceHolder holder) { 454 long surfaceControl = createFromWindow(holder.getSurface()); 455 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 456 Color.RED); 457 setNullBuffer(surfaceControl); 458 } 459 }, 460 new PixelChecker(Color.YELLOW) { //10000 461 @Override 462 public boolean checkPixels(int pixelCount, int width, int height) { 463 return pixelCount > 9000 && pixelCount < 11000; 464 } 465 }); 466 } 467 468 @Test testSurfaceTransaction_setBuffer_parentAndChild()469 public void testSurfaceTransaction_setBuffer_parentAndChild() { 470 verifyTest( 471 new BasicSurfaceHolderCallback() { 472 @Override 473 public void surfaceCreated(SurfaceHolder holder) { 474 long parentSurfaceControl = createFromWindow(holder.getSurface()); 475 long childSurfaceControl = create(parentSurfaceControl); 476 477 setSolidBuffer(parentSurfaceControl, DEFAULT_LAYOUT_WIDTH, 478 DEFAULT_LAYOUT_HEIGHT, Color.BLUE); 479 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 480 DEFAULT_LAYOUT_HEIGHT, Color.RED); 481 } 482 }, 483 new PixelChecker(Color.RED) { //10000 484 @Override 485 public boolean checkPixels(int pixelCount, int width, int height) { 486 return pixelCount > 9000 && pixelCount < 11000; 487 } 488 }); 489 } 490 491 @Test testSurfaceTransaction_setBuffer_childOnly()492 public void testSurfaceTransaction_setBuffer_childOnly() { 493 verifyTest( 494 new BasicSurfaceHolderCallback() { 495 @Override 496 public void surfaceCreated(SurfaceHolder holder) { 497 long parentSurfaceControl = createFromWindow(holder.getSurface()); 498 long childSurfaceControl = create(parentSurfaceControl); 499 500 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 501 DEFAULT_LAYOUT_HEIGHT, Color.RED); 502 } 503 }, 504 new PixelChecker(Color.RED) { //10000 505 @Override 506 public boolean checkPixels(int pixelCount, int width, int height) { 507 return pixelCount > 9000 && pixelCount < 11000; 508 } 509 }); 510 } 511 512 @Test testSurfaceTransaction_setVisibility_show()513 public void testSurfaceTransaction_setVisibility_show() { 514 verifyTest( 515 new BasicSurfaceHolderCallback() { 516 @Override 517 public void surfaceCreated(SurfaceHolder holder) { 518 long surfaceControl = createFromWindow(holder.getSurface()); 519 520 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 521 Color.RED); 522 setVisibility(surfaceControl, true); 523 } 524 }, 525 new PixelChecker(Color.RED) { //10000 526 @Override 527 public boolean checkPixels(int pixelCount, int width, int height) { 528 return pixelCount > 9000 && pixelCount < 11000; 529 } 530 }); 531 } 532 533 @Test testSurfaceTransaction_setVisibility_hide()534 public void testSurfaceTransaction_setVisibility_hide() { 535 verifyTest( 536 new BasicSurfaceHolderCallback() { 537 @Override 538 public void surfaceCreated(SurfaceHolder holder) { 539 long surfaceControl = createFromWindow(holder.getSurface()); 540 541 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 542 Color.RED); 543 setVisibility(surfaceControl, false); 544 } 545 }, 546 new PixelChecker(Color.YELLOW) { //10000 547 @Override 548 public boolean checkPixels(int pixelCount, int width, int height) { 549 return pixelCount > 9000 && pixelCount < 11000; 550 } 551 }); 552 } 553 554 @Test testSurfaceTransaction_setBufferOpaque_opaque()555 public void testSurfaceTransaction_setBufferOpaque_opaque() { 556 verifyTest( 557 new BasicSurfaceHolderCallback() { 558 @Override 559 public void surfaceCreated(SurfaceHolder holder) { 560 long surfaceControl = createFromWindow(holder.getSurface()); 561 562 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 563 PixelColor.TRANSLUCENT_RED); 564 setBufferOpaque(surfaceControl, true); 565 } 566 }, 567 new PixelChecker(Color.RED) { //10000 568 @Override 569 public boolean checkPixels(int pixelCount, int width, int height) { 570 return pixelCount > 9000 && pixelCount < 11000; 571 } 572 }); 573 } 574 575 @Test testSurfaceTransaction_setBufferOpaque_translucent()576 public void testSurfaceTransaction_setBufferOpaque_translucent() { 577 verifyTest( 578 new BasicSurfaceHolderCallback() { 579 @Override 580 public void surfaceCreated(SurfaceHolder holder) { 581 long surfaceControl = createFromWindow(holder.getSurface()); 582 583 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 584 PixelColor.TRANSLUCENT_RED); 585 setBufferOpaque(surfaceControl, false); 586 } 587 }, 588 // setBufferOpaque is an optimization that can be used by SurfaceFlinger. 589 // It isn't required to affect SurfaceFlinger's behavior. 590 // 591 // Ideally we would check for a specific blending of red with a layer below 592 // it. Unfortunately we don't know what blending the layer will use and 593 // we don't know what variation the GPU/DPU/blitter might have. Although 594 // we don't know what shade of red might be present, we can at least check 595 // that the optimization doesn't cause the framework to drop the buffer entirely. 596 new PixelChecker(Color.YELLOW, false /* logWhenNoMatch */) { 597 @Override 598 public boolean checkPixels(int pixelCount, int width, int height) { 599 return pixelCount == 0; 600 } 601 }); 602 } 603 604 @Test testSurfaceTransaction_setDestinationRect()605 public void testSurfaceTransaction_setDestinationRect() { 606 verifyTest( 607 new BasicSurfaceHolderCallback() { 608 @Override 609 public void surfaceCreated(SurfaceHolder holder) { 610 long surfaceControl = createFromWindow(holder.getSurface()); 611 612 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 613 Color.RED); 614 } 615 }, 616 new PixelChecker(Color.RED) { //10000 617 @Override 618 public boolean checkPixels(int pixelCount, int width, int height) { 619 return pixelCount > 9000 && pixelCount < 11000; 620 } 621 }); 622 } 623 624 @Test testSurfaceTransaction_setDestinationRect_small()625 public void testSurfaceTransaction_setDestinationRect_small() { 626 verifyTest( 627 new BasicSurfaceHolderCallback() { 628 @Override 629 public void surfaceCreated(SurfaceHolder holder) { 630 long surfaceControl = createFromWindow(holder.getSurface()); 631 632 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 633 Color.RED); 634 setGeometry(surfaceControl, 0, 0, 100, 100, 10, 10, 50, 50, 0); 635 } 636 }, 637 new RectChecker(DEFAULT_RECT) { 638 @Override 639 public PixelColor getExpectedColor(int x, int y) { 640 if (x >= 10 && x < 50 && y >= 10 && y < 50) { 641 return RED; 642 } else { 643 return YELLOW; 644 } 645 } 646 }); 647 } 648 649 @Test testSurfaceTransaction_setDestinationRect_childSmall()650 public void testSurfaceTransaction_setDestinationRect_childSmall() { 651 verifyTest( 652 new BasicSurfaceHolderCallback() { 653 @Override 654 public void surfaceCreated(SurfaceHolder holder) { 655 long parentSurfaceControl = createFromWindow(holder.getSurface()); 656 long childSurfaceControl = create(parentSurfaceControl); 657 658 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 659 DEFAULT_LAYOUT_HEIGHT, Color.RED); 660 setGeometry(childSurfaceControl, 0, 0, 100, 100, 10, 10, 50, 50, 0); 661 } 662 }, 663 new RectChecker(DEFAULT_RECT) { 664 @Override 665 public PixelColor getExpectedColor(int x, int y) { 666 if (x >= 10 && x < 50 && y >= 10 && y < 50) { 667 return RED; 668 } else { 669 return YELLOW; 670 } 671 } 672 }); 673 } 674 675 @Test testSurfaceTransaction_setDestinationRect_extraLarge()676 public void testSurfaceTransaction_setDestinationRect_extraLarge() { 677 verifyTest( 678 new BasicSurfaceHolderCallback() { 679 @Override 680 public void surfaceCreated(SurfaceHolder holder) { 681 long surfaceControl = createFromWindow(holder.getSurface()); 682 683 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 684 Color.RED); 685 setGeometry(surfaceControl, 0, 0, 100, 100, -100, -100, 200, 200, 0); 686 } 687 }, 688 new PixelChecker(Color.RED) { //10000 689 @Override 690 public boolean checkPixels(int pixelCount, int width, int height) { 691 return pixelCount > 9000 && pixelCount < 11000; 692 } 693 }); 694 } 695 696 @Test testSurfaceTransaction_setDestinationRect_childExtraLarge()697 public void testSurfaceTransaction_setDestinationRect_childExtraLarge() { 698 verifyTest( 699 new BasicSurfaceHolderCallback() { 700 @Override 701 public void surfaceCreated(SurfaceHolder holder) { 702 long parentSurfaceControl = createFromWindow(holder.getSurface()); 703 long childSurfaceControl = create(parentSurfaceControl); 704 705 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 706 DEFAULT_LAYOUT_HEIGHT, Color.RED); 707 setGeometry(childSurfaceControl, 0, 0, 100, 100, -100, -100, 200, 200, 0); 708 } 709 }, 710 new PixelChecker(Color.RED) { //10000 711 @Override 712 public boolean checkPixels(int pixelCount, int width, int height) { 713 return pixelCount > 9000 && pixelCount < 11000; 714 } 715 }); 716 } 717 718 @Test testSurfaceTransaction_setDestinationRect_negativeOffset()719 public void testSurfaceTransaction_setDestinationRect_negativeOffset() { 720 verifyTest( 721 new BasicSurfaceHolderCallback() { 722 @Override 723 public void surfaceCreated(SurfaceHolder holder) { 724 long surfaceControl = createFromWindow(holder.getSurface()); 725 726 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 727 Color.RED); 728 setGeometry(surfaceControl, 0, 0, 100, 100, -30, -20, 50, 50, 0); 729 } 730 }, 731 new RectChecker(DEFAULT_RECT) { 732 @Override 733 public PixelColor getExpectedColor(int x, int y) { 734 if (x < 80 && y < 70) { 735 return RED; 736 } else { 737 return YELLOW; 738 } 739 } 740 }); 741 } 742 743 @Test testSurfaceTransaction_setDestinationRect_outOfParentBounds()744 public void testSurfaceTransaction_setDestinationRect_outOfParentBounds() { 745 verifyTest( 746 new BasicSurfaceHolderCallback() { 747 @Override 748 public void surfaceCreated(SurfaceHolder holder) { 749 long surfaceControl = createFromWindow(holder.getSurface()); 750 751 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 752 Color.RED); 753 setGeometry(surfaceControl, 0, 0, 100, 100, 50, 50, 110, 105, 0); 754 } 755 }, 756 new RectChecker(DEFAULT_RECT) { 757 @Override 758 public PixelColor getExpectedColor(int x, int y) { 759 if (x >= 50 && y >= 50) { 760 return RED; 761 } else { 762 return YELLOW; 763 } 764 } 765 }); 766 } 767 768 @Test testSurfaceTransaction_setDestinationRect_twoLayers()769 public void testSurfaceTransaction_setDestinationRect_twoLayers() { 770 verifyTest( 771 new BasicSurfaceHolderCallback() { 772 @Override 773 public void surfaceCreated(SurfaceHolder holder) { 774 long surfaceControl1 = createFromWindow(holder.getSurface()); 775 long surfaceControl2 = createFromWindow(holder.getSurface()); 776 777 setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 778 Color.RED); 779 setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 780 Color.BLUE); 781 setGeometry(surfaceControl1, 0, 0, 100, 100, 10, 10, 30, 40, 0); 782 setGeometry(surfaceControl2, 0, 0, 100, 100, 70, 20, 90, 50, 0); 783 } 784 }, 785 new RectChecker(DEFAULT_RECT) { 786 @Override 787 public PixelColor getExpectedColor(int x, int y) { 788 if (x >= 10 && x < 30 && y >= 10 && y < 40) { 789 return RED; 790 } else if (x >= 70 && x < 90 && y >= 20 && y < 50) { 791 return BLUE; 792 } else { 793 return YELLOW; 794 } 795 } 796 }); 797 } 798 799 @Test testSurfaceTransaction_setSourceRect()800 public void testSurfaceTransaction_setSourceRect() { 801 verifyTest( 802 new BasicSurfaceHolderCallback() { 803 @Override 804 public void surfaceCreated(SurfaceHolder holder) { 805 long surfaceControl = createFromWindow(holder.getSurface()); 806 807 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 808 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 809 Color.MAGENTA, Color.GREEN); 810 } 811 }, 812 new RectChecker(DEFAULT_RECT) { 813 @Override 814 public PixelColor getExpectedColor(int x, int y) { 815 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 816 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 817 if (x < halfWidth && y < halfHeight) { 818 return RED; 819 } else if (x >= halfWidth && y < halfHeight) { 820 return BLUE; 821 } else if (x < halfWidth && y >= halfHeight) { 822 return GREEN; 823 } else { 824 return MAGENTA; 825 } 826 } 827 }); 828 } 829 830 @Test testSurfaceTransaction_setSourceRect_smallCentered()831 public void testSurfaceTransaction_setSourceRect_smallCentered() { 832 // These rectangles leave two 10px strips unchecked to allow blended pixels due to GL 833 // texture filtering. 834 Rect topLeft = new Rect(0, 0, 45, 45); 835 Rect topRight = new Rect(55, 0, 100, 45); 836 Rect bottomLeft = new Rect(0, 55, 45, 100); 837 Rect bottomRight = new Rect(55, 55, 100, 100); 838 verifyTest( 839 new BasicSurfaceHolderCallback() { 840 @Override 841 public void surfaceCreated(SurfaceHolder holder) { 842 long surfaceControl = createFromWindow(holder.getSurface()); 843 844 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 845 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 846 Color.MAGENTA, Color.GREEN); 847 setGeometry(surfaceControl, 10, 10, 90, 90, 0, 0, 100, 100, 0); 848 } 849 }, 850 851 new RectChecker(List.of(topLeft, topRight, bottomLeft, bottomRight)) { 852 @Override 853 public PixelColor getExpectedColor(int x, int y) { 854 if (topLeft.contains(x, y)) { 855 return RED; 856 } else if (topRight.contains(x, y)) { 857 return BLUE; 858 } else if (bottomLeft.contains(x, y)) { 859 return GREEN; 860 } else if (bottomRight.contains(x, y)) { 861 return MAGENTA; 862 } 863 throw new AssertionError(String.format("Unexpected pixel (%d, %d)", x, y)); 864 } 865 }); 866 } 867 868 @Test testSurfaceTransaction_setSourceRect_small()869 public void testSurfaceTransaction_setSourceRect_small() { 870 // These rectangles leave a 10px strip unchecked to allow blended pixels due to GL 871 // texture filtering. 872 Rect topHalf = new Rect(0, 0, 100, 45); 873 Rect bottomHalf = new Rect(0, 55, 100, 100); 874 verifyTest( 875 new BasicSurfaceHolderCallback() { 876 @Override 877 public void surfaceCreated(SurfaceHolder holder) { 878 long surfaceControl = createFromWindow(holder.getSurface()); 879 880 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 881 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 882 Color.MAGENTA, Color.GREEN); 883 setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 100, 100, 0); 884 } 885 }, 886 new RectChecker(List.of(topHalf, bottomHalf)) { 887 @Override 888 public PixelColor getExpectedColor(int x, int y) { 889 if (topHalf.contains(x, y)) { 890 return BLUE; 891 } else if (bottomHalf.contains(x, y)) { 892 return MAGENTA; 893 } 894 throw new AssertionError(String.format("Unexpected pixel (%d, %d)", x, y)); 895 } 896 }); 897 } 898 899 @Test testSurfaceTransaction_setSourceRect_extraLarge()900 public void testSurfaceTransaction_setSourceRect_extraLarge() { 901 verifyTest( 902 new BasicSurfaceHolderCallback() { 903 @Override 904 public void surfaceCreated(SurfaceHolder holder) { 905 long surfaceControl = createFromWindow(holder.getSurface()); 906 907 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 908 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 909 Color.MAGENTA, Color.GREEN); 910 setGeometry(surfaceControl, -50, -50, 150, 150, 0, 0, 100, 100, 0); 911 } 912 }, 913 914 new RectChecker(DEFAULT_RECT) { 915 @Override 916 public PixelColor getExpectedColor(int x, int y) { 917 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 918 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 919 if (x < halfWidth && y < halfHeight) { 920 return RED; 921 } else if (x >= halfWidth && y < halfHeight) { 922 return BLUE; 923 } else if (x < halfWidth && y >= halfHeight) { 924 return GREEN; 925 } else { 926 return MAGENTA; 927 } 928 } 929 }); 930 } 931 932 @Test testSurfaceTransaction_setSourceRect_badOffset()933 public void testSurfaceTransaction_setSourceRect_badOffset() { 934 verifyTest( 935 new BasicSurfaceHolderCallback() { 936 @Override 937 public void surfaceCreated(SurfaceHolder holder) { 938 long surfaceControl = createFromWindow(holder.getSurface()); 939 940 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 941 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 942 Color.MAGENTA, Color.GREEN); 943 setGeometry(surfaceControl, -50, -50, 50, 50, 0, 0, 100, 100, 0); 944 } 945 }, 946 new PixelChecker(Color.RED) { //10000 947 @Override 948 public boolean checkPixels(int pixelCount, int width, int height) { 949 return pixelCount > 9000 && pixelCount < 11000; 950 } 951 }); 952 } 953 954 @Test testSurfaceTransaction_setTransform_flipH()955 public void testSurfaceTransaction_setTransform_flipH() { 956 verifyTest( 957 new BasicSurfaceHolderCallback() { 958 @Override 959 public void surfaceCreated(SurfaceHolder holder) { 960 long surfaceControl = createFromWindow(holder.getSurface()); 961 962 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 963 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 964 Color.MAGENTA, Color.GREEN); 965 setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 100, 100, 966 /*NATIVE_WINDOW_TRANSFORM_FLIP_H*/ 1); 967 } 968 }, 969 new RectChecker(DEFAULT_RECT) { 970 @Override 971 public PixelColor getExpectedColor(int x, int y) { 972 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 973 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 974 if (x < halfWidth && y < halfHeight) { 975 return BLUE; 976 } else if (x >= halfWidth && y < halfHeight) { 977 return RED; 978 } else if (x < halfWidth && y >= halfHeight) { 979 return MAGENTA; 980 } else { 981 return GREEN; 982 } 983 } 984 }); 985 } 986 987 @Test testSurfaceTransaction_setTransform_rotate180()988 public void testSurfaceTransaction_setTransform_rotate180() { 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, 0, 0, 100, 100, 0, 0, 100, 100, 999 /*NATIVE_WINDOW_TRANSFORM_ROT_180*/ 3); 1000 } 1001 }, 1002 new RectChecker(DEFAULT_RECT) { 1003 @Override 1004 public PixelColor getExpectedColor(int x, int y) { 1005 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1006 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1007 if (x < halfWidth && y < halfHeight) { 1008 return MAGENTA; 1009 } else if (x >= halfWidth && y < halfHeight) { 1010 return GREEN; 1011 } else if (x < halfWidth && y >= halfHeight) { 1012 return BLUE; 1013 } else { 1014 return RED; 1015 } 1016 } 1017 }); 1018 } 1019 1020 @Test testSurfaceTransaction_setDamageRegion_all()1021 public void testSurfaceTransaction_setDamageRegion_all() { 1022 verifyTest( 1023 new BasicSurfaceHolderCallback() { 1024 @Override 1025 public void surfaceCreated(SurfaceHolder holder) { 1026 long surfaceControl = createFromWindow(holder.getSurface()); 1027 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1028 Color.RED); 1029 1030 long surfaceTransaction = createSurfaceTransaction(); 1031 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 1032 DEFAULT_LAYOUT_HEIGHT, Color.BLUE); 1033 nSurfaceTransaction_setDamageRegion(surfaceControl, surfaceTransaction, 0, 1034 0, 100, 100); 1035 applyAndDeleteSurfaceTransaction(surfaceTransaction); 1036 } 1037 }, 1038 new PixelChecker(Color.BLUE) { //10000 1039 @Override 1040 public boolean checkPixels(int pixelCount, int width, int height) { 1041 return pixelCount > 9000 && pixelCount < 11000; 1042 } 1043 }); 1044 } 1045 1046 @Test testSurfaceTransaction_setZOrder_zero()1047 public void testSurfaceTransaction_setZOrder_zero() { 1048 verifyTest( 1049 new BasicSurfaceHolderCallback() { 1050 @Override 1051 public void surfaceCreated(SurfaceHolder holder) { 1052 long surfaceControl1 = createFromWindow(holder.getSurface()); 1053 long surfaceControl2 = createFromWindow(holder.getSurface()); 1054 setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1055 Color.RED); 1056 setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1057 Color.MAGENTA); 1058 1059 setZOrder(surfaceControl1, 1); 1060 setZOrder(surfaceControl2, 0); 1061 } 1062 }, 1063 new RectChecker(DEFAULT_RECT) { 1064 @Override 1065 public PixelColor getExpectedColor(int x, int y) { 1066 return RED; 1067 } 1068 }); 1069 } 1070 1071 @Test testSurfaceTransaction_setZOrder_positive()1072 public void testSurfaceTransaction_setZOrder_positive() { 1073 verifyTest( 1074 new BasicSurfaceHolderCallback() { 1075 @Override 1076 public void surfaceCreated(SurfaceHolder holder) { 1077 long surfaceControl1 = createFromWindow(holder.getSurface()); 1078 long surfaceControl2 = createFromWindow(holder.getSurface()); 1079 setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1080 Color.RED); 1081 setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1082 Color.MAGENTA); 1083 1084 setZOrder(surfaceControl1, 1); 1085 setZOrder(surfaceControl2, 5); 1086 } 1087 }, 1088 new RectChecker(DEFAULT_RECT) { 1089 @Override 1090 public PixelColor getExpectedColor(int x, int y) { 1091 return MAGENTA; 1092 } 1093 }); 1094 } 1095 1096 @Test testSurfaceTransaction_setZOrder_negative()1097 public void testSurfaceTransaction_setZOrder_negative() { 1098 verifyTest( 1099 new BasicSurfaceHolderCallback() { 1100 @Override 1101 public void surfaceCreated(SurfaceHolder holder) { 1102 long surfaceControl1 = createFromWindow(holder.getSurface()); 1103 long surfaceControl2 = createFromWindow(holder.getSurface()); 1104 setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1105 Color.RED); 1106 setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1107 Color.MAGENTA); 1108 1109 setZOrder(surfaceControl1, 1); 1110 setZOrder(surfaceControl2, -15); 1111 } 1112 }, 1113 new RectChecker(DEFAULT_RECT) { 1114 @Override 1115 public PixelColor getExpectedColor(int x, int y) { 1116 return RED; 1117 } 1118 }); 1119 } 1120 1121 @Test testSurfaceTransaction_setZOrder_max()1122 public void testSurfaceTransaction_setZOrder_max() { 1123 verifyTest( 1124 new BasicSurfaceHolderCallback() { 1125 @Override 1126 public void surfaceCreated(SurfaceHolder holder) { 1127 long surfaceControl1 = createFromWindow(holder.getSurface()); 1128 long surfaceControl2 = createFromWindow(holder.getSurface()); 1129 setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1130 Color.RED); 1131 setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1132 Color.MAGENTA); 1133 1134 setZOrder(surfaceControl1, 1); 1135 setZOrder(surfaceControl2, Integer.MAX_VALUE); 1136 } 1137 }, 1138 new RectChecker(DEFAULT_RECT) { 1139 @Override 1140 public PixelColor getExpectedColor(int x, int y) { 1141 return MAGENTA; 1142 } 1143 }); 1144 } 1145 1146 @Test testSurfaceTransaction_setZOrder_min()1147 public void testSurfaceTransaction_setZOrder_min() { 1148 verifyTest( 1149 new BasicSurfaceHolderCallback() { 1150 @Override 1151 public void surfaceCreated(SurfaceHolder holder) { 1152 long surfaceControl1 = createFromWindow(holder.getSurface()); 1153 long surfaceControl2 = createFromWindow(holder.getSurface()); 1154 setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1155 Color.RED); 1156 setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1157 Color.MAGENTA); 1158 1159 setZOrder(surfaceControl1, 1); 1160 setZOrder(surfaceControl2, Integer.MIN_VALUE); 1161 } 1162 }, 1163 new RectChecker(DEFAULT_RECT) { 1164 @Override 1165 public PixelColor getExpectedColor(int x, int y) { 1166 return RED; 1167 } 1168 }); 1169 } 1170 1171 @Test testSurfaceTransaction_setOnComplete()1172 public void testSurfaceTransaction_setOnComplete() { 1173 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 1174 verifyTest( 1175 new BasicSurfaceHolderCallback() { 1176 @Override 1177 public void surfaceCreated(SurfaceHolder holder) { 1178 long surfaceControl = createFromWindow(holder.getSurface()); 1179 1180 long surfaceTransaction = createSurfaceTransaction(); 1181 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 1182 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1183 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, 1184 false /* waitForFence */, onCompleteCallback); 1185 applyAndDeleteSurfaceTransaction(surfaceTransaction); 1186 1187 // Wait for callbacks to fire. 1188 try { 1189 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 1190 } catch (InterruptedException e) { 1191 } 1192 if (onCompleteCallback.mLatch.getCount() > 0) { 1193 Log.e(TAG, "Failed to wait for callback"); 1194 } 1195 } 1196 }, 1197 new PixelChecker(Color.RED) { //10000 1198 @Override 1199 public boolean checkPixels(int pixelCount, int width, int height) { 1200 return pixelCount > 9000 && pixelCount < 11000; 1201 } 1202 }); 1203 1204 // Validate we got callbacks. 1205 assertEquals(0, onCompleteCallback.mLatch.getCount()); 1206 assertTrue(onCompleteCallback.mCallbackTime > 0); 1207 } 1208 1209 @Test 1210 @RequiresDevice // emulators can't support sync fences testSurfaceTransaction_setDesiredPresentTime_now()1211 public void testSurfaceTransaction_setDesiredPresentTime_now() { 1212 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 1213 verifyTest( 1214 new BasicSurfaceHolderCallback() { 1215 @Override 1216 public void surfaceCreated(SurfaceHolder holder) { 1217 long surfaceControl = createFromWindow(holder.getSurface()); 1218 1219 long surfaceTransaction = createSurfaceTransaction(); 1220 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 1221 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1222 mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime( 1223 surfaceTransaction, 0); 1224 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, 1225 true /* waitForFence */, onCompleteCallback); 1226 applyAndDeleteSurfaceTransaction(surfaceTransaction); 1227 // Wait for callbacks to fire. 1228 try { 1229 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 1230 } catch (InterruptedException e) { 1231 } 1232 if (onCompleteCallback.mLatch.getCount() > 0) { 1233 Log.e(TAG, "Failed to wait for callback"); 1234 } 1235 } 1236 }, 1237 new PixelChecker(Color.RED) { //10000 1238 @Override 1239 public boolean checkPixels(int pixelCount, int width, int height) { 1240 return pixelCount > 9000 && pixelCount < 11000; 1241 } 1242 }); 1243 1244 assertEquals(0, onCompleteCallback.mLatch.getCount()); 1245 assertTrue(onCompleteCallback.mCallbackTime > 0); 1246 assertTrue(onCompleteCallback.mLatchTime > 0); 1247 1248 assertTrue("transaction was presented too early. presentTime=" 1249 + onCompleteCallback.mPresentTime, 1250 onCompleteCallback.mPresentTime >= mDesiredPresentTime); 1251 } 1252 1253 @Test 1254 @RequiresDevice // emulators can't support sync fences testSurfaceTransaction_setDesiredPresentTime_30ms()1255 public void testSurfaceTransaction_setDesiredPresentTime_30ms() { 1256 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 1257 verifyTest( 1258 new BasicSurfaceHolderCallback() { 1259 @Override 1260 public void surfaceCreated(SurfaceHolder holder) { 1261 long surfaceControl = createFromWindow(holder.getSurface()); 1262 1263 long surfaceTransaction = createSurfaceTransaction(); 1264 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 1265 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1266 mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime( 1267 surfaceTransaction, 30000000); 1268 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, 1269 true /* waitForFence */, onCompleteCallback); 1270 applyAndDeleteSurfaceTransaction(surfaceTransaction); 1271 // Wait for callbacks to fire. 1272 try { 1273 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 1274 } catch (InterruptedException e) { 1275 } 1276 if (onCompleteCallback.mLatch.getCount() > 0) { 1277 Log.e(TAG, "Failed to wait for callback"); 1278 } 1279 } 1280 }, 1281 new PixelChecker(Color.RED) { //10000 1282 @Override 1283 public boolean checkPixels(int pixelCount, int width, int height) { 1284 return pixelCount > 9000 && pixelCount < 11000; 1285 } 1286 }); 1287 1288 assertEquals(0, onCompleteCallback.mLatch.getCount()); 1289 assertTrue(onCompleteCallback.mCallbackTime > 0); 1290 assertTrue(onCompleteCallback.mLatchTime > 0); 1291 1292 assertTrue("transaction was presented too early. presentTime=" 1293 + onCompleteCallback.mPresentTime, 1294 onCompleteCallback.mPresentTime >= mDesiredPresentTime); 1295 } 1296 1297 @Test 1298 @RequiresDevice // emulators can't support sync fences testSurfaceTransaction_setDesiredPresentTime_100ms()1299 public void testSurfaceTransaction_setDesiredPresentTime_100ms() { 1300 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 1301 verifyTest( 1302 new BasicSurfaceHolderCallback() { 1303 @Override 1304 public void surfaceCreated(SurfaceHolder holder) { 1305 long surfaceControl = createFromWindow(holder.getSurface()); 1306 1307 long surfaceTransaction = createSurfaceTransaction(); 1308 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 1309 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1310 mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime( 1311 surfaceTransaction, 100000000); 1312 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, 1313 true /* waitForFence */, onCompleteCallback); 1314 applyAndDeleteSurfaceTransaction(surfaceTransaction); 1315 // Wait for callbacks to fire. 1316 try { 1317 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 1318 } catch (InterruptedException e) { 1319 } 1320 if (onCompleteCallback.mLatch.getCount() > 0) { 1321 Log.e(TAG, "Failed to wait for callback"); 1322 } 1323 } 1324 }, 1325 new PixelChecker(Color.RED) { //10000 1326 @Override 1327 public boolean checkPixels(int pixelCount, int width, int height) { 1328 return pixelCount > 9000 && pixelCount < 11000; 1329 } 1330 }); 1331 1332 assertEquals(0, onCompleteCallback.mLatch.getCount()); 1333 1334 assertTrue(onCompleteCallback.mCallbackTime > 0); 1335 assertTrue(onCompleteCallback.mLatchTime > 0); 1336 1337 assertTrue("transaction was presented too early. presentTime=" 1338 + onCompleteCallback.mPresentTime, 1339 onCompleteCallback.mPresentTime >= mDesiredPresentTime); 1340 } 1341 1342 @Test testSurfaceTransaction_setBufferAlpha_1_0()1343 public void testSurfaceTransaction_setBufferAlpha_1_0() { 1344 verifyTest( 1345 new BasicSurfaceHolderCallback() { 1346 @Override 1347 public void surfaceCreated(SurfaceHolder holder) { 1348 long surfaceControl = createFromWindow(holder.getSurface()); 1349 1350 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1351 Color.RED); 1352 setBufferAlpha(surfaceControl, 1.0); 1353 } 1354 }, 1355 new PixelChecker(Color.RED) { //10000 1356 @Override 1357 public boolean checkPixels(int pixelCount, int width, int height) { 1358 return pixelCount > 9000 && pixelCount < 11000; 1359 } 1360 }); 1361 } 1362 1363 @Test testSurfaceTransaction_setBufferAlpha_0_5()1364 public void testSurfaceTransaction_setBufferAlpha_0_5() { 1365 BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() { 1366 @Override 1367 public void surfaceCreated(SurfaceHolder holder) { 1368 long surfaceControl = createFromWindow(holder.getSurface()); 1369 1370 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1371 Color.RED); 1372 setBufferAlpha(surfaceControl, 0.5); 1373 } 1374 }; 1375 verifyTest(callback, 1376 new PixelChecker(Color.YELLOW, false /* logWhenNoMatch */) { 1377 @Override 1378 public boolean checkPixels(int pixelCount, int width, int height) { 1379 return pixelCount == 0; 1380 } 1381 }); 1382 verifyTest(callback, 1383 new PixelChecker(Color.RED, false /* logWhenNoMatch */) { 1384 @Override 1385 public boolean checkPixels(int pixelCount, int width, int height) { 1386 return pixelCount == 0; 1387 } 1388 }); 1389 } 1390 1391 @Test testSurfaceTransaction_setBufferAlpha_0_0()1392 public void testSurfaceTransaction_setBufferAlpha_0_0() { 1393 verifyTest( 1394 new BasicSurfaceHolderCallback() { 1395 @Override 1396 public void surfaceCreated(SurfaceHolder holder) { 1397 long surfaceControl = createFromWindow(holder.getSurface()); 1398 1399 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1400 Color.RED); 1401 setBufferAlpha(surfaceControl, 0.0); 1402 } 1403 }, 1404 new PixelChecker(Color.YELLOW) { //10000 1405 @Override 1406 public boolean checkPixels(int pixelCount, int width, int height) { 1407 return pixelCount > 9000 && pixelCount < 11000; 1408 } 1409 }); 1410 } 1411 1412 @Test testSurfaceTransaction_reparent()1413 public void testSurfaceTransaction_reparent() { 1414 verifyTest( 1415 new BasicSurfaceHolderCallback() { 1416 @Override 1417 public void surfaceCreated(SurfaceHolder holder) { 1418 long parentSurfaceControl1 = createFromWindow(holder.getSurface()); 1419 long parentSurfaceControl2 = createFromWindow(holder.getSurface()); 1420 long childSurfaceControl = create(parentSurfaceControl1); 1421 1422 setGeometry(parentSurfaceControl1, 0, 0, 100, 100, 0, 0, 25, 100, 0); 1423 setGeometry(parentSurfaceControl2, 0, 0, 100, 100, 25, 0, 100, 100, 0); 1424 1425 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 1426 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1427 1428 reparent(childSurfaceControl, parentSurfaceControl2); 1429 } 1430 }, 1431 new RectChecker(DEFAULT_RECT) { 1432 @Override 1433 public PixelColor getExpectedColor(int x, int y) { 1434 if (x >= 25) { 1435 return RED; 1436 } else { 1437 return YELLOW; 1438 } 1439 } 1440 }); 1441 } 1442 1443 @Test testSurfaceTransaction_reparent_null()1444 public void testSurfaceTransaction_reparent_null() { 1445 verifyTest( 1446 new BasicSurfaceHolderCallback() { 1447 @Override 1448 public void surfaceCreated(SurfaceHolder holder) { 1449 long parentSurfaceControl = createFromWindow(holder.getSurface()); 1450 long childSurfaceControl = create(parentSurfaceControl); 1451 1452 setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 1453 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1454 1455 reparent(childSurfaceControl, 0); 1456 } 1457 }, 1458 new PixelChecker(Color.YELLOW) { //10000 1459 @Override 1460 public boolean checkPixels(int pixelCount, int width, int height) { 1461 return pixelCount > 9000 && pixelCount < 11000; 1462 } 1463 }); 1464 } 1465 1466 @Test testSurfaceTransaction_setColor()1467 public void testSurfaceTransaction_setColor() { 1468 verifyTest( 1469 new BasicSurfaceHolderCallback() { 1470 @Override 1471 public void surfaceCreated(SurfaceHolder holder) { 1472 long surfaceControl = createFromWindow(holder.getSurface()); 1473 1474 setColor(surfaceControl, 0, 1.0f, 0, 1.0f); 1475 } 1476 }, 1477 new PixelChecker(Color.GREEN) { // 10000 1478 @Override 1479 public boolean checkPixels(int pixelCount, int width, int height) { 1480 return pixelCount > 9000 && pixelCount < 11000; 1481 } 1482 }); 1483 } 1484 1485 @Test testSurfaceTransaction_noColorNoBuffer()1486 public void testSurfaceTransaction_noColorNoBuffer() { 1487 verifyTest( 1488 new BasicSurfaceHolderCallback() { 1489 @Override 1490 public void surfaceCreated(SurfaceHolder holder) { 1491 long parentSurfaceControl = createFromWindow(holder.getSurface()); 1492 long childSurfaceControl = create(parentSurfaceControl); 1493 1494 setColor(parentSurfaceControl, 0, 1.0f, 0, 1.0f); 1495 } 1496 }, 1497 new PixelChecker(Color.GREEN) { // 10000 1498 @Override 1499 public boolean checkPixels(int pixelCount, int width, int height) { 1500 return pixelCount > 9000 && pixelCount < 11000; 1501 } 1502 }); 1503 } 1504 1505 @Test testSurfaceTransaction_setColorAlpha()1506 public void testSurfaceTransaction_setColorAlpha() { 1507 verifyTest( 1508 new BasicSurfaceHolderCallback() { 1509 @Override 1510 public void surfaceCreated(SurfaceHolder holder) { 1511 long parentSurfaceControl = createFromWindow(holder.getSurface()); 1512 setColor(parentSurfaceControl, 0, 0, 1.0f, 0); 1513 } 1514 }, 1515 new PixelChecker(Color.YELLOW) { // 10000 1516 @Override 1517 public boolean checkPixels(int pixelCount, int width, int height) { 1518 return pixelCount > 9000 && pixelCount < 11000; 1519 } 1520 }); 1521 } 1522 1523 @Test testSurfaceTransaction_setColorAndBuffer()1524 public void testSurfaceTransaction_setColorAndBuffer() { 1525 verifyTest( 1526 new BasicSurfaceHolderCallback() { 1527 @Override 1528 public void surfaceCreated(SurfaceHolder holder) { 1529 long surfaceControl = createFromWindow(holder.getSurface()); 1530 1531 setSolidBuffer( 1532 surfaceControl, DEFAULT_LAYOUT_WIDTH, 1533 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1534 setColor(surfaceControl, 0, 1.0f, 0, 1.0f); 1535 } 1536 }, 1537 new PixelChecker(Color.RED) { // 10000 1538 @Override 1539 public boolean checkPixels(int pixelCount, int width, int height) { 1540 return pixelCount > 9000 && pixelCount < 11000; 1541 } 1542 }); 1543 } 1544 1545 @Test testSurfaceTransaction_setColorAndBuffer_bufferAlpha_0_5()1546 public void testSurfaceTransaction_setColorAndBuffer_bufferAlpha_0_5() { 1547 verifyTest( 1548 new BasicSurfaceHolderCallback() { 1549 @Override 1550 public void surfaceCreated(SurfaceHolder holder) { 1551 long surfaceControl = createFromWindow(holder.getSurface()); 1552 1553 setSolidBuffer( 1554 surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1555 Color.RED); 1556 setBufferAlpha(surfaceControl, 0.5); 1557 setColor(surfaceControl, 0, 0, 1.0f, 1.0f); 1558 } 1559 }, 1560 new PixelChecker(Color.RED, false /* logWhenNoMatch */) { 1561 @Override 1562 public boolean checkPixels(int pixelCount, int width, int height) { 1563 return pixelCount == 0; 1564 } 1565 }); 1566 } 1567 1568 @Test testSurfaceTransaction_setBufferNoColor_bufferAlpha_0()1569 public void testSurfaceTransaction_setBufferNoColor_bufferAlpha_0() { 1570 verifyTest( 1571 new BasicSurfaceHolderCallback() { 1572 @Override 1573 public void surfaceCreated(SurfaceHolder holder) { 1574 long surfaceControlA = createFromWindow(holder.getSurface()); 1575 long surfaceControlB = createFromWindow(holder.getSurface()); 1576 1577 setColor(surfaceControlA, 1.0f, 0, 0, 1.0f); 1578 setSolidBuffer(surfaceControlB, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1579 Color.TRANSPARENT); 1580 1581 setZOrder(surfaceControlA, 1); 1582 setZOrder(surfaceControlB, 2); 1583 } 1584 }, 1585 new PixelChecker(Color.RED) { // 10000 1586 @Override 1587 public boolean checkPixels(int pixelCount, int width, int height) { 1588 return pixelCount > 9000 && pixelCount < 11000; 1589 } 1590 }); 1591 } 1592 1593 @Test testSurfaceTransaction_setColorAndBuffer_hide()1594 public void testSurfaceTransaction_setColorAndBuffer_hide() { 1595 verifyTest( 1596 new BasicSurfaceHolderCallback() { 1597 @Override 1598 public void surfaceCreated(SurfaceHolder holder) { 1599 long parentSurfaceControl = createFromWindow(holder.getSurface()); 1600 long childSurfaceControl = create(parentSurfaceControl); 1601 1602 setColor(parentSurfaceControl, 0, 1.0f, 0, 1.0f); 1603 1604 setSolidBuffer( 1605 childSurfaceControl, DEFAULT_LAYOUT_WIDTH, 1606 DEFAULT_LAYOUT_HEIGHT, Color.RED); 1607 setColor(childSurfaceControl, 0, 0, 1.0f, 1.0f); 1608 setVisibility(childSurfaceControl, false); 1609 } 1610 }, 1611 new PixelChecker(Color.GREEN) { // 10000 1612 @Override 1613 public boolean checkPixels(int pixelCount, int width, int height) { 1614 return pixelCount > 9000 && pixelCount < 11000; 1615 } 1616 }); 1617 } 1618 1619 @Test testSurfaceTransaction_zOrderMultipleSurfaces()1620 public void testSurfaceTransaction_zOrderMultipleSurfaces() { 1621 verifyTest( 1622 new BasicSurfaceHolderCallback() { 1623 @Override 1624 public void surfaceCreated(SurfaceHolder holder) { 1625 long surfaceControlA = createFromWindow(holder.getSurface()); 1626 long surfaceControlB = createFromWindow(holder.getSurface()); 1627 1628 // blue color layer of A is above the green buffer and red color layer 1629 // of B 1630 setColor(surfaceControlA, 0, 0, 1.0f, 1.0f); 1631 setSolidBuffer( 1632 surfaceControlB, DEFAULT_LAYOUT_WIDTH, 1633 DEFAULT_LAYOUT_HEIGHT, Color.GREEN); 1634 setColor(surfaceControlB, 1.0f, 0, 0, 1.0f); 1635 setZOrder(surfaceControlA, 5); 1636 setZOrder(surfaceControlB, 4); 1637 } 1638 }, 1639 new PixelChecker(Color.BLUE) { // 10000 1640 @Override 1641 public boolean checkPixels(int pixelCount, int width, int height) { 1642 return pixelCount > 9000 && pixelCount < 11000; 1643 } 1644 }); 1645 } 1646 1647 @Test testSurfaceTransaction_zOrderMultipleSurfacesWithParent()1648 public void testSurfaceTransaction_zOrderMultipleSurfacesWithParent() { 1649 verifyTest( 1650 new BasicSurfaceHolderCallback() { 1651 @Override 1652 public void surfaceCreated(SurfaceHolder holder) { 1653 long parentSurfaceControl = createFromWindow(holder.getSurface()); 1654 long surfaceControlA = create(parentSurfaceControl); 1655 long surfaceControlB = create(parentSurfaceControl); 1656 1657 setColor(surfaceControlA, 0, 1.0f, 0, 1.0f); 1658 setSolidBuffer( 1659 surfaceControlA, DEFAULT_LAYOUT_WIDTH, 1660 DEFAULT_LAYOUT_HEIGHT, Color.GREEN); 1661 setColor(surfaceControlB, 1.0f, 0, 0, 1.0f); 1662 setZOrder(surfaceControlA, 3); 1663 setZOrder(surfaceControlB, 4); 1664 } 1665 }, 1666 new PixelChecker(Color.RED) { // 10000 1667 @Override 1668 public boolean checkPixels(int pixelCount, int width, int height) { 1669 return pixelCount > 9000 && pixelCount < 11000; 1670 } 1671 }); 1672 } 1673 1674 @Test testSurfaceTransaction_setPosition()1675 public void testSurfaceTransaction_setPosition() { 1676 verifyTest( 1677 new BasicSurfaceHolderCallback() { 1678 @Override 1679 public void surfaceCreated(SurfaceHolder holder) { 1680 long surfaceControl = createFromWindow(holder.getSurface()); 1681 1682 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1683 Color.RED); 1684 setPosition(surfaceControl, 20, 10); 1685 } 1686 }, 1687 new RectChecker(DEFAULT_RECT) { 1688 @Override 1689 public PixelColor getExpectedColor(int x, int y) { 1690 if (x >= 20 && y >= 10) { 1691 return RED; 1692 } else { 1693 return YELLOW; 1694 } 1695 } 1696 }); 1697 } 1698 1699 @Test testSurfaceTransaction_setPositionNegative()1700 public void testSurfaceTransaction_setPositionNegative() { 1701 verifyTest( 1702 new BasicSurfaceHolderCallback() { 1703 @Override 1704 public void surfaceCreated(SurfaceHolder holder) { 1705 long surfaceControl = createFromWindow(holder.getSurface()); 1706 1707 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1708 Color.RED); 1709 // Offset -20, -10 1710 setPosition(surfaceControl, -20, -10); 1711 } 1712 }, 1713 new RectChecker(DEFAULT_RECT) { 1714 @Override 1715 public PixelColor getExpectedColor(int x, int y) { 1716 if (x < DEFAULT_LAYOUT_WIDTH - 20 && y < DEFAULT_LAYOUT_HEIGHT - 10) { 1717 return RED; 1718 } else { 1719 return YELLOW; 1720 } 1721 } 1722 }); 1723 } 1724 1725 @Test testSurfaceTransaction_setScale()1726 public void testSurfaceTransaction_setScale() { 1727 verifyTest( 1728 new BasicSurfaceHolderCallback() { 1729 @Override 1730 public void surfaceCreated(SurfaceHolder holder) { 1731 long surfaceControl = createFromWindow(holder.getSurface()); 1732 1733 setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, 1734 Color.RED); 1735 setScale(surfaceControl, .5f, .5f); 1736 } 1737 }, 1738 new RectChecker(DEFAULT_RECT) { 1739 @Override 1740 public PixelColor getExpectedColor(int x, int y) { 1741 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1742 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1743 if (x < halfWidth && y < halfHeight) { 1744 return RED; 1745 } else { 1746 return YELLOW; 1747 } 1748 } 1749 }); 1750 } 1751 1752 @Test testSurfaceTransaction_scaleToZero()1753 public void testSurfaceTransaction_scaleToZero() { 1754 verifyTest( 1755 new BasicSurfaceHolderCallback() { 1756 @Override 1757 public void surfaceCreated(SurfaceHolder holder) { 1758 long parentSurfaceControl = createFromWindow(holder.getSurface()); 1759 long childSurfaceControl = create(parentSurfaceControl); 1760 1761 setSolidBuffer(parentSurfaceControl, 1762 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.YELLOW); 1763 setSolidBuffer(childSurfaceControl, 1764 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.RED); 1765 setScale(childSurfaceControl, 0f, 0f); 1766 } 1767 }, 1768 new PixelChecker(Color.YELLOW) { 1769 @Override 1770 public boolean checkPixels(int matchingPixelCount, int width, int height) { 1771 return matchingPixelCount > 9000 & matchingPixelCount < 11000; 1772 } 1773 }); 1774 } 1775 1776 @Test testSurfaceTransaction_setPositionAndScale()1777 public void testSurfaceTransaction_setPositionAndScale() { 1778 verifyTest( 1779 new BasicSurfaceHolderCallback() { 1780 @Override 1781 public void surfaceCreated(SurfaceHolder holder) { 1782 long surfaceControl = createFromWindow(holder.getSurface()); 1783 1784 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 1785 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 1786 Color.MAGENTA, Color.GREEN); 1787 1788 // Set the position to -50, -50 in parent space then scale 2x in each 1789 // direction relative to 0,0. The end result should be a -50,-50,150,150 1790 // buffer coverage or essentially a 2x center-scale 1791 1792 setPosition(surfaceControl, -50, -50); 1793 setScale(surfaceControl, 2, 2); 1794 } 1795 }, 1796 new RectChecker(new Rect(0, 0, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT)) { 1797 @Override 1798 public PixelColor getExpectedColor(int x, int y) { 1799 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1800 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1801 if (x < halfWidth && y < halfHeight) { 1802 return RED; 1803 } else if (x >= halfWidth && y < halfHeight) { 1804 return BLUE; 1805 } else if (x < halfWidth && y >= halfHeight) { 1806 return GREEN; 1807 } else { 1808 return MAGENTA; 1809 } 1810 } 1811 1812 @Override 1813 public boolean checkPixels(int matchingPixelCount, int width, int height) { 1814 // There will be sampling artifacts along the center line, ignore those 1815 return matchingPixelCount > 9000 && matchingPixelCount < 11000; 1816 } 1817 }); 1818 } 1819 1820 @Test testSurfaceTransaction_setBufferTransform90()1821 public void testSurfaceTransaction_setBufferTransform90() { 1822 verifyTest( 1823 new BasicSurfaceHolderCallback() { 1824 @Override 1825 public void surfaceCreated(SurfaceHolder holder) { 1826 long surfaceControl = createFromWindow(holder.getSurface()); 1827 1828 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 1829 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 1830 Color.MAGENTA, Color.GREEN); 1831 setPosition(surfaceControl, -50, -50); 1832 setBufferTransform(surfaceControl, /* NATIVE_WINDOW_TRANSFORM_ROT_90 */ 4); 1833 } 1834 }, 1835 new RectChecker(DEFAULT_RECT) { 1836 @Override 1837 public PixelColor getExpectedColor(int x, int y) { 1838 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1839 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1840 if (x < halfWidth && y < halfHeight) { 1841 return BLUE; 1842 } else { 1843 return YELLOW; 1844 } 1845 } 1846 }); 1847 } 1848 1849 @Test testSurfaceTransaction_setCropSmall()1850 public void testSurfaceTransaction_setCropSmall() { 1851 verifyTest( 1852 new BasicSurfaceHolderCallback() { 1853 @Override 1854 public void surfaceCreated(SurfaceHolder holder) { 1855 long surfaceControl = createFromWindow(holder.getSurface()); 1856 1857 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 1858 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 1859 Color.MAGENTA, Color.GREEN); 1860 setCrop(surfaceControl, new Rect(0, 0, 50, 50)); 1861 } 1862 }, 1863 1864 new RectChecker(DEFAULT_RECT) { 1865 @Override 1866 public PixelColor getExpectedColor(int x, int y) { 1867 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1868 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1869 if (x < halfWidth && y < halfHeight) { 1870 return RED; 1871 } else { 1872 return YELLOW; 1873 } 1874 } 1875 }); 1876 } 1877 1878 @Test testSurfaceTransaction_setCropLarge()1879 public void testSurfaceTransaction_setCropLarge() { 1880 verifyTest( 1881 new BasicSurfaceHolderCallback() { 1882 @Override 1883 public void surfaceCreated(SurfaceHolder holder) { 1884 long surfaceControl = createFromWindow(holder.getSurface()); 1885 1886 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 1887 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 1888 Color.MAGENTA, Color.GREEN); 1889 setCrop(surfaceControl, new Rect(0, 0, 150, 150)); 1890 } 1891 }, 1892 1893 new RectChecker(DEFAULT_RECT) { 1894 @Override 1895 public PixelColor getExpectedColor(int x, int y) { 1896 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1897 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1898 if (x < halfWidth && y < halfHeight) { 1899 return RED; 1900 } else if (x >= halfWidth && y < halfHeight) { 1901 return BLUE; 1902 } else if (x < halfWidth && y >= halfHeight) { 1903 return GREEN; 1904 } else { 1905 return MAGENTA; 1906 } 1907 } 1908 }); 1909 } 1910 1911 @Test testSurfaceTransaction_setCropOffset()1912 public void testSurfaceTransaction_setCropOffset() { 1913 verifyTest( 1914 new BasicSurfaceHolderCallback() { 1915 @Override 1916 public void surfaceCreated(SurfaceHolder holder) { 1917 long surfaceControl = createFromWindow(holder.getSurface()); 1918 1919 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 1920 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 1921 Color.MAGENTA, Color.GREEN); 1922 setCrop(surfaceControl, new Rect(50, 50, 100, 100)); 1923 } 1924 }, new RectChecker(DEFAULT_RECT) { 1925 @Override 1926 public PixelColor getExpectedColor(int x, int y) { 1927 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1928 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1929 // Only Magenta is visible in the lower right quadrant 1930 if (x >= halfWidth && y >= halfHeight) { 1931 return MAGENTA; 1932 } else { 1933 return YELLOW; 1934 } 1935 } 1936 }); 1937 } 1938 1939 @Test testSurfaceTransaction_setCropNegative()1940 public void testSurfaceTransaction_setCropNegative() { 1941 verifyTest( 1942 new BasicSurfaceHolderCallback() { 1943 @Override 1944 public void surfaceCreated(SurfaceHolder holder) { 1945 long surfaceControl = createFromWindow(holder.getSurface()); 1946 1947 setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, 1948 DEFAULT_LAYOUT_HEIGHT, Color.RED, Color.BLUE, 1949 Color.MAGENTA, Color.GREEN); 1950 setCrop(surfaceControl, new Rect(-50, -50, 50, 50)); 1951 } 1952 }, new RectChecker(DEFAULT_RECT) { 1953 @Override 1954 public PixelColor getExpectedColor(int x, int y) { 1955 int halfWidth = DEFAULT_LAYOUT_WIDTH / 2; 1956 int halfHeight = DEFAULT_LAYOUT_HEIGHT / 2; 1957 if (x < halfWidth && y < halfHeight) { 1958 return RED; 1959 } else { 1960 return YELLOW; 1961 } 1962 } 1963 }); 1964 } 1965 1966 // Returns success of the surface transaction to decide whether to continue the test, such as 1967 // additional assertions. verifySetFrameTimeline(boolean usePreferredIndex, SurfaceHolder holder)1968 private boolean verifySetFrameTimeline(boolean usePreferredIndex, SurfaceHolder holder) { 1969 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 1970 long surfaceControl = nSurfaceControl_createFromWindow(holder.getSurface()); 1971 assertTrue("failed to create surface control", surfaceControl != 0); 1972 long surfaceTransaction = createSurfaceTransaction(); 1973 long buffer = nSurfaceTransaction_setSolidBuffer(surfaceControl, surfaceTransaction, 1974 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.RED); 1975 assertTrue("failed to set buffer", buffer != 0); 1976 1977 // Get choreographer frame timelines. 1978 FrameCallbackData frameCallbackData = nGetFrameTimelines(); 1979 FrameTimeline[] frameTimelines = frameCallbackData.getFrameTimelines(); 1980 1981 int timelineIndex = frameCallbackData.getPreferredFrameTimelineIndex(); 1982 if (!usePreferredIndex) { 1983 if (frameTimelines.length == 1) { 1984 // If there is only one frame timeline then it is already the preferred timeline. 1985 // Thus testing a non-preferred index is impossible. 1986 Log.i(TAG, "Non-preferred frame timeline does not exist"); 1987 return false; 1988 } 1989 if (timelineIndex == frameTimelines.length - 1) { 1990 timelineIndex--; 1991 } else { 1992 timelineIndex++; 1993 } 1994 } 1995 FrameTimeline frameTimeline = frameTimelines[timelineIndex]; 1996 long vsyncId = frameTimeline.getVsyncId(); 1997 assertTrue("Vsync ID not valid", vsyncId > 0); 1998 1999 Trace.beginSection("Surface transaction created " + vsyncId); 2000 nSurfaceTransaction_setFrameTimeline(surfaceTransaction, vsyncId); 2001 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, 2002 true /* waitForFence */, onCompleteCallback); 2003 applyAndDeleteSurfaceTransaction(surfaceTransaction); 2004 Trace.endSection(); 2005 2006 Trace.beginSection("Wait for complete callback " + vsyncId); 2007 // Wait for callbacks to fire. 2008 try { 2009 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 2010 } catch (InterruptedException e) { 2011 } 2012 if (onCompleteCallback.mLatch.getCount() > 0) { 2013 Log.e(TAG, "Failed to wait for callback"); 2014 } 2015 Trace.endSection(); 2016 2017 assertEquals(0, onCompleteCallback.mLatch.getCount()); 2018 assertTrue(onCompleteCallback.mCallbackTime > 0); 2019 assertTrue(onCompleteCallback.mLatchTime > 0); 2020 2021 long periodNanos = (long) (1e9 / mActivity.getDisplay().getRefreshRate()); 2022 long threshold = periodNanos / 2; 2023 // Check that the frame did not present earlier than the frame timeline chosen from setting 2024 // a vsyncId in the surface transaction; this should be guaranteed as part of the API 2025 // specification. Don't check whether the frame presents on-time since it can be flaky from 2026 // other delays. 2027 assertTrue("Frame presented too early using frame timeline index=" + timelineIndex 2028 + " (preferred index=" + frameCallbackData.getPreferredFrameTimelineIndex() 2029 + ", preferred vsyncId=" 2030 + frameTimelines[frameCallbackData.getPreferredFrameTimelineIndex()] 2031 .getVsyncId() 2032 + "), vsyncId=" + frameTimeline.getVsyncId() + ", actual presentation time=" 2033 + onCompleteCallback.mPresentTime + ", expected presentation time=" 2034 + frameTimeline.getExpectedPresentTime() + ", actual - expected diff (ns)=" 2035 + (onCompleteCallback.mPresentTime - frameTimeline.getExpectedPresentTime()) 2036 + ", acceptable diff threshold (ns)= " + threshold, 2037 onCompleteCallback.mPresentTime 2038 > frameTimeline.getExpectedPresentTime() - threshold); 2039 return true; 2040 } 2041 2042 @Test 2043 @RequiresDevice // emulators can't support sync fences testSurfaceTransaction_setFrameTimeline_preferredIndex()2044 public void testSurfaceTransaction_setFrameTimeline_preferredIndex() { 2045 Trace.beginSection( 2046 "testSurfaceTransaction_setFrameTimeline_preferredIndex"); 2047 Trace.endSection(); 2048 2049 BasicSurfaceHolderCallback basicSurfaceHolderCallback = new BasicSurfaceHolderCallback() { 2050 @Override 2051 public void surfaceCreated(SurfaceHolder surfaceHolder) { 2052 // Noop. 2053 } 2054 }; 2055 final CountDownLatch readyFence = new CountDownLatch(1); 2056 ASurfaceControlTestActivity.SurfaceHolderCallback surfaceHolderCallback = 2057 new ASurfaceControlTestActivity.SurfaceHolderCallback( 2058 new SurfaceHolderCallback(basicSurfaceHolderCallback), readyFence, 2059 mActivity.getParentFrameLayout().getRootSurfaceControl()); 2060 mActivity.createSurface(surfaceHolderCallback); 2061 try { 2062 assertTrue("timeout", readyFence.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)); 2063 } catch (InterruptedException e) { 2064 Assert.fail("interrupted"); 2065 } 2066 if (!verifySetFrameTimeline(true, mActivity.getSurfaceView().getHolder())) return; 2067 mActivity.verifyScreenshot( 2068 new PixelChecker(Color.RED) { //10000 2069 @Override 2070 public boolean checkPixels(int pixelCount, int width, int height) { 2071 return pixelCount > 9000 && pixelCount < 11000; 2072 } 2073 }, mName); 2074 2075 } 2076 2077 @Test 2078 @RequiresDevice // emulators can't support sync fences testSurfaceTransaction_setFrameTimeline_notPreferredIndex()2079 public void testSurfaceTransaction_setFrameTimeline_notPreferredIndex() { 2080 Trace.beginSection( 2081 "testSurfaceTransaction_setFrameTimeline_notPreferredIndex"); 2082 Trace.endSection(); 2083 2084 BasicSurfaceHolderCallback basicSurfaceHolderCallback = new BasicSurfaceHolderCallback() { 2085 @Override 2086 public void surfaceCreated(SurfaceHolder surfaceHolder) { 2087 // Noop. 2088 } 2089 }; 2090 final CountDownLatch readyFence = new CountDownLatch(1); 2091 ASurfaceControlTestActivity.SurfaceHolderCallback surfaceHolderCallback = 2092 new ASurfaceControlTestActivity.SurfaceHolderCallback( 2093 new SurfaceHolderCallback(basicSurfaceHolderCallback), readyFence, 2094 mActivity.getParentFrameLayout().getRootSurfaceControl()); 2095 mActivity.createSurface(surfaceHolderCallback); 2096 try { 2097 assertTrue("timeout", readyFence.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)); 2098 } catch (InterruptedException e) { 2099 Assert.fail("interrupted"); 2100 } 2101 if (!verifySetFrameTimeline(false, mActivity.getSurfaceView().getHolder())) return; 2102 mActivity.verifyScreenshot( 2103 new PixelChecker(Color.RED) { //10000 2104 @Override 2105 public boolean checkPixels(int pixelCount, int width, int height) { 2106 return pixelCount > 9000 && pixelCount < 11000; 2107 } 2108 }, mName); 2109 2110 } 2111 2112 static class TimedTransactionListener implements 2113 ASurfaceControlTestUtils.TransactionCompleteListener { 2114 long mCallbackTime = -1; 2115 long mLatchTime = -1; 2116 long mPresentTime = -1; 2117 CountDownLatch mLatch = new CountDownLatch(1); 2118 2119 @Override onTransactionComplete(long inLatchTime, long presentTime)2120 public void onTransactionComplete(long inLatchTime, long presentTime) { 2121 mCallbackTime = SystemClock.elapsedRealtime(); 2122 mLatchTime = inLatchTime; 2123 mPresentTime = presentTime; 2124 mLatch.countDown(); 2125 } 2126 } 2127 2128 @Test testSurfaceTransactionOnCommitCallback_emptyTransaction()2129 public void testSurfaceTransactionOnCommitCallback_emptyTransaction() 2130 throws InterruptedException { 2131 // Create and send an empty transaction with onCommit and onComplete callbacks. 2132 long surfaceTransaction = nSurfaceTransaction_create(); 2133 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 2134 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, false /* waitForFence */, 2135 onCompleteCallback); 2136 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 2137 nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, onCommitCallback); 2138 nSurfaceTransaction_apply(surfaceTransaction); 2139 nSurfaceTransaction_delete(surfaceTransaction); 2140 2141 // Wait for callbacks to fire. 2142 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 2143 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 2144 2145 // Validate we got callbacks. 2146 assertEquals(0, onCommitCallback.mLatch.getCount()); 2147 assertTrue(onCommitCallback.mCallbackTime > 0); 2148 assertEquals(0, onCompleteCallback.mLatch.getCount()); 2149 assertTrue(onCompleteCallback.mCallbackTime > 0); 2150 2151 // Validate we received the callbacks in expected order. 2152 assertTrue(onCommitCallback.mCallbackTime <= onCompleteCallback.mCallbackTime); 2153 } 2154 2155 @Test testSurfaceTransactionOnCommitCallback_bufferTransaction()2156 public void testSurfaceTransactionOnCommitCallback_bufferTransaction() 2157 throws Throwable { 2158 // Create and send a transaction with a buffer update and with onCommit and onComplete 2159 // callbacks. 2160 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 2161 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 2162 verifyTest( 2163 new BasicSurfaceHolderCallback() { 2164 @Override 2165 public void surfaceCreated(SurfaceHolder holder) { 2166 long surfaceTransaction = nSurfaceTransaction_create(); 2167 long surfaceControl = createFromWindow(holder.getSurface()); 2168 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 2169 DEFAULT_LAYOUT_HEIGHT, Color.RED); 2170 nSurfaceTransaction_setOnCompleteCallback( 2171 surfaceTransaction /* waitForFence */, false, 2172 onCompleteCallback); 2173 nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, 2174 onCommitCallback); 2175 nSurfaceTransaction_apply(surfaceTransaction); 2176 nSurfaceTransaction_delete(surfaceTransaction); 2177 2178 // Wait for callbacks to fire. 2179 try { 2180 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 2181 } catch (InterruptedException e) { 2182 } 2183 if (onCommitCallback.mLatch.getCount() > 0) { 2184 Log.e(TAG, "Failed to wait for commit callback"); 2185 } 2186 } 2187 }, 2188 new PixelChecker(Color.RED) { //10000 2189 @Override 2190 public boolean checkPixels(int pixelCount, int width, int height) { 2191 return pixelCount > 9000 && pixelCount < 11000; 2192 } 2193 }); 2194 2195 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 2196 2197 // Validate we got callbacks with a valid latch time. 2198 assertEquals(0, onCommitCallback.mLatch.getCount()); 2199 assertTrue(onCommitCallback.mCallbackTime > 0); 2200 assertTrue(onCommitCallback.mLatchTime > 0); 2201 assertEquals(0, onCompleteCallback.mLatch.getCount()); 2202 assertTrue(onCompleteCallback.mCallbackTime > 0); 2203 assertTrue(onCompleteCallback.mLatchTime > 0); 2204 2205 // Validate we received the callbacks in expected order and the latch times reported 2206 // matches. 2207 assertTrue(onCommitCallback.mCallbackTime <= onCompleteCallback.mCallbackTime); 2208 assertEquals(onCommitCallback.mLatchTime, onCompleteCallback.mLatchTime); 2209 } 2210 2211 @Test testSurfaceTransactionOnCommitCallback_geometryTransaction()2212 public void testSurfaceTransactionOnCommitCallback_geometryTransaction() 2213 throws Throwable { 2214 // Create and send a transaction with a buffer update and with onCommit and onComplete 2215 // callbacks. 2216 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 2217 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 2218 verifyTest( 2219 new BasicSurfaceHolderCallback() { 2220 @Override 2221 public void surfaceCreated(SurfaceHolder holder) { 2222 long surfaceTransaction = nSurfaceTransaction_create(); 2223 long surfaceControl = createFromWindow(holder.getSurface()); 2224 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 2225 DEFAULT_LAYOUT_HEIGHT, Color.RED); 2226 nSurfaceTransaction_apply(surfaceTransaction); 2227 nSurfaceTransaction_delete(surfaceTransaction); 2228 surfaceTransaction = nSurfaceTransaction_create(); 2229 nSurfaceTransaction_setPosition(surfaceControl, surfaceTransaction, 1, 0); 2230 nSurfaceTransaction_setOnCompleteCallback(surfaceTransaction, 2231 false /* waitForFence */, onCompleteCallback); 2232 nSurfaceTransaction_setOnCommitCallback(surfaceTransaction, 2233 onCommitCallback); 2234 nSurfaceTransaction_apply(surfaceTransaction); 2235 nSurfaceTransaction_delete(surfaceTransaction); 2236 } 2237 }, 2238 new RectChecker(DEFAULT_RECT) { 2239 @Override 2240 public PixelColor getExpectedColor(int x, int y) { 2241 if (x >= 1) { 2242 return RED; 2243 } else { 2244 return YELLOW; 2245 } 2246 } 2247 }); 2248 2249 // Wait for callbacks to fire. 2250 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 2251 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 2252 2253 // Validate we got callbacks with a valid latch time. 2254 assertTrue(onCommitCallback.mLatch.getCount() == 0); 2255 assertTrue(onCommitCallback.mCallbackTime > 0); 2256 assertTrue(onCommitCallback.mLatchTime > 0); 2257 assertTrue(onCompleteCallback.mLatch.getCount() == 0); 2258 assertTrue(onCompleteCallback.mCallbackTime > 0); 2259 assertTrue(onCompleteCallback.mLatchTime > 0); 2260 2261 // Validate we received the callbacks in expected order and the latch times reported 2262 // matches. 2263 assertTrue(onCommitCallback.mCallbackTime <= onCompleteCallback.mCallbackTime); 2264 assertTrue(onCommitCallback.mLatchTime == onCompleteCallback.mLatchTime); 2265 } 2266 2267 @Test testSurfaceTransactionOnCommitCallback_withoutContext()2268 public void testSurfaceTransactionOnCommitCallback_withoutContext() 2269 throws InterruptedException { 2270 // Create and send an empty transaction with onCommit callbacks without context. 2271 long surfaceTransaction = nSurfaceTransaction_create(); 2272 TimedTransactionListener onCommitCallback = new TimedTransactionListener(); 2273 nSurfaceTransaction_setOnCommitCallbackWithoutContext(surfaceTransaction, onCommitCallback); 2274 nSurfaceTransaction_apply(surfaceTransaction); 2275 nSurfaceTransaction_delete(surfaceTransaction); 2276 2277 // Wait for callbacks to fire. 2278 onCommitCallback.mLatch.await(1, TimeUnit.SECONDS); 2279 2280 // Validate we got callbacks. 2281 assertEquals(0, onCommitCallback.mLatch.getCount()); 2282 assertTrue(onCommitCallback.mCallbackTime > 0); 2283 } 2284 2285 @Test testSurfaceTransactionOnCompleteCallback_withoutContext()2286 public void testSurfaceTransactionOnCompleteCallback_withoutContext() 2287 throws InterruptedException { 2288 // Create and send an empty transaction with onComplete callbacks without context. 2289 long surfaceTransaction = nSurfaceTransaction_create(); 2290 TimedTransactionListener onCompleteCallback = new TimedTransactionListener(); 2291 nSurfaceTransaction_setOnCompleteCallbackWithoutContext(surfaceTransaction, 2292 false /* waitForFence */, onCompleteCallback); 2293 nSurfaceTransaction_apply(surfaceTransaction); 2294 nSurfaceTransaction_delete(surfaceTransaction); 2295 2296 // Wait for callbacks to fire. 2297 onCompleteCallback.mLatch.await(1, TimeUnit.SECONDS); 2298 2299 // Validate we got callbacks. 2300 assertEquals(0, onCompleteCallback.mLatch.getCount()); 2301 assertTrue(onCompleteCallback.mCallbackTime > 0); 2302 } 2303 2304 @Test testSetExtendedRangeBrightness()2305 public void testSetExtendedRangeBrightness() throws Exception { 2306 mActivity.awaitReadyState(); 2307 Display display = mActivity.getDisplay(); 2308 if (!display.isHdrSdrRatioAvailable()) { 2309 assertEquals(1.0f, display.getHdrSdrRatio(), 0.0001f); 2310 } 2311 // Set something super low so that if hdr/sdr ratio is available, we'll get some level 2312 // of HDR probably 2313 mActivity.getWindow().getAttributes().screenBrightness = 0.01f; 2314 // Wait for the screenBrightness to be picked up by VRI 2315 WidgetTestUtils.runOnMainAndDrawSync(mActivity.getParentFrameLayout(), () -> {}); 2316 CountDownLatch hdrReady = new CountDownLatch(1); 2317 Exception[] listenerErrors = new Exception[1]; 2318 if (display.isHdrSdrRatioAvailable()) { 2319 display.registerHdrSdrRatioChangedListener(Runnable::run, new Consumer<Display>() { 2320 boolean mIsRegistered = true; 2321 2322 @Override 2323 public void accept(Display updatedDisplay) { 2324 try { 2325 assertEquals(display.getDisplayId(), updatedDisplay.getDisplayId()); 2326 assertTrue(mIsRegistered); 2327 if (display.getHdrSdrRatio() > 2.f) { 2328 hdrReady.countDown(); 2329 display.unregisterHdrSdrRatioChangedListener(this); 2330 mIsRegistered = false; 2331 } 2332 } catch (Exception e) { 2333 synchronized (mActivity) { 2334 listenerErrors[0] = e; 2335 hdrReady.countDown(); 2336 } 2337 } 2338 } 2339 }); 2340 } else { 2341 assertThrows(IllegalStateException.class, () -> 2342 display.registerHdrSdrRatioChangedListener(Runnable::run, ignored -> {})); 2343 } 2344 2345 final int extendedDataspace = DataSpace.pack(DataSpace.STANDARD_BT709, 2346 DataSpace.TRANSFER_SRGB, DataSpace.RANGE_EXTENDED); 2347 2348 verifyTest( 2349 new BasicSurfaceHolderCallback() { 2350 @Override 2351 public void surfaceCreated(SurfaceHolder holder) { 2352 long surfaceTransaction = nSurfaceTransaction_create(); 2353 long surfaceControl = createFromWindow(holder.getSurface()); 2354 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 2355 DEFAULT_LAYOUT_HEIGHT, Color.WHITE); 2356 nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction, 2357 extendedDataspace); 2358 nSurfaceTransaction_setExtendedRangeBrightness(surfaceControl, 2359 surfaceTransaction, 3.f, 3.f); 2360 nSurfaceTransaction_apply(surfaceTransaction); 2361 nSurfaceTransaction_delete(surfaceTransaction); 2362 } 2363 }, 2364 new PixelChecker(Color.WHITE) { //10000 2365 @Override 2366 public boolean checkPixels(int pixelCount, int width, int height) { 2367 return pixelCount > 9000 && pixelCount < 11000; 2368 } 2369 }); 2370 2371 // This isn't actually an error if it never happens, it's not _required_ that there's HDR 2372 // headroom available... 2373 if (display.isHdrSdrRatioAvailable()) { 2374 hdrReady.await(1, TimeUnit.SECONDS); 2375 } 2376 2377 if (display.getHdrSdrRatio() > 2.f) { 2378 verifyTest( 2379 new BasicSurfaceHolderCallback() { 2380 @Override 2381 public void surfaceCreated(SurfaceHolder holder) { 2382 long surfaceTransaction = nSurfaceTransaction_create(); 2383 long surfaceControl = createFromWindow(holder.getSurface()); 2384 setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH, 2385 DEFAULT_LAYOUT_HEIGHT, Color.WHITE); 2386 nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction, 2387 extendedDataspace); 2388 nSurfaceTransaction_setExtendedRangeBrightness(surfaceControl, 2389 surfaceTransaction, 3.f, 3.f); 2390 nSurfaceTransaction_apply(surfaceTransaction); 2391 nSurfaceTransaction_delete(surfaceTransaction); 2392 } 2393 }, 2394 new PixelChecker(Color.WHITE) { //10000 2395 @Override 2396 public boolean checkPixels(int pixelCount, int width, int height) { 2397 return pixelCount > 9000 && pixelCount < 11000; 2398 } 2399 }); 2400 } 2401 2402 synchronized (mActivity) { 2403 if (listenerErrors[0] != null) { 2404 throw listenerErrors[0]; 2405 } 2406 } 2407 } 2408 getStableHdrSdrRatio(Display display)2409 private float getStableHdrSdrRatio(Display display) { 2410 float ratio = -1f; 2411 float incomingRatio = display.getHdrSdrRatio(); 2412 long startMillis = SystemClock.uptimeMillis(); 2413 try { 2414 do { 2415 ratio = incomingRatio; 2416 TimeUnit.MILLISECONDS.sleep(500); 2417 incomingRatio = display.getHdrSdrRatio(); 2418 // Bail if the ratio settled or if it's been way too long. 2419 } while (Math.abs(ratio - incomingRatio) > 0.01 2420 && SystemClock.uptimeMillis() - startMillis < 10000); 2421 } catch (InterruptedException e) { 2422 throw new RuntimeException(e); 2423 } 2424 return ratio; 2425 } 2426 2427 @Test testSetDesiredHdrHeadroom()2428 public void testSetDesiredHdrHeadroom() throws Exception { 2429 mActivity.awaitReadyState(); 2430 Display display = mActivity.getDisplay(); 2431 assumeTrue(display.isHdrSdrRatioAvailable()); 2432 2433 final int dataspace = DataSpace.DATASPACE_BT2020_HLG; 2434 2435 AtomicLong surfaceControlContainer = new AtomicLong(); 2436 2437 final CountDownLatch readyFence = new CountDownLatch(1); 2438 ASurfaceControlTestActivity.SurfaceHolderCallback surfaceHolderCallback = 2439 new ASurfaceControlTestActivity.SurfaceHolderCallback( 2440 new SurfaceHolderCallback(new BasicSurfaceHolderCallback() { 2441 @Override 2442 public void surfaceCreated(SurfaceHolder holder) { 2443 long surfaceTransaction = nSurfaceTransaction_create(); 2444 long surfaceControl = createFromWindow(holder.getSurface()); 2445 surfaceControlContainer.set(surfaceControl); 2446 setSolidBuffer(surfaceControl, surfaceTransaction, 2447 DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT, Color.WHITE); 2448 nSurfaceTransaction_setDataSpace(surfaceControl, surfaceTransaction, 2449 dataspace); 2450 nSurfaceTransaction_apply(surfaceTransaction); 2451 nSurfaceTransaction_delete(surfaceTransaction); 2452 } 2453 }), 2454 readyFence, 2455 mActivity.getParentFrameLayout().getRootSurfaceControl()); 2456 mActivity.createSurface(surfaceHolderCallback); 2457 try { 2458 assertTrue("timeout", readyFence.await(WAIT_TIMEOUT_S, TimeUnit.SECONDS)); 2459 } catch (InterruptedException e) { 2460 Assert.fail("interrupted"); 2461 } 2462 2463 float headroom = getStableHdrSdrRatio(display); 2464 // Require some small threshold for allowable headroom 2465 assumeTrue(headroom > 1.02f); 2466 float targetHeadroom = 1.f + (headroom - 1.f) / 2; 2467 2468 mActivity.runOnUiThread(() -> { 2469 long surfaceTransaction = nSurfaceTransaction_create(); 2470 nSurfaceTransaction_setDesiredHdrHeadroom( 2471 surfaceControlContainer.get(), surfaceTransaction, targetHeadroom); 2472 nSurfaceTransaction_apply(surfaceTransaction); 2473 nSurfaceTransaction_delete(surfaceTransaction); 2474 }); 2475 2476 assertTrue("Headroom restriction is not respected", 2477 getStableHdrSdrRatio(display) <= (targetHeadroom + 0.01)); 2478 2479 mActivity.runOnUiThread(() -> { 2480 long surfaceTransaction = nSurfaceTransaction_create(); 2481 nSurfaceTransaction_setDesiredHdrHeadroom( 2482 surfaceControlContainer.get(), surfaceTransaction, 0.f); 2483 nSurfaceTransaction_apply(surfaceTransaction); 2484 nSurfaceTransaction_delete(surfaceTransaction); 2485 }); 2486 2487 assertTrue("Removed headroom restriction is not respected", 2488 getStableHdrSdrRatio(display) > targetHeadroom); 2489 } 2490 } 2491