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