19869eb38607552105baa88a0fcba610461045eb5Dake Gu/*
29869eb38607552105baa88a0fcba610461045eb5Dake Gu * Copyright (C) 2016 The Android Open Source Project
39869eb38607552105baa88a0fcba610461045eb5Dake Gu *
49869eb38607552105baa88a0fcba610461045eb5Dake Gu * Licensed under the Apache License, Version 2.0 (the "License");
59869eb38607552105baa88a0fcba610461045eb5Dake Gu * you may not use this file except in compliance with the License.
69869eb38607552105baa88a0fcba610461045eb5Dake Gu * You may obtain a copy of the License at
79869eb38607552105baa88a0fcba610461045eb5Dake Gu *
89869eb38607552105baa88a0fcba610461045eb5Dake Gu *      http://www.apache.org/licenses/LICENSE-2.0
99869eb38607552105baa88a0fcba610461045eb5Dake Gu *
109869eb38607552105baa88a0fcba610461045eb5Dake Gu * Unless required by applicable law or agreed to in writing, software
119869eb38607552105baa88a0fcba610461045eb5Dake Gu * distributed under the License is distributed on an "AS IS" BASIS,
129869eb38607552105baa88a0fcba610461045eb5Dake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139869eb38607552105baa88a0fcba610461045eb5Dake Gu * See the License for the specific language governing permissions and
149869eb38607552105baa88a0fcba610461045eb5Dake Gu * limitations under the License.
159869eb38607552105baa88a0fcba610461045eb5Dake Gu */
16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.app;
179869eb38607552105baa88a0fcba610461045eb5Dake Gu
189869eb38607552105baa88a0fcba610461045eb5Dake Guimport static org.junit.Assert.assertEquals;
1989097f67f988ebba714a95e10369665280db0c27Dake Guimport static org.junit.Assert.assertFalse;
2089097f67f988ebba714a95e10369665280db0c27Dake Guimport static org.junit.Assert.assertNull;
219869eb38607552105baa88a0fcba610461045eb5Dake Guimport static org.junit.Assert.assertTrue;
229869eb38607552105baa88a0fcba610461045eb5Dake Gu
239869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.animation.PropertyValuesHolder;
246525e063fbbd691a8553f4fc77f3960f93bea34dDake Guimport android.content.Intent;
259869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.graphics.Bitmap;
269869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.graphics.BitmapFactory;
279869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.graphics.Rect;
289869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.graphics.drawable.ColorDrawable;
299869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.graphics.drawable.Drawable;
309869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.net.Uri;
3189097f67f988ebba714a95e10369665280db0c27Dake Guimport android.os.Build;
329869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.os.Bundle;
33f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Guimport android.os.SystemClock;
349869eb38607552105baa88a0fcba610461045eb5Dake Guimport android.support.test.InstrumentationRegistry;
356525e063fbbd691a8553f4fc77f3960f93bea34dDake Guimport android.support.test.filters.LargeTest;
368b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Guimport android.support.test.filters.SdkSuppress;
378619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.KeyEvent;
388619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport android.view.View;
398619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas
408619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.fragment.app.Fragment;
41ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.R;
42ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.graphics.FitWidthBitmapDrawable;
43ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.media.MediaPlayerGlue;
44ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.media.PlaybackGlueHost;
45ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.testutils.PollingCheck;
46ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.transition.TransitionHelper;
47ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.util.StateMachine;
48ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.DetailsParallax;
49ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.DetailsParallaxDrawable;
50ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.ParallaxTarget;
51ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.RecyclerViewParallax;
52ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.widget.VerticalGridView;
539869eb38607552105baa88a0fcba610461045eb5Dake Gu
549869eb38607552105baa88a0fcba610461045eb5Dake Guimport org.junit.Test;
559869eb38607552105baa88a0fcba610461045eb5Dake Guimport org.junit.runner.RunWith;
569869eb38607552105baa88a0fcba610461045eb5Dake Guimport org.junit.runners.JUnit4;
579869eb38607552105baa88a0fcba610461045eb5Dake Gu
589869eb38607552105baa88a0fcba610461045eb5Dake Gu/**
599869eb38607552105baa88a0fcba610461045eb5Dake Gu * Unit tests for {@link DetailsSupportFragment}.
609869eb38607552105baa88a0fcba610461045eb5Dake Gu */
619869eb38607552105baa88a0fcba610461045eb5Dake Gu@RunWith(JUnit4.class)
626525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu@LargeTest
639869eb38607552105baa88a0fcba610461045eb5Dake Gupublic class DetailsSupportFragmentTest extends SingleSupportFragmentTestBase {
649869eb38607552105baa88a0fcba610461045eb5Dake Gu
659869eb38607552105baa88a0fcba610461045eb5Dake Gu    static final int PARALLAX_VERTICAL_OFFSET = -300;
669869eb38607552105baa88a0fcba610461045eb5Dake Gu
67f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    static int getCoverDrawableAlpha(DetailsSupportFragmentBackgroundController controller) {
68f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        return ((FitWidthBitmapDrawable) controller.mParallaxDrawable.getCoverDrawable())
69f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                .getAlpha();
70f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
71f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
729869eb38607552105baa88a0fcba610461045eb5Dake Gu    public static class DetailsSupportFragmentParallax extends DetailsTestSupportFragment {
739869eb38607552105baa88a0fcba610461045eb5Dake Gu
749869eb38607552105baa88a0fcba610461045eb5Dake Gu        private DetailsParallaxDrawable mParallaxDrawable;
759869eb38607552105baa88a0fcba610461045eb5Dake Gu
769869eb38607552105baa88a0fcba610461045eb5Dake Gu        public DetailsSupportFragmentParallax() {
779869eb38607552105baa88a0fcba610461045eb5Dake Gu            super();
789869eb38607552105baa88a0fcba610461045eb5Dake Gu            mMinVerticalOffset = PARALLAX_VERTICAL_OFFSET;
799869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
809869eb38607552105baa88a0fcba610461045eb5Dake Gu
819869eb38607552105baa88a0fcba610461045eb5Dake Gu        @Override
829869eb38607552105baa88a0fcba610461045eb5Dake Gu        public void onCreate(Bundle savedInstanceState) {
839869eb38607552105baa88a0fcba610461045eb5Dake Gu            super.onCreate(savedInstanceState);
849869eb38607552105baa88a0fcba610461045eb5Dake Gu            Drawable coverDrawable = new FitWidthBitmapDrawable();
859869eb38607552105baa88a0fcba610461045eb5Dake Gu            mParallaxDrawable = new DetailsParallaxDrawable(
869869eb38607552105baa88a0fcba610461045eb5Dake Gu                    getActivity(),
879869eb38607552105baa88a0fcba610461045eb5Dake Gu                    getParallax(),
889869eb38607552105baa88a0fcba610461045eb5Dake Gu                    coverDrawable,
899869eb38607552105baa88a0fcba610461045eb5Dake Gu                    new ParallaxTarget.PropertyValuesHolderTarget(
909869eb38607552105baa88a0fcba610461045eb5Dake Gu                            coverDrawable,
919869eb38607552105baa88a0fcba610461045eb5Dake Gu                            PropertyValuesHolder.ofInt("verticalOffset", 0, mMinVerticalOffset)
929869eb38607552105baa88a0fcba610461045eb5Dake Gu                    )
939869eb38607552105baa88a0fcba610461045eb5Dake Gu            );
949869eb38607552105baa88a0fcba610461045eb5Dake Gu
959869eb38607552105baa88a0fcba610461045eb5Dake Gu            BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity());
969869eb38607552105baa88a0fcba610461045eb5Dake Gu            backgroundManager.attach(getActivity().getWindow());
979869eb38607552105baa88a0fcba610461045eb5Dake Gu            backgroundManager.setDrawable(mParallaxDrawable);
989869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
999869eb38607552105baa88a0fcba610461045eb5Dake Gu
1009869eb38607552105baa88a0fcba610461045eb5Dake Gu        @Override
1019869eb38607552105baa88a0fcba610461045eb5Dake Gu        public void onStart() {
1029869eb38607552105baa88a0fcba610461045eb5Dake Gu            super.onStart();
1039869eb38607552105baa88a0fcba610461045eb5Dake Gu            setItem(new PhotoItem("Hello world", "Fake content goes here",
104ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman));
1059869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
1069869eb38607552105baa88a0fcba610461045eb5Dake Gu
1079869eb38607552105baa88a0fcba610461045eb5Dake Gu        @Override
1089869eb38607552105baa88a0fcba610461045eb5Dake Gu        public void onResume() {
1099869eb38607552105baa88a0fcba610461045eb5Dake Gu            super.onResume();
1109869eb38607552105baa88a0fcba610461045eb5Dake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
111ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
1129869eb38607552105baa88a0fcba610461045eb5Dake Gu            ((FitWidthBitmapDrawable) mParallaxDrawable.getCoverDrawable()).setBitmap(bitmap);
1139869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
1149869eb38607552105baa88a0fcba610461045eb5Dake Gu
1159869eb38607552105baa88a0fcba610461045eb5Dake Gu        DetailsParallaxDrawable getParallaxDrawable() {
1169869eb38607552105baa88a0fcba610461045eb5Dake Gu            return mParallaxDrawable;
1179869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
1189869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
1199869eb38607552105baa88a0fcba610461045eb5Dake Gu
1209869eb38607552105baa88a0fcba610461045eb5Dake Gu    @Test
1219869eb38607552105baa88a0fcba610461045eb5Dake Gu    public void parallaxSetupTest() {
122dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity =
123dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentTest.DetailsSupportFragmentParallax.class,
1249869eb38607552105baa88a0fcba610461045eb5Dake Gu                new SingleSupportFragmentTestBase.Options().uiVisibility(
1259869eb38607552105baa88a0fcba610461045eb5Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
1269869eb38607552105baa88a0fcba610461045eb5Dake Gu
1279869eb38607552105baa88a0fcba610461045eb5Dake Gu        double delta = 0.0002;
128dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        DetailsParallax dpm = ((DetailsSupportFragment) activity.getTestFragment()).getParallax();
1299869eb38607552105baa88a0fcba610461045eb5Dake Gu
1309869eb38607552105baa88a0fcba610461045eb5Dake Gu        RecyclerViewParallax.ChildPositionProperty frameTop =
1319869eb38607552105baa88a0fcba610461045eb5Dake Gu                (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowTop();
1329869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(0f, frameTop.getFraction(), delta);
1339869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(0f, frameTop.getAdapterPosition(), delta);
1349869eb38607552105baa88a0fcba610461045eb5Dake Gu
1359869eb38607552105baa88a0fcba610461045eb5Dake Gu
1369869eb38607552105baa88a0fcba610461045eb5Dake Gu        RecyclerViewParallax.ChildPositionProperty frameBottom =
1379869eb38607552105baa88a0fcba610461045eb5Dake Gu                (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowBottom();
1389869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(1f, frameBottom.getFraction(), delta);
1399869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(0f, frameBottom.getAdapterPosition(), delta);
1409869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
1419869eb38607552105baa88a0fcba610461045eb5Dake Gu
1429869eb38607552105baa88a0fcba610461045eb5Dake Gu    @Test
1439869eb38607552105baa88a0fcba610461045eb5Dake Gu    public void parallaxTest() throws Throwable {
144dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(DetailsSupportFragmentParallax.class,
1459869eb38607552105baa88a0fcba610461045eb5Dake Gu                new Options().uiVisibility(
1469869eb38607552105baa88a0fcba610461045eb5Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
1479869eb38607552105baa88a0fcba610461045eb5Dake Gu
1489869eb38607552105baa88a0fcba610461045eb5Dake Gu        final DetailsSupportFragmentParallax detailsFragment =
149dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentParallax) activity.getTestFragment();
1509869eb38607552105baa88a0fcba610461045eb5Dake Gu        DetailsParallaxDrawable drawable =
1519869eb38607552105baa88a0fcba610461045eb5Dake Gu                detailsFragment.getParallaxDrawable();
1529869eb38607552105baa88a0fcba610461045eb5Dake Gu        final FitWidthBitmapDrawable bitmapDrawable = (FitWidthBitmapDrawable)
1539869eb38607552105baa88a0fcba610461045eb5Dake Gu                drawable.getCoverDrawable();
1549869eb38607552105baa88a0fcba610461045eb5Dake Gu
1559869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
1569869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
1579869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
1589869eb38607552105baa88a0fcba610461045eb5Dake Gu                return detailsFragment.getRowsSupportFragment().getAdapter() != null
1599869eb38607552105baa88a0fcba610461045eb5Dake Gu                        && detailsFragment.getRowsSupportFragment().getAdapter().size() > 1;
1609869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
1619869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
1629869eb38607552105baa88a0fcba610461045eb5Dake Gu
1639869eb38607552105baa88a0fcba610461045eb5Dake Gu        final VerticalGridView verticalGridView = detailsFragment.getRowsSupportFragment()
1649869eb38607552105baa88a0fcba610461045eb5Dake Gu                .getVerticalGridView();
1659869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int windowHeight = verticalGridView.getHeight();
1669869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int windowWidth = verticalGridView.getWidth();
1679869eb38607552105baa88a0fcba610461045eb5Dake Gu        // make sure background manager attached to window is same size as VerticalGridView
1689869eb38607552105baa88a0fcba610461045eb5Dake Gu        // i.e. no status bar.
169dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        assertEquals(windowHeight, activity.getWindow().getDecorView().getHeight());
170dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        assertEquals(windowWidth, activity.getWindow().getDecorView().getWidth());
1719869eb38607552105baa88a0fcba610461045eb5Dake Gu
1729869eb38607552105baa88a0fcba610461045eb5Dake Gu        final View detailsFrame = verticalGridView.findViewById(R.id.details_frame);
1739869eb38607552105baa88a0fcba610461045eb5Dake Gu
1749869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(windowWidth, bitmapDrawable.getBounds().width());
1759869eb38607552105baa88a0fcba610461045eb5Dake Gu
1769869eb38607552105baa88a0fcba610461045eb5Dake Gu        final Rect detailsFrameRect = new Rect();
1779869eb38607552105baa88a0fcba610461045eb5Dake Gu        detailsFrameRect.set(0, 0, detailsFrame.getWidth(), detailsFrame.getHeight());
1789869eb38607552105baa88a0fcba610461045eb5Dake Gu        verticalGridView.offsetDescendantRectToMyCoords(detailsFrame, detailsFrameRect);
1799869eb38607552105baa88a0fcba610461045eb5Dake Gu
1809869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(Math.min(windowHeight, detailsFrameRect.top),
1819869eb38607552105baa88a0fcba610461045eb5Dake Gu                bitmapDrawable.getBounds().height());
1829869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(0, bitmapDrawable.getVerticalOffset());
1839869eb38607552105baa88a0fcba610461045eb5Dake Gu
1849869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue("TitleView is visible", detailsFragment.getView()
1859869eb38607552105baa88a0fcba610461045eb5Dake Gu                .findViewById(R.id.browse_title_group).getVisibility() == View.VISIBLE);
1869869eb38607552105baa88a0fcba610461045eb5Dake Gu
1879869eb38607552105baa88a0fcba610461045eb5Dake Gu        activityTestRule.runOnUiThread(new Runnable() {
1889869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
1899869eb38607552105baa88a0fcba610461045eb5Dake Gu            public void run() {
1909869eb38607552105baa88a0fcba610461045eb5Dake Gu                verticalGridView.scrollToPosition(1);
1919869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
1929869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
1939869eb38607552105baa88a0fcba610461045eb5Dake Gu
1949869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
1959869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
1969869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
1979869eb38607552105baa88a0fcba610461045eb5Dake Gu                return bitmapDrawable.getVerticalOffset() == PARALLAX_VERTICAL_OFFSET
1989869eb38607552105baa88a0fcba610461045eb5Dake Gu                        && detailsFragment.getView()
1999869eb38607552105baa88a0fcba610461045eb5Dake Gu                        .findViewById(R.id.browse_title_group).getVisibility() != View.VISIBLE;
2009869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
2019869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
2029869eb38607552105baa88a0fcba610461045eb5Dake Gu
2039869eb38607552105baa88a0fcba610461045eb5Dake Gu        detailsFrameRect.set(0, 0, detailsFrame.getWidth(), detailsFrame.getHeight());
2049869eb38607552105baa88a0fcba610461045eb5Dake Gu        verticalGridView.offsetDescendantRectToMyCoords(detailsFrame, detailsFrameRect);
2059869eb38607552105baa88a0fcba610461045eb5Dake Gu
2069869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(0, bitmapDrawable.getBounds().top);
2079869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(Math.max(detailsFrameRect.top, 0), bitmapDrawable.getBounds().bottom);
2089869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(windowWidth, bitmapDrawable.getBounds().width());
2099869eb38607552105baa88a0fcba610461045eb5Dake Gu
2109869eb38607552105baa88a0fcba610461045eb5Dake Gu        ColorDrawable colorDrawable = (ColorDrawable) (drawable.getChildAt(1).getDrawable());
2119869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(windowWidth, colorDrawable.getBounds().width());
2129869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(detailsFrameRect.bottom, colorDrawable.getBounds().top);
2139869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(windowHeight, colorDrawable.getBounds().bottom);
2149869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
2159869eb38607552105baa88a0fcba610461045eb5Dake Gu
2169869eb38607552105baa88a0fcba610461045eb5Dake Gu    public static class DetailsSupportFragmentWithVideo extends DetailsTestSupportFragment {
2179869eb38607552105baa88a0fcba610461045eb5Dake Gu
2189869eb38607552105baa88a0fcba610461045eb5Dake Gu        final DetailsSupportFragmentBackgroundController mDetailsBackground =
2199869eb38607552105baa88a0fcba610461045eb5Dake Gu                new DetailsSupportFragmentBackgroundController(this);
2209869eb38607552105baa88a0fcba610461045eb5Dake Gu        MediaPlayerGlue mGlue;
2219869eb38607552105baa88a0fcba610461045eb5Dake Gu
2229869eb38607552105baa88a0fcba610461045eb5Dake Gu        public DetailsSupportFragmentWithVideo() {
2239869eb38607552105baa88a0fcba610461045eb5Dake Gu            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
2249869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
2259869eb38607552105baa88a0fcba610461045eb5Dake Gu
2269869eb38607552105baa88a0fcba610461045eb5Dake Gu        @Override
2279869eb38607552105baa88a0fcba610461045eb5Dake Gu        public void onCreate(Bundle savedInstanceState) {
2289869eb38607552105baa88a0fcba610461045eb5Dake Gu            super.onCreate(savedInstanceState);
2299869eb38607552105baa88a0fcba610461045eb5Dake Gu            mDetailsBackground.enableParallax();
2309869eb38607552105baa88a0fcba610461045eb5Dake Gu            mGlue = new MediaPlayerGlue(getActivity());
2319869eb38607552105baa88a0fcba610461045eb5Dake Gu            mDetailsBackground.setupVideoPlayback(mGlue);
2329869eb38607552105baa88a0fcba610461045eb5Dake Gu
2339869eb38607552105baa88a0fcba610461045eb5Dake Gu            mGlue.setMode(MediaPlayerGlue.REPEAT_ALL);
2349869eb38607552105baa88a0fcba610461045eb5Dake Gu            mGlue.setArtist("A Googleer");
2359869eb38607552105baa88a0fcba610461045eb5Dake Gu            mGlue.setTitle("Diving with Sharks");
2369869eb38607552105baa88a0fcba610461045eb5Dake Gu            mGlue.setMediaSource(
237ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    Uri.parse("android.resource://androidx.leanback.test/raw/video"));
2389869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
2399869eb38607552105baa88a0fcba610461045eb5Dake Gu
2409869eb38607552105baa88a0fcba610461045eb5Dake Gu        @Override
2419869eb38607552105baa88a0fcba610461045eb5Dake Gu        public void onStart() {
2429869eb38607552105baa88a0fcba610461045eb5Dake Gu            super.onStart();
2439869eb38607552105baa88a0fcba610461045eb5Dake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
244ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
2459869eb38607552105baa88a0fcba610461045eb5Dake Gu            mDetailsBackground.setCoverBitmap(bitmap);
2469869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
2479869eb38607552105baa88a0fcba610461045eb5Dake Gu
2489869eb38607552105baa88a0fcba610461045eb5Dake Gu        @Override
2499869eb38607552105baa88a0fcba610461045eb5Dake Gu        public void onStop() {
2509869eb38607552105baa88a0fcba610461045eb5Dake Gu            mDetailsBackground.setCoverBitmap(null);
2519869eb38607552105baa88a0fcba610461045eb5Dake Gu            super.onStop();
2529869eb38607552105baa88a0fcba610461045eb5Dake Gu        }
2539869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
2549869eb38607552105baa88a0fcba610461045eb5Dake Gu
2556525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public static class DetailsSupportFragmentWithVideo1 extends DetailsSupportFragmentWithVideo {
2566525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
2576525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        @Override
2586525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        public void onCreate(Bundle savedInstanceState) {
2596525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            super.onCreate(savedInstanceState);
2606525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            setItem(new PhotoItem("Hello world", "Fake content goes here",
261ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman));
2626525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        }
2636525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
2646525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
2656525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public static class DetailsSupportFragmentWithVideo2 extends DetailsSupportFragmentWithVideo {
2666525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
2676525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        @Override
2686525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        public void onStart() {
2696525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            super.onStart();
2706525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            setItem(new PhotoItem("Hello world", "Fake content goes here",
271ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman));
2726525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        }
2736525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
2746525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
2756525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    private void navigateBetweenRowsAndVideoUsingRequestFocusInternal(Class cls)
2766525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            throws Throwable {
277dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(cls,
2789869eb38607552105baa88a0fcba610461045eb5Dake Gu                new Options().uiVisibility(
2799869eb38607552105baa88a0fcba610461045eb5Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
2809869eb38607552105baa88a0fcba610461045eb5Dake Gu
2819869eb38607552105baa88a0fcba610461045eb5Dake Gu        final DetailsSupportFragmentWithVideo detailsFragment =
282dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentWithVideo) activity.getTestFragment();
2839869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
2849869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
2859869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
2869869eb38607552105baa88a0fcba610461045eb5Dake Gu                return detailsFragment.mVideoSupportFragment != null
2879869eb38607552105baa88a0fcba610461045eb5Dake Gu                        && detailsFragment.mVideoSupportFragment.getView() != null
2889869eb38607552105baa88a0fcba610461045eb5Dake Gu                        && detailsFragment.mGlue.isMediaPlaying();
2899869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
2909869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
2919869eb38607552105baa88a0fcba610461045eb5Dake Gu
2929869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
2939869eb38607552105baa88a0fcba610461045eb5Dake Gu                .getHeight();
2949869eb38607552105baa88a0fcba610461045eb5Dake Gu        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
2959869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int originalFirstRowTop = firstRow.getTop();
2969869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(firstRow.hasFocus());
2976525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
2989869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
2999869eb38607552105baa88a0fcba610461045eb5Dake Gu
3009869eb38607552105baa88a0fcba610461045eb5Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
3019869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3029869eb38607552105baa88a0fcba610461045eb5Dake Gu            public void run() {
3039869eb38607552105baa88a0fcba610461045eb5Dake Gu                detailsFragment.mVideoSupportFragment.getView().requestFocus();
3049869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3059869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3069869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
3079869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3089869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
3099869eb38607552105baa88a0fcba610461045eb5Dake Gu                return firstRow.getTop() >= screenHeight;
3109869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3119869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3129869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertFalse(detailsFragment.isShowingTitle());
3139869eb38607552105baa88a0fcba610461045eb5Dake Gu
3149869eb38607552105baa88a0fcba610461045eb5Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
3159869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3169869eb38607552105baa88a0fcba610461045eb5Dake Gu            public void run() {
3179869eb38607552105baa88a0fcba610461045eb5Dake Gu                detailsFragment.getRowsSupportFragment().getVerticalGridView().requestFocus();
3189869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3199869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3209869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
3219869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3229869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
3239869eb38607552105baa88a0fcba610461045eb5Dake Gu                return firstRow.getTop() == originalFirstRowTop;
3249869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3259869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3269869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
3279869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
3289869eb38607552105baa88a0fcba610461045eb5Dake Gu
3299869eb38607552105baa88a0fcba610461045eb5Dake Gu    @Test
3306525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public void navigateBetweenRowsAndVideoUsingRequestFocus1() throws Throwable {
3316525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsSupportFragmentWithVideo1.class);
3326525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
3336525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
3346525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    @Test
3356525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public void navigateBetweenRowsAndVideoUsingRequestFocus2() throws Throwable {
3366525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsSupportFragmentWithVideo2.class);
3376525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
3386525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
3396525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    private void navigateBetweenRowsAndVideoUsingDPADInternal(Class cls) throws Throwable {
340dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(cls,
3419869eb38607552105baa88a0fcba610461045eb5Dake Gu                new Options().uiVisibility(
3429869eb38607552105baa88a0fcba610461045eb5Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
3439869eb38607552105baa88a0fcba610461045eb5Dake Gu
3449869eb38607552105baa88a0fcba610461045eb5Dake Gu        final DetailsSupportFragmentWithVideo detailsFragment =
345dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentWithVideo) activity.getTestFragment();
3466525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // wait video playing
3479869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
3489869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3499869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
3509869eb38607552105baa88a0fcba610461045eb5Dake Gu                return detailsFragment.mVideoSupportFragment != null
3519869eb38607552105baa88a0fcba610461045eb5Dake Gu                        && detailsFragment.mVideoSupportFragment.getView() != null
3529869eb38607552105baa88a0fcba610461045eb5Dake Gu                        && detailsFragment.mGlue.isMediaPlaying();
3539869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3549869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3559869eb38607552105baa88a0fcba610461045eb5Dake Gu
3569869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
3579869eb38607552105baa88a0fcba610461045eb5Dake Gu                .getHeight();
3589869eb38607552105baa88a0fcba610461045eb5Dake Gu        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
3599869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int originalFirstRowTop = firstRow.getTop();
3609869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(firstRow.hasFocus());
3616525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
3629869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
3639869eb38607552105baa88a0fcba610461045eb5Dake Gu
3646525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // navigate to video
3659869eb38607552105baa88a0fcba610461045eb5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
3669869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
3679869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3689869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
3699869eb38607552105baa88a0fcba610461045eb5Dake Gu                return firstRow.getTop() >= screenHeight;
3709869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3719869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3729869eb38607552105baa88a0fcba610461045eb5Dake Gu
3736525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // wait auto hide play controls done:
3746525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
3756525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            @Override
3766525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            public boolean canProceed() {
3776525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
3786525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            }
3796525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        });
3806525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
3816525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // navigate to details
3826525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        sendKeys(KeyEvent.KEYCODE_BACK);
3839869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
3849869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
3859869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
3869869eb38607552105baa88a0fcba610461045eb5Dake Gu                return firstRow.getTop() == originalFirstRowTop;
3879869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
3889869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
3899869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
3909869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
3919869eb38607552105baa88a0fcba610461045eb5Dake Gu
3929869eb38607552105baa88a0fcba610461045eb5Dake Gu    @Test
3936525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public void navigateBetweenRowsAndVideoUsingDPAD1() throws Throwable {
3946525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsSupportFragmentWithVideo1.class);
3956525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
3966525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
3976525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    @Test
3986525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public void navigateBetweenRowsAndVideoUsingDPAD2() throws Throwable {
3996525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsSupportFragmentWithVideo2.class);
4006525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
4016525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
402f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    public static class EmptyFragmentClass extends Fragment {
403f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
404f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onStart() {
405f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onStart();
406f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            getActivity().finish();
407f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
408f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
409f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
4106525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    private void fragmentOnStartWithVideoInternal(Class cls) throws Throwable {
411dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        final SingleSupportFragmentTestActivity activity = launchAndWaitActivity(cls,
4126525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                new Options().uiVisibility(
4136525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
4146525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4156525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        final DetailsSupportFragmentWithVideo detailsFragment =
416dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentWithVideo) activity.getTestFragment();
4176525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // wait video playing
4186525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
4196525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            @Override
4206525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            public boolean canProceed() {
4216525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                return detailsFragment.mVideoSupportFragment != null
4226525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                        && detailsFragment.mVideoSupportFragment.getView() != null
4236525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                        && detailsFragment.mGlue.isMediaPlaying();
4246525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            }
4256525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        });
4266525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4276525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
4286525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                .getHeight();
4296525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
4306525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        final int originalFirstRowTop = firstRow.getTop();
4316525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(firstRow.hasFocus());
4326525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
4336525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(detailsFragment.isShowingTitle());
4346525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4356525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // navigate to video
4366525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
4376525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
4386525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            @Override
4396525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            public boolean canProceed() {
4406525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                return firstRow.getTop() >= screenHeight;
4416525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            }
4426525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        });
4436525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4446525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        // start an empty activity
4456525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
4466525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                new Runnable() {
4476525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                    @Override
4486525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                    public void run() {
449dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        Intent intent = new Intent(activity, SingleSupportFragmentTestActivity.class);
4506525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                        intent.putExtra(SingleSupportFragmentTestActivity.EXTRA_FRAGMENT_NAME,
451f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                                EmptyFragmentClass.class.getName());
452dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        activity.startActivity(intent);
4536525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                    }
4546525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                }
4556525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        );
4566525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        PollingCheck.waitFor(2000, new PollingCheck.PollingCheckCondition() {
4576525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            @Override
4586525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            public boolean canProceed() {
4596525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu                return detailsFragment.isResumed();
4606525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu            }
4616525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        });
4626525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
4636525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
4646525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4656525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    @Test
4666525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public void fragmentOnStartWithVideo1() throws Throwable {
4676525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        fragmentOnStartWithVideoInternal(DetailsSupportFragmentWithVideo1.class);
4686525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
4696525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4706525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    @Test
4716525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    public void fragmentOnStartWithVideo2() throws Throwable {
4726525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        fragmentOnStartWithVideoInternal(DetailsSupportFragmentWithVideo2.class);
4736525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    }
4746525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu
4756525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu    @Test
4769869eb38607552105baa88a0fcba610461045eb5Dake Gu    public void navigateBetweenRowsAndTitle() throws Throwable {
477dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity =
478dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsTestSupportFragment.class, new Options().uiVisibility(
4799869eb38607552105baa88a0fcba610461045eb5Dake Gu                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
4809869eb38607552105baa88a0fcba610461045eb5Dake Gu        final DetailsTestSupportFragment detailsFragment =
481dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsTestSupportFragment) activity.getTestFragment();
4829869eb38607552105baa88a0fcba610461045eb5Dake Gu
4839869eb38607552105baa88a0fcba610461045eb5Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
4849869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
4859869eb38607552105baa88a0fcba610461045eb5Dake Gu            public void run() {
4869869eb38607552105baa88a0fcba610461045eb5Dake Gu                detailsFragment.setOnSearchClickedListener(new View.OnClickListener() {
4879869eb38607552105baa88a0fcba610461045eb5Dake Gu                    @Override
4889869eb38607552105baa88a0fcba610461045eb5Dake Gu                    public void onClick(View view) {
4899869eb38607552105baa88a0fcba610461045eb5Dake Gu                    }
4909869eb38607552105baa88a0fcba610461045eb5Dake Gu                });
4919869eb38607552105baa88a0fcba610461045eb5Dake Gu                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
492ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                        androidx.leanback.test.R.drawable.spiderman));
4939869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
4949869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
4959869eb38607552105baa88a0fcba610461045eb5Dake Gu
4969869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
4979869eb38607552105baa88a0fcba610461045eb5Dake Gu            @Override
4989869eb38607552105baa88a0fcba610461045eb5Dake Gu            public boolean canProceed() {
4999869eb38607552105baa88a0fcba610461045eb5Dake Gu                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
5009869eb38607552105baa88a0fcba610461045eb5Dake Gu            }
5019869eb38607552105baa88a0fcba610461045eb5Dake Gu        });
5029869eb38607552105baa88a0fcba610461045eb5Dake Gu        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
5039869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int originalFirstRowTop = firstRow.getTop();
5049869eb38607552105baa88a0fcba610461045eb5Dake Gu        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
5059869eb38607552105baa88a0fcba610461045eb5Dake Gu                .getHeight();
5069869eb38607552105baa88a0fcba610461045eb5Dake Gu
5079869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(firstRow.hasFocus());
5089869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
5096525e063fbbd691a8553f4fc77f3960f93bea34dDake Gu        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
5109869eb38607552105baa88a0fcba610461045eb5Dake Gu
5119869eb38607552105baa88a0fcba610461045eb5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
5129869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
5139869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
5149869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.getTitleView().hasFocus());
5159869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(originalFirstRowTop, firstRow.getTop());
5169869eb38607552105baa88a0fcba610461045eb5Dake Gu
5179869eb38607552105baa88a0fcba610461045eb5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
5189869eb38607552105baa88a0fcba610461045eb5Dake Gu        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
5199869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(detailsFragment.isShowingTitle());
5209869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertTrue(firstRow.hasFocus());
5219869eb38607552105baa88a0fcba610461045eb5Dake Gu        assertEquals(originalFirstRowTop, firstRow.getTop());
5229869eb38607552105baa88a0fcba610461045eb5Dake Gu    }
523f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
524f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    public static class DetailsSupportFragmentWithNoVideo extends DetailsTestSupportFragment {
525f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
526f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final DetailsSupportFragmentBackgroundController mDetailsBackground =
527f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new DetailsSupportFragmentBackgroundController(this);
528f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
529f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public DetailsSupportFragmentWithNoVideo() {
530f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
531f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
532f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
533f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
534f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onCreate(Bundle savedInstanceState) {
535f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onCreate(savedInstanceState);
536f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mDetailsBackground.enableParallax();
537f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
538f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            setItem(new PhotoItem("Hello world", "Fake content goes here",
539ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman));
540f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
541f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
542f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
543f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onStart() {
544f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onStart();
545f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
546ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
547f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mDetailsBackground.setCoverBitmap(bitmap);
548f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
549f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
550f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
551f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onStop() {
552f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mDetailsBackground.setCoverBitmap(null);
553f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onStop();
554f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
555f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
556f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
557f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    @Test
558f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    public void lateSetupVideo() {
559dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        final SingleSupportFragmentTestActivity activity =
560dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
561f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
562f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final DetailsSupportFragmentWithNoVideo detailsFragment =
563dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentWithNoVideo) activity.getTestFragment();
564f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
565f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
566f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
567f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
568f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
569f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
570f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
571f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
572f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
573f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                .getHeight();
574f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
575f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(firstRow.hasFocus());
576f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(detailsFragment.isShowingTitle());
577f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
578f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
579f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
580f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(firstRow.hasFocus());
581f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
582f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        SystemClock.sleep(1000);
583f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
584f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new Runnable() {
585f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    @Override
586f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    public void run() {
587dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
588f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
589f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
590f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setArtist("A Googleer");
591f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setTitle("Diving with Sharks");
592f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setMediaSource(Uri.parse(
593ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
594f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    }
595f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                }
596f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        );
597f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
598f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        // after setup Video Playback the DPAD up will navigate to Video Fragment.
599a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
600a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu                @Override
601a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu                    public boolean canProceed() {
602a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu                        return detailsFragment.mVideoSupportFragment != null
603a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu                                && detailsFragment.mVideoSupportFragment.getView() != null;
604a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu                }
605a43689a5797d22853aad74c4fa23539b640a8f3fDake Gu        });
606f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
607f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
608f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
609f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
610f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
611f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
612f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        .getPlaybackGlue()).isMediaPlaying();
613f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
614f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
615f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
616f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
617f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
618f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
619f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
620f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
621f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
622f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        // wait a little bit to replace with new Glue
623f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        SystemClock.sleep(1000);
624f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
625f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new Runnable() {
626f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    @Override
627f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    public void run() {
628dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity);
629f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
630f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue2.setMode(MediaPlayerGlue.REPEAT_ALL);
631f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue2.setArtist("A Googleer");
632f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue2.setTitle("Diving with Sharks");
633f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue2.setMediaSource(Uri.parse(
634ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
635f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    }
636f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                }
637f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        );
638f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
639f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        // test switchToRows() and switchToVideo()
640f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
641f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new Runnable() {
642f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    @Override
643f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    public void run() {
644f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        detailsFragment.mDetailsBackgroundController.switchToRows();
645f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    }
646f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                }
647f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        );
648f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(detailsFragment.mRowsSupportFragment.getView().hasFocus());
649f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
650f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
651f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new Runnable() {
652f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    @Override
653f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    public void run() {
654f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        detailsFragment.mDetailsBackgroundController.switchToVideo();
655f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    }
656f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                }
657f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        );
658f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
659f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
660f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
661f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
662f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    @Test
663c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin    public void sharedGlueHost() {
664c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        final SingleSupportFragmentTestActivity activity =
665c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
666c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
667c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        final DetailsSupportFragmentWithNoVideo detailsFragment =
668c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                (DetailsSupportFragmentWithNoVideo) activity.getTestFragment();
669c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
670c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        SystemClock.sleep(1000);
671c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        InstrumentationRegistry.getInstrumentation().runOnMainSync(
672c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                new Runnable() {
673c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                    @Override
674c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                    public void run() {
675c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        final MediaPlayerGlue glue1 = new MediaPlayerGlue(activity);
676c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue1);
677c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        glue1.setArtist("A Googleer");
678c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        glue1.setTitle("Diving with Sharks");
679c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        glue1.setMediaSource(Uri.parse(
680ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
681c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                    }
682c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                }
683c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        );
684c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
685c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        // after setup Video Playback the DPAD up will navigate to Video Fragment.
686c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
687c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin            @Override
688c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin            public boolean canProceed() {
689c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                return detailsFragment.mVideoSupportFragment != null
690c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        && detailsFragment.mVideoSupportFragment.getView() != null;
691c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin            }
692c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        });
693c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
694c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        final MediaPlayerGlue glue1 = (MediaPlayerGlue) detailsFragment
695c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                .mDetailsBackgroundController
696c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                .getPlaybackGlue();
697c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        PlaybackGlueHost playbackGlueHost = glue1.getHost();
698c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
699c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        // wait a little bit to replace with new Glue
700c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        SystemClock.sleep(1000);
701c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        InstrumentationRegistry.getInstrumentation().runOnMainSync(
702c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                new Runnable() {
703c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                    @Override
704c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                    public void run() {
705c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity);
706c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
707c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        glue2.setArtist("A Googleer");
708c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        glue2.setTitle("Diving with Sharks");
709c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        glue2.setMediaSource(Uri.parse(
710ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
711c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                    }
712c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                }
713c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        );
714c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
715c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        // wait for new glue to get its glue host
716c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
717c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin            @Override
718c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin            public boolean canProceed() {
719c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                MediaPlayerGlue mediaPlayerGlue = (MediaPlayerGlue) detailsFragment
720c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        .mDetailsBackgroundController
721c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        .getPlaybackGlue();
722c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                return mediaPlayerGlue != null && mediaPlayerGlue != glue1
723c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                        && mediaPlayerGlue.getHost() != null;
724c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin            }
725c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        });
726c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
727c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        final MediaPlayerGlue glue2 = (MediaPlayerGlue) detailsFragment
728c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                .mDetailsBackgroundController
729c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin                .getPlaybackGlue();
730c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
731c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        assertTrue(glue1.getHost() == null);
732c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin        assertTrue(glue2.getHost() == playbackGlueHost);
733c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin    }
734c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin
735c65ceae1251b35fbf4aa72df7b5d20e764bed9d2Wei-Hsin    @Test
736f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    public void clearVideo() {
737dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        final SingleSupportFragmentTestActivity activity =
738dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
739f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
740f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final DetailsSupportFragmentWithNoVideo detailsFragment =
741dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentWithNoVideo) activity.getTestFragment();
742f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
743f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
744f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
745f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
746f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
747f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
748f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
749f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
750f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
751f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                .getHeight();
752f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
753f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(firstRow.hasFocus());
754f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(detailsFragment.isShowingTitle());
755f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
756f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
757f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        SystemClock.sleep(1000);
758f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
759f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new Runnable() {
760f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    @Override
761f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    public void run() {
762dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
763f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
764f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
765f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setArtist("A Googleer");
766f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setTitle("Diving with Sharks");
767f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        glue.setMediaSource(Uri.parse(
768ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
769f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    }
770f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                }
771f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        );
772f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
773f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
774f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
775f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
776f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
777f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        .getPlaybackGlue()).isMediaPlaying();
778f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
779f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
780f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
781f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
782f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
783f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
784f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
785f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
786f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
7873bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu        // wait a little bit then reset glue
788f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        SystemClock.sleep(1000);
789f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
790f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new Runnable() {
791f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    @Override
792f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    public void run() {
793f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(null);
794f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                    }
795f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                }
796f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        );
7973bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu        // background should fade in upon reset playback
798f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
799f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            @Override
800f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            public boolean canProceed() {
801f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                return 255 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
802f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            }
803f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        });
804f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
805f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
806f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    public static class DetailsSupportFragmentWithNoItem extends DetailsTestSupportFragment {
807f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
808f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final DetailsSupportFragmentBackgroundController mDetailsBackground =
809f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                new DetailsSupportFragmentBackgroundController(this);
810f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
811f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public DetailsSupportFragmentWithNoItem() {
812f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
813f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
814f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
815f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
816f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onCreate(Bundle savedInstanceState) {
817f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onCreate(savedInstanceState);
818f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mDetailsBackground.enableParallax();
819f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
820f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
821f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
822f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onStart() {
823f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onStart();
824f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
825ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
826f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mDetailsBackground.setCoverBitmap(bitmap);
827f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
828f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
829f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        @Override
830f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        public void onStop() {
831f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            mDetailsBackground.setCoverBitmap(null);
832f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu            super.onStop();
833f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        }
834f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
835f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
836f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    @Test
837f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    public void noInitialItem() {
838dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity =
839dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentWithNoItem.class, new Options().uiVisibility(
840f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
841f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final DetailsSupportFragmentWithNoItem detailsFragment =
842dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentWithNoItem) activity.getTestFragment();
843f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
844f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        final int recyclerViewHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
845f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu                .getHeight();
846f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertTrue(recyclerViewHeight > 0);
847f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu
848f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
849f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        Drawable coverDrawable = detailsFragment.mDetailsBackgroundController.getCoverDrawable();
850f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertEquals(0, coverDrawable.getBounds().top);
851f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertEquals(recyclerViewHeight, coverDrawable.getBounds().bottom);
852f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        Drawable bottomDrawable = detailsFragment.mDetailsBackgroundController.getBottomDrawable();
853f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().top);
854f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().bottom);
855f87eb1d84dfee2f1be9ea326754829b1eff4967fDake Gu    }
85689097f67f988ebba714a95e10369665280db0c27Dake Gu
85789097f67f988ebba714a95e10369665280db0c27Dake Gu    public static class DetailsSupportFragmentSwitchToVideoInOnCreate extends DetailsTestSupportFragment {
85889097f67f988ebba714a95e10369665280db0c27Dake Gu
85989097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentBackgroundController mDetailsBackground =
86089097f67f988ebba714a95e10369665280db0c27Dake Gu                new DetailsSupportFragmentBackgroundController(this);
86189097f67f988ebba714a95e10369665280db0c27Dake Gu
86289097f67f988ebba714a95e10369665280db0c27Dake Gu        public DetailsSupportFragmentSwitchToVideoInOnCreate() {
86389097f67f988ebba714a95e10369665280db0c27Dake Gu            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
86489097f67f988ebba714a95e10369665280db0c27Dake Gu        }
86589097f67f988ebba714a95e10369665280db0c27Dake Gu
86689097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
86789097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onCreate(Bundle savedInstanceState) {
86889097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onCreate(savedInstanceState);
86989097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.enableParallax();
87089097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.switchToVideo();
87189097f67f988ebba714a95e10369665280db0c27Dake Gu        }
87289097f67f988ebba714a95e10369665280db0c27Dake Gu
87389097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
87489097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onStart() {
87589097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onStart();
87689097f67f988ebba714a95e10369665280db0c27Dake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
877ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
87889097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.setCoverBitmap(bitmap);
87989097f67f988ebba714a95e10369665280db0c27Dake Gu        }
88089097f67f988ebba714a95e10369665280db0c27Dake Gu
88189097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
88289097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onStop() {
88389097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.setCoverBitmap(null);
88489097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onStop();
88589097f67f988ebba714a95e10369665280db0c27Dake Gu        }
88689097f67f988ebba714a95e10369665280db0c27Dake Gu    }
88789097f67f988ebba714a95e10369665280db0c27Dake Gu
88889097f67f988ebba714a95e10369665280db0c27Dake Gu    @Test
88989097f67f988ebba714a95e10369665280db0c27Dake Gu    public void switchToVideoInOnCreate() {
890dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        final SingleSupportFragmentTestActivity activity =
891dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentSwitchToVideoInOnCreate.class,
89289097f67f988ebba714a95e10369665280db0c27Dake Gu                new Options().uiVisibility(
89389097f67f988ebba714a95e10369665280db0c27Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
89489097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentSwitchToVideoInOnCreate detailsFragment =
895dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentSwitchToVideoInOnCreate) activity.getTestFragment();
89689097f67f988ebba714a95e10369665280db0c27Dake Gu
89789097f67f988ebba714a95e10369665280db0c27Dake Gu        // the pending enter transition flag should be automatically cleared
89889097f67f988ebba714a95e10369665280db0c27Dake Gu        assertEquals(StateMachine.STATUS_INVOKED,
89989097f67f988ebba714a95e10369665280db0c27Dake Gu                detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus());
900dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        assertNull(TransitionHelper.getEnterTransition(activity.getWindow()));
90189097f67f988ebba714a95e10369665280db0c27Dake Gu        assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
90289097f67f988ebba714a95e10369665280db0c27Dake Gu        assertTrue(detailsFragment.getRowsSupportFragment().getView().hasFocus());
90389097f67f988ebba714a95e10369665280db0c27Dake Gu        //SystemClock.sleep(5000);
90489097f67f988ebba714a95e10369665280db0c27Dake Gu        assertFalse(detailsFragment.isShowingTitle());
90589097f67f988ebba714a95e10369665280db0c27Dake Gu
90689097f67f988ebba714a95e10369665280db0c27Dake Gu        SystemClock.sleep(1000);
90789097f67f988ebba714a95e10369665280db0c27Dake Gu        assertNull(detailsFragment.mVideoSupportFragment);
90889097f67f988ebba714a95e10369665280db0c27Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
90989097f67f988ebba714a95e10369665280db0c27Dake Gu                new Runnable() {
91089097f67f988ebba714a95e10369665280db0c27Dake Gu                    @Override
91189097f67f988ebba714a95e10369665280db0c27Dake Gu                    public void run() {
912dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
91389097f67f988ebba714a95e10369665280db0c27Dake Gu                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
91489097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
91589097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setArtist("A Googleer");
91689097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setTitle("Diving with Sharks");
91789097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setMediaSource(Uri.parse(
918ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
91989097f67f988ebba714a95e10369665280db0c27Dake Gu                    }
92089097f67f988ebba714a95e10369665280db0c27Dake Gu                }
92189097f67f988ebba714a95e10369665280db0c27Dake Gu        );
92289097f67f988ebba714a95e10369665280db0c27Dake Gu        // once the video fragment is created it would be immediately assigned focus
92389097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
92489097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
92589097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
92689097f67f988ebba714a95e10369665280db0c27Dake Gu                return detailsFragment.mVideoSupportFragment != null
92789097f67f988ebba714a95e10369665280db0c27Dake Gu                        && detailsFragment.mVideoSupportFragment.getView() != null
92889097f67f988ebba714a95e10369665280db0c27Dake Gu                        && detailsFragment.mVideoSupportFragment.getView().hasFocus();
92989097f67f988ebba714a95e10369665280db0c27Dake Gu            }
93089097f67f988ebba714a95e10369665280db0c27Dake Gu        });
93189097f67f988ebba714a95e10369665280db0c27Dake Gu        // wait auto hide play controls done:
93289097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
93389097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
93489097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
93589097f67f988ebba714a95e10369665280db0c27Dake Gu                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
93689097f67f988ebba714a95e10369665280db0c27Dake Gu            }
93789097f67f988ebba714a95e10369665280db0c27Dake Gu        });
93889097f67f988ebba714a95e10369665280db0c27Dake Gu
93989097f67f988ebba714a95e10369665280db0c27Dake Gu        // switchToRows does nothing if there is no row
94089097f67f988ebba714a95e10369665280db0c27Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
94189097f67f988ebba714a95e10369665280db0c27Dake Gu                new Runnable() {
94289097f67f988ebba714a95e10369665280db0c27Dake Gu                    @Override
94389097f67f988ebba714a95e10369665280db0c27Dake Gu                    public void run() {
94489097f67f988ebba714a95e10369665280db0c27Dake Gu                        detailsFragment.mDetailsBackgroundController.switchToRows();
94589097f67f988ebba714a95e10369665280db0c27Dake Gu                    }
94689097f67f988ebba714a95e10369665280db0c27Dake Gu                }
94789097f67f988ebba714a95e10369665280db0c27Dake Gu        );
94889097f67f988ebba714a95e10369665280db0c27Dake Gu        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
94989097f67f988ebba714a95e10369665280db0c27Dake Gu
95089097f67f988ebba714a95e10369665280db0c27Dake Gu        // create item, it should be layout outside screen
95189097f67f988ebba714a95e10369665280db0c27Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
95289097f67f988ebba714a95e10369665280db0c27Dake Gu                new Runnable() {
95389097f67f988ebba714a95e10369665280db0c27Dake Gu                    @Override
95489097f67f988ebba714a95e10369665280db0c27Dake Gu                    public void run() {
95589097f67f988ebba714a95e10369665280db0c27Dake Gu                        detailsFragment.setItem(new PhotoItem("Hello world",
95689097f67f988ebba714a95e10369665280db0c27Dake Gu                                "Fake content goes here",
957ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                androidx.leanback.test.R.drawable.spiderman));
95889097f67f988ebba714a95e10369665280db0c27Dake Gu                    }
95989097f67f988ebba714a95e10369665280db0c27Dake Gu                }
96089097f67f988ebba714a95e10369665280db0c27Dake Gu        );
96189097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
96289097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
96389097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
96489097f67f988ebba714a95e10369665280db0c27Dake Gu                return detailsFragment.getVerticalGridView().getChildCount() > 0
96589097f67f988ebba714a95e10369665280db0c27Dake Gu                        && detailsFragment.getVerticalGridView().getChildAt(0).getTop()
96689097f67f988ebba714a95e10369665280db0c27Dake Gu                        >= detailsFragment.getVerticalGridView().getHeight();
96789097f67f988ebba714a95e10369665280db0c27Dake Gu            }
96889097f67f988ebba714a95e10369665280db0c27Dake Gu        });
96989097f67f988ebba714a95e10369665280db0c27Dake Gu
97089097f67f988ebba714a95e10369665280db0c27Dake Gu        // pressing BACK will return to details row
97189097f67f988ebba714a95e10369665280db0c27Dake Gu        sendKeys(KeyEvent.KEYCODE_BACK);
97289097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
97389097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
97489097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
97589097f67f988ebba714a95e10369665280db0c27Dake Gu                return detailsFragment.getVerticalGridView().getChildAt(0).getTop()
97689097f67f988ebba714a95e10369665280db0c27Dake Gu                        < (detailsFragment.getVerticalGridView().getHeight() * 0.7f);
97789097f67f988ebba714a95e10369665280db0c27Dake Gu            }
97889097f67f988ebba714a95e10369665280db0c27Dake Gu        });
97989097f67f988ebba714a95e10369665280db0c27Dake Gu        assertTrue(detailsFragment.getVerticalGridView().getChildAt(0).hasFocus());
98089097f67f988ebba714a95e10369665280db0c27Dake Gu    }
98189097f67f988ebba714a95e10369665280db0c27Dake Gu
98289097f67f988ebba714a95e10369665280db0c27Dake Gu    @Test
98389097f67f988ebba714a95e10369665280db0c27Dake Gu    public void switchToVideoBackToQuit() {
984dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        final SingleSupportFragmentTestActivity activity =
985dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentSwitchToVideoInOnCreate.class,
98689097f67f988ebba714a95e10369665280db0c27Dake Gu                new Options().uiVisibility(
98789097f67f988ebba714a95e10369665280db0c27Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
98889097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentSwitchToVideoInOnCreate detailsFragment =
989dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                (DetailsSupportFragmentSwitchToVideoInOnCreate) activity.getTestFragment();
99089097f67f988ebba714a95e10369665280db0c27Dake Gu
99189097f67f988ebba714a95e10369665280db0c27Dake Gu        // the pending enter transition flag should be automatically cleared
99289097f67f988ebba714a95e10369665280db0c27Dake Gu        assertEquals(StateMachine.STATUS_INVOKED,
99389097f67f988ebba714a95e10369665280db0c27Dake Gu                detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus());
994dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        assertNull(TransitionHelper.getEnterTransition(activity.getWindow()));
99589097f67f988ebba714a95e10369665280db0c27Dake Gu        assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
99689097f67f988ebba714a95e10369665280db0c27Dake Gu        assertTrue(detailsFragment.getRowsSupportFragment().getView().hasFocus());
99789097f67f988ebba714a95e10369665280db0c27Dake Gu        assertFalse(detailsFragment.isShowingTitle());
99889097f67f988ebba714a95e10369665280db0c27Dake Gu
99989097f67f988ebba714a95e10369665280db0c27Dake Gu        SystemClock.sleep(1000);
100089097f67f988ebba714a95e10369665280db0c27Dake Gu        assertNull(detailsFragment.mVideoSupportFragment);
100189097f67f988ebba714a95e10369665280db0c27Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(
100289097f67f988ebba714a95e10369665280db0c27Dake Gu                new Runnable() {
100389097f67f988ebba714a95e10369665280db0c27Dake Gu                    @Override
100489097f67f988ebba714a95e10369665280db0c27Dake Gu                    public void run() {
1005dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
100689097f67f988ebba714a95e10369665280db0c27Dake Gu                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
100789097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
100889097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setArtist("A Googleer");
100989097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setTitle("Diving with Sharks");
101089097f67f988ebba714a95e10369665280db0c27Dake Gu                        glue.setMediaSource(Uri.parse(
1011ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                                "android.resource://androidx.leanback.test/raw/video"));
101289097f67f988ebba714a95e10369665280db0c27Dake Gu                    }
101389097f67f988ebba714a95e10369665280db0c27Dake Gu                }
101489097f67f988ebba714a95e10369665280db0c27Dake Gu        );
101589097f67f988ebba714a95e10369665280db0c27Dake Gu        // once the video fragment is created it would be immediately assigned focus
101689097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
101789097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
101889097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
101989097f67f988ebba714a95e10369665280db0c27Dake Gu                return detailsFragment.mVideoSupportFragment != null
102089097f67f988ebba714a95e10369665280db0c27Dake Gu                        && detailsFragment.mVideoSupportFragment.getView() != null
102189097f67f988ebba714a95e10369665280db0c27Dake Gu                        && detailsFragment.mVideoSupportFragment.getView().hasFocus();
102289097f67f988ebba714a95e10369665280db0c27Dake Gu            }
102389097f67f988ebba714a95e10369665280db0c27Dake Gu        });
102489097f67f988ebba714a95e10369665280db0c27Dake Gu        // wait auto hide play controls done:
102589097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
102689097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
102789097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
102889097f67f988ebba714a95e10369665280db0c27Dake Gu                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
102989097f67f988ebba714a95e10369665280db0c27Dake Gu            }
103089097f67f988ebba714a95e10369665280db0c27Dake Gu        });
103189097f67f988ebba714a95e10369665280db0c27Dake Gu
103289097f67f988ebba714a95e10369665280db0c27Dake Gu        // before any details row is presented, pressing BACK will quit the activity
103389097f67f988ebba714a95e10369665280db0c27Dake Gu        sendKeys(KeyEvent.KEYCODE_BACK);
1034dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        PollingCheck.waitFor(4000, new PollingCheck.ActivityDestroy(activity));
103589097f67f988ebba714a95e10369665280db0c27Dake Gu    }
103689097f67f988ebba714a95e10369665280db0c27Dake Gu
103789097f67f988ebba714a95e10369665280db0c27Dake Gu    public static class DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition
103889097f67f988ebba714a95e10369665280db0c27Dake Gu            extends DetailsTestSupportFragment {
103989097f67f988ebba714a95e10369665280db0c27Dake Gu
104089097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentBackgroundController mDetailsBackground =
104189097f67f988ebba714a95e10369665280db0c27Dake Gu                new DetailsSupportFragmentBackgroundController(this);
104289097f67f988ebba714a95e10369665280db0c27Dake Gu
104389097f67f988ebba714a95e10369665280db0c27Dake Gu        public DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition() {
104489097f67f988ebba714a95e10369665280db0c27Dake Gu            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
104589097f67f988ebba714a95e10369665280db0c27Dake Gu        }
104689097f67f988ebba714a95e10369665280db0c27Dake Gu
104789097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
104889097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onCreate(Bundle savedInstanceState) {
104989097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onCreate(savedInstanceState);
105089097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.enableParallax();
105189097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.switchToVideo();
105289097f67f988ebba714a95e10369665280db0c27Dake Gu            prepareEntranceTransition();
105389097f67f988ebba714a95e10369665280db0c27Dake Gu        }
105489097f67f988ebba714a95e10369665280db0c27Dake Gu
105589097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
105689097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onViewCreated(View view, Bundle savedInstanceState) {
105789097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onViewCreated(view, savedInstanceState);
105889097f67f988ebba714a95e10369665280db0c27Dake Gu        }
105989097f67f988ebba714a95e10369665280db0c27Dake Gu
106089097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
106189097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onStart() {
106289097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onStart();
106389097f67f988ebba714a95e10369665280db0c27Dake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
1064ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
106589097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.setCoverBitmap(bitmap);
106689097f67f988ebba714a95e10369665280db0c27Dake Gu        }
106789097f67f988ebba714a95e10369665280db0c27Dake Gu
106889097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
106989097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onStop() {
107089097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.setCoverBitmap(null);
107189097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onStop();
107289097f67f988ebba714a95e10369665280db0c27Dake Gu        }
107389097f67f988ebba714a95e10369665280db0c27Dake Gu    }
107489097f67f988ebba714a95e10369665280db0c27Dake Gu
107589097f67f988ebba714a95e10369665280db0c27Dake Gu    @Test
107689097f67f988ebba714a95e10369665280db0c27Dake Gu    public void switchToVideoInOnCreateAndPrepareEntranceTransition() {
1077dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(
1078dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition.class,
107989097f67f988ebba714a95e10369665280db0c27Dake Gu                new Options().uiVisibility(
108089097f67f988ebba714a95e10369665280db0c27Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
108189097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition detailsFragment =
108289097f67f988ebba714a95e10369665280db0c27Dake Gu                (DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition)
1083dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        activity.getTestFragment();
108489097f67f988ebba714a95e10369665280db0c27Dake Gu
108589097f67f988ebba714a95e10369665280db0c27Dake Gu        assertEquals(StateMachine.STATUS_INVOKED,
108689097f67f988ebba714a95e10369665280db0c27Dake Gu                detailsFragment.STATE_ENTRANCE_COMPLETE.getStatus());
108789097f67f988ebba714a95e10369665280db0c27Dake Gu    }
108889097f67f988ebba714a95e10369665280db0c27Dake Gu
108989097f67f988ebba714a95e10369665280db0c27Dake Gu    public static class DetailsSupportFragmentEntranceTransition
109089097f67f988ebba714a95e10369665280db0c27Dake Gu            extends DetailsTestSupportFragment {
109189097f67f988ebba714a95e10369665280db0c27Dake Gu
109289097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentBackgroundController mDetailsBackground =
109389097f67f988ebba714a95e10369665280db0c27Dake Gu                new DetailsSupportFragmentBackgroundController(this);
109489097f67f988ebba714a95e10369665280db0c27Dake Gu
109589097f67f988ebba714a95e10369665280db0c27Dake Gu        public DetailsSupportFragmentEntranceTransition() {
109689097f67f988ebba714a95e10369665280db0c27Dake Gu            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
109789097f67f988ebba714a95e10369665280db0c27Dake Gu        }
109889097f67f988ebba714a95e10369665280db0c27Dake Gu
109989097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
110089097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onCreate(Bundle savedInstanceState) {
110189097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onCreate(savedInstanceState);
110289097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.enableParallax();
110389097f67f988ebba714a95e10369665280db0c27Dake Gu            prepareEntranceTransition();
110489097f67f988ebba714a95e10369665280db0c27Dake Gu        }
110589097f67f988ebba714a95e10369665280db0c27Dake Gu
110689097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
110789097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onStart() {
110889097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onStart();
110989097f67f988ebba714a95e10369665280db0c27Dake Gu            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
1110ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                    androidx.leanback.test.R.drawable.spiderman);
111189097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.setCoverBitmap(bitmap);
111289097f67f988ebba714a95e10369665280db0c27Dake Gu        }
111389097f67f988ebba714a95e10369665280db0c27Dake Gu
111489097f67f988ebba714a95e10369665280db0c27Dake Gu        @Override
111589097f67f988ebba714a95e10369665280db0c27Dake Gu        public void onStop() {
111689097f67f988ebba714a95e10369665280db0c27Dake Gu            mDetailsBackground.setCoverBitmap(null);
111789097f67f988ebba714a95e10369665280db0c27Dake Gu            super.onStop();
111889097f67f988ebba714a95e10369665280db0c27Dake Gu        }
111989097f67f988ebba714a95e10369665280db0c27Dake Gu    }
112089097f67f988ebba714a95e10369665280db0c27Dake Gu
112189097f67f988ebba714a95e10369665280db0c27Dake Gu    @Test
112289097f67f988ebba714a95e10369665280db0c27Dake Gu    public void entranceTransitionBlocksSwitchToVideo() {
1123dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu        SingleSupportFragmentTestActivity activity =
1124dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                launchAndWaitActivity(DetailsSupportFragmentEntranceTransition.class,
112589097f67f988ebba714a95e10369665280db0c27Dake Gu                new Options().uiVisibility(
112689097f67f988ebba714a95e10369665280db0c27Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
112789097f67f988ebba714a95e10369665280db0c27Dake Gu        final DetailsSupportFragmentEntranceTransition detailsFragment =
112889097f67f988ebba714a95e10369665280db0c27Dake Gu                (DetailsSupportFragmentEntranceTransition)
1129dec38f028e4991e352cb45f0e3c1bc85fd9b973dDake Gu                        activity.getTestFragment();
113089097f67f988ebba714a95e10369665280db0c27Dake Gu
113189097f67f988ebba714a95e10369665280db0c27Dake Gu        if (Build.VERSION.SDK_INT < 21) {
113289097f67f988ebba714a95e10369665280db0c27Dake Gu            // when enter transition is not supported, mCanUseHost is immmediately true
113389097f67f988ebba714a95e10369665280db0c27Dake Gu            assertTrue(detailsFragment.mDetailsBackgroundController.mCanUseHost);
113489097f67f988ebba714a95e10369665280db0c27Dake Gu        } else {
113589097f67f988ebba714a95e10369665280db0c27Dake Gu            // calling switchToVideo() between prepareEntranceTransition and entrance transition
113689097f67f988ebba714a95e10369665280db0c27Dake Gu            // finishes will be ignored.
113789097f67f988ebba714a95e10369665280db0c27Dake Gu            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
113889097f67f988ebba714a95e10369665280db0c27Dake Gu                @Override
113989097f67f988ebba714a95e10369665280db0c27Dake Gu                public void run() {
114089097f67f988ebba714a95e10369665280db0c27Dake Gu                    detailsFragment.mDetailsBackgroundController.switchToVideo();
114189097f67f988ebba714a95e10369665280db0c27Dake Gu                }
114289097f67f988ebba714a95e10369665280db0c27Dake Gu            });
114389097f67f988ebba714a95e10369665280db0c27Dake Gu            assertFalse(detailsFragment.mDetailsBackgroundController.mCanUseHost);
114489097f67f988ebba714a95e10369665280db0c27Dake Gu        }
114589097f67f988ebba714a95e10369665280db0c27Dake Gu        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
114689097f67f988ebba714a95e10369665280db0c27Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
114789097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
114889097f67f988ebba714a95e10369665280db0c27Dake Gu            public void run() {
114989097f67f988ebba714a95e10369665280db0c27Dake Gu                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
1150ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                        androidx.leanback.test.R.drawable.spiderman));
115189097f67f988ebba714a95e10369665280db0c27Dake Gu                detailsFragment.startEntranceTransition();
115289097f67f988ebba714a95e10369665280db0c27Dake Gu            }
115389097f67f988ebba714a95e10369665280db0c27Dake Gu        });
115489097f67f988ebba714a95e10369665280db0c27Dake Gu        // once Entrance transition is finished, mCanUseHost will be true
115589097f67f988ebba714a95e10369665280db0c27Dake Gu        // and we can switchToVideo and fade out the background.
115689097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
115789097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
115889097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
115989097f67f988ebba714a95e10369665280db0c27Dake Gu                return detailsFragment.mDetailsBackgroundController.mCanUseHost;
116089097f67f988ebba714a95e10369665280db0c27Dake Gu            }
116189097f67f988ebba714a95e10369665280db0c27Dake Gu        });
116289097f67f988ebba714a95e10369665280db0c27Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
116389097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
116489097f67f988ebba714a95e10369665280db0c27Dake Gu            public void run() {
116589097f67f988ebba714a95e10369665280db0c27Dake Gu                detailsFragment.mDetailsBackgroundController.switchToVideo();
116689097f67f988ebba714a95e10369665280db0c27Dake Gu            }
116789097f67f988ebba714a95e10369665280db0c27Dake Gu        });
116889097f67f988ebba714a95e10369665280db0c27Dake Gu        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
116989097f67f988ebba714a95e10369665280db0c27Dake Gu            @Override
117089097f67f988ebba714a95e10369665280db0c27Dake Gu            public boolean canProceed() {
117189097f67f988ebba714a95e10369665280db0c27Dake Gu                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
117289097f67f988ebba714a95e10369665280db0c27Dake Gu            }
117389097f67f988ebba714a95e10369665280db0c27Dake Gu        });
117489097f67f988ebba714a95e10369665280db0c27Dake Gu    }
117589097f67f988ebba714a95e10369665280db0c27Dake Gu
11768b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu    public static class DetailsSupportFragmentEntranceTransitionTimeout extends DetailsTestSupportFragment {
11778b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu
11788b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        public DetailsSupportFragmentEntranceTransitionTimeout() {
11798b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        }
11808b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu
11818b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        @Override
11828b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        public void onCreate(Bundle savedInstanceState) {
11838b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            super.onCreate(savedInstanceState);
11848b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            prepareEntranceTransition();
11858b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        }
11868b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu
11878b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu    }
11888b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu
11898b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu    @Test
11908b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
11918b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu    public void startEntranceTransitionAfterDestroyed() {
11928b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(
11938b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                DetailsSupportFragmentEntranceTransition.class, new Options().uiVisibility(
11948b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN),
11958b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                1000);
11968b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        final DetailsSupportFragmentEntranceTransition detailsFragment =
11978b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                (DetailsSupportFragmentEntranceTransition)
11988b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                        activity.getTestFragment();
11998b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu
12008b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
12018b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            @Override
12028b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            public void run() {
12038b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
1204ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas                        androidx.leanback.test.R.drawable.spiderman));
12058b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            }
12068b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        });
12078b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        SystemClock.sleep(100);
12088b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        activity.finish();
12098b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity));
12108b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
12118b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            @Override
12128b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            public void run() {
12138b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu                detailsFragment.startEntranceTransition();
12148b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu            }
12158b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu        });
12168b66ca38dbb9f4af7814e7048a14924deb6251a9Dake Gu    }
12179869eb38607552105baa88a0fcba610461045eb5Dake Gu}
1218