DetailsSupportFragmentTest.java revision f87eb1d84dfee2f1be9ea326754829b1eff4967f
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 junit.framework.TestCase.assertFalse;
22
23import static org.junit.Assert.assertEquals;
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.Bundle;
36import android.os.SystemClock;
37import android.support.test.InstrumentationRegistry;
38import android.support.test.filters.LargeTest;
39import android.support.v17.leanback.R;
40import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
41import android.support.v17.leanback.media.MediaPlayerGlue;
42import android.support.v17.leanback.testutils.PollingCheck;
43import android.support.v17.leanback.widget.DetailsParallax;
44import android.support.v17.leanback.widget.DetailsParallaxDrawable;
45import android.support.v17.leanback.widget.ParallaxTarget;
46import android.support.v17.leanback.widget.RecyclerViewParallax;
47import android.support.v17.leanback.widget.VerticalGridView;
48import android.view.KeyEvent;
49import android.view.View;
50
51import org.junit.Test;
52import org.junit.runner.RunWith;
53import org.junit.runners.JUnit4;
54
55/**
56 * Unit tests for {@link DetailsSupportFragment}.
57 */
58@RunWith(JUnit4.class)
59@LargeTest
60public class DetailsSupportFragmentTest extends SingleSupportFragmentTestBase {
61
62    static final int PARALLAX_VERTICAL_OFFSET = -300;
63
64    static int getCoverDrawableAlpha(DetailsSupportFragmentBackgroundController controller) {
65        return ((FitWidthBitmapDrawable) controller.mParallaxDrawable.getCoverDrawable())
66                .getAlpha();
67    }
68
69    public static class DetailsSupportFragmentParallax extends DetailsTestSupportFragment {
70
71        private DetailsParallaxDrawable mParallaxDrawable;
72
73        public DetailsSupportFragmentParallax() {
74            super();
75            mMinVerticalOffset = PARALLAX_VERTICAL_OFFSET;
76        }
77
78        @Override
79        public void onCreate(Bundle savedInstanceState) {
80            super.onCreate(savedInstanceState);
81            Drawable coverDrawable = new FitWidthBitmapDrawable();
82            mParallaxDrawable = new DetailsParallaxDrawable(
83                    getActivity(),
84                    getParallax(),
85                    coverDrawable,
86                    new ParallaxTarget.PropertyValuesHolderTarget(
87                            coverDrawable,
88                            PropertyValuesHolder.ofInt("verticalOffset", 0, mMinVerticalOffset)
89                    )
90            );
91
92            BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity());
93            backgroundManager.attach(getActivity().getWindow());
94            backgroundManager.setDrawable(mParallaxDrawable);
95        }
96
97        @Override
98        public void onStart() {
99            super.onStart();
100            setItem(new PhotoItem("Hello world", "Fake content goes here",
101                    android.support.v17.leanback.test.R.drawable.spiderman));
102        }
103
104        @Override
105        public void onResume() {
106            super.onResume();
107            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
108                    android.support.v17.leanback.test.R.drawable.spiderman);
109            ((FitWidthBitmapDrawable) mParallaxDrawable.getCoverDrawable()).setBitmap(bitmap);
110        }
111
112        DetailsParallaxDrawable getParallaxDrawable() {
113            return mParallaxDrawable;
114        }
115    }
116
117    @Test
118    public void parallaxSetupTest() {
119        launchAndWaitActivity(DetailsSupportFragmentTest.DetailsSupportFragmentParallax.class,
120                new SingleSupportFragmentTestBase.Options().uiVisibility(
121                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
122
123        double delta = 0.0002;
124        DetailsParallax dpm = ((DetailsSupportFragment) mActivity.getTestFragment()).getParallax();
125
126        RecyclerViewParallax.ChildPositionProperty frameTop =
127                (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowTop();
128        assertEquals(0f, frameTop.getFraction(), delta);
129        assertEquals(0f, frameTop.getAdapterPosition(), delta);
130
131
132        RecyclerViewParallax.ChildPositionProperty frameBottom =
133                (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowBottom();
134        assertEquals(1f, frameBottom.getFraction(), delta);
135        assertEquals(0f, frameBottom.getAdapterPosition(), delta);
136    }
137
138    @Test
139    public void parallaxTest() throws Throwable {
140        launchAndWaitActivity(DetailsSupportFragmentParallax.class,
141                new Options().uiVisibility(
142                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
143
144        final DetailsSupportFragmentParallax detailsFragment =
145                (DetailsSupportFragmentParallax) mActivity.getTestFragment();
146        DetailsParallaxDrawable drawable =
147                detailsFragment.getParallaxDrawable();
148        final FitWidthBitmapDrawable bitmapDrawable = (FitWidthBitmapDrawable)
149                drawable.getCoverDrawable();
150
151        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
152            @Override
153            public boolean canProceed() {
154                return detailsFragment.getRowsSupportFragment().getAdapter() != null
155                        && detailsFragment.getRowsSupportFragment().getAdapter().size() > 1;
156            }
157        });
158
159        final VerticalGridView verticalGridView = detailsFragment.getRowsSupportFragment()
160                .getVerticalGridView();
161        final int windowHeight = verticalGridView.getHeight();
162        final int windowWidth = verticalGridView.getWidth();
163        // make sure background manager attached to window is same size as VerticalGridView
164        // i.e. no status bar.
165        assertEquals(windowHeight, mActivity.getWindow().getDecorView().getHeight());
166        assertEquals(windowWidth, mActivity.getWindow().getDecorView().getWidth());
167
168        final View detailsFrame = verticalGridView.findViewById(R.id.details_frame);
169
170        assertEquals(windowWidth, bitmapDrawable.getBounds().width());
171
172        final Rect detailsFrameRect = new Rect();
173        detailsFrameRect.set(0, 0, detailsFrame.getWidth(), detailsFrame.getHeight());
174        verticalGridView.offsetDescendantRectToMyCoords(detailsFrame, detailsFrameRect);
175
176        assertEquals(Math.min(windowHeight, detailsFrameRect.top),
177                bitmapDrawable.getBounds().height());
178        assertEquals(0, bitmapDrawable.getVerticalOffset());
179
180        assertTrue("TitleView is visible", detailsFragment.getView()
181                .findViewById(R.id.browse_title_group).getVisibility() == View.VISIBLE);
182
183        activityTestRule.runOnUiThread(new Runnable() {
184            @Override
185            public void run() {
186                verticalGridView.scrollToPosition(1);
187            }
188        });
189
190        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
191            @Override
192            public boolean canProceed() {
193                return bitmapDrawable.getVerticalOffset() == PARALLAX_VERTICAL_OFFSET
194                        && detailsFragment.getView()
195                        .findViewById(R.id.browse_title_group).getVisibility() != View.VISIBLE;
196            }
197        });
198
199        detailsFrameRect.set(0, 0, detailsFrame.getWidth(), detailsFrame.getHeight());
200        verticalGridView.offsetDescendantRectToMyCoords(detailsFrame, detailsFrameRect);
201
202        assertEquals(0, bitmapDrawable.getBounds().top);
203        assertEquals(Math.max(detailsFrameRect.top, 0), bitmapDrawable.getBounds().bottom);
204        assertEquals(windowWidth, bitmapDrawable.getBounds().width());
205
206        ColorDrawable colorDrawable = (ColorDrawable) (drawable.getChildAt(1).getDrawable());
207        assertEquals(windowWidth, colorDrawable.getBounds().width());
208        assertEquals(detailsFrameRect.bottom, colorDrawable.getBounds().top);
209        assertEquals(windowHeight, colorDrawable.getBounds().bottom);
210    }
211
212    public static class DetailsSupportFragmentWithVideo extends DetailsTestSupportFragment {
213
214        final DetailsSupportFragmentBackgroundController mDetailsBackground =
215                new DetailsSupportFragmentBackgroundController(this);
216        MediaPlayerGlue mGlue;
217
218        public DetailsSupportFragmentWithVideo() {
219            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
220        }
221
222        @Override
223        public void onCreate(Bundle savedInstanceState) {
224            super.onCreate(savedInstanceState);
225            mDetailsBackground.enableParallax();
226            mGlue = new MediaPlayerGlue(getActivity());
227            mDetailsBackground.setupVideoPlayback(mGlue);
228
229            mGlue.setMode(MediaPlayerGlue.REPEAT_ALL);
230            mGlue.setArtist("A Googleer");
231            mGlue.setTitle("Diving with Sharks");
232            mGlue.setMediaSource(
233                    Uri.parse("android.resource://android.support.v17.leanback.test/raw/video"));
234        }
235
236        @Override
237        public void onStart() {
238            super.onStart();
239            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
240                    android.support.v17.leanback.test.R.drawable.spiderman);
241            mDetailsBackground.setCoverBitmap(bitmap);
242        }
243
244        @Override
245        public void onStop() {
246            mDetailsBackground.setCoverBitmap(null);
247            super.onStop();
248        }
249    }
250
251    public static class DetailsSupportFragmentWithVideo1 extends DetailsSupportFragmentWithVideo {
252
253        @Override
254        public void onCreate(Bundle savedInstanceState) {
255            super.onCreate(savedInstanceState);
256            setItem(new PhotoItem("Hello world", "Fake content goes here",
257                    android.support.v17.leanback.test.R.drawable.spiderman));
258        }
259    }
260
261    public static class DetailsSupportFragmentWithVideo2 extends DetailsSupportFragmentWithVideo {
262
263        @Override
264        public void onStart() {
265            super.onStart();
266            setItem(new PhotoItem("Hello world", "Fake content goes here",
267                    android.support.v17.leanback.test.R.drawable.spiderman));
268        }
269    }
270
271    private void navigateBetweenRowsAndVideoUsingRequestFocusInternal(Class cls)
272            throws Throwable {
273        launchAndWaitActivity(cls,
274                new Options().uiVisibility(
275                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
276
277        final DetailsSupportFragmentWithVideo detailsFragment =
278                (DetailsSupportFragmentWithVideo) mActivity.getTestFragment();
279        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
280            @Override
281            public boolean canProceed() {
282                return detailsFragment.mVideoSupportFragment != null
283                        && detailsFragment.mVideoSupportFragment.getView() != null
284                        && detailsFragment.mGlue.isMediaPlaying();
285            }
286        });
287
288        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
289                .getHeight();
290        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
291        final int originalFirstRowTop = firstRow.getTop();
292        assertTrue(firstRow.hasFocus());
293        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
294        assertTrue(detailsFragment.isShowingTitle());
295
296        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
297            @Override
298            public void run() {
299                detailsFragment.mVideoSupportFragment.getView().requestFocus();
300            }
301        });
302        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
303            @Override
304            public boolean canProceed() {
305                return firstRow.getTop() >= screenHeight;
306            }
307        });
308        assertFalse(detailsFragment.isShowingTitle());
309
310        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
311            @Override
312            public void run() {
313                detailsFragment.getRowsSupportFragment().getVerticalGridView().requestFocus();
314            }
315        });
316        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
317            @Override
318            public boolean canProceed() {
319                return firstRow.getTop() == originalFirstRowTop;
320            }
321        });
322        assertTrue(detailsFragment.isShowingTitle());
323    }
324
325    @Test
326    public void navigateBetweenRowsAndVideoUsingRequestFocus1() throws Throwable {
327        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsSupportFragmentWithVideo1.class);
328    }
329
330    @Test
331    public void navigateBetweenRowsAndVideoUsingRequestFocus2() throws Throwable {
332        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsSupportFragmentWithVideo2.class);
333    }
334
335    private void navigateBetweenRowsAndVideoUsingDPADInternal(Class cls) throws Throwable {
336        launchAndWaitActivity(cls,
337                new Options().uiVisibility(
338                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
339
340        final DetailsSupportFragmentWithVideo detailsFragment =
341                (DetailsSupportFragmentWithVideo) mActivity.getTestFragment();
342        // wait video playing
343        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
344            @Override
345            public boolean canProceed() {
346                return detailsFragment.mVideoSupportFragment != null
347                        && detailsFragment.mVideoSupportFragment.getView() != null
348                        && detailsFragment.mGlue.isMediaPlaying();
349            }
350        });
351
352        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
353                .getHeight();
354        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
355        final int originalFirstRowTop = firstRow.getTop();
356        assertTrue(firstRow.hasFocus());
357        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
358        assertTrue(detailsFragment.isShowingTitle());
359
360        // navigate to video
361        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
362        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
363            @Override
364            public boolean canProceed() {
365                return firstRow.getTop() >= screenHeight;
366            }
367        });
368
369        // wait auto hide play controls done:
370        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
371            @Override
372            public boolean canProceed() {
373                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
374            }
375        });
376
377        // navigate to details
378        sendKeys(KeyEvent.KEYCODE_BACK);
379        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
380            @Override
381            public boolean canProceed() {
382                return firstRow.getTop() == originalFirstRowTop;
383            }
384        });
385        assertTrue(detailsFragment.isShowingTitle());
386    }
387
388    @Test
389    public void navigateBetweenRowsAndVideoUsingDPAD1() throws Throwable {
390        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsSupportFragmentWithVideo1.class);
391    }
392
393    @Test
394    public void navigateBetweenRowsAndVideoUsingDPAD2() throws Throwable {
395        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsSupportFragmentWithVideo2.class);
396    }
397
398    public static class EmptyFragmentClass extends Fragment {
399        @Override
400        public void onStart() {
401            super.onStart();
402            getActivity().finish();
403        }
404    }
405
406    private void fragmentOnStartWithVideoInternal(Class cls) throws Throwable {
407        launchAndWaitActivity(cls,
408                new Options().uiVisibility(
409                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
410
411        final DetailsSupportFragmentWithVideo detailsFragment =
412                (DetailsSupportFragmentWithVideo) mActivity.getTestFragment();
413        // wait video playing
414        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
415            @Override
416            public boolean canProceed() {
417                return detailsFragment.mVideoSupportFragment != null
418                        && detailsFragment.mVideoSupportFragment.getView() != null
419                        && detailsFragment.mGlue.isMediaPlaying();
420            }
421        });
422
423        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
424                .getHeight();
425        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
426        final int originalFirstRowTop = firstRow.getTop();
427        assertTrue(firstRow.hasFocus());
428        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
429        assertTrue(detailsFragment.isShowingTitle());
430
431        // navigate to video
432        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
433        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
434            @Override
435            public boolean canProceed() {
436                return firstRow.getTop() >= screenHeight;
437            }
438        });
439
440        // start an empty activity
441        InstrumentationRegistry.getInstrumentation().runOnMainSync(
442                new Runnable() {
443                    @Override
444                    public void run() {
445                        Intent intent = new Intent(mActivity, SingleSupportFragmentTestActivity.class);
446                        intent.putExtra(SingleSupportFragmentTestActivity.EXTRA_FRAGMENT_NAME,
447                                EmptyFragmentClass.class.getName());
448                        mActivity.startActivity(intent);
449                    }
450                }
451        );
452        PollingCheck.waitFor(2000, new PollingCheck.PollingCheckCondition() {
453            @Override
454            public boolean canProceed() {
455                return detailsFragment.isResumed();
456            }
457        });
458        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
459    }
460
461    @Test
462    public void fragmentOnStartWithVideo1() throws Throwable {
463        fragmentOnStartWithVideoInternal(DetailsSupportFragmentWithVideo1.class);
464    }
465
466    @Test
467    public void fragmentOnStartWithVideo2() throws Throwable {
468        fragmentOnStartWithVideoInternal(DetailsSupportFragmentWithVideo2.class);
469    }
470
471    @Test
472    public void navigateBetweenRowsAndTitle() throws Throwable {
473        launchAndWaitActivity(DetailsTestSupportFragment.class, new Options().uiVisibility(
474                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
475        final DetailsTestSupportFragment detailsFragment =
476                (DetailsTestSupportFragment) mActivity.getTestFragment();
477
478        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
479            @Override
480            public void run() {
481                detailsFragment.setOnSearchClickedListener(new View.OnClickListener() {
482                    @Override
483                    public void onClick(View view) {
484                    }
485                });
486                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
487                        android.support.v17.leanback.test.R.drawable.spiderman));
488            }
489        });
490
491        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
492            @Override
493            public boolean canProceed() {
494                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
495            }
496        });
497        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
498        final int originalFirstRowTop = firstRow.getTop();
499        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
500                .getHeight();
501
502        assertTrue(firstRow.hasFocus());
503        assertTrue(detailsFragment.isShowingTitle());
504        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
505
506        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
507        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
508        assertTrue(detailsFragment.isShowingTitle());
509        assertTrue(detailsFragment.getTitleView().hasFocus());
510        assertEquals(originalFirstRowTop, firstRow.getTop());
511
512        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
513        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
514        assertTrue(detailsFragment.isShowingTitle());
515        assertTrue(firstRow.hasFocus());
516        assertEquals(originalFirstRowTop, firstRow.getTop());
517    }
518
519    public static class DetailsSupportFragmentWithNoVideo extends DetailsTestSupportFragment {
520
521        final DetailsSupportFragmentBackgroundController mDetailsBackground =
522                new DetailsSupportFragmentBackgroundController(this);
523
524        public DetailsSupportFragmentWithNoVideo() {
525            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
526        }
527
528        @Override
529        public void onCreate(Bundle savedInstanceState) {
530            super.onCreate(savedInstanceState);
531            mDetailsBackground.enableParallax();
532
533            setItem(new PhotoItem("Hello world", "Fake content goes here",
534                    android.support.v17.leanback.test.R.drawable.spiderman));
535        }
536
537        @Override
538        public void onStart() {
539            super.onStart();
540            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
541                    android.support.v17.leanback.test.R.drawable.spiderman);
542            mDetailsBackground.setCoverBitmap(bitmap);
543        }
544
545        @Override
546        public void onStop() {
547            mDetailsBackground.setCoverBitmap(null);
548            super.onStop();
549        }
550    }
551
552    @Test
553    public void lateSetupVideo() {
554        launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
555                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
556        final DetailsSupportFragmentWithNoVideo detailsFragment =
557                (DetailsSupportFragmentWithNoVideo) mActivity.getTestFragment();
558
559        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
560            @Override
561            public void run() {
562                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
563                        android.support.v17.leanback.test.R.drawable.spiderman));
564            }
565        });
566
567        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
568            @Override
569            public boolean canProceed() {
570                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
571            }
572        });
573        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
574        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
575                .getHeight();
576
577        assertTrue(firstRow.hasFocus());
578        assertTrue(detailsFragment.isShowingTitle());
579        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
580
581        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
582        assertTrue(firstRow.hasFocus());
583
584        SystemClock.sleep(1000);
585        InstrumentationRegistry.getInstrumentation().runOnMainSync(
586                new Runnable() {
587                    @Override
588                    public void run() {
589                        final MediaPlayerGlue glue = new MediaPlayerGlue(mActivity);
590                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
591                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
592                        glue.setArtist("A Googleer");
593                        glue.setTitle("Diving with Sharks");
594                        glue.setMediaSource(Uri.parse(
595                                "android.resource://android.support.v17.leanback.test/raw/video"));
596                    }
597                }
598        );
599
600        // after setup Video Playback the DPAD up will navigate to Video Fragment.
601        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
602        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
603        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
604            @Override
605            public boolean canProceed() {
606                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
607                        .getPlaybackGlue()).isMediaPlaying();
608            }
609        });
610        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
611            @Override
612            public boolean canProceed() {
613                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
614            }
615        });
616
617        // wait a little bit to replace with new Glue
618        SystemClock.sleep(1000);
619        InstrumentationRegistry.getInstrumentation().runOnMainSync(
620                new Runnable() {
621                    @Override
622                    public void run() {
623                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(mActivity);
624                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
625                        glue2.setMode(MediaPlayerGlue.REPEAT_ALL);
626                        glue2.setArtist("A Googleer");
627                        glue2.setTitle("Diving with Sharks");
628                        glue2.setMediaSource(Uri.parse(
629                                "android.resource://android.support.v17.leanback.test/raw/video"));
630                    }
631                }
632        );
633
634        // test switchToRows() and switchToVideo()
635        InstrumentationRegistry.getInstrumentation().runOnMainSync(
636                new Runnable() {
637                    @Override
638                    public void run() {
639                        detailsFragment.mDetailsBackgroundController.switchToRows();
640                    }
641                }
642        );
643        assertTrue(detailsFragment.mRowsSupportFragment.getView().hasFocus());
644        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
645        InstrumentationRegistry.getInstrumentation().runOnMainSync(
646                new Runnable() {
647                    @Override
648                    public void run() {
649                        detailsFragment.mDetailsBackgroundController.switchToVideo();
650                    }
651                }
652        );
653        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
654        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
655    }
656
657    @Test
658    public void clearVideo() {
659        launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
660                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
661        final DetailsSupportFragmentWithNoVideo detailsFragment =
662                (DetailsSupportFragmentWithNoVideo) mActivity.getTestFragment();
663
664        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
665            @Override
666            public void run() {
667                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
668                        android.support.v17.leanback.test.R.drawable.spiderman));
669            }
670        });
671
672        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
673            @Override
674            public boolean canProceed() {
675                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
676            }
677        });
678        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
679        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
680                .getHeight();
681
682        assertTrue(firstRow.hasFocus());
683        assertTrue(detailsFragment.isShowingTitle());
684        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
685
686        SystemClock.sleep(1000);
687        InstrumentationRegistry.getInstrumentation().runOnMainSync(
688                new Runnable() {
689                    @Override
690                    public void run() {
691                        final MediaPlayerGlue glue = new MediaPlayerGlue(mActivity);
692                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
693                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
694                        glue.setArtist("A Googleer");
695                        glue.setTitle("Diving with Sharks");
696                        glue.setMediaSource(Uri.parse(
697                                "android.resource://android.support.v17.leanback.test/raw/video"));
698                    }
699                }
700        );
701
702        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
703            @Override
704            public boolean canProceed() {
705                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
706                        .getPlaybackGlue()).isMediaPlaying();
707            }
708        });
709        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
710            @Override
711            public boolean canProceed() {
712                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
713            }
714        });
715
716        // wait a little bit then clear glue
717        SystemClock.sleep(1000);
718        InstrumentationRegistry.getInstrumentation().runOnMainSync(
719                new Runnable() {
720                    @Override
721                    public void run() {
722                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(null);
723                    }
724                }
725        );
726        // background should fade in upon clear playback
727        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
728            @Override
729            public boolean canProceed() {
730                return 255 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
731            }
732        });
733    }
734
735    public static class DetailsSupportFragmentWithNoItem extends DetailsTestSupportFragment {
736
737        final DetailsSupportFragmentBackgroundController mDetailsBackground =
738                new DetailsSupportFragmentBackgroundController(this);
739
740        public DetailsSupportFragmentWithNoItem() {
741            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
742        }
743
744        @Override
745        public void onCreate(Bundle savedInstanceState) {
746            super.onCreate(savedInstanceState);
747            mDetailsBackground.enableParallax();
748        }
749
750        @Override
751        public void onStart() {
752            super.onStart();
753            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
754                    android.support.v17.leanback.test.R.drawable.spiderman);
755            mDetailsBackground.setCoverBitmap(bitmap);
756        }
757
758        @Override
759        public void onStop() {
760            mDetailsBackground.setCoverBitmap(null);
761            super.onStop();
762        }
763    }
764
765    @Test
766    public void noInitialItem() {
767        launchAndWaitActivity(DetailsSupportFragmentWithNoItem.class, new Options().uiVisibility(
768                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
769        final DetailsSupportFragmentWithNoItem detailsFragment =
770                (DetailsSupportFragmentWithNoItem) mActivity.getTestFragment();
771
772        final int recyclerViewHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
773                .getHeight();
774        assertTrue(recyclerViewHeight > 0);
775
776        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
777        assertEquals(255, detailsFragment.mDetailsBackgroundController.mParallaxDrawable
778                .getAlpha());
779        Drawable coverDrawable = detailsFragment.mDetailsBackgroundController.getCoverDrawable();
780        assertEquals(0, coverDrawable.getBounds().top);
781        assertEquals(recyclerViewHeight, coverDrawable.getBounds().bottom);
782        Drawable bottomDrawable = detailsFragment.mDetailsBackgroundController.getBottomDrawable();
783        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().top);
784        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().bottom);
785    }
786}
787