DetailsFragmentTest.java revision c6c4e8e836f3608446fb472916418f9df660d46a
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.v17.leanback.app; 17 18import static org.junit.Assert.assertEquals; 19import static org.junit.Assert.assertFalse; 20import static org.junit.Assert.assertNull; 21import static org.junit.Assert.assertTrue; 22 23import android.animation.PropertyValuesHolder; 24import android.app.Fragment; 25import android.content.Intent; 26import android.graphics.Bitmap; 27import android.graphics.BitmapFactory; 28import android.graphics.Rect; 29import android.graphics.drawable.ColorDrawable; 30import android.graphics.drawable.Drawable; 31import android.net.Uri; 32import android.os.Build; 33import android.os.Bundle; 34import android.os.SystemClock; 35import android.support.test.InstrumentationRegistry; 36import android.support.test.filters.LargeTest; 37import android.support.v17.leanback.R; 38import android.support.v17.leanback.graphics.FitWidthBitmapDrawable; 39import android.support.v17.leanback.media.MediaPlayerGlue; 40import android.support.v17.leanback.media.PlaybackGlueHost; 41import android.support.v17.leanback.testutils.PollingCheck; 42import android.support.v17.leanback.transition.TransitionHelper; 43import android.support.v17.leanback.util.StateMachine; 44import android.support.v17.leanback.widget.DetailsParallax; 45import android.support.v17.leanback.widget.DetailsParallaxDrawable; 46import android.support.v17.leanback.widget.ParallaxTarget; 47import android.support.v17.leanback.widget.RecyclerViewParallax; 48import android.support.v17.leanback.widget.VerticalGridView; 49import android.view.KeyEvent; 50import android.view.View; 51 52import org.junit.Test; 53import org.junit.runner.RunWith; 54import org.junit.runners.JUnit4; 55 56/** 57 * Unit tests for {@link DetailsFragment}. 58 */ 59@RunWith(JUnit4.class) 60@LargeTest 61public class DetailsFragmentTest extends SingleFragmentTestBase { 62 63 static final int PARALLAX_VERTICAL_OFFSET = -300; 64 65 static int getCoverDrawableAlpha(DetailsFragmentBackgroundController controller) { 66 return ((FitWidthBitmapDrawable) controller.mParallaxDrawable.getCoverDrawable()) 67 .getAlpha(); 68 } 69 70 public static class DetailsFragmentParallax extends DetailsTestFragment { 71 72 private DetailsParallaxDrawable mParallaxDrawable; 73 74 public DetailsFragmentParallax() { 75 super(); 76 mMinVerticalOffset = PARALLAX_VERTICAL_OFFSET; 77 } 78 79 @Override 80 public void onCreate(Bundle savedInstanceState) { 81 super.onCreate(savedInstanceState); 82 Drawable coverDrawable = new FitWidthBitmapDrawable(); 83 mParallaxDrawable = new DetailsParallaxDrawable( 84 getActivity(), 85 getParallax(), 86 coverDrawable, 87 new ParallaxTarget.PropertyValuesHolderTarget( 88 coverDrawable, 89 PropertyValuesHolder.ofInt("verticalOffset", 0, mMinVerticalOffset) 90 ) 91 ); 92 93 BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity()); 94 backgroundManager.attach(getActivity().getWindow()); 95 backgroundManager.setDrawable(mParallaxDrawable); 96 } 97 98 @Override 99 public void onStart() { 100 super.onStart(); 101 setItem(new PhotoItem("Hello world", "Fake content goes here", 102 android.support.v17.leanback.test.R.drawable.spiderman)); 103 } 104 105 @Override 106 public void onResume() { 107 super.onResume(); 108 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 109 android.support.v17.leanback.test.R.drawable.spiderman); 110 ((FitWidthBitmapDrawable) mParallaxDrawable.getCoverDrawable()).setBitmap(bitmap); 111 } 112 113 DetailsParallaxDrawable getParallaxDrawable() { 114 return mParallaxDrawable; 115 } 116 } 117 118 @Test 119 public void parallaxSetupTest() { 120 SingleFragmentTestActivity activity = 121 launchAndWaitActivity(DetailsFragmentTest.DetailsFragmentParallax.class, 122 new SingleFragmentTestBase.Options().uiVisibility( 123 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 124 125 double delta = 0.0002; 126 DetailsParallax dpm = ((DetailsFragment) activity.getTestFragment()).getParallax(); 127 128 RecyclerViewParallax.ChildPositionProperty frameTop = 129 (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowTop(); 130 assertEquals(0f, frameTop.getFraction(), delta); 131 assertEquals(0f, frameTop.getAdapterPosition(), delta); 132 133 134 RecyclerViewParallax.ChildPositionProperty frameBottom = 135 (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowBottom(); 136 assertEquals(1f, frameBottom.getFraction(), delta); 137 assertEquals(0f, frameBottom.getAdapterPosition(), delta); 138 } 139 140 @Test 141 public void parallaxTest() throws Throwable { 142 SingleFragmentTestActivity activity = launchAndWaitActivity(DetailsFragmentParallax.class, 143 new Options().uiVisibility( 144 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 145 146 final DetailsFragmentParallax detailsFragment = 147 (DetailsFragmentParallax) activity.getTestFragment(); 148 DetailsParallaxDrawable drawable = 149 detailsFragment.getParallaxDrawable(); 150 final FitWidthBitmapDrawable bitmapDrawable = (FitWidthBitmapDrawable) 151 drawable.getCoverDrawable(); 152 153 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 154 @Override 155 public boolean canProceed() { 156 return detailsFragment.getRowsFragment().getAdapter() != null 157 && detailsFragment.getRowsFragment().getAdapter().size() > 1; 158 } 159 }); 160 161 final VerticalGridView verticalGridView = detailsFragment.getRowsFragment() 162 .getVerticalGridView(); 163 final int windowHeight = verticalGridView.getHeight(); 164 final int windowWidth = verticalGridView.getWidth(); 165 // make sure background manager attached to window is same size as VerticalGridView 166 // i.e. no status bar. 167 assertEquals(windowHeight, activity.getWindow().getDecorView().getHeight()); 168 assertEquals(windowWidth, activity.getWindow().getDecorView().getWidth()); 169 170 final View detailsFrame = verticalGridView.findViewById(R.id.details_frame); 171 172 assertEquals(windowWidth, bitmapDrawable.getBounds().width()); 173 174 final Rect detailsFrameRect = new Rect(); 175 detailsFrameRect.set(0, 0, detailsFrame.getWidth(), detailsFrame.getHeight()); 176 verticalGridView.offsetDescendantRectToMyCoords(detailsFrame, detailsFrameRect); 177 178 assertEquals(Math.min(windowHeight, detailsFrameRect.top), 179 bitmapDrawable.getBounds().height()); 180 assertEquals(0, bitmapDrawable.getVerticalOffset()); 181 182 assertTrue("TitleView is visible", detailsFragment.getView() 183 .findViewById(R.id.browse_title_group).getVisibility() == View.VISIBLE); 184 185 activityTestRule.runOnUiThread(new Runnable() { 186 @Override 187 public void run() { 188 verticalGridView.scrollToPosition(1); 189 } 190 }); 191 192 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 193 @Override 194 public boolean canProceed() { 195 return bitmapDrawable.getVerticalOffset() == PARALLAX_VERTICAL_OFFSET 196 && detailsFragment.getView() 197 .findViewById(R.id.browse_title_group).getVisibility() != View.VISIBLE; 198 } 199 }); 200 201 detailsFrameRect.set(0, 0, detailsFrame.getWidth(), detailsFrame.getHeight()); 202 verticalGridView.offsetDescendantRectToMyCoords(detailsFrame, detailsFrameRect); 203 204 assertEquals(0, bitmapDrawable.getBounds().top); 205 assertEquals(Math.max(detailsFrameRect.top, 0), bitmapDrawable.getBounds().bottom); 206 assertEquals(windowWidth, bitmapDrawable.getBounds().width()); 207 208 ColorDrawable colorDrawable = (ColorDrawable) (drawable.getChildAt(1).getDrawable()); 209 assertEquals(windowWidth, colorDrawable.getBounds().width()); 210 assertEquals(detailsFrameRect.bottom, colorDrawable.getBounds().top); 211 assertEquals(windowHeight, colorDrawable.getBounds().bottom); 212 } 213 214 public static class DetailsFragmentWithVideo extends DetailsTestFragment { 215 216 final DetailsFragmentBackgroundController mDetailsBackground = 217 new DetailsFragmentBackgroundController(this); 218 MediaPlayerGlue mGlue; 219 220 public DetailsFragmentWithVideo() { 221 mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100; 222 } 223 224 @Override 225 public void onCreate(Bundle savedInstanceState) { 226 super.onCreate(savedInstanceState); 227 mDetailsBackground.enableParallax(); 228 mGlue = new MediaPlayerGlue(getActivity()); 229 mDetailsBackground.setupVideoPlayback(mGlue); 230 231 mGlue.setMode(MediaPlayerGlue.REPEAT_ALL); 232 mGlue.setArtist("A Googleer"); 233 mGlue.setTitle("Diving with Sharks"); 234 mGlue.setMediaSource( 235 Uri.parse("android.resource://android.support.v17.leanback.test/raw/video")); 236 } 237 238 @Override 239 public void onStart() { 240 super.onStart(); 241 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 242 android.support.v17.leanback.test.R.drawable.spiderman); 243 mDetailsBackground.setCoverBitmap(bitmap); 244 } 245 246 @Override 247 public void onStop() { 248 mDetailsBackground.setCoverBitmap(null); 249 super.onStop(); 250 } 251 } 252 253 public static class DetailsFragmentWithVideo1 extends DetailsFragmentWithVideo { 254 255 @Override 256 public void onCreate(Bundle savedInstanceState) { 257 super.onCreate(savedInstanceState); 258 setItem(new PhotoItem("Hello world", "Fake content goes here", 259 android.support.v17.leanback.test.R.drawable.spiderman)); 260 } 261 } 262 263 public static class DetailsFragmentWithVideo2 extends DetailsFragmentWithVideo { 264 265 @Override 266 public void onStart() { 267 super.onStart(); 268 setItem(new PhotoItem("Hello world", "Fake content goes here", 269 android.support.v17.leanback.test.R.drawable.spiderman)); 270 } 271 } 272 273 private void navigateBetweenRowsAndVideoUsingRequestFocusInternal(Class cls) 274 throws Throwable { 275 SingleFragmentTestActivity activity = launchAndWaitActivity(cls, 276 new Options().uiVisibility( 277 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 278 279 final DetailsFragmentWithVideo detailsFragment = 280 (DetailsFragmentWithVideo) activity.getTestFragment(); 281 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 282 @Override 283 public boolean canProceed() { 284 return detailsFragment.mVideoFragment != null 285 && detailsFragment.mVideoFragment.getView() != null 286 && detailsFragment.mGlue.isMediaPlaying(); 287 } 288 }); 289 290 final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView() 291 .getHeight(); 292 final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0); 293 final int originalFirstRowTop = firstRow.getTop(); 294 assertTrue(firstRow.hasFocus()); 295 assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight); 296 assertTrue(detailsFragment.isShowingTitle()); 297 298 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 299 @Override 300 public void run() { 301 detailsFragment.mVideoFragment.getView().requestFocus(); 302 } 303 }); 304 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 305 @Override 306 public boolean canProceed() { 307 return firstRow.getTop() >= screenHeight; 308 } 309 }); 310 assertFalse(detailsFragment.isShowingTitle()); 311 312 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 313 @Override 314 public void run() { 315 detailsFragment.getRowsFragment().getVerticalGridView().requestFocus(); 316 } 317 }); 318 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 319 @Override 320 public boolean canProceed() { 321 return firstRow.getTop() == originalFirstRowTop; 322 } 323 }); 324 assertTrue(detailsFragment.isShowingTitle()); 325 } 326 327 @Test 328 public void navigateBetweenRowsAndVideoUsingRequestFocus1() throws Throwable { 329 navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsFragmentWithVideo1.class); 330 } 331 332 @Test 333 public void navigateBetweenRowsAndVideoUsingRequestFocus2() throws Throwable { 334 navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsFragmentWithVideo2.class); 335 } 336 337 private void navigateBetweenRowsAndVideoUsingDPADInternal(Class cls) throws Throwable { 338 SingleFragmentTestActivity activity = launchAndWaitActivity(cls, 339 new Options().uiVisibility( 340 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 341 342 final DetailsFragmentWithVideo detailsFragment = 343 (DetailsFragmentWithVideo) activity.getTestFragment(); 344 // wait video playing 345 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 346 @Override 347 public boolean canProceed() { 348 return detailsFragment.mVideoFragment != null 349 && detailsFragment.mVideoFragment.getView() != null 350 && detailsFragment.mGlue.isMediaPlaying(); 351 } 352 }); 353 354 final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView() 355 .getHeight(); 356 final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0); 357 final int originalFirstRowTop = firstRow.getTop(); 358 assertTrue(firstRow.hasFocus()); 359 assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight); 360 assertTrue(detailsFragment.isShowingTitle()); 361 362 // navigate to video 363 sendKeys(KeyEvent.KEYCODE_DPAD_UP); 364 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 365 @Override 366 public boolean canProceed() { 367 return firstRow.getTop() >= screenHeight; 368 } 369 }); 370 371 // wait auto hide play controls done: 372 PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() { 373 @Override 374 public boolean canProceed() { 375 return ((PlaybackFragment) detailsFragment.mVideoFragment).mBgAlpha == 0; 376 } 377 }); 378 379 // navigate to details 380 sendKeys(KeyEvent.KEYCODE_BACK); 381 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 382 @Override 383 public boolean canProceed() { 384 return firstRow.getTop() == originalFirstRowTop; 385 } 386 }); 387 assertTrue(detailsFragment.isShowingTitle()); 388 } 389 390 @Test 391 public void navigateBetweenRowsAndVideoUsingDPAD1() throws Throwable { 392 navigateBetweenRowsAndVideoUsingDPADInternal(DetailsFragmentWithVideo1.class); 393 } 394 395 @Test 396 public void navigateBetweenRowsAndVideoUsingDPAD2() throws Throwable { 397 navigateBetweenRowsAndVideoUsingDPADInternal(DetailsFragmentWithVideo2.class); 398 } 399 400 public static class EmptyFragmentClass extends Fragment { 401 @Override 402 public void onStart() { 403 super.onStart(); 404 getActivity().finish(); 405 } 406 } 407 408 private void fragmentOnStartWithVideoInternal(Class cls) throws Throwable { 409 final SingleFragmentTestActivity activity = launchAndWaitActivity(cls, 410 new Options().uiVisibility( 411 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 412 413 final DetailsFragmentWithVideo detailsFragment = 414 (DetailsFragmentWithVideo) activity.getTestFragment(); 415 // wait video playing 416 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 417 @Override 418 public boolean canProceed() { 419 return detailsFragment.mVideoFragment != null 420 && detailsFragment.mVideoFragment.getView() != null 421 && detailsFragment.mGlue.isMediaPlaying(); 422 } 423 }); 424 425 final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView() 426 .getHeight(); 427 final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0); 428 final int originalFirstRowTop = firstRow.getTop(); 429 assertTrue(firstRow.hasFocus()); 430 assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight); 431 assertTrue(detailsFragment.isShowingTitle()); 432 433 // navigate to video 434 sendKeys(KeyEvent.KEYCODE_DPAD_UP); 435 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 436 @Override 437 public boolean canProceed() { 438 return firstRow.getTop() >= screenHeight; 439 } 440 }); 441 442 // start an empty activity 443 InstrumentationRegistry.getInstrumentation().runOnMainSync( 444 new Runnable() { 445 @Override 446 public void run() { 447 Intent intent = new Intent(activity, SingleFragmentTestActivity.class); 448 intent.putExtra(SingleFragmentTestActivity.EXTRA_FRAGMENT_NAME, 449 EmptyFragmentClass.class.getName()); 450 activity.startActivity(intent); 451 } 452 } 453 ); 454 PollingCheck.waitFor(2000, new PollingCheck.PollingCheckCondition() { 455 @Override 456 public boolean canProceed() { 457 return detailsFragment.isResumed(); 458 } 459 }); 460 assertTrue(detailsFragment.mVideoFragment.getView().hasFocus()); 461 } 462 463 @Test 464 public void fragmentOnStartWithVideo1() throws Throwable { 465 fragmentOnStartWithVideoInternal(DetailsFragmentWithVideo1.class); 466 } 467 468 @Test 469 public void fragmentOnStartWithVideo2() throws Throwable { 470 fragmentOnStartWithVideoInternal(DetailsFragmentWithVideo2.class); 471 } 472 473 @Test 474 public void navigateBetweenRowsAndTitle() throws Throwable { 475 SingleFragmentTestActivity activity = 476 launchAndWaitActivity(DetailsTestFragment.class, new Options().uiVisibility( 477 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 478 final DetailsTestFragment detailsFragment = 479 (DetailsTestFragment) activity.getTestFragment(); 480 481 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 482 @Override 483 public void run() { 484 detailsFragment.setOnSearchClickedListener(new View.OnClickListener() { 485 @Override 486 public void onClick(View view) { 487 } 488 }); 489 detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here", 490 android.support.v17.leanback.test.R.drawable.spiderman)); 491 } 492 }); 493 494 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 495 @Override 496 public boolean canProceed() { 497 return detailsFragment.getRowsFragment().getVerticalGridView().getChildCount() > 0; 498 } 499 }); 500 final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0); 501 final int originalFirstRowTop = firstRow.getTop(); 502 final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView() 503 .getHeight(); 504 505 assertTrue(firstRow.hasFocus()); 506 assertTrue(detailsFragment.isShowingTitle()); 507 assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight); 508 509 sendKeys(KeyEvent.KEYCODE_DPAD_UP); 510 PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow)); 511 assertTrue(detailsFragment.isShowingTitle()); 512 assertTrue(detailsFragment.getTitleView().hasFocus()); 513 assertEquals(originalFirstRowTop, firstRow.getTop()); 514 515 sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); 516 PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow)); 517 assertTrue(detailsFragment.isShowingTitle()); 518 assertTrue(firstRow.hasFocus()); 519 assertEquals(originalFirstRowTop, firstRow.getTop()); 520 } 521 522 public static class DetailsFragmentWithNoVideo extends DetailsTestFragment { 523 524 final DetailsFragmentBackgroundController mDetailsBackground = 525 new DetailsFragmentBackgroundController(this); 526 527 public DetailsFragmentWithNoVideo() { 528 mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100; 529 } 530 531 @Override 532 public void onCreate(Bundle savedInstanceState) { 533 super.onCreate(savedInstanceState); 534 mDetailsBackground.enableParallax(); 535 536 setItem(new PhotoItem("Hello world", "Fake content goes here", 537 android.support.v17.leanback.test.R.drawable.spiderman)); 538 } 539 540 @Override 541 public void onStart() { 542 super.onStart(); 543 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 544 android.support.v17.leanback.test.R.drawable.spiderman); 545 mDetailsBackground.setCoverBitmap(bitmap); 546 } 547 548 @Override 549 public void onStop() { 550 mDetailsBackground.setCoverBitmap(null); 551 super.onStop(); 552 } 553 } 554 555 @Test 556 public void lateSetupVideo() { 557 final SingleFragmentTestActivity activity = 558 launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility( 559 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 560 final DetailsFragmentWithNoVideo detailsFragment = 561 (DetailsFragmentWithNoVideo) activity.getTestFragment(); 562 563 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 564 @Override 565 public boolean canProceed() { 566 return detailsFragment.getRowsFragment().getVerticalGridView().getChildCount() > 0; 567 } 568 }); 569 final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0); 570 final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView() 571 .getHeight(); 572 573 assertTrue(firstRow.hasFocus()); 574 assertTrue(detailsFragment.isShowingTitle()); 575 assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight); 576 577 sendKeys(KeyEvent.KEYCODE_DPAD_UP); 578 assertTrue(firstRow.hasFocus()); 579 580 SystemClock.sleep(1000); 581 InstrumentationRegistry.getInstrumentation().runOnMainSync( 582 new Runnable() { 583 @Override 584 public void run() { 585 final MediaPlayerGlue glue = new MediaPlayerGlue(activity); 586 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue); 587 glue.setMode(MediaPlayerGlue.REPEAT_ALL); 588 glue.setArtist("A Googleer"); 589 glue.setTitle("Diving with Sharks"); 590 glue.setMediaSource(Uri.parse( 591 "android.resource://android.support.v17.leanback.test/raw/video")); 592 } 593 } 594 ); 595 596 // after setup Video Playback the DPAD up will navigate to Video Fragment. 597 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 598 @Override 599 public boolean canProceed() { 600 return detailsFragment.mVideoFragment != null 601 && detailsFragment.mVideoFragment.getView() != null; 602 } 603 }); 604 sendKeys(KeyEvent.KEYCODE_DPAD_UP); 605 assertTrue(detailsFragment.mVideoFragment.getView().hasFocus()); 606 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 607 @Override 608 public boolean canProceed() { 609 return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController 610 .getPlaybackGlue()).isMediaPlaying(); 611 } 612 }); 613 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 614 @Override 615 public boolean canProceed() { 616 return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController); 617 } 618 }); 619 620 // wait a little bit to replace with new Glue 621 SystemClock.sleep(1000); 622 InstrumentationRegistry.getInstrumentation().runOnMainSync( 623 new Runnable() { 624 @Override 625 public void run() { 626 final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity); 627 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2); 628 glue2.setMode(MediaPlayerGlue.REPEAT_ALL); 629 glue2.setArtist("A Googleer"); 630 glue2.setTitle("Diving with Sharks"); 631 glue2.setMediaSource(Uri.parse( 632 "android.resource://android.support.v17.leanback.test/raw/video")); 633 } 634 } 635 ); 636 637 // test switchToRows() and switchToVideo() 638 InstrumentationRegistry.getInstrumentation().runOnMainSync( 639 new Runnable() { 640 @Override 641 public void run() { 642 detailsFragment.mDetailsBackgroundController.switchToRows(); 643 } 644 } 645 ); 646 assertTrue(detailsFragment.mRowsFragment.getView().hasFocus()); 647 PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow)); 648 InstrumentationRegistry.getInstrumentation().runOnMainSync( 649 new Runnable() { 650 @Override 651 public void run() { 652 detailsFragment.mDetailsBackgroundController.switchToVideo(); 653 } 654 } 655 ); 656 assertTrue(detailsFragment.mVideoFragment.getView().hasFocus()); 657 PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow)); 658 } 659 660 @Test 661 public void sharedGlueHost() { 662 final SingleFragmentTestActivity activity = 663 launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility( 664 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 665 final DetailsFragmentWithNoVideo detailsFragment = 666 (DetailsFragmentWithNoVideo) activity.getTestFragment(); 667 668 SystemClock.sleep(1000); 669 InstrumentationRegistry.getInstrumentation().runOnMainSync( 670 new Runnable() { 671 @Override 672 public void run() { 673 final MediaPlayerGlue glue1 = new MediaPlayerGlue(activity); 674 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue1); 675 glue1.setArtist("A Googleer"); 676 glue1.setTitle("Diving with Sharks"); 677 glue1.setMediaSource(Uri.parse( 678 "android.resource://android.support.v17.leanback.test/raw/video")); 679 } 680 } 681 ); 682 683 // after setup Video Playback the DPAD up will navigate to Video Fragment. 684 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 685 @Override 686 public boolean canProceed() { 687 return detailsFragment.mVideoFragment != null 688 && detailsFragment.mVideoFragment.getView() != null; 689 } 690 }); 691 692 final MediaPlayerGlue glue1 = (MediaPlayerGlue) detailsFragment 693 .mDetailsBackgroundController 694 .getPlaybackGlue(); 695 PlaybackGlueHost playbackGlueHost = glue1.getHost(); 696 697 // wait a little bit to replace with new Glue 698 SystemClock.sleep(1000); 699 InstrumentationRegistry.getInstrumentation().runOnMainSync( 700 new Runnable() { 701 @Override 702 public void run() { 703 final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity); 704 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2); 705 glue2.setArtist("A Googleer"); 706 glue2.setTitle("Diving with Sharks"); 707 glue2.setMediaSource(Uri.parse( 708 "android.resource://android.support.v17.leanback.test/raw/video")); 709 } 710 } 711 ); 712 713 // wait for new glue to get its glue host 714 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 715 @Override 716 public boolean canProceed() { 717 MediaPlayerGlue mediaPlayerGlue = (MediaPlayerGlue) detailsFragment 718 .mDetailsBackgroundController 719 .getPlaybackGlue(); 720 return mediaPlayerGlue != null && mediaPlayerGlue != glue1 721 && mediaPlayerGlue.getHost() != null; 722 } 723 }); 724 725 final MediaPlayerGlue glue2 = (MediaPlayerGlue) detailsFragment 726 .mDetailsBackgroundController 727 .getPlaybackGlue(); 728 729 assertTrue(glue1.getHost() == null); 730 assertTrue(glue2.getHost() == playbackGlueHost); 731 } 732 733 @Test 734 public void clearVideo() { 735 final SingleFragmentTestActivity activity = 736 launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility( 737 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 738 final DetailsFragmentWithNoVideo detailsFragment = 739 (DetailsFragmentWithNoVideo) activity.getTestFragment(); 740 741 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 742 @Override 743 public boolean canProceed() { 744 return detailsFragment.getRowsFragment().getVerticalGridView().getChildCount() > 0; 745 } 746 }); 747 final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0); 748 final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView() 749 .getHeight(); 750 751 assertTrue(firstRow.hasFocus()); 752 assertTrue(detailsFragment.isShowingTitle()); 753 assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight); 754 755 SystemClock.sleep(1000); 756 InstrumentationRegistry.getInstrumentation().runOnMainSync( 757 new Runnable() { 758 @Override 759 public void run() { 760 final MediaPlayerGlue glue = new MediaPlayerGlue(activity); 761 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue); 762 glue.setMode(MediaPlayerGlue.REPEAT_ALL); 763 glue.setArtist("A Googleer"); 764 glue.setTitle("Diving with Sharks"); 765 glue.setMediaSource(Uri.parse( 766 "android.resource://android.support.v17.leanback.test/raw/video")); 767 } 768 } 769 ); 770 771 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 772 @Override 773 public boolean canProceed() { 774 return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController 775 .getPlaybackGlue()).isMediaPlaying(); 776 } 777 }); 778 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 779 @Override 780 public boolean canProceed() { 781 return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController); 782 } 783 }); 784 785 // wait a little bit then reset glue 786 SystemClock.sleep(1000); 787 InstrumentationRegistry.getInstrumentation().runOnMainSync( 788 new Runnable() { 789 @Override 790 public void run() { 791 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(null); 792 } 793 } 794 ); 795 // background should fade in upon reset playback 796 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 797 @Override 798 public boolean canProceed() { 799 return 255 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController); 800 } 801 }); 802 } 803 804 public static class DetailsFragmentWithNoItem extends DetailsTestFragment { 805 806 final DetailsFragmentBackgroundController mDetailsBackground = 807 new DetailsFragmentBackgroundController(this); 808 809 public DetailsFragmentWithNoItem() { 810 mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100; 811 } 812 813 @Override 814 public void onCreate(Bundle savedInstanceState) { 815 super.onCreate(savedInstanceState); 816 mDetailsBackground.enableParallax(); 817 } 818 819 @Override 820 public void onStart() { 821 super.onStart(); 822 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 823 android.support.v17.leanback.test.R.drawable.spiderman); 824 mDetailsBackground.setCoverBitmap(bitmap); 825 } 826 827 @Override 828 public void onStop() { 829 mDetailsBackground.setCoverBitmap(null); 830 super.onStop(); 831 } 832 } 833 834 @Test 835 public void noInitialItem() { 836 SingleFragmentTestActivity activity = 837 launchAndWaitActivity(DetailsFragmentWithNoItem.class, new Options().uiVisibility( 838 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 839 final DetailsFragmentWithNoItem detailsFragment = 840 (DetailsFragmentWithNoItem) activity.getTestFragment(); 841 842 final int recyclerViewHeight = detailsFragment.getRowsFragment().getVerticalGridView() 843 .getHeight(); 844 assertTrue(recyclerViewHeight > 0); 845 846 assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController)); 847 Drawable coverDrawable = detailsFragment.mDetailsBackgroundController.getCoverDrawable(); 848 assertEquals(0, coverDrawable.getBounds().top); 849 assertEquals(recyclerViewHeight, coverDrawable.getBounds().bottom); 850 Drawable bottomDrawable = detailsFragment.mDetailsBackgroundController.getBottomDrawable(); 851 assertEquals(recyclerViewHeight, bottomDrawable.getBounds().top); 852 assertEquals(recyclerViewHeight, bottomDrawable.getBounds().bottom); 853 } 854 855 public static class DetailsFragmentSwitchToVideoInOnCreate extends DetailsTestFragment { 856 857 final DetailsFragmentBackgroundController mDetailsBackground = 858 new DetailsFragmentBackgroundController(this); 859 860 public DetailsFragmentSwitchToVideoInOnCreate() { 861 mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100; 862 } 863 864 @Override 865 public void onCreate(Bundle savedInstanceState) { 866 super.onCreate(savedInstanceState); 867 mDetailsBackground.enableParallax(); 868 mDetailsBackground.switchToVideo(); 869 } 870 871 @Override 872 public void onStart() { 873 super.onStart(); 874 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 875 android.support.v17.leanback.test.R.drawable.spiderman); 876 mDetailsBackground.setCoverBitmap(bitmap); 877 } 878 879 @Override 880 public void onStop() { 881 mDetailsBackground.setCoverBitmap(null); 882 super.onStop(); 883 } 884 } 885 886 @Test 887 public void switchToVideoInOnCreate() { 888 final SingleFragmentTestActivity activity = 889 launchAndWaitActivity(DetailsFragmentSwitchToVideoInOnCreate.class, 890 new Options().uiVisibility( 891 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 892 final DetailsFragmentSwitchToVideoInOnCreate detailsFragment = 893 (DetailsFragmentSwitchToVideoInOnCreate) activity.getTestFragment(); 894 895 // the pending enter transition flag should be automatically cleared 896 assertEquals(StateMachine.STATUS_INVOKED, 897 detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus()); 898 assertNull(TransitionHelper.getEnterTransition(activity.getWindow())); 899 assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController)); 900 assertTrue(detailsFragment.getRowsFragment().getView().hasFocus()); 901 //SystemClock.sleep(5000); 902 assertFalse(detailsFragment.isShowingTitle()); 903 904 SystemClock.sleep(1000); 905 assertNull(detailsFragment.mVideoFragment); 906 InstrumentationRegistry.getInstrumentation().runOnMainSync( 907 new Runnable() { 908 @Override 909 public void run() { 910 final MediaPlayerGlue glue = new MediaPlayerGlue(activity); 911 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue); 912 glue.setMode(MediaPlayerGlue.REPEAT_ALL); 913 glue.setArtist("A Googleer"); 914 glue.setTitle("Diving with Sharks"); 915 glue.setMediaSource(Uri.parse( 916 "android.resource://android.support.v17.leanback.test/raw/video")); 917 } 918 } 919 ); 920 // once the video fragment is created it would be immediately assigned focus 921 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 922 @Override 923 public boolean canProceed() { 924 return detailsFragment.mVideoFragment != null 925 && detailsFragment.mVideoFragment.getView() != null 926 && detailsFragment.mVideoFragment.getView().hasFocus(); 927 } 928 }); 929 // wait auto hide play controls done: 930 PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() { 931 @Override 932 public boolean canProceed() { 933 return ((PlaybackFragment) detailsFragment.mVideoFragment).mBgAlpha == 0; 934 } 935 }); 936 937 // switchToRows does nothing if there is no row 938 InstrumentationRegistry.getInstrumentation().runOnMainSync( 939 new Runnable() { 940 @Override 941 public void run() { 942 detailsFragment.mDetailsBackgroundController.switchToRows(); 943 } 944 } 945 ); 946 assertTrue(detailsFragment.mVideoFragment.getView().hasFocus()); 947 948 // create item, it should be layout outside screen 949 InstrumentationRegistry.getInstrumentation().runOnMainSync( 950 new Runnable() { 951 @Override 952 public void run() { 953 detailsFragment.setItem(new PhotoItem("Hello world", 954 "Fake content goes here", 955 android.support.v17.leanback.test.R.drawable.spiderman)); 956 } 957 } 958 ); 959 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 960 @Override 961 public boolean canProceed() { 962 return detailsFragment.getVerticalGridView().getChildCount() > 0 963 && detailsFragment.getVerticalGridView().getChildAt(0).getTop() 964 >= detailsFragment.getVerticalGridView().getHeight(); 965 } 966 }); 967 968 // pressing BACK will return to details row 969 sendKeys(KeyEvent.KEYCODE_BACK); 970 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 971 @Override 972 public boolean canProceed() { 973 return detailsFragment.getVerticalGridView().getChildAt(0).getTop() 974 < (detailsFragment.getVerticalGridView().getHeight() * 0.7f); 975 } 976 }); 977 assertTrue(detailsFragment.getVerticalGridView().getChildAt(0).hasFocus()); 978 } 979 980 @Test 981 public void switchToVideoBackToQuit() { 982 final SingleFragmentTestActivity activity = 983 launchAndWaitActivity(DetailsFragmentSwitchToVideoInOnCreate.class, 984 new Options().uiVisibility( 985 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 986 final DetailsFragmentSwitchToVideoInOnCreate detailsFragment = 987 (DetailsFragmentSwitchToVideoInOnCreate) activity.getTestFragment(); 988 989 // the pending enter transition flag should be automatically cleared 990 assertEquals(StateMachine.STATUS_INVOKED, 991 detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus()); 992 assertNull(TransitionHelper.getEnterTransition(activity.getWindow())); 993 assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController)); 994 assertTrue(detailsFragment.getRowsFragment().getView().hasFocus()); 995 assertFalse(detailsFragment.isShowingTitle()); 996 997 SystemClock.sleep(1000); 998 assertNull(detailsFragment.mVideoFragment); 999 InstrumentationRegistry.getInstrumentation().runOnMainSync( 1000 new Runnable() { 1001 @Override 1002 public void run() { 1003 final MediaPlayerGlue glue = new MediaPlayerGlue(activity); 1004 detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue); 1005 glue.setMode(MediaPlayerGlue.REPEAT_ALL); 1006 glue.setArtist("A Googleer"); 1007 glue.setTitle("Diving with Sharks"); 1008 glue.setMediaSource(Uri.parse( 1009 "android.resource://android.support.v17.leanback.test/raw/video")); 1010 } 1011 } 1012 ); 1013 // once the video fragment is created it would be immediately assigned focus 1014 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 1015 @Override 1016 public boolean canProceed() { 1017 return detailsFragment.mVideoFragment != null 1018 && detailsFragment.mVideoFragment.getView() != null 1019 && detailsFragment.mVideoFragment.getView().hasFocus(); 1020 } 1021 }); 1022 // wait auto hide play controls done: 1023 PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() { 1024 @Override 1025 public boolean canProceed() { 1026 return ((PlaybackFragment) detailsFragment.mVideoFragment).mBgAlpha == 0; 1027 } 1028 }); 1029 1030 // before any details row is presented, pressing BACK will quit the activity 1031 sendKeys(KeyEvent.KEYCODE_BACK); 1032 PollingCheck.waitFor(4000, new PollingCheck.ActivityDestroy(activity)); 1033 } 1034 1035 public static class DetailsFragmentSwitchToVideoAndPrepareEntranceTransition 1036 extends DetailsTestFragment { 1037 1038 final DetailsFragmentBackgroundController mDetailsBackground = 1039 new DetailsFragmentBackgroundController(this); 1040 1041 public DetailsFragmentSwitchToVideoAndPrepareEntranceTransition() { 1042 mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100; 1043 } 1044 1045 @Override 1046 public void onCreate(Bundle savedInstanceState) { 1047 super.onCreate(savedInstanceState); 1048 mDetailsBackground.enableParallax(); 1049 mDetailsBackground.switchToVideo(); 1050 prepareEntranceTransition(); 1051 } 1052 1053 @Override 1054 public void onViewCreated(View view, Bundle savedInstanceState) { 1055 super.onViewCreated(view, savedInstanceState); 1056 } 1057 1058 @Override 1059 public void onStart() { 1060 super.onStart(); 1061 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 1062 android.support.v17.leanback.test.R.drawable.spiderman); 1063 mDetailsBackground.setCoverBitmap(bitmap); 1064 } 1065 1066 @Override 1067 public void onStop() { 1068 mDetailsBackground.setCoverBitmap(null); 1069 super.onStop(); 1070 } 1071 } 1072 1073 @Test 1074 public void switchToVideoInOnCreateAndPrepareEntranceTransition() { 1075 SingleFragmentTestActivity activity = launchAndWaitActivity( 1076 DetailsFragmentSwitchToVideoAndPrepareEntranceTransition.class, 1077 new Options().uiVisibility( 1078 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 1079 final DetailsFragmentSwitchToVideoAndPrepareEntranceTransition detailsFragment = 1080 (DetailsFragmentSwitchToVideoAndPrepareEntranceTransition) 1081 activity.getTestFragment(); 1082 1083 assertEquals(StateMachine.STATUS_INVOKED, 1084 detailsFragment.STATE_ENTRANCE_COMPLETE.getStatus()); 1085 } 1086 1087 public static class DetailsFragmentEntranceTransition 1088 extends DetailsTestFragment { 1089 1090 final DetailsFragmentBackgroundController mDetailsBackground = 1091 new DetailsFragmentBackgroundController(this); 1092 1093 public DetailsFragmentEntranceTransition() { 1094 mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100; 1095 } 1096 1097 @Override 1098 public void onCreate(Bundle savedInstanceState) { 1099 super.onCreate(savedInstanceState); 1100 mDetailsBackground.enableParallax(); 1101 prepareEntranceTransition(); 1102 } 1103 1104 @Override 1105 public void onStart() { 1106 super.onStart(); 1107 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), 1108 android.support.v17.leanback.test.R.drawable.spiderman); 1109 mDetailsBackground.setCoverBitmap(bitmap); 1110 } 1111 1112 @Override 1113 public void onStop() { 1114 mDetailsBackground.setCoverBitmap(null); 1115 super.onStop(); 1116 } 1117 } 1118 1119 @Test 1120 public void entranceTransitionBlocksSwitchToVideo() { 1121 SingleFragmentTestActivity activity = 1122 launchAndWaitActivity(DetailsFragmentEntranceTransition.class, 1123 new Options().uiVisibility( 1124 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0); 1125 final DetailsFragmentEntranceTransition detailsFragment = 1126 (DetailsFragmentEntranceTransition) 1127 activity.getTestFragment(); 1128 1129 if (Build.VERSION.SDK_INT < 21) { 1130 // when enter transition is not supported, mCanUseHost is immmediately true 1131 assertTrue(detailsFragment.mDetailsBackgroundController.mCanUseHost); 1132 } else { 1133 // calling switchToVideo() between prepareEntranceTransition and entrance transition 1134 // finishes will be ignored. 1135 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 1136 @Override 1137 public void run() { 1138 detailsFragment.mDetailsBackgroundController.switchToVideo(); 1139 } 1140 }); 1141 assertFalse(detailsFragment.mDetailsBackgroundController.mCanUseHost); 1142 } 1143 assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController)); 1144 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 1145 @Override 1146 public void run() { 1147 detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here", 1148 android.support.v17.leanback.test.R.drawable.spiderman)); 1149 detailsFragment.startEntranceTransition(); 1150 } 1151 }); 1152 // once Entrance transition is finished, mCanUseHost will be true 1153 // and we can switchToVideo and fade out the background. 1154 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 1155 @Override 1156 public boolean canProceed() { 1157 return detailsFragment.mDetailsBackgroundController.mCanUseHost; 1158 } 1159 }); 1160 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 1161 @Override 1162 public void run() { 1163 detailsFragment.mDetailsBackgroundController.switchToVideo(); 1164 } 1165 }); 1166 PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() { 1167 @Override 1168 public boolean canProceed() { 1169 return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController); 1170 } 1171 }); 1172 } 1173 1174} 1175