Reuse PlayBackGlueHost when switching PlayBackGlue

Bug: 37222175
Test: sharedGlueHost() in DetailsFragmentTest
Change-Id: Icdbbfe28c11ef456743cbd2290892e2136862c6a
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java
index f6f389c..e3fc820 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java
@@ -116,6 +116,8 @@
     int mSolidColor;
     boolean mCanUseHost = false;
 
+    private Fragment mLastVideoFragmentForGlueHost;
+
     /**
      * Creates a DetailsFragmentBackgroundController for a DetailsFragment. Note that
      * each DetailsFragment can only associate with one DetailsFragmentBackgroundController.
@@ -227,13 +229,23 @@
         if (mPlaybackGlue == playbackGlue) {
             return;
         }
+
+        PlaybackGlueHost playbackGlueHost = null;
         if (mPlaybackGlue != null) {
+            playbackGlueHost = mPlaybackGlue.getHost();
             mPlaybackGlue.setHost(null);
         }
+
         mPlaybackGlue = playbackGlue;
         mVideoHelper.setPlaybackGlue(mPlaybackGlue);
         if (mCanUseHost && mPlaybackGlue != null) {
-            mPlaybackGlue.setHost(onCreateGlueHost());
+            if (playbackGlueHost == null
+                    || mLastVideoFragmentForGlueHost != findOrCreateVideoFragment()) {
+                mPlaybackGlue.setHost(onCreateGlueHost());
+                mLastVideoFragmentForGlueHost = findOrCreateVideoFragment();
+            } else {
+                mPlaybackGlue.setHost(playbackGlueHost);
+            }
         }
     }
 
@@ -299,6 +311,7 @@
             mCanUseHost = true;
             if (mPlaybackGlue != null) {
                 mPlaybackGlue.setHost(onCreateGlueHost());
+                mLastVideoFragmentForGlueHost = findOrCreateVideoFragment();
             }
         }
         if (mPlaybackGlue != null && mPlaybackGlue.isReadyForPlayback()) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java
index 763b84f..6a951c9 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java
@@ -119,6 +119,8 @@
     int mSolidColor;
     boolean mCanUseHost = false;
 
+    private Fragment mLastVideoSupportFragmentForGlueHost;
+
     /**
      * Creates a DetailsSupportFragmentBackgroundController for a DetailsSupportFragment. Note that
      * each DetailsSupportFragment can only associate with one DetailsSupportFragmentBackgroundController.
@@ -230,13 +232,23 @@
         if (mPlaybackGlue == playbackGlue) {
             return;
         }
+
+        PlaybackGlueHost playbackGlueHost = null;
         if (mPlaybackGlue != null) {
+            playbackGlueHost = mPlaybackGlue.getHost();
             mPlaybackGlue.setHost(null);
         }
+
         mPlaybackGlue = playbackGlue;
         mVideoHelper.setPlaybackGlue(mPlaybackGlue);
         if (mCanUseHost && mPlaybackGlue != null) {
-            mPlaybackGlue.setHost(onCreateGlueHost());
+            if (playbackGlueHost == null
+                    || mLastVideoSupportFragmentForGlueHost != findOrCreateVideoSupportFragment()) {
+                mPlaybackGlue.setHost(onCreateGlueHost());
+                mLastVideoSupportFragmentForGlueHost = findOrCreateVideoSupportFragment();
+            } else {
+                mPlaybackGlue.setHost(playbackGlueHost);
+            }
         }
     }
 
@@ -302,6 +314,7 @@
             mCanUseHost = true;
             if (mPlaybackGlue != null) {
                 mPlaybackGlue.setHost(onCreateGlueHost());
+                mLastVideoSupportFragmentForGlueHost = findOrCreateVideoSupportFragment();
             }
         }
         if (mPlaybackGlue != null && mPlaybackGlue.isReadyForPlayback()) {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
index 913edac..2c361f4 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
@@ -37,6 +37,7 @@
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
 import android.support.v17.leanback.media.MediaPlayerGlue;
+import android.support.v17.leanback.media.PlaybackGlueHost;
 import android.support.v17.leanback.testutils.PollingCheck;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.util.StateMachine;
@@ -665,6 +666,87 @@
     }
 
     @Test
+    public void sharedGlueHost() {
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentWithNoVideo detailsFragment =
+                (DetailsFragmentWithNoVideo) activity.getTestFragment();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+            }
+        });
+
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue1 = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue1);
+                        glue1.setArtist("A Googleer");
+                        glue1.setTitle("Diving with Sharks");
+                        glue1.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // after setup Video Playback the DPAD up will navigate to Video Fragment.
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoFragment != null
+                        && detailsFragment.mVideoFragment.getView() != null;
+            }
+        });
+
+        final MediaPlayerGlue glue1 = (MediaPlayerGlue) detailsFragment
+                .mDetailsBackgroundController
+                .getPlaybackGlue();
+        PlaybackGlueHost playbackGlueHost = glue1.getHost();
+
+        // wait a little bit to replace with new Glue
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
+                        glue2.setArtist("A Googleer");
+                        glue2.setTitle("Diving with Sharks");
+                        glue2.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // wait for new glue to get its glue host
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                MediaPlayerGlue mediaPlayerGlue = (MediaPlayerGlue) detailsFragment
+                        .mDetailsBackgroundController
+                        .getPlaybackGlue();
+                return mediaPlayerGlue != null && mediaPlayerGlue != glue1
+                        && mediaPlayerGlue.getHost() != null;
+            }
+        });
+
+        final MediaPlayerGlue glue2 = (MediaPlayerGlue) detailsFragment
+                .mDetailsBackgroundController
+                .getPlaybackGlue();
+
+        assertTrue(glue1.getHost() == null);
+        assertTrue(glue2.getHost() == playbackGlueHost);
+    }
+
+    @Test
     public void clearVideo() {
         final SingleFragmentTestActivity activity =
                 launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility(
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
index 39ab734..b4322ec 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
@@ -40,6 +40,7 @@
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
 import android.support.v17.leanback.media.MediaPlayerGlue;
+import android.support.v17.leanback.media.PlaybackGlueHost;
 import android.support.v17.leanback.testutils.PollingCheck;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.util.StateMachine;
@@ -668,6 +669,87 @@
     }
 
     @Test
+    public void sharedGlueHost() {
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentWithNoVideo detailsFragment =
+                (DetailsSupportFragmentWithNoVideo) activity.getTestFragment();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+            }
+        });
+
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue1 = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue1);
+                        glue1.setArtist("A Googleer");
+                        glue1.setTitle("Diving with Sharks");
+                        glue1.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // after setup Video Playback the DPAD up will navigate to Video Fragment.
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoSupportFragment != null
+                        && detailsFragment.mVideoSupportFragment.getView() != null;
+            }
+        });
+
+        final MediaPlayerGlue glue1 = (MediaPlayerGlue) detailsFragment
+                .mDetailsBackgroundController
+                .getPlaybackGlue();
+        PlaybackGlueHost playbackGlueHost = glue1.getHost();
+
+        // wait a little bit to replace with new Glue
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
+                        glue2.setArtist("A Googleer");
+                        glue2.setTitle("Diving with Sharks");
+                        glue2.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // wait for new glue to get its glue host
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                MediaPlayerGlue mediaPlayerGlue = (MediaPlayerGlue) detailsFragment
+                        .mDetailsBackgroundController
+                        .getPlaybackGlue();
+                return mediaPlayerGlue != null && mediaPlayerGlue != glue1
+                        && mediaPlayerGlue.getHost() != null;
+            }
+        });
+
+        final MediaPlayerGlue glue2 = (MediaPlayerGlue) detailsFragment
+                .mDetailsBackgroundController
+                .getPlaybackGlue();
+
+        assertTrue(glue1.getHost() == null);
+        assertTrue(glue2.getHost() == playbackGlueHost);
+    }
+
+    @Test
     public void clearVideo() {
         final SingleSupportFragmentTestActivity activity =
                 launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(