Merge "Make BrowseAnimationFragment working" into lmp-dev
diff --git a/samples/SupportLeanbackDemos/res/drawable-xhdpi/grid_bg.png b/samples/SupportLeanbackDemos/res/drawable-xhdpi/bg.png
similarity index 100%
rename from samples/SupportLeanbackDemos/res/drawable-xhdpi/grid_bg.png
rename to samples/SupportLeanbackDemos/res/drawable-xhdpi/bg.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/drawable/details_img_16x9.png b/samples/SupportLeanbackDemos/res/drawable/details_img_16x9.png
new file mode 100644
index 0000000..daa505d
--- /dev/null
+++ b/samples/SupportLeanbackDemos/res/drawable/details_img_16x9.png
Binary files differ
diff --git a/samples/SupportLeanbackDemos/res/layout/playback_controls.xml b/samples/SupportLeanbackDemos/res/layout/playback_controls.xml
index 357184c..0c9f43c 100644
--- a/samples/SupportLeanbackDemos/res/layout/playback_controls.xml
+++ b/samples/SupportLeanbackDemos/res/layout/playback_controls.xml
@@ -15,9 +15,20 @@
      limitations under the License.
 -->
 
-<fragment xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="com.example.android.leanback.PlaybackOverlayFragment"
-    android:id="@+id/playback_controls_fragment"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-/>
+    android:layout_height="match_parent" >
+
+    <ImageView
+        android:id="@+id/media_content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:src="@drawable/bg" />
+
+    <fragment
+        android:id="@+id/playback_controls_fragment"
+        android:name="com.example.android.leanback.PlaybackOverlayFragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
index db674a2..44cd34a 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
@@ -13,16 +13,28 @@
  */
 package com.example.android.leanback;
 
+import java.util.ArrayList;
+
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
 import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
 import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsUpAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsDownAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ShuffleAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.SkipNextAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.SkipPreviousAction;
 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
 import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.VerticalGridView;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
 import android.support.v17.leanback.widget.OnActionClickedListener;
@@ -34,17 +46,25 @@
     private static final String TAG = "leanback.PlaybackControlsFragment";
 
     private static final boolean SHOW_DETAIL = true;
-    private static final boolean SHOW_IMAGE = true;
     private static final boolean HIDE_MORE_ACTIONS = false;
-    private static final int TOTAL_TIME_MS = 120 * 1000;
-    private static final int NUM_ROWS = 3;
+    private static final int PRIMARY_CONTROLS = 5;
+    private static final boolean SHOW_IMAGE = PRIMARY_CONTROLS <= 5;
+    private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;
+    private static final int MORE_ROWS = 3;
 
     private ArrayObjectAdapter mRowsAdapter;
     private ArrayObjectAdapter mPrimaryActionsAdapter;
     private ArrayObjectAdapter mSecondaryActionsAdapter;
-    private PlaybackControlsRow.PlayPauseAction mPlayPauseAction;
-    private PlaybackControlsRow.RepeatAction mRepeatAction;
+    private PlayPauseAction mPlayPauseAction;
+    private RepeatAction mRepeatAction;
+    private ThumbsUpAction mThumbsUpAction;
+    private ThumbsDownAction mThumbsDownAction;
+    private ShuffleAction mShuffleAction;
+    private SkipNextAction mSkipNextAction;
+    private SkipPreviousAction mSkipPreviousAction;
     private PlaybackControlsRow mPlaybackControlsRow;
+    private ArrayList<MediaItem> mItems = new ArrayList<MediaItem>();
+    private int mCurrentItem;
     private Handler mHandler;
     private Runnable mRunnable;
 
@@ -55,12 +75,12 @@
 
         mHandler = new Handler();
 
+        setBackgroundType(BACKGROUND_TYPE);
+        setFadingEnabled(false);
+
         setupRows();
     }
 
-    private static void notifyChanged(ArrayObjectAdapter adapter, Action action) {
-        adapter.notifyArrayItemRangeChanged(adapter.indexOf(action), 1);
-    }
 
     private void setupRows() {
         ClassPresenterSelector ps = new ClassPresenterSelector();
@@ -68,28 +88,28 @@
         PlaybackControlsRowPresenter playbackControlsRowPresenter;
         if (SHOW_DETAIL) {
             playbackControlsRowPresenter = new PlaybackControlsRowPresenter(
-                    new DetailsDescriptionPresenter());
+                    new DescriptionPresenter());
         } else {
             playbackControlsRowPresenter = new PlaybackControlsRowPresenter();
         }
         playbackControlsRowPresenter.setOnActionClickedListener(new OnActionClickedListener() {
             public void onActionClicked(Action action) {
-                Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show();
                 if (action.getId() == mPlayPauseAction.getId()) {
-                    if (mPlayPauseAction.isPlayIconShown()) {
-                        int totalTime = mPlaybackControlsRow.getTotalTime();
-                        if (totalTime > 0 && mPlaybackControlsRow.getCurrentTime() >= totalTime) {
-                            mPlaybackControlsRow.setCurrentTime(0);
-                        }
+                    if (mPlayPauseAction.getIndex() == PlayPauseAction.PLAY) {
                         startProgressAutomation();
+                        setFadingEnabled(true);
                     } else {
                         stopProgressAutomation();
+                        setFadingEnabled(false);
                     }
-                    mPlayPauseAction.toggle();
-                    notifyChanged(mPrimaryActionsAdapter, mPlayPauseAction);
-                } else if (action.getId() == mRepeatAction.getId()) {
-                    mRepeatAction.next();
-                    notifyChanged(mSecondaryActionsAdapter, mRepeatAction);
+                } else if (action.getId() == mSkipNextAction.getId()) {
+                    next();
+                } else if (action.getId() == mSkipPreviousAction.getId()) {
+                    Toast.makeText(getActivity(), "TODO", Toast.LENGTH_SHORT).show();
+                }
+                if (action instanceof PlaybackControlsRow.MultiAction) {
+                    ((PlaybackControlsRow.MultiAction) action).nextIndex();
+                    notifyChanged(action);
                 }
             }
         });
@@ -100,6 +120,7 @@
         mRowsAdapter = new ArrayObjectAdapter(ps);
 
         addPlaybackControlsRow();
+        addOtherRows();
 
         setAdapter(mRowsAdapter);
     }
@@ -107,42 +128,91 @@
     private void addPlaybackControlsRow() {
         Context context = getActivity();
 
-        ControlButtonPresenterSelector presenterSelector = new ControlButtonPresenterSelector();
-        mPrimaryActionsAdapter = new ArrayObjectAdapter(presenterSelector);
-        mSecondaryActionsAdapter = new ArrayObjectAdapter(presenterSelector);
-
         if (SHOW_DETAIL) {
-            mPlaybackControlsRow = new PlaybackControlsRow("Playback Controls Title");
+            mPlaybackControlsRow = new PlaybackControlsRow(new MediaItem());
         } else {
             mPlaybackControlsRow = new PlaybackControlsRow();
         }
-        if (SHOW_IMAGE) {
-            mPlaybackControlsRow.setImageDrawable(context.getResources().getDrawable(
-                    R.drawable.details_img));
-        }
-        mPlaybackControlsRow.setPrimaryActionsAdapter(mPrimaryActionsAdapter);
-        mPlaybackControlsRow.setSecondaryActionsAdapter(mSecondaryActionsAdapter);
-        mPlaybackControlsRow.setTotalTime(TOTAL_TIME_MS);
-        mPlaybackControlsRow.setCurrentTime(10 * 1000);
-        mPlaybackControlsRow.setBufferedProgress(75 * 1000);
-
         mRowsAdapter.add(mPlaybackControlsRow);
 
-        mPlayPauseAction = new PlaybackControlsRow.PlayPauseAction(context);
-        mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
+        mItems = new ArrayList<MediaItem>();
+        mItems.add(new MediaItem("Awesome Tune", "The More Awesome Band", R.drawable.details_img, 15*1000));
+        mItems.add(new MediaItem("Pretty nice Tune", "The Nice Guys", R.drawable.details_img, 10*1000));
+        mCurrentItem = 1;
+        updatePlaybackRow(mCurrentItem);
 
-        mPrimaryActionsAdapter.add(new PlaybackControlsRow.SkipPreviousAction(context));
-        mPrimaryActionsAdapter.add(new PlaybackControlsRow.RewindAction(context));
+        ControlButtonPresenterSelector presenterSelector = new ControlButtonPresenterSelector();
+        mPrimaryActionsAdapter = new ArrayObjectAdapter(presenterSelector);
+        mSecondaryActionsAdapter = new ArrayObjectAdapter(presenterSelector);
+        mPlaybackControlsRow.setPrimaryActionsAdapter(mPrimaryActionsAdapter);
+        mPlaybackControlsRow.setSecondaryActionsAdapter(mSecondaryActionsAdapter);
+
+        mPlayPauseAction = new PlayPauseAction(context);
+        mRepeatAction = new RepeatAction(context);
+        mThumbsUpAction = new ThumbsUpAction(context);
+        mThumbsDownAction = new ThumbsDownAction(context);
+        mShuffleAction = new ShuffleAction(context);
+        mSkipNextAction = new PlaybackControlsRow.SkipNextAction(context);
+        mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(context);
+
+        if (PRIMARY_CONTROLS > 5) {
+            mPrimaryActionsAdapter.add(mThumbsUpAction);
+        } else {
+            mSecondaryActionsAdapter.add(mThumbsUpAction);
+        }
+        mPrimaryActionsAdapter.add(mSkipPreviousAction);
+        if (PRIMARY_CONTROLS > 3) {
+            mPrimaryActionsAdapter.add(new PlaybackControlsRow.RewindAction(context));
+        }
         mPrimaryActionsAdapter.add(mPlayPauseAction);
-        mPrimaryActionsAdapter.add(new PlaybackControlsRow.FastForwardAction(context));
-        mPrimaryActionsAdapter.add(new PlaybackControlsRow.SkipNextAction(context));
+        if (PRIMARY_CONTROLS > 3) {
+            mPrimaryActionsAdapter.add(new PlaybackControlsRow.FastForwardAction(context));
+        }
+        mPrimaryActionsAdapter.add(mSkipNextAction);
 
-        mSecondaryActionsAdapter.add(new PlaybackControlsRow.ThumbsUpAction(context));
         mSecondaryActionsAdapter.add(mRepeatAction);
-        mSecondaryActionsAdapter.add(new PlaybackControlsRow.ShuffleAction(context));
-        mSecondaryActionsAdapter.add(new PlaybackControlsRow.ThumbsDownAction(context));
+        mSecondaryActionsAdapter.add(mShuffleAction);
+        if (PRIMARY_CONTROLS > 5) {
+            mPrimaryActionsAdapter.add(mThumbsDownAction);
+        } else {
+            mSecondaryActionsAdapter.add(mThumbsDownAction);
+        }
+        mSecondaryActionsAdapter.add(new PlaybackControlsRow.HighQualityAction(context));
+        mSecondaryActionsAdapter.add(new PlaybackControlsRow.ClosedCaptioningAction(context));
+    }
 
-        for (int i = 0; i < NUM_ROWS; ++i) {
+    private void notifyChanged(Action action) {
+        ArrayObjectAdapter adapter = mPrimaryActionsAdapter;
+        if (adapter.indexOf(action) >= 0) {
+            adapter.notifyArrayItemRangeChanged(adapter.indexOf(action), 1);
+            return;
+        }
+        adapter = mSecondaryActionsAdapter;
+        if (adapter.indexOf(action) >= 0) {
+            adapter.notifyArrayItemRangeChanged(adapter.indexOf(action), 1);
+            return;
+        }
+    }
+
+    private void updatePlaybackRow(int index) {
+        if (mPlaybackControlsRow.getItem() != null) {
+            MediaItem item = (MediaItem) mPlaybackControlsRow.getItem();
+            item.title = mItems.get(index).title;
+            item.subtitle = mItems.get(index).subtitle;
+        }
+        if (SHOW_IMAGE) {
+            mPlaybackControlsRow.setImageDrawable(getResources().getDrawable(
+                    mItems.get(mCurrentItem).imageResId));
+        }
+        mRowsAdapter.notifyArrayItemRangeChanged(0, 1);
+
+        mPlaybackControlsRow.setTotalTime(mItems.get(mCurrentItem).durationMs);
+        mPlaybackControlsRow.setCurrentTime(0);
+        mPlaybackControlsRow.setBufferedProgress(75 * 1000);
+    }
+
+    private void addOtherRows() {
+        for (int i = 0; i < MORE_ROWS; ++i) {
             ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
             listRowAdapter.add("Some related content");
             listRowAdapter.add("Other related content");
@@ -151,22 +221,35 @@
         }
     }
 
+    private int getUpdatePeriod() {
+        if (getView() == null || mPlaybackControlsRow.getTotalTime() <= 0) {
+            return 1000;
+        }
+        return Math.max(16, mPlaybackControlsRow.getTotalTime() / getView().getWidth());
+    }
+
     private void startProgressAutomation() {
-        int width = getView().getWidth();
-        final int totalTime = mPlaybackControlsRow.getTotalTime();
-        final int updateFreq = totalTime <= 0 ? 1000 :
-                Math.max(16, totalTime / width);
         mRunnable = new Runnable() {
             @Override
             public void run() {
-                int currentTime = mPlaybackControlsRow.getCurrentTime() + updateFreq;
+                int updatePeriod = getUpdatePeriod();
+                int currentTime = mPlaybackControlsRow.getCurrentTime() + updatePeriod;
+                int totalTime = mPlaybackControlsRow.getTotalTime();
                 mPlaybackControlsRow.setCurrentTime(currentTime);
-                if (totalTime <= 0 || totalTime > currentTime) {
-                    mHandler.postDelayed(this, updateFreq);
+                if (totalTime > 0 && totalTime <= currentTime) {
+                    next();
                 }
+                mHandler.postDelayed(this, updatePeriod);
             }
         };
-        mHandler.postDelayed(mRunnable, updateFreq);
+        mHandler.postDelayed(mRunnable, getUpdatePeriod());
+    }
+
+    private void next() {
+        if (++mCurrentItem >= mItems.size()) {
+            mCurrentItem = 0;
+        }
+        updatePlaybackRow(mCurrentItem);
     }
 
     private void stopProgressAutomation() {
@@ -174,4 +257,29 @@
             mHandler.removeCallbacks(mRunnable);
         }
     }
+
+    static class MediaItem {
+        String title;
+        String subtitle;
+        int imageResId;
+        int durationMs;
+
+        MediaItem() {
+        }
+
+        MediaItem(String title, String subtitle, int imageResId, int durationMs) {
+            this.title = title;
+            this.subtitle = subtitle;
+            this.imageResId = imageResId;
+            this.durationMs = durationMs;
+        }
+    }
+
+    static class DescriptionPresenter extends AbstractDetailsDescriptionPresenter {
+        @Override
+        protected void onBindDescription(ViewHolder vh, Object item) {
+            vh.getTitle().setText(((MediaItem) item).title);
+            vh.getSubtitle().setText(((MediaItem) item).subtitle);
+        }
+    }
 }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java
index c5262b9..5107be5f 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/VerticalGridActivity.java
@@ -24,6 +24,7 @@
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.vertical_grid);
-        getWindow().setBackgroundDrawableResource(R.drawable.grid_bg);
+        // TODO: use BackgroundManager here
+        getWindow().setBackgroundDrawableResource(R.drawable.bg);
     }
 }