diff --git a/samples/SupportLeanbackDemos/AndroidManifest.xml b/samples/SupportLeanbackDemos/AndroidManifest.xml
index 7b8b946..f8a1646 100644
--- a/samples/SupportLeanbackDemos/AndroidManifest.xml
+++ b/samples/SupportLeanbackDemos/AndroidManifest.xml
@@ -115,25 +115,9 @@
             android:launchMode="singleTask"
             android:exported="true" />
 
-        <activity android:name="PlaybackOverlayActivity"
-            android:configChanges=
-                "screenSize|smallestScreenSize|screenLayout|orientation"
-            android:resizeableActivity="true"
-            android:supportsPictureInPicture="true"
-            android:launchMode="singleTask"
-            android:exported="true" />
-
-        <activity android:name="PlaybackOverlaySupportActivity"
-            android:configChanges=
-                "screenSize|smallestScreenSize|screenLayout|orientation"
-            android:resizeableActivity="true"
-            android:supportsPictureInPicture="true"
-            android:launchMode="singleTask"
-            android:exported="true" />
-
         <activity android:name="VerticalGridActivity"
-            android:theme="@style/Theme.Example.Leanback.VerticalGrid"
-            android:exported="true" />
+                  android:theme="@style/Theme.Example.Leanback.VerticalGrid"
+                  android:exported="true" />
 
         <activity android:name="VerticalGridSupportActivity"
             android:theme="@style/Theme.Example.Leanback.VerticalGrid"
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
index bb282f4..c8177b6 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
@@ -116,7 +116,7 @@
                     actions.clear(ACTION_RENT);
                     dor.setItem(mPhotoItem.getTitle() + "(Rented)");
                 } else if (action.getId() == ACTION_PLAY) {
-                    Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+                    Intent intent = new Intent(context, PlaybackActivity.class);
                     getActivity().startActivity(intent);
                 }
             }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
index 8e7a127..0f15590 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
@@ -119,7 +119,7 @@
                     actions.clear(ACTION_RENT);
                     dor.setItem(mPhotoItem.getTitle() + "(Rented)");
                 } else if (action.getId() == ACTION_PLAY) {
-                    Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+                    Intent intent = new Intent(context, PlaybackSupportActivity.class);
                     getActivity().startActivity(intent);
                 }
             }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
index 116003f..15a0769 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
@@ -121,10 +121,6 @@
                     R.string.playback_description);
             addAction(actions, PlaybackTransportControlSupportActivity.class,
                     R.string.playback_support, R.string.playback_support_description);
-            addAction(actions, PlaybackOverlayActivity.class, R.string.playbackoverlay,
-                    R.string.playbackoverlay_description);
-            addAction(actions, PlaybackOverlaySupportActivity.class,
-                    R.string.playbackoverlay_support, R.string.playbackoverlay_support_description);
             addAction(actions, VideoActivity.class, R.string.video_playback,
                     R.string.playback_description);
             addAction(actions, VideoSupportActivity.class, R.string.video_playback_support,
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
index 4d5b4cc..6524243 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
@@ -174,7 +174,7 @@
                             mDetailsBackground.switchToVideo();
                         }
                     } else {
-                        Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+                        Intent intent = new Intent(context, PlaybackActivity.class);
                         getActivity().startActivity(intent);
                     }
                 } else if (action.getId() == ACTION_RENT) {
@@ -189,14 +189,14 @@
                         setupMainVideo();
                         mDetailsBackground.switchToVideo();
                     } else {
-                        Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+                        Intent intent = new Intent(context, PlaybackActivity.class);
                         getActivity().startActivity(intent);
                     }
                 } else if (action.getId() == ACTION_PLAY) {
                     if (TEST_BACKGROUND_PLAYER) {
                         mDetailsBackground.switchToVideo();
                     } else {
-                        Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+                        Intent intent = new Intent(context, PlaybackActivity.class);
                         getActivity().startActivity(intent);
                     }
                 }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
index db7d594..f8570aa 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
@@ -177,7 +177,7 @@
                             mDetailsBackground.switchToVideo();
                         }
                     } else {
-                        Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+                        Intent intent = new Intent(context, PlaybackSupportActivity.class);
                         getActivity().startActivity(intent);
                     }
                 } else if (action.getId() == ACTION_RENT) {
@@ -192,14 +192,14 @@
                         setupMainVideo();
                         mDetailsBackground.switchToVideo();
                     } else {
-                        Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+                        Intent intent = new Intent(context, PlaybackSupportActivity.class);
                         getActivity().startActivity(intent);
                     }
                 } else if (action.getId() == ACTION_PLAY) {
                     if (TEST_BACKGROUND_PLAYER) {
                         mDetailsBackground.switchToVideo();
                     } else {
-                        Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+                        Intent intent = new Intent(context, PlaybackSupportActivity.class);
                         getActivity().startActivity(intent);
                     }
                 }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlHelper.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlHelper.java
deleted file mode 100644
index e0becaa..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlHelper.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.example.android.leanback;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.support.v17.leanback.app.PlaybackControlGlue;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Toast;
-
-abstract class PlaybackControlHelper extends PlaybackControlGlue {
-    /**
-     * Change the location of the thumbs up/down controls
-     */
-    private static final boolean THUMBS_PRIMARY = true;
-
-    private static final String FAUX_TITLE = "A short song of silence";
-    private static final String FAUX_SUBTITLE = "2014";
-    private static final int FAUX_DURATION = 33 * 1000;
-
-    // These should match the playback service FF behavior
-    private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
-
-    private boolean mIsPlaying;
-    private int mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
-    private long mStartTime;
-    private long mStartPosition = 0;
-
-    private PlaybackControlsRow.RepeatAction mRepeatAction;
-    private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
-    private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
-    private PlaybackControlsRow.PictureInPictureAction mPipAction;
-
-    private Handler mHandler = new Handler();
-    // simulating whether the media is yet prepared and ready to play
-    private boolean mInitialized = true;
-
-    private final Runnable mUpdateProgressRunnable = new Runnable() {
-        @Override
-        public void run() {
-            updateProgress();
-            mHandler.postDelayed(this, getUpdatePeriod());
-        }
-    };
-
-    PlaybackControlHelper(Context context, PlaybackOverlayFragment fragment) {
-        super(context, fragment, sFastForwardSpeeds);
-        mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
-        mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
-        mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
-        mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
-        mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
-        mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
-    }
-
-    @Override
-    public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
-        PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
-
-        ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
-        getControlsRow().setSecondaryActionsAdapter(adapter);
-        if (!THUMBS_PRIMARY) {
-            adapter.add(mThumbsDownAction);
-        }
-        if (android.os.Build.VERSION.SDK_INT > 23) {
-            adapter.add(mPipAction);
-        }
-        adapter.add(mRepeatAction);
-        if (!THUMBS_PRIMARY) {
-            adapter.add(mThumbsUpAction);
-        }
-
-        return presenter;
-    }
-
-    @Override
-    protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
-            PresenterSelector presenterSelector) {
-        SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
-        if (THUMBS_PRIMARY) {
-            adapter.set(PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
-            adapter.set(PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
-        }
-        return adapter;
-    }
-
-    @Override
-    public void onActionClicked(Action action) {
-        if (shouldDispatchAction(action)) {
-            dispatchAction(action);
-            return;
-        }
-        super.onActionClicked(action);
-    }
-
-    @Override
-    public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
-        if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
-            Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
-            if (shouldDispatchAction(action)) {
-                dispatchAction(action);
-                return true;
-            }
-        }
-        return super.onKey(view, keyCode, keyEvent);
-    }
-
-    private boolean shouldDispatchAction(Action action) {
-        return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
-    }
-
-    private void dispatchAction(Action action) {
-        Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
-        PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
-        multiAction.nextIndex();
-        notifyActionChanged(multiAction);
-    }
-
-    private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
-        int index;
-        index = getPrimaryActionsAdapter().indexOf(action);
-        if (index >= 0) {
-            getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
-        } else {
-            index = getSecondaryActionsAdapter().indexOf(action);
-            if (index >= 0) {
-                getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
-            }
-        }
-    }
-
-    private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
-        return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
-    }
-
-    private ArrayObjectAdapter getSecondaryActionsAdapter() {
-        return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
-    }
-
-    @Override
-    public boolean hasValidMedia() {
-        return mInitialized;
-    }
-
-    @Override
-    public boolean isMediaPlaying() {
-        return mIsPlaying;
-    }
-
-    @Override
-    public CharSequence getMediaTitle() {
-        return FAUX_TITLE;
-    }
-
-    @Override
-    public CharSequence getMediaSubtitle() {
-        return FAUX_SUBTITLE;
-    }
-
-    @Override
-    public int getMediaDuration() {
-        return mInitialized ? FAUX_DURATION : 0;
-    }
-
-    @Override
-    public Drawable getMediaArt() {
-        return null;
-    }
-
-    @Override
-    public long getSupportedActions() {
-        return PlaybackControlGlue.ACTION_PLAY_PAUSE |
-                PlaybackControlGlue.ACTION_FAST_FORWARD |
-                PlaybackControlGlue.ACTION_REWIND;
-    }
-
-    @Override
-    public int getCurrentSpeedId() {
-        return mSpeed;
-    }
-
-    @Override
-    public int getCurrentPosition() {
-        int speed;
-        if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
-            speed = 0;
-        } else if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_NORMAL) {
-            speed = 1;
-        } else if (mSpeed >= PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
-            int index = mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
-            speed = getFastForwardSpeeds()[index];
-        } else if (mSpeed <= -PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
-            int index = -mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
-            speed = -getRewindSpeeds()[index];
-        } else {
-            return -1;
-        }
-        long position = mStartPosition +
-                (System.currentTimeMillis() - mStartTime) * speed;
-        if (position > getMediaDuration()) {
-            position = getMediaDuration();
-            onPlaybackComplete(true);
-        } else if (position < 0) {
-            position = 0;
-            onPlaybackComplete(false);
-        }
-        return (int) position;
-    }
-
-    void onPlaybackComplete(final boolean ended) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
-                    pausePlayback();
-                } else {
-                    startPlayback(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL);
-                }
-                mStartPosition = 0;
-                onStateChanged();
-            }
-        });
-    }
-
-    @Override
-    protected void startPlayback(int speed) {
-        if (speed == mSpeed) {
-            return;
-        }
-        mStartPosition = getCurrentPosition();
-        mSpeed = speed;
-        mIsPlaying = true;
-        mStartTime = System.currentTimeMillis();
-    }
-
-    @Override
-    protected void pausePlayback() {
-        if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
-            return;
-        }
-        mStartPosition = getCurrentPosition();
-        mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
-        mIsPlaying = false;
-    }
-
-    @Override
-    protected void skipToNext() {
-        // Not supported
-    }
-
-    @Override
-    protected void skipToPrevious() {
-        // Not supported
-    }
-
-    @Override
-    public void enableProgressUpdating(boolean enable) {
-        mHandler.removeCallbacks(mUpdateProgressRunnable);
-        if (enable) {
-            mUpdateProgressRunnable.run();
-        }
-    }
-
-    public boolean isInitialized() {
-        return mInitialized;
-    }
-
-    public void setInitialized(boolean initialized) {
-        if (mInitialized != initialized) {
-            mInitialized = initialized;
-            onMetadataChanged();
-            onStateChanged();
-        }
-    }
-};
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java
deleted file mode 100644
index 4ae5b37..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java
+++ /dev/null
@@ -1,301 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackControlHelper.java.  DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.example.android.leanback;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.support.v17.leanback.app.PlaybackControlSupportGlue;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Toast;
-
-abstract class PlaybackControlSupportHelper extends PlaybackControlSupportGlue {
-    /**
-     * Change the location of the thumbs up/down controls
-     */
-    private static final boolean THUMBS_PRIMARY = true;
-
-    private static final String FAUX_TITLE = "A short song of silence";
-    private static final String FAUX_SUBTITLE = "2014";
-    private static final int FAUX_DURATION = 33 * 1000;
-
-    // These should match the playback service FF behavior
-    private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
-
-    private boolean mIsPlaying;
-    private int mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
-    private long mStartTime;
-    private long mStartPosition = 0;
-
-    private PlaybackControlsRow.RepeatAction mRepeatAction;
-    private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
-    private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
-    private PlaybackControlsRow.PictureInPictureAction mPipAction;
-
-    private Handler mHandler = new Handler();
-    // simulating whether the media is yet prepared and ready to play
-    private boolean mInitialized = true;
-
-    private final Runnable mUpdateProgressRunnable = new Runnable() {
-        @Override
-        public void run() {
-            updateProgress();
-            mHandler.postDelayed(this, getUpdatePeriod());
-        }
-    };
-
-    PlaybackControlSupportHelper(Context context, PlaybackOverlaySupportFragment fragment) {
-        super(context, fragment, sFastForwardSpeeds);
-        mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
-        mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
-        mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
-        mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
-        mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
-        mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
-    }
-
-    @Override
-    public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
-        PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
-
-        ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
-        getControlsRow().setSecondaryActionsAdapter(adapter);
-        if (!THUMBS_PRIMARY) {
-            adapter.add(mThumbsDownAction);
-        }
-        if (android.os.Build.VERSION.SDK_INT > 23) {
-            adapter.add(mPipAction);
-        }
-        adapter.add(mRepeatAction);
-        if (!THUMBS_PRIMARY) {
-            adapter.add(mThumbsUpAction);
-        }
-
-        return presenter;
-    }
-
-    @Override
-    protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
-            PresenterSelector presenterSelector) {
-        SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
-        if (THUMBS_PRIMARY) {
-            adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
-            adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
-        }
-        return adapter;
-    }
-
-    @Override
-    public void onActionClicked(Action action) {
-        if (shouldDispatchAction(action)) {
-            dispatchAction(action);
-            return;
-        }
-        super.onActionClicked(action);
-    }
-
-    @Override
-    public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
-        if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
-            Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
-            if (shouldDispatchAction(action)) {
-                dispatchAction(action);
-                return true;
-            }
-        }
-        return super.onKey(view, keyCode, keyEvent);
-    }
-
-    private boolean shouldDispatchAction(Action action) {
-        return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
-    }
-
-    private void dispatchAction(Action action) {
-        Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
-        PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
-        multiAction.nextIndex();
-        notifyActionChanged(multiAction);
-    }
-
-    private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
-        int index;
-        index = getPrimaryActionsAdapter().indexOf(action);
-        if (index >= 0) {
-            getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
-        } else {
-            index = getSecondaryActionsAdapter().indexOf(action);
-            if (index >= 0) {
-                getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
-            }
-        }
-    }
-
-    private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
-        return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
-    }
-
-    private ArrayObjectAdapter getSecondaryActionsAdapter() {
-        return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
-    }
-
-    @Override
-    public boolean hasValidMedia() {
-        return mInitialized;
-    }
-
-    @Override
-    public boolean isMediaPlaying() {
-        return mIsPlaying;
-    }
-
-    @Override
-    public CharSequence getMediaTitle() {
-        return FAUX_TITLE;
-    }
-
-    @Override
-    public CharSequence getMediaSubtitle() {
-        return FAUX_SUBTITLE;
-    }
-
-    @Override
-    public int getMediaDuration() {
-        return mInitialized ? FAUX_DURATION : 0;
-    }
-
-    @Override
-    public Drawable getMediaArt() {
-        return null;
-    }
-
-    @Override
-    public long getSupportedActions() {
-        return PlaybackControlSupportGlue.ACTION_PLAY_PAUSE |
-                PlaybackControlSupportGlue.ACTION_FAST_FORWARD |
-                PlaybackControlSupportGlue.ACTION_REWIND;
-    }
-
-    @Override
-    public int getCurrentSpeedId() {
-        return mSpeed;
-    }
-
-    @Override
-    public int getCurrentPosition() {
-        int speed;
-        if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
-            speed = 0;
-        } else if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL) {
-            speed = 1;
-        } else if (mSpeed >= PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
-            int index = mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
-            speed = getFastForwardSpeeds()[index];
-        } else if (mSpeed <= -PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
-            int index = -mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
-            speed = -getRewindSpeeds()[index];
-        } else {
-            return -1;
-        }
-        long position = mStartPosition +
-                (System.currentTimeMillis() - mStartTime) * speed;
-        if (position > getMediaDuration()) {
-            position = getMediaDuration();
-            onPlaybackComplete(true);
-        } else if (position < 0) {
-            position = 0;
-            onPlaybackComplete(false);
-        }
-        return (int) position;
-    }
-
-    void onPlaybackComplete(final boolean ended) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
-                    pausePlayback();
-                } else {
-                    startPlayback(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL);
-                }
-                mStartPosition = 0;
-                onStateChanged();
-            }
-        });
-    }
-
-    @Override
-    protected void startPlayback(int speed) {
-        if (speed == mSpeed) {
-            return;
-        }
-        mStartPosition = getCurrentPosition();
-        mSpeed = speed;
-        mIsPlaying = true;
-        mStartTime = System.currentTimeMillis();
-    }
-
-    @Override
-    protected void pausePlayback() {
-        if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
-            return;
-        }
-        mStartPosition = getCurrentPosition();
-        mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
-        mIsPlaying = false;
-    }
-
-    @Override
-    protected void skipToNext() {
-        // Not supported
-    }
-
-    @Override
-    protected void skipToPrevious() {
-        // Not supported
-    }
-
-    @Override
-    public void enableProgressUpdating(boolean enable) {
-        mHandler.removeCallbacks(mUpdateProgressRunnable);
-        if (enable) {
-            mUpdateProgressRunnable.run();
-        }
-    }
-
-    public boolean isInitialized() {
-        return mInitialized;
-    }
-
-    public void setInitialized(boolean initialized) {
-        if (mInitialized != initialized) {
-            mInitialized = initialized;
-            onMetadataChanged();
-            onStateChanged();
-        }
-    }
-};
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayActivity.java
deleted file mode 100644
index 764b169..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayActivity.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PlaybackOverlayActivity extends Activity {
-    private List<PictureInPictureListener> mListeners = new ArrayList<>();
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.playback_controls);
-    }
-
-    @Override
-    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        for (PictureInPictureListener listener : mListeners) {
-            listener.onPictureInPictureModeChanged(isInPictureInPictureMode);
-        }
-    }
-
-    public void registerPictureInPictureListener(PictureInPictureListener listener) {
-        mListeners.add(listener);
-    }
-
-    public void unregisterPictureInPictureListener(PictureInPictureListener listener) {
-        mListeners.remove(listener);
-    }
-
-    public interface PictureInPictureListener {
-        void onPictureInPictureModeChanged(boolean isInPictureInPictureMode);
-    }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
deleted file mode 100644
index 369c464..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.content.Context;
-import android.os.Build;
-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.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.OnItemViewSelectedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.util.Log;
-
-public class PlaybackOverlayFragment
-        extends android.support.v17.leanback.app.PlaybackOverlayFragment
-        implements PlaybackOverlayActivity.PictureInPictureListener {
-    private static final String TAG = "leanback.PlaybackControlsFragment";
-
-    /**
-     * Change this to choose a different overlay background.
-     */
-    private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;
-
-    /**
-     * Change the number of related content rows.
-     */
-    private static final int RELATED_CONTENT_ROWS = 3;
-
-    /**
-     * Change this to select hidden
-     */
-    private static final boolean SECONDARY_HIDDEN = false;
-
-    private static final int ROW_CONTROLS = 0;
-
-    private PlaybackControlHelper mGlue;
-    final Handler mHandler = new Handler();
-
-    // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
-    // called and the playback row UI should be updated after this delay.
-    private static final int MEDIA_PREPARATION_DELAY = 500;
-
-    private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
-        @Override
-        public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
-                                  RowPresenter.ViewHolder rowViewHolder, Row row) {
-            Log.i(TAG, "onItemClicked: " + item + " row " + row);
-            if (item instanceof Action) {
-                mGlue.onActionClicked((Action) item);
-            }
-        }
-    };
-
-    private OnItemViewSelectedListener mOnItemViewSelectedListener =
-            new OnItemViewSelectedListener() {
-                @Override
-                public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
-                                           RowPresenter.ViewHolder rowViewHolder, Row row) {
-                    Log.i(TAG, "onItemSelected: " + item + " row " + row);
-                }
-    };
-
-    @Override
-    public SparseArrayObjectAdapter getAdapter() {
-        return (SparseArrayObjectAdapter) super.getAdapter();
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        Log.i(TAG, "onCreate");
-        super.onCreate(savedInstanceState);
-
-        setBackgroundType(BACKGROUND_TYPE);
-        setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-
-        createComponents(getActivity());
-    }
-
-    private void createComponents(Context context) {
-        mGlue = new PlaybackControlHelper(context, this) {
-            @Override
-            public int getUpdatePeriod() {
-                long totalTime = getControlsRow().getDuration();
-                if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
-                    return 1000;
-                }
-                return 16;
-            }
-
-            @Override
-            protected void onRowChanged(PlaybackControlsRow row) {
-                if (getAdapter() == null) {
-                    return;
-                }
-                int index = getAdapter().indexOf(row);
-                if (index >= 0) {
-                    getAdapter().notifyArrayItemRangeChanged(index, 1);
-                }
-            }
-
-            @Override
-            public void onActionClicked(Action action) {
-                if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    if (Build.VERSION.SDK_INT >= 24) {
-                        getActivity().enterPictureInPictureMode();
-                    }
-                    return;
-                }
-                super.onActionClicked(action);
-            }
-        };
-
-        mGlue.setInitialized(false);
-        mHandler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                mGlue.setInitialized(true);
-            }
-        }, MEDIA_PREPARATION_DELAY);
-        mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
-
-        PlaybackControlsRowPresenter playbackControlsRowPresenter =
-                mGlue.createControlsRowAndPresenter();
-        playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
-        ClassPresenterSelector selector = new ClassPresenterSelector();
-        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
-        selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
-
-        setAdapter(new SparseArrayObjectAdapter(selector));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
-
-        // Add related content rows
-        for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
-            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
-            listRowAdapter.add("Some related content");
-            listRowAdapter.add("Other related content");
-            HeaderItem header = new HeaderItem(i, "Row " + i);
-            getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
-        }
-
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        mGlue.setFadingEnabled(true);
-        mGlue.enableProgressUpdating(true);
-        ((PlaybackOverlayActivity) getActivity()).registerPictureInPictureListener(this);
-    }
-
-    @Override
-    public void onStop() {
-        mGlue.enableProgressUpdating(false);
-        ((PlaybackOverlayActivity) getActivity()).unregisterPictureInPictureListener(this);
-        super.onStop();
-    }
-
-    @Override
-    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        if (isInPictureInPictureMode) {
-            // Hide the controls in picture-in-picture mode.
-            setFadingEnabled(true);
-            fadeOut();
-        } else {
-            setFadingEnabled(mGlue.isPlaying());
-        }
-    }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java
deleted file mode 100644
index 56f1df9..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackOverlayActivity.java.  DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.support.v4.app.FragmentActivity;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PlaybackOverlaySupportActivity extends FragmentActivity {
-    private List<PictureInPictureListener> mListeners = new ArrayList<>();
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.playback_controls_support);
-    }
-
-    @Override
-    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        for (PictureInPictureListener listener : mListeners) {
-            listener.onPictureInPictureModeChanged(isInPictureInPictureMode);
-        }
-    }
-
-    public void registerPictureInPictureListener(PictureInPictureListener listener) {
-        mListeners.add(listener);
-    }
-
-    public void unregisterPictureInPictureListener(PictureInPictureListener listener) {
-        mListeners.remove(listener);
-    }
-
-    public interface PictureInPictureListener {
-        void onPictureInPictureModeChanged(boolean isInPictureInPictureMode);
-    }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
deleted file mode 100644
index 5642557..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
+++ /dev/null
@@ -1,195 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackOverlayFragment.java.  DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.content.Context;
-import android.os.Build;
-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.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.OnItemViewSelectedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.util.Log;
-
-public class PlaybackOverlaySupportFragment
-        extends android.support.v17.leanback.app.PlaybackOverlaySupportFragment
-        implements PlaybackOverlaySupportActivity.PictureInPictureListener {
-    private static final String TAG = "leanback.PlaybackControlsFragment";
-
-    /**
-     * Change this to choose a different overlay background.
-     */
-    private static final int BACKGROUND_TYPE = PlaybackOverlaySupportFragment.BG_LIGHT;
-
-    /**
-     * Change the number of related content rows.
-     */
-    private static final int RELATED_CONTENT_ROWS = 3;
-
-    /**
-     * Change this to select hidden
-     */
-    private static final boolean SECONDARY_HIDDEN = false;
-
-    private static final int ROW_CONTROLS = 0;
-
-    private PlaybackControlSupportHelper mGlue;
-    final Handler mHandler = new Handler();
-
-    // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
-    // called and the playback row UI should be updated after this delay.
-    private static final int MEDIA_PREPARATION_DELAY = 500;
-
-    private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
-        @Override
-        public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
-                                  RowPresenter.ViewHolder rowViewHolder, Row row) {
-            Log.i(TAG, "onItemClicked: " + item + " row " + row);
-            if (item instanceof Action) {
-                mGlue.onActionClicked((Action) item);
-            }
-        }
-    };
-
-    private OnItemViewSelectedListener mOnItemViewSelectedListener =
-            new OnItemViewSelectedListener() {
-                @Override
-                public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
-                                           RowPresenter.ViewHolder rowViewHolder, Row row) {
-                    Log.i(TAG, "onItemSelected: " + item + " row " + row);
-                }
-    };
-
-    @Override
-    public SparseArrayObjectAdapter getAdapter() {
-        return (SparseArrayObjectAdapter) super.getAdapter();
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        Log.i(TAG, "onCreate");
-        super.onCreate(savedInstanceState);
-
-        setBackgroundType(BACKGROUND_TYPE);
-        setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-
-        createComponents(getActivity());
-    }
-
-    private void createComponents(Context context) {
-        mGlue = new PlaybackControlSupportHelper(context, this) {
-            @Override
-            public int getUpdatePeriod() {
-                long totalTime = getControlsRow().getDuration();
-                if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
-                    return 1000;
-                }
-                return 16;
-            }
-
-            @Override
-            protected void onRowChanged(PlaybackControlsRow row) {
-                if (getAdapter() == null) {
-                    return;
-                }
-                int index = getAdapter().indexOf(row);
-                if (index >= 0) {
-                    getAdapter().notifyArrayItemRangeChanged(index, 1);
-                }
-            }
-
-            @Override
-            public void onActionClicked(Action action) {
-                if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    if (Build.VERSION.SDK_INT >= 24) {
-                        getActivity().enterPictureInPictureMode();
-                    }
-                    return;
-                }
-                super.onActionClicked(action);
-            }
-        };
-
-        mGlue.setInitialized(false);
-        mHandler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                mGlue.setInitialized(true);
-            }
-        }, MEDIA_PREPARATION_DELAY);
-        mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
-
-        PlaybackControlsRowPresenter playbackControlsRowPresenter =
-                mGlue.createControlsRowAndPresenter();
-        playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
-        ClassPresenterSelector selector = new ClassPresenterSelector();
-        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
-        selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
-
-        setAdapter(new SparseArrayObjectAdapter(selector));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
-
-        // Add related content rows
-        for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
-            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
-            listRowAdapter.add("Some related content");
-            listRowAdapter.add("Other related content");
-            HeaderItem header = new HeaderItem(i, "Row " + i);
-            getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
-        }
-
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        mGlue.setFadingEnabled(true);
-        mGlue.enableProgressUpdating(true);
-        ((PlaybackOverlaySupportActivity) getActivity()).registerPictureInPictureListener(this);
-    }
-
-    @Override
-    public void onStop() {
-        mGlue.enableProgressUpdating(false);
-        ((PlaybackOverlaySupportActivity) getActivity()).unregisterPictureInPictureListener(this);
-        super.onStop();
-    }
-
-    @Override
-    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
-        if (isInPictureInPictureMode) {
-            // Hide the controls in picture-in-picture mode.
-            setFadingEnabled(true);
-            fadeOut();
-        } else {
-            setFadingEnabled(mGlue.isPlaying());
-        }
-    }
-}
diff --git a/v17/leanback/api/26.0.0.ignore b/v17/leanback/api/26.0.0.ignore
new file mode 100644
index 0000000..81d1fe5
--- /dev/null
+++ b/v17/leanback/api/26.0.0.ignore
@@ -0,0 +1,2 @@
+036d6d4
+07abbac
diff --git a/v17/leanback/api/current.txt b/v17/leanback/api/current.txt
index 00e764b..d67ba42 100644
--- a/v17/leanback/api/current.txt
+++ b/v17/leanback/api/current.txt
@@ -658,53 +658,6 @@
     method protected final void startEnterAnimation(boolean);
   }
 
-  public abstract deprecated class PlaybackControlGlue extends android.support.v17.leanback.media.PlaybackControlGlue {
-    ctor public PlaybackControlGlue(android.content.Context, int[]);
-    ctor public PlaybackControlGlue(android.content.Context, int[], int[]);
-    ctor public PlaybackControlGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[]);
-    ctor public PlaybackControlGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[], int[]);
-    method public android.support.v17.leanback.widget.PlaybackControlsRowPresenter createControlsRowAndPresenter();
-    method protected android.support.v17.leanback.widget.SparseArrayObjectAdapter createPrimaryActionsAdapter(android.support.v17.leanback.widget.PresenterSelector);
-    method public android.support.v17.leanback.app.PlaybackOverlayFragment getFragment();
-    method public deprecated android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
-    method public final void next();
-    method protected void onRowChanged(android.support.v17.leanback.widget.PlaybackControlsRow);
-    method public final void pause();
-    method protected deprecated void pausePlayback();
-    method public final void play(int);
-    method public final void previous();
-    method public deprecated void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
-    method protected deprecated void skipToNext();
-    method protected deprecated void skipToPrevious();
-    method protected deprecated void startPlayback(int);
-  }
-
-  public static abstract deprecated interface PlaybackControlGlue.InputEventHandler {
-    method public abstract boolean handleInputEvent(android.view.InputEvent);
-  }
-
-  public abstract deprecated class PlaybackControlSupportGlue extends android.support.v17.leanback.app.PlaybackControlGlue {
-    ctor public PlaybackControlSupportGlue(android.content.Context, int[]);
-    ctor public PlaybackControlSupportGlue(android.content.Context, int[], int[]);
-    ctor public PlaybackControlSupportGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlaySupportFragment, int[]);
-    ctor public PlaybackControlSupportGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlaySupportFragment, int[], int[]);
-    field public static final int ACTION_CUSTOM_LEFT_FIRST = 1; // 0x1
-    field public static final int ACTION_CUSTOM_RIGHT_FIRST = 4096; // 0x1000
-    field public static final int ACTION_FAST_FORWARD = 128; // 0x80
-    field public static final int ACTION_PLAY_PAUSE = 64; // 0x40
-    field public static final int ACTION_REWIND = 32; // 0x20
-    field public static final int ACTION_SKIP_TO_NEXT = 256; // 0x100
-    field public static final int ACTION_SKIP_TO_PREVIOUS = 16; // 0x10
-    field public static final int PLAYBACK_SPEED_FAST_L0 = 10; // 0xa
-    field public static final int PLAYBACK_SPEED_FAST_L1 = 11; // 0xb
-    field public static final int PLAYBACK_SPEED_FAST_L2 = 12; // 0xc
-    field public static final int PLAYBACK_SPEED_FAST_L3 = 13; // 0xd
-    field public static final int PLAYBACK_SPEED_FAST_L4 = 14; // 0xe
-    field public static final int PLAYBACK_SPEED_INVALID = -1; // 0xffffffff
-    field public static final int PLAYBACK_SPEED_NORMAL = 1; // 0x1
-    field public static final int PLAYBACK_SPEED_PAUSED = 0; // 0x0
-  }
-
   public class PlaybackFragment extends android.app.Fragment {
     ctor public PlaybackFragment();
     method public deprecated void fadeOut();
@@ -746,62 +699,6 @@
     method public void setPlaybackSeekUiClient(android.support.v17.leanback.widget.PlaybackSeekUi.Client);
   }
 
-  public deprecated class PlaybackOverlayFragment extends android.support.v17.leanback.app.DetailsFragment {
-    ctor public PlaybackOverlayFragment();
-    method public void fadeOut();
-    method public int getBackgroundType();
-    method public final android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler getEventHandler();
-    method public android.support.v17.leanback.app.PlaybackOverlayFragment.OnFadeCompleteListener getFadeCompleteListener();
-    method public final deprecated android.support.v17.leanback.app.PlaybackOverlayFragment.InputEventHandler getInputEventHandler();
-    method public boolean isFadingEnabled();
-    method public void setBackgroundType(int);
-    method public final void setEventHandler(android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler);
-    method public void setFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlayFragment.OnFadeCompleteListener);
-    method public void setFadingEnabled(boolean);
-    method public final deprecated void setInputEventHandler(android.support.v17.leanback.app.PlaybackOverlayFragment.InputEventHandler);
-    method public void tickle();
-    field public static final int BG_DARK = 1; // 0x1
-    field public static final int BG_LIGHT = 2; // 0x2
-    field public static final int BG_NONE = 0; // 0x0
-  }
-
-  public static abstract deprecated interface PlaybackOverlayFragment.InputEventHandler implements android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler {
-  }
-
-  public static class PlaybackOverlayFragment.OnFadeCompleteListener {
-    ctor public PlaybackOverlayFragment.OnFadeCompleteListener();
-    method public void onFadeInComplete();
-    method public void onFadeOutComplete();
-  }
-
-  public deprecated class PlaybackOverlaySupportFragment extends android.support.v17.leanback.app.DetailsSupportFragment {
-    ctor public PlaybackOverlaySupportFragment();
-    method public void fadeOut();
-    method public int getBackgroundType();
-    method public final android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler getEventHandler();
-    method public android.support.v17.leanback.app.PlaybackOverlaySupportFragment.OnFadeCompleteListener getFadeCompleteListener();
-    method public final deprecated android.support.v17.leanback.app.PlaybackOverlaySupportFragment.InputEventHandler getInputEventHandler();
-    method public boolean isFadingEnabled();
-    method public void setBackgroundType(int);
-    method public final void setEventHandler(android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler);
-    method public void setFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlaySupportFragment.OnFadeCompleteListener);
-    method public void setFadingEnabled(boolean);
-    method public final deprecated void setInputEventHandler(android.support.v17.leanback.app.PlaybackOverlaySupportFragment.InputEventHandler);
-    method public void tickle();
-    field public static final int BG_DARK = 1; // 0x1
-    field public static final int BG_LIGHT = 2; // 0x2
-    field public static final int BG_NONE = 0; // 0x0
-  }
-
-  public static abstract deprecated interface PlaybackOverlaySupportFragment.InputEventHandler implements android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler {
-  }
-
-  public static class PlaybackOverlaySupportFragment.OnFadeCompleteListener {
-    ctor public PlaybackOverlaySupportFragment.OnFadeCompleteListener();
-    method public void onFadeInComplete();
-    method public void onFadeOutComplete();
-  }
-
   public class PlaybackSupportFragment extends android.support.v4.app.Fragment {
     ctor public PlaybackSupportFragment();
     method public deprecated void fadeOut();
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
deleted file mode 100644
index d74fd11..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.support.v17.leanback.app;
-
-import android.content.Context;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.View;
-
-/**
- * A helper class for managing a {@link android.support.v17.leanback.widget.PlaybackControlsRow}
- * and {@link PlaybackGlueHost} that implements a
- * recommended approach to handling standard playback control actions such as play/pause,
- * fast forward/rewind at progressive speed levels, and skip to next/previous. This helper class
- * is a glue layer in that manages the configuration of and interaction between the
- * leanback UI components by defining a functional interface to the media player.
- *
- * <p>You can instantiate a concrete subclass such as MediaPlayerGlue or you must
- * subclass this abstract helper.  To create a subclass you must implement all of the
- * abstract methods and the subclass must invoke {@link #onMetadataChanged()} and
- * {@link #onStateChanged()} appropriately.
- * </p>
- *
- * <p>To use an instance of the glue layer, first construct an instance.  Constructor parameters
- * inform the glue what speed levels are supported for fast forward/rewind.
- * </p>
- *
- * <p>If you have your own controls row you must pass it to {@link #setControlsRow}.
- * The row will be updated by the glue layer based on the media metadata and playback state.
- * Alternatively, you may call {@link #createControlsRowAndPresenter()} which will set a controls
- * row and return a row presenter you can use to present the row.
- * </p>
- *
- * <p>The helper sets a {@link android.support.v17.leanback.widget.SparseArrayObjectAdapter}
- * on the controls row as the primary actions adapter, and adds actions to it. You can provide
- * additional actions by overriding {@link #createPrimaryActionsAdapter}. This helper does not
- * deal in secondary actions so those you may add separately.
- * </p>
- *
- * <p>Provide a click listener on your fragment and if an action is clicked, call
- * {@link #onActionClicked}. If you set a listener by calling {@link #setOnItemViewClickedListener},
- * your listener will be called for all unhandled actions.
- * </p>
- *
- * <p>This helper implements a key event handler. If you pass a
- * {@link PlaybackOverlayFragment}, it will configure its
- * fragment to intercept all key events.  Otherwise, you should set the glue object as key event
- * handler to the ViewHolder when bound by your row presenter; see
- * {@link RowPresenter.ViewHolder#setOnKeyListener(android.view.View.OnKeyListener)}.
- * </p>
- *
- * <p>To update the controls row progress during playback, override {@link #enableProgressUpdating}
- * to manage the lifecycle of a periodic callback to {@link #updateProgress()}.
- * {@link #getUpdatePeriod()} provides a recommended update period.
- * </p>
- * @deprecated Use {@link android.support.v17.leanback.media.PlaybackControlGlue}
- */
-@Deprecated
-public abstract class PlaybackControlGlue extends
-        android.support.v17.leanback.media.PlaybackControlGlue {
-
-    OnItemViewClickedListener mExternalOnItemViewClickedListener;
-
-    /**
-     * Constructor for the glue.
-     *
-     * @param context
-     * @param seekSpeeds Array of seek speeds for fast forward and rewind.
-     */
-    public PlaybackControlGlue(Context context, int[] seekSpeeds) {
-        super(context, seekSpeeds, seekSpeeds);
-    }
-
-    /**
-     * Constructor for the glue.
-     *
-     * @param context
-     * @param fastForwardSpeeds Array of seek speeds for fast forward.
-     * @param rewindSpeeds Array of seek speeds for rewind.
-     */
-    public PlaybackControlGlue(Context context,
-                               int[] fastForwardSpeeds,
-                               int[] rewindSpeeds) {
-        super(context, fastForwardSpeeds, rewindSpeeds);
-    }
-
-    /**
-     * Constructor for the glue.
-     *
-     * @param context
-     * @param fragment Optional; if using a {@link PlaybackOverlayFragment}, pass it in.
-     * @param seekSpeeds Array of seek speeds for fast forward and rewind.
-     */
-    public PlaybackControlGlue(Context context,
-                               PlaybackOverlayFragment fragment,
-                               int[] seekSpeeds) {
-        this(context, fragment, seekSpeeds, seekSpeeds);
-    }
-
-    /**
-     * Constructor for the glue.
-     *
-     * @param context
-     * @param fragment Optional; if using a {@link PlaybackOverlayFragment}, pass it in.
-     * @param fastForwardSpeeds Array of seek speeds for fast forward.
-     * @param rewindSpeeds Array of seek speeds for rewind.
-     */
-    public PlaybackControlGlue(Context context,
-                               PlaybackOverlayFragment fragment,
-                               int[] fastForwardSpeeds,
-                               int[] rewindSpeeds) {
-        super(context, fastForwardSpeeds, rewindSpeeds);
-        setHost(fragment == null ? (PlaybackGlueHost) null : new PlaybackGlueHostOld(fragment));
-    }
-
-    @Override
-    protected void onAttachedToHost(PlaybackGlueHost host) {
-        super.onAttachedToHost(host);
-        if (host instanceof PlaybackGlueHostOld) {
-            ((PlaybackGlueHostOld) host).mGlue = this;
-        }
-    }
-
-    /**
-     * Returns the fragment.
-     */
-    public PlaybackOverlayFragment getFragment() {
-        if (getHost() instanceof PlaybackGlueHostOld) {
-            return ((PlaybackGlueHostOld)getHost()).mFragment;
-        }
-        return null;
-    }
-
-    /**
-     * Start playback at the given speed.
-     * @deprecated use {@link #play()} instead.
-     *
-     * @param speed The desired playback speed.  For normal playback this will be
-     *              {@link #PLAYBACK_SPEED_NORMAL}; higher positive values for fast forward,
-     *              and negative values for rewind.
-     */
-    @Deprecated
-    protected void startPlayback(int speed) {}
-
-    /**
-     * Pause playback.
-     * @deprecated use {@link #pause()} instead.
-     */
-    @Deprecated
-    protected void pausePlayback() {}
-
-    /**
-     * Skip to the next track.
-     * @deprecated use {@link #next()} instead.
-     */
-    @Deprecated
-    protected void skipToNext() {}
-
-    /**
-     * Skip to the previous track.
-     * @deprecated use {@link #previous()} instead.
-     */
-    @Deprecated
-    protected void skipToPrevious() {}
-
-    @Override
-    public final void next() {
-        skipToNext();
-    }
-
-    @Override
-    public final void previous() {
-        skipToPrevious();
-    }
-
-    @Override
-    public final void play(int speed) {
-        startPlayback(speed);
-    }
-
-    @Override
-    public final void pause() {
-        pausePlayback();
-    }
-
-    /**
-     * This method invoked when the playback controls row has changed. The adapter
-     * containing this row should be notified.
-     */
-    protected void onRowChanged(PlaybackControlsRow row) {
-    }
-
-    /**
-     * Set the {@link OnItemViewClickedListener} to be called if the click event
-     * is not handled internally.
-     * @param listener
-     * @deprecated Don't call this. Instead use the listener on the fragment yourself.
-     */
-    @Deprecated
-    public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
-        mExternalOnItemViewClickedListener = listener;
-    }
-
-    /**
-     * Returns the {@link OnItemViewClickedListener}.
-     * @deprecated Don't call this. Instead use the listener on the fragment yourself.
-     */
-    @Deprecated
-    public OnItemViewClickedListener getOnItemViewClickedListener() {
-        return mExternalOnItemViewClickedListener;
-    }
-
-    @Override
-    protected void onCreateControlsRowAndPresenter() {
-        // backward compatible, we dont create row / presenter by default.
-        // User is expected to call createControlsRowAndPresenter() or setControlsRow()
-        // explicitly.
-    }
-
-    /**
-     * Helper method for instantiating a
-     * {@link android.support.v17.leanback.widget.PlaybackControlsRow} and corresponding
-     * {@link android.support.v17.leanback.widget.PlaybackControlsRowPresenter}.
-     */
-    public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
-        super.onCreateControlsRowAndPresenter();
-        return getControlsRowPresenter();
-    }
-
-    @Override
-    protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
-            PresenterSelector presenterSelector) {
-        return super.createPrimaryActionsAdapter(presenterSelector);
-    }
-
-    /**
-     * Interface allowing the application to handle input events.
-     * @deprecated Use
-     * {@link PlaybackGlueHost#setOnKeyInterceptListener(View.OnKeyListener)}.
-     */
-    @Deprecated
-    public interface InputEventHandler {
-        /**
-         * Called when an {@link InputEvent} is received.
-         *
-         * @return If the event should be consumed, return true. To allow the event to
-         * continue on to the next handler, return false.
-         */
-        boolean handleInputEvent(InputEvent event);
-    }
-
-    static final class PlaybackGlueHostOld extends PlaybackGlueHost {
-        final PlaybackOverlayFragment mFragment;
-        PlaybackControlGlue mGlue;
-        OnActionClickedListener mActionClickedListener;
-
-        public PlaybackGlueHostOld(PlaybackOverlayFragment fragment) {
-            mFragment = fragment;
-            mFragment.setOnItemViewClickedListener(new OnItemViewClickedListener() {
-                @Override
-                public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
-                                          RowPresenter.ViewHolder rowViewHolder, Row row) {
-                    if (item instanceof Action
-                            && rowViewHolder instanceof PlaybackRowPresenter.ViewHolder
-                            && mActionClickedListener != null) {
-                        mActionClickedListener.onActionClicked((Action) item);
-                    } else if (mGlue != null && mGlue.getOnItemViewClickedListener() != null) {
-                        mGlue.getOnItemViewClickedListener().onItemClicked(itemViewHolder,
-                                item, rowViewHolder, row);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void setFadingEnabled(boolean enable) {
-            mFragment.setFadingEnabled(enable);
-        }
-
-        @Override
-        public void setOnKeyInterceptListener(final View.OnKeyListener onKeyListener) {
-            mFragment.setEventHandler( new InputEventHandler() {
-                @Override
-                public boolean handleInputEvent(InputEvent event) {
-                    if (event instanceof KeyEvent) {
-                        KeyEvent keyEvent = (KeyEvent) event;
-                        return onKeyListener.onKey(null, keyEvent.getKeyCode(), keyEvent);
-                    }
-                    return false;
-                }
-            });
-        }
-
-        @Override
-        public void setOnActionClickedListener(final OnActionClickedListener listener) {
-            mActionClickedListener = listener;
-        }
-
-        @Override
-        public void setHostCallback(HostCallback callback) {
-            mFragment.setHostCallback(callback);
-        }
-
-        @Override
-        public void fadeOut() {
-            mFragment.fadeOut();
-        }
-
-        @Override
-        public void notifyPlaybackRowChanged() {
-            mGlue.onRowChanged(mGlue.getControlsRow());
-        }
-    }
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
deleted file mode 100644
index b3d19ae..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/* This file is auto-generated from PlaybackControlGlue.java.  DO NOT MODIFY. */
-
-package android.support.v17.leanback.app;
-
-import android.content.Context;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.View;
-
-/**
- * @deprecated Use {@link android.support.v17.leanback.media.PlaybackControlGlue} and
- * {@link PlaybackSupportFragmentGlueHost} for {@link PlaybackSupportFragment}.
- */
-@Deprecated
-public abstract class PlaybackControlSupportGlue extends PlaybackControlGlue {
-    /**
-     * The adapter key for the first custom control on the left side
-     * of the predefined primary controls.
-     */
-    public static final int ACTION_CUSTOM_LEFT_FIRST = PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST;
-
-    /**
-     * The adapter key for the skip to previous control.
-     */
-    public static final int ACTION_SKIP_TO_PREVIOUS = PlaybackControlGlue.ACTION_SKIP_TO_PREVIOUS;
-
-    /**
-     * The adapter key for the rewind control.
-     */
-    public static final int ACTION_REWIND = PlaybackControlGlue.ACTION_REWIND;
-
-    /**
-     * The adapter key for the play/pause control.
-     */
-    public static final int ACTION_PLAY_PAUSE = PlaybackControlGlue.ACTION_PLAY_PAUSE;
-
-    /**
-     * The adapter key for the fast forward control.
-     */
-    public static final int ACTION_FAST_FORWARD = PlaybackControlGlue.ACTION_FAST_FORWARD;
-
-    /**
-     * The adapter key for the skip to next control.
-     */
-    public static final int ACTION_SKIP_TO_NEXT = PlaybackControlGlue.ACTION_SKIP_TO_NEXT;
-
-    /**
-     * The adapter key for the first custom control on the right side
-     * of the predefined primary controls.
-     */
-    public static final int ACTION_CUSTOM_RIGHT_FIRST =
-            PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST;
-
-    /**
-     * Invalid playback speed.
-     */
-    public static final int PLAYBACK_SPEED_INVALID = PlaybackControlGlue.PLAYBACK_SPEED_INVALID;
-
-    /**
-     * Speed representing playback state that is paused.
-     */
-    public static final int PLAYBACK_SPEED_PAUSED = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
-
-    /**
-     * Speed representing playback state that is playing normally.
-     */
-    public static final int PLAYBACK_SPEED_NORMAL = PlaybackControlGlue.PLAYBACK_SPEED_NORMAL;
-
-    /**
-     * The initial (level 0) fast forward playback speed.
-     * The negative of this value is for rewind at the same speed.
-     */
-    public static final int PLAYBACK_SPEED_FAST_L0 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
-
-    /**
-     * The level 1 fast forward playback speed.
-     * The negative of this value is for rewind at the same speed.
-     */
-    public static final int PLAYBACK_SPEED_FAST_L1 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1;
-
-    /**
-     * The level 2 fast forward playback speed.
-     * The negative of this value is for rewind at the same speed.
-     */
-    public static final int PLAYBACK_SPEED_FAST_L2 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2;
-
-    /**
-     * The level 3 fast forward playback speed.
-     * The negative of this value is for rewind at the same speed.
-     */
-    public static final int PLAYBACK_SPEED_FAST_L3 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L3;
-
-    /**
-     * The level 4 fast forward playback speed.
-     * The negative of this value is for rewind at the same speed.
-     */
-    public static final int PLAYBACK_SPEED_FAST_L4 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L4;
-
-    public PlaybackControlSupportGlue(Context context, int[] seekSpeeds) {
-        this(context, null, seekSpeeds, seekSpeeds);
-    }
-
-    public PlaybackControlSupportGlue(
-            Context context, int[] fastForwardSpeeds, int[] rewindSpeeds) {
-        this(context, null, fastForwardSpeeds, rewindSpeeds);
-    }
-
-    public PlaybackControlSupportGlue(
-            Context context,
-            PlaybackOverlaySupportFragment fragment,
-            int[] seekSpeeds) {
-        this(context, fragment, seekSpeeds, seekSpeeds);
-    }
-
-    public PlaybackControlSupportGlue(
-            Context context,
-            PlaybackOverlaySupportFragment fragment,
-            int[] fastForwardSpeeds,
-            int[] rewindSpeeds) {
-        super(context, fastForwardSpeeds, rewindSpeeds);
-        setHost(fragment == null ? null : new PlaybackSupportGlueHostOld(fragment));
-    }
-
-    @Override
-    protected void onAttachedToHost(PlaybackGlueHost host) {
-        super.onAttachedToHost(host);
-        if (host instanceof PlaybackSupportGlueHostOld) {
-            ((PlaybackSupportGlueHostOld) host).mGlue = this;
-        }
-    }
-
-    static final class PlaybackSupportGlueHostOld extends PlaybackGlueHost {
-        final PlaybackOverlaySupportFragment mFragment;
-        PlaybackControlSupportGlue mGlue;
-        OnActionClickedListener mActionClickedListener;
-
-        public PlaybackSupportGlueHostOld(PlaybackOverlaySupportFragment fragment) {
-            mFragment = fragment;
-            mFragment.setOnItemViewClickedListener(new OnItemViewClickedListener() {
-                @Override
-                public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
-                                          RowPresenter.ViewHolder rowViewHolder, Row row) {
-                    if (item instanceof Action
-                            && rowViewHolder instanceof PlaybackRowPresenter.ViewHolder
-                            && mActionClickedListener != null) {
-                        mActionClickedListener.onActionClicked((Action) item);
-                    } else if (mGlue != null && mGlue.getOnItemViewClickedListener() != null) {
-                        mGlue.getOnItemViewClickedListener().onItemClicked(itemViewHolder,
-                                item, rowViewHolder, row);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void setFadingEnabled(boolean enable) {
-            mFragment.setFadingEnabled(enable);
-        }
-
-        @Override
-        public void setOnKeyInterceptListener(final View.OnKeyListener onKeyListenerr) {
-            mFragment.setEventHandler( new InputEventHandler() {
-                @Override
-                public boolean handleInputEvent(InputEvent event) {
-                    if (event instanceof KeyEvent) {
-                        KeyEvent keyEvent = (KeyEvent) event;
-                        return onKeyListenerr.onKey(null, keyEvent.getKeyCode(), keyEvent);
-                    }
-                    return false;
-                }
-            });
-        }
-
-        @Override
-        public void setOnActionClickedListener(final OnActionClickedListener listener) {
-            mActionClickedListener = listener;
-        }
-
-        @Override
-        public void setHostCallback(HostCallback callback) {
-            mFragment.setHostCallback(callback);
-        }
-
-        @Override
-        public void fadeOut() {
-            mFragment.fadeOut();
-        }
-
-        @Override
-        public void notifyPlaybackRowChanged() {
-            mGlue.onRowChanged(mGlue.getControlsRow());
-        }
-    }
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
deleted file mode 100644
index d4b532b..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.support.v17.leanback.app;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v17.leanback.R;
-import android.support.v17.leanback.animation.LogAccelerateInterpolator;
-import android.support.v17.leanback.animation.LogDecelerateInterpolator;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.ItemAlignmentFacet;
-import android.support.v17.leanback.widget.ItemBridgeAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * A fragment for displaying playback controls and related content.
- * <p>
- * A PlaybackOverlayFragment renders the elements of its {@link ObjectAdapter} as a set
- * of rows in a vertical list.  The Adapter's {@link PresenterSelector} must maintain subclasses
- * of {@link RowPresenter}.
- * </p>
- * <p>
- * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
- * at position 0 in the adapter.
- * </p>
- * <p>
- *  This class is now deprecated, please us
- * </p>
- * @deprecated Use {@link PlaybackFragment}.
- */
-@Deprecated
-public class PlaybackOverlayFragment extends DetailsFragment {
-
-    /**
-     * No background.
-     */
-    public static final int BG_NONE = 0;
-
-    /**
-     * A dark translucent background.
-     */
-    public static final int BG_DARK = 1;
-
-    /**
-     * A light translucent background.
-     */
-    public static final int BG_LIGHT = 2;
-
-    /**
-     * Listener allowing the application to receive notification of fade in and/or fade out
-     * completion events.
-     */
-    public static class OnFadeCompleteListener {
-        public void onFadeInComplete() {
-        }
-        public void onFadeOutComplete() {
-        }
-    }
-
-    static final String TAG = "PlaybackOF";
-    static final boolean DEBUG = false;
-    private static final int ANIMATION_MULTIPLIER = 1;
-
-    static int START_FADE_OUT = 1;
-
-    // Fading status
-    static final int IDLE = 0;
-    private static final int IN = 1;
-    static final int OUT = 2;
-
-    private int mOtherRowsCenterToBottom;
-    private int mPaddingBottom;
-    private View mRootView;
-    private int mBackgroundType = BG_DARK;
-    private int mBgDarkColor;
-    private int mBgLightColor;
-    private int mShowTimeMs;
-    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
-    int mAnimationTranslateY;
-    OnFadeCompleteListener mFadeCompleteListener;
-    private PlaybackControlGlue.InputEventHandler mInputEventHandler;
-    boolean mFadingEnabled = true;
-    int mFadingStatus = IDLE;
-    int mBgAlpha;
-    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
-    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
-    private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
-    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
-    boolean mResetControlsToPrimaryActionsPending;
-    PlaybackGlueHost.HostCallback mHostCallback;
-
-    private final Animator.AnimatorListener mFadeListener =
-            new Animator.AnimatorListener() {
-        @Override
-        public void onAnimationStart(Animator animation) {
-            enableVerticalGridAnimations(false);
-        }
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-        }
-        @Override
-        public void onAnimationCancel(Animator animation) {
-        }
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
-            if (mBgAlpha > 0) {
-                enableVerticalGridAnimations(true);
-                startFadeTimer();
-                if (mFadeCompleteListener != null) {
-                    mFadeCompleteListener.onFadeInComplete();
-                }
-            } else {
-                VerticalGridView verticalView = getVerticalGridView();
-                // reset focus to the primary actions only if the selected row was the controls row
-                if (verticalView != null && verticalView.getSelectedPosition() == 0) {
-                    resetControlsToPrimaryActions(null);
-                }
-                if (mFadeCompleteListener != null) {
-                    mFadeCompleteListener.onFadeOutComplete();
-                }
-            }
-            mFadingStatus = IDLE;
-        }
-    };
-
-    static class FadeHandler extends Handler {
-        @Override
-        public void handleMessage(Message message) {
-            PlaybackOverlayFragment fragment;
-            if (message.what == START_FADE_OUT) {
-                fragment = ((WeakReference<PlaybackOverlayFragment>) message.obj).get();
-                if (fragment != null && fragment.mFadingEnabled) {
-                    fragment.fade(false);
-                }
-            }
-        }
-    }
-
-    static final Handler sHandler = new FadeHandler();
-
-    final WeakReference<PlaybackOverlayFragment> mFragmentReference =  new WeakReference(this);
-
-    private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
-            new VerticalGridView.OnTouchInterceptListener() {
-        @Override
-        public boolean onInterceptTouchEvent(MotionEvent event) {
-            return onInterceptInputEvent(event);
-        }
-    };
-
-    private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
-            new VerticalGridView.OnKeyInterceptListener() {
-        @Override
-        public boolean onInterceptKeyEvent(KeyEvent event) {
-            return onInterceptInputEvent(event);
-        }
-    };
-
-    void setBgAlpha(int alpha) {
-        mBgAlpha = alpha;
-        if (mRootView != null) {
-            mRootView.getBackground().setAlpha(alpha);
-        }
-    }
-
-    void enableVerticalGridAnimations(boolean enable) {
-        if (getVerticalGridView() != null) {
-            getVerticalGridView().setAnimateChildLayout(enable);
-        }
-    }
-
-    void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
-        if (vh == null && getVerticalGridView() != null) {
-            vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
-        }
-        if (vh == null) {
-            mResetControlsToPrimaryActionsPending = true;
-        } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
-            mResetControlsToPrimaryActionsPending = false;
-            ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
-                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
-        }
-    }
-
-    /**
-     * Enables or disables view fading.  If enabled,
-     * the view will be faded in when the fragment starts,
-     * and will fade out after a time period.  The timeout
-     * period is reset each time {@link #tickle} is called.
-     *
-     */
-    public void setFadingEnabled(boolean enabled) {
-        if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
-        if (enabled != mFadingEnabled) {
-            mFadingEnabled = enabled;
-            if (mFadingEnabled) {
-                if (isResumed() && mFadingStatus == IDLE
-                        && !sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
-                    startFadeTimer();
-                }
-            } else {
-                // Ensure fully opaque
-                sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-                fade(true);
-            }
-        }
-    }
-
-    /**
-     * Returns true if view fading is enabled.
-     */
-    public boolean isFadingEnabled() {
-        return mFadingEnabled;
-    }
-
-    /**
-     * Sets the listener to be called when fade in or out has completed.
-     */
-    public void setFadeCompleteListener(OnFadeCompleteListener listener) {
-        mFadeCompleteListener = listener;
-    }
-
-    /**
-     * Returns the listener to be called when fade in or out has completed.
-     */
-    public OnFadeCompleteListener getFadeCompleteListener() {
-        return mFadeCompleteListener;
-    }
-
-    @Deprecated
-    public interface InputEventHandler extends PlaybackControlGlue.InputEventHandler {
-    }
-
-    /**
-     * Sets the input event handler.
-     */
-    @Deprecated
-    public final void setInputEventHandler(InputEventHandler handler) {
-        mInputEventHandler = handler;
-    }
-
-    /**
-     * Returns the input event handler.
-     */
-    @Deprecated
-    public final InputEventHandler getInputEventHandler() {
-        return (InputEventHandler)mInputEventHandler;
-    }
-
-    /**
-     * Sets the input event handler.
-     */
-    public final void setEventHandler(PlaybackControlGlue.InputEventHandler handler) {
-        mInputEventHandler = handler;
-    }
-
-    /**
-     * Returns the input event handler.
-     */
-    public final PlaybackControlGlue.InputEventHandler getEventHandler() {
-        return mInputEventHandler;
-    }
-
-    /**
-     * Tickles the playback controls.  Fades in the view if it was faded out,
-     * otherwise resets the fade out timer.  Tickling on input events is handled
-     * by the fragment.
-     */
-    public void tickle() {
-        if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
-        if (!mFadingEnabled || !isResumed()) {
-            return;
-        }
-        if (sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
-            // Restart the timer
-            startFadeTimer();
-        } else {
-            fade(true);
-        }
-    }
-
-    /**
-     * Fades out the playback overlay immediately.
-     */
-    public void fadeOut() {
-        sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-        fade(false);
-    }
-
-    /**
-     * Sets the {@link PlaybackGlueHost.HostCallback}. Implementor of this interface will
-     * take appropriate actions to take action when the hosting fragment starts/stops processing.
-     */
-    void setHostCallback(PlaybackGlueHost.HostCallback hostCallback) {
-        this.mHostCallback = hostCallback;
-    }
-
-    @Override
-    public void onStop() {
-        if (mHostCallback != null) {
-            mHostCallback.onHostStop();
-        }
-        super.onStop();
-    }
-
-    @Override
-    public void onPause() {
-        if (mHostCallback != null) {
-            mHostCallback.onHostPause();
-        }
-        super.onPause();
-    }
-
-    private boolean areControlsHidden() {
-        return mFadingStatus == IDLE && mBgAlpha == 0;
-    }
-
-    boolean onInterceptInputEvent(InputEvent event) {
-        final boolean controlsHidden = areControlsHidden();
-        if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
-        boolean consumeEvent = false;
-        int keyCode = KeyEvent.KEYCODE_UNKNOWN;
-
-        if (mInputEventHandler != null) {
-            consumeEvent = mInputEventHandler.handleInputEvent(event);
-        }
-        if (event instanceof KeyEvent) {
-            keyCode = ((KeyEvent) event).getKeyCode();
-        }
-
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_CENTER:
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-            case KeyEvent.KEYCODE_DPAD_UP:
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                // Event may be consumed; regardless, if controls are hidden then these keys will
-                // bring up the controls.
-                if (controlsHidden) {
-                    consumeEvent = true;
-                }
-                tickle();
-                break;
-            case KeyEvent.KEYCODE_BACK:
-            case KeyEvent.KEYCODE_ESCAPE:
-                // If fading enabled and controls are not hidden, back will be consumed to fade
-                // them out (even if the key was consumed by the handler).
-                if (mFadingEnabled && !controlsHidden) {
-                    consumeEvent = true;
-                    sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-                    fade(false);
-                } else if (consumeEvent) {
-                    tickle();
-                }
-                break;
-            default:
-                if (consumeEvent) {
-                    tickle();
-                }
-        }
-        return consumeEvent;
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mFadingEnabled) {
-            setBgAlpha(0);
-            fade(true);
-        }
-        getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
-        getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
-        if (mHostCallback != null) {
-            mHostCallback.onHostResume();
-        }
-    }
-
-    void startFadeTimer() {
-        sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-        sHandler.sendMessageDelayed(sHandler.obtainMessage(START_FADE_OUT, mFragmentReference),
-                mShowTimeMs);
-    }
-
-    private static ValueAnimator loadAnimator(Context context, int resId) {
-        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
-        animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
-        return animator;
-    }
-
-    private void loadBgAnimator() {
-        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                setBgAlpha((Integer) arg0.getAnimatedValue());
-            }
-        };
-
-        Context context = FragmentUtil.getContext(this);
-        mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
-        mBgFadeInAnimator.addUpdateListener(listener);
-        mBgFadeInAnimator.addListener(mFadeListener);
-
-        mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
-        mBgFadeOutAnimator.addUpdateListener(listener);
-        mBgFadeOutAnimator.addListener(mFadeListener);
-    }
-
-    private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
-    private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
-
-    View getControlRowView() {
-        if (getVerticalGridView() == null) {
-            return null;
-        }
-        RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
-        if (vh == null) {
-            return null;
-        }
-        return vh.itemView;
-    }
-
-    private void loadControlRowAnimator() {
-        final AnimatorListener listener = new AnimatorListener() {
-            @Override
-            void getViews(ArrayList<View> views) {
-                View view = getControlRowView();
-                if (view != null) {
-                    views.add(view);
-                }
-            }
-        };
-        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                View view = getControlRowView();
-                if (view != null) {
-                    final float fraction = (Float) arg0.getAnimatedValue();
-                    if (DEBUG) Log.v(TAG, "fraction " + fraction);
-                    view.setAlpha(fraction);
-                    view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
-                }
-            }
-        };
-
-        Context context = FragmentUtil.getContext(this);
-        mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
-        mControlRowFadeInAnimator.addUpdateListener(updateListener);
-        mControlRowFadeInAnimator.addListener(listener);
-        mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
-        mControlRowFadeOutAnimator = loadAnimator(context,
-                R.animator.lb_playback_controls_fade_out);
-        mControlRowFadeOutAnimator.addUpdateListener(updateListener);
-        mControlRowFadeOutAnimator.addListener(listener);
-        mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
-    }
-
-    private void loadOtherRowAnimator() {
-        final AnimatorListener listener = new AnimatorListener() {
-            @Override
-            void getViews(ArrayList<View> views) {
-                if (getVerticalGridView() == null) {
-                    return;
-                }
-                final int count = getVerticalGridView().getChildCount();
-                for (int i = 0; i < count; i++) {
-                    View view = getVerticalGridView().getChildAt(i);
-                    if (view != null) {
-                        views.add(view);
-                    }
-                }
-            }
-        };
-        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                if (getVerticalGridView() == null) {
-                    return;
-                }
-                final float fraction = (Float) arg0.getAnimatedValue();
-                for (View view : listener.mViews) {
-                    if (getVerticalGridView().getChildPosition(view) > 0) {
-                        view.setAlpha(fraction);
-                        view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
-                    }
-                }
-            }
-        };
-
-        Context context = FragmentUtil.getContext(this);
-        mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
-        mOtherRowFadeInAnimator.addListener(listener);
-        mOtherRowFadeInAnimator.addUpdateListener(updateListener);
-        mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
-        mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
-        mOtherRowFadeOutAnimator.addListener(listener);
-        mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
-        mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
-    }
-
-    private void loadDescriptionAnimator() {
-        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                if (getVerticalGridView() == null) {
-                    return;
-                }
-                ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
-                        getVerticalGridView().findViewHolderForPosition(0);
-                if (adapterVh != null && adapterVh.getViewHolder()
-                        instanceof PlaybackControlsRowPresenter.ViewHolder) {
-                    final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
-                            adapterVh.getViewHolder()).mDescriptionViewHolder;
-                    if (vh != null) {
-                        vh.view.setAlpha((Float) arg0.getAnimatedValue());
-                    }
-                }
-            }
-        };
-
-        Context context = FragmentUtil.getContext(this);
-        mDescriptionFadeInAnimator = loadAnimator(context,
-                R.animator.lb_playback_description_fade_in);
-        mDescriptionFadeInAnimator.addUpdateListener(listener);
-        mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
-        mDescriptionFadeOutAnimator = loadAnimator(context,
-                R.animator.lb_playback_description_fade_out);
-        mDescriptionFadeOutAnimator.addUpdateListener(listener);
-    }
-
-    void fade(boolean fadeIn) {
-        if (DEBUG) Log.v(TAG, "fade " + fadeIn);
-        if (getView() == null) {
-            return;
-        }
-        if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
-            if (DEBUG) Log.v(TAG, "requested fade in progress");
-            return;
-        }
-        if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
-            if (DEBUG) Log.v(TAG, "fade is no-op");
-            return;
-        }
-
-        mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0
-                ? mMajorFadeTranslateY : mMinorFadeTranslateY;
-
-        if (mFadingStatus == IDLE) {
-            if (fadeIn) {
-                mBgFadeInAnimator.start();
-                mControlRowFadeInAnimator.start();
-                mOtherRowFadeInAnimator.start();
-                mDescriptionFadeInAnimator.start();
-            } else {
-                mBgFadeOutAnimator.start();
-                mControlRowFadeOutAnimator.start();
-                mOtherRowFadeOutAnimator.start();
-                mDescriptionFadeOutAnimator.start();
-            }
-        } else {
-            if (fadeIn) {
-                mBgFadeOutAnimator.reverse();
-                mControlRowFadeOutAnimator.reverse();
-                mOtherRowFadeOutAnimator.reverse();
-                mDescriptionFadeOutAnimator.reverse();
-            } else {
-                mBgFadeInAnimator.reverse();
-                mControlRowFadeInAnimator.reverse();
-                mOtherRowFadeInAnimator.reverse();
-                mDescriptionFadeInAnimator.reverse();
-            }
-        }
-        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
-                : R.string.lb_playback_controls_hidden));
-
-        // If fading in while control row is focused, set initial translationY so
-        // views slide in from below.
-        if (fadeIn && mFadingStatus == IDLE) {
-            final int count = getVerticalGridView().getChildCount();
-            for (int i = 0; i < count; i++) {
-                getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
-            }
-        }
-
-        mFadingStatus = fadeIn ? IN : OUT;
-    }
-
-    /**
-     * Sets the list of rows for the fragment.
-     */
-    @Override
-    public void setAdapter(ObjectAdapter adapter) {
-        if (getAdapter() != null) {
-            getAdapter().unregisterObserver(mObserver);
-        }
-        super.setAdapter(adapter);
-        if (adapter != null) {
-            adapter.registerObserver(mObserver);
-        }
-    }
-
-    @Override
-    protected void setupPresenter(Presenter rowPresenter) {
-        if (rowPresenter instanceof PlaybackRowPresenter) {
-            if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
-                ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
-                ItemAlignmentFacet.ItemAlignmentDef def =
-                        new ItemAlignmentFacet.ItemAlignmentDef();
-                def.setItemAlignmentOffset(0);
-                def.setItemAlignmentOffsetPercent(100);
-                itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
-                        {def});
-                rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
-            }
-        } else {
-            super.setupPresenter(rowPresenter);
-        }
-    }
-
-    @Override
-    void setVerticalGridViewLayout(VerticalGridView listview) {
-        if (listview == null) {
-            return;
-        }
-
-        // we set the base line of alignment to -paddingBottom
-        listview.setWindowAlignmentOffset(-mPaddingBottom);
-        listview.setWindowAlignmentOffsetPercent(
-                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
-
-        // align other rows that arent the last to center of screen, since our baseline is
-        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
-        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
-        listview.setItemAlignmentOffsetPercent(50);
-
-        // Push last row to the bottom padding
-        // Padding affects alignment when last row is focused
-        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
-                listview.getPaddingRight(), mPaddingBottom);
-        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mOtherRowsCenterToBottom = getResources()
-                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
-        mPaddingBottom =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
-        mBgDarkColor =
-                getResources().getColor(R.color.lb_playback_controls_background_dark);
-        mBgLightColor =
-                getResources().getColor(R.color.lb_playback_controls_background_light);
-        mShowTimeMs =
-                getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
-        mMajorFadeTranslateY =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
-        mMinorFadeTranslateY =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
-
-        loadBgAnimator();
-        loadControlRowAnimator();
-        loadOtherRowAnimator();
-        loadDescriptionAnimator();
-    }
-
-    /**
-     * Sets the background type.
-     *
-     * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
-     */
-    public void setBackgroundType(int type) {
-        switch (type) {
-        case BG_LIGHT:
-        case BG_DARK:
-        case BG_NONE:
-            if (type != mBackgroundType) {
-                mBackgroundType = type;
-                updateBackground();
-            }
-            break;
-        default:
-            throw new IllegalArgumentException("Invalid background type");
-        }
-    }
-
-    /**
-     * Returns the background type.
-     */
-    public int getBackgroundType() {
-        return mBackgroundType;
-    }
-
-    private void updateBackground() {
-        if (mRootView != null) {
-            int color = mBgDarkColor;
-            switch (mBackgroundType) {
-                case BG_DARK: break;
-                case BG_LIGHT: color = mBgLightColor; break;
-                case BG_NONE: color = Color.TRANSPARENT; break;
-            }
-            mRootView.setBackground(new ColorDrawable(color));
-        }
-    }
-
-    void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
-        // Add extra space between rows 0 and 1
-        if (vh == null && getVerticalGridView() != null) {
-            vh = (ItemBridgeAdapter.ViewHolder)
-                    getVerticalGridView().findViewHolderForPosition(0);
-        }
-        if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
-            final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
-            ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
-                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
-                    adapterSize > 1);
-        }
-    }
-
-    private final ItemBridgeAdapter.AdapterListener mAdapterListener =
-            new ItemBridgeAdapter.AdapterListener() {
-        @Override
-        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
-            if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
-            if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
-                if (DEBUG) Log.v(TAG, "setting alpha to 0");
-                vh.getViewHolder().view.setAlpha(0);
-            }
-            if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) {
-                resetControlsToPrimaryActions(vh);
-            }
-        }
-        @Override
-        public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
-            if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
-            // Reset animation state
-            vh.getViewHolder().view.setAlpha(1f);
-            vh.getViewHolder().view.setTranslationY(0);
-            if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
-                Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder)
-                        vh.getViewHolder()).mDescriptionViewHolder;
-                if (descriptionVh != null) {
-                    descriptionVh.view.setAlpha(1f);
-                }
-            }
-        }
-        @Override
-        public void onBind(ItemBridgeAdapter.ViewHolder vh) {
-            if (vh.getPosition() == 0) {
-                updateControlsBottomSpace(vh);
-            }
-        }
-    };
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        mRootView = super.onCreateView(inflater, container, savedInstanceState);
-        mBgAlpha = 255;
-        updateBackground();
-        getRowsFragment().setExternalAdapterListener(mAdapterListener);
-        return mRootView;
-    }
-
-    @Override
-    public void onDestroyView() {
-        mRootView = null;
-        if (mHostCallback != null) {
-            mHostCallback.onHostDestroy();
-        }
-        super.onDestroyView();
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        // Workaround problem VideoView forcing itself to focused, let controls take focus.
-        getRowsFragment().getView().requestFocus();
-        if (mHostCallback != null) {
-            mHostCallback.onHostStart();
-        }
-    }
-
-    private final DataObserver mObserver = new DataObserver() {
-        @Override
-        public void onChanged() {
-            updateControlsBottomSpace(null);
-        }
-    };
-
-    static abstract class AnimatorListener implements Animator.AnimatorListener {
-        ArrayList<View> mViews = new ArrayList<View>();
-        ArrayList<Integer> mLayerType = new ArrayList<Integer>();
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-        }
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-        }
-        @Override
-        public void onAnimationStart(Animator animation) {
-            getViews(mViews);
-            for (View view : mViews) {
-                mLayerType.add(view.getLayerType());
-                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            }
-        }
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            for (int i = 0; i < mViews.size(); i++) {
-                mViews.get(i).setLayerType(mLayerType.get(i), null);
-            }
-            mLayerType.clear();
-            mViews.clear();
-        }
-        abstract void getViews(ArrayList<View> views);
-
-    };
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
deleted file mode 100644
index d751320..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ /dev/null
@@ -1,866 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackOverlayFragment.java.  DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.support.v17.leanback.app;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v17.leanback.R;
-import android.support.v17.leanback.animation.LogAccelerateInterpolator;
-import android.support.v17.leanback.animation.LogDecelerateInterpolator;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.ItemAlignmentFacet;
-import android.support.v17.leanback.widget.ItemBridgeAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * A fragment for displaying playback controls and related content.
- * <p>
- * A PlaybackOverlaySupportFragment renders the elements of its {@link ObjectAdapter} as a set
- * of rows in a vertical list.  The Adapter's {@link PresenterSelector} must maintain subclasses
- * of {@link RowPresenter}.
- * </p>
- * <p>
- * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
- * at position 0 in the adapter.
- * </p>
- * <p>
- *  This class is now deprecated, please us
- * </p>
- * @deprecated Use {@link PlaybackSupportFragment}.
- */
-@Deprecated
-public class PlaybackOverlaySupportFragment extends DetailsSupportFragment {
-
-    /**
-     * No background.
-     */
-    public static final int BG_NONE = 0;
-
-    /**
-     * A dark translucent background.
-     */
-    public static final int BG_DARK = 1;
-
-    /**
-     * A light translucent background.
-     */
-    public static final int BG_LIGHT = 2;
-
-    /**
-     * Listener allowing the application to receive notification of fade in and/or fade out
-     * completion events.
-     */
-    public static class OnFadeCompleteListener {
-        public void onFadeInComplete() {
-        }
-        public void onFadeOutComplete() {
-        }
-    }
-
-    static final String TAG = "PlaybackOF";
-    static final boolean DEBUG = false;
-    private static final int ANIMATION_MULTIPLIER = 1;
-
-    static int START_FADE_OUT = 1;
-
-    // Fading status
-    static final int IDLE = 0;
-    private static final int IN = 1;
-    static final int OUT = 2;
-
-    private int mOtherRowsCenterToBottom;
-    private int mPaddingBottom;
-    private View mRootView;
-    private int mBackgroundType = BG_DARK;
-    private int mBgDarkColor;
-    private int mBgLightColor;
-    private int mShowTimeMs;
-    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
-    int mAnimationTranslateY;
-    OnFadeCompleteListener mFadeCompleteListener;
-    private PlaybackControlGlue.InputEventHandler mInputEventHandler;
-    boolean mFadingEnabled = true;
-    int mFadingStatus = IDLE;
-    int mBgAlpha;
-    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
-    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
-    private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
-    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
-    boolean mResetControlsToPrimaryActionsPending;
-    PlaybackGlueHost.HostCallback mHostCallback;
-
-    private final Animator.AnimatorListener mFadeListener =
-            new Animator.AnimatorListener() {
-        @Override
-        public void onAnimationStart(Animator animation) {
-            enableVerticalGridAnimations(false);
-        }
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-        }
-        @Override
-        public void onAnimationCancel(Animator animation) {
-        }
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
-            if (mBgAlpha > 0) {
-                enableVerticalGridAnimations(true);
-                startFadeTimer();
-                if (mFadeCompleteListener != null) {
-                    mFadeCompleteListener.onFadeInComplete();
-                }
-            } else {
-                VerticalGridView verticalView = getVerticalGridView();
-                // reset focus to the primary actions only if the selected row was the controls row
-                if (verticalView != null && verticalView.getSelectedPosition() == 0) {
-                    resetControlsToPrimaryActions(null);
-                }
-                if (mFadeCompleteListener != null) {
-                    mFadeCompleteListener.onFadeOutComplete();
-                }
-            }
-            mFadingStatus = IDLE;
-        }
-    };
-
-    static class FadeHandler extends Handler {
-        @Override
-        public void handleMessage(Message message) {
-            PlaybackOverlaySupportFragment fragment;
-            if (message.what == START_FADE_OUT) {
-                fragment = ((WeakReference<PlaybackOverlaySupportFragment>) message.obj).get();
-                if (fragment != null && fragment.mFadingEnabled) {
-                    fragment.fade(false);
-                }
-            }
-        }
-    }
-
-    static final Handler sHandler = new FadeHandler();
-
-    final WeakReference<PlaybackOverlaySupportFragment> mFragmentReference =  new WeakReference(this);
-
-    private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
-            new VerticalGridView.OnTouchInterceptListener() {
-        @Override
-        public boolean onInterceptTouchEvent(MotionEvent event) {
-            return onInterceptInputEvent(event);
-        }
-    };
-
-    private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
-            new VerticalGridView.OnKeyInterceptListener() {
-        @Override
-        public boolean onInterceptKeyEvent(KeyEvent event) {
-            return onInterceptInputEvent(event);
-        }
-    };
-
-    void setBgAlpha(int alpha) {
-        mBgAlpha = alpha;
-        if (mRootView != null) {
-            mRootView.getBackground().setAlpha(alpha);
-        }
-    }
-
-    void enableVerticalGridAnimations(boolean enable) {
-        if (getVerticalGridView() != null) {
-            getVerticalGridView().setAnimateChildLayout(enable);
-        }
-    }
-
-    void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
-        if (vh == null && getVerticalGridView() != null) {
-            vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
-        }
-        if (vh == null) {
-            mResetControlsToPrimaryActionsPending = true;
-        } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
-            mResetControlsToPrimaryActionsPending = false;
-            ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
-                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
-        }
-    }
-
-    /**
-     * Enables or disables view fading.  If enabled,
-     * the view will be faded in when the fragment starts,
-     * and will fade out after a time period.  The timeout
-     * period is reset each time {@link #tickle} is called.
-     *
-     */
-    public void setFadingEnabled(boolean enabled) {
-        if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
-        if (enabled != mFadingEnabled) {
-            mFadingEnabled = enabled;
-            if (mFadingEnabled) {
-                if (isResumed() && mFadingStatus == IDLE
-                        && !sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
-                    startFadeTimer();
-                }
-            } else {
-                // Ensure fully opaque
-                sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-                fade(true);
-            }
-        }
-    }
-
-    /**
-     * Returns true if view fading is enabled.
-     */
-    public boolean isFadingEnabled() {
-        return mFadingEnabled;
-    }
-
-    /**
-     * Sets the listener to be called when fade in or out has completed.
-     */
-    public void setFadeCompleteListener(OnFadeCompleteListener listener) {
-        mFadeCompleteListener = listener;
-    }
-
-    /**
-     * Returns the listener to be called when fade in or out has completed.
-     */
-    public OnFadeCompleteListener getFadeCompleteListener() {
-        return mFadeCompleteListener;
-    }
-
-    @Deprecated
-    public interface InputEventHandler extends PlaybackControlGlue.InputEventHandler {
-    }
-
-    /**
-     * Sets the input event handler.
-     */
-    @Deprecated
-    public final void setInputEventHandler(InputEventHandler handler) {
-        mInputEventHandler = handler;
-    }
-
-    /**
-     * Returns the input event handler.
-     */
-    @Deprecated
-    public final InputEventHandler getInputEventHandler() {
-        return (InputEventHandler)mInputEventHandler;
-    }
-
-    /**
-     * Sets the input event handler.
-     */
-    public final void setEventHandler(PlaybackControlGlue.InputEventHandler handler) {
-        mInputEventHandler = handler;
-    }
-
-    /**
-     * Returns the input event handler.
-     */
-    public final PlaybackControlGlue.InputEventHandler getEventHandler() {
-        return mInputEventHandler;
-    }
-
-    /**
-     * Tickles the playback controls.  Fades in the view if it was faded out,
-     * otherwise resets the fade out timer.  Tickling on input events is handled
-     * by the fragment.
-     */
-    public void tickle() {
-        if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
-        if (!mFadingEnabled || !isResumed()) {
-            return;
-        }
-        if (sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
-            // Restart the timer
-            startFadeTimer();
-        } else {
-            fade(true);
-        }
-    }
-
-    /**
-     * Fades out the playback overlay immediately.
-     */
-    public void fadeOut() {
-        sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-        fade(false);
-    }
-
-    /**
-     * Sets the {@link PlaybackGlueHost.HostCallback}. Implementor of this interface will
-     * take appropriate actions to take action when the hosting fragment starts/stops processing.
-     */
-    void setHostCallback(PlaybackGlueHost.HostCallback hostCallback) {
-        this.mHostCallback = hostCallback;
-    }
-
-    @Override
-    public void onStop() {
-        if (mHostCallback != null) {
-            mHostCallback.onHostStop();
-        }
-        super.onStop();
-    }
-
-    @Override
-    public void onPause() {
-        if (mHostCallback != null) {
-            mHostCallback.onHostPause();
-        }
-        super.onPause();
-    }
-
-    private boolean areControlsHidden() {
-        return mFadingStatus == IDLE && mBgAlpha == 0;
-    }
-
-    boolean onInterceptInputEvent(InputEvent event) {
-        final boolean controlsHidden = areControlsHidden();
-        if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
-        boolean consumeEvent = false;
-        int keyCode = KeyEvent.KEYCODE_UNKNOWN;
-
-        if (mInputEventHandler != null) {
-            consumeEvent = mInputEventHandler.handleInputEvent(event);
-        }
-        if (event instanceof KeyEvent) {
-            keyCode = ((KeyEvent) event).getKeyCode();
-        }
-
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_CENTER:
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-            case KeyEvent.KEYCODE_DPAD_UP:
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                // Event may be consumed; regardless, if controls are hidden then these keys will
-                // bring up the controls.
-                if (controlsHidden) {
-                    consumeEvent = true;
-                }
-                tickle();
-                break;
-            case KeyEvent.KEYCODE_BACK:
-            case KeyEvent.KEYCODE_ESCAPE:
-                // If fading enabled and controls are not hidden, back will be consumed to fade
-                // them out (even if the key was consumed by the handler).
-                if (mFadingEnabled && !controlsHidden) {
-                    consumeEvent = true;
-                    sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-                    fade(false);
-                } else if (consumeEvent) {
-                    tickle();
-                }
-                break;
-            default:
-                if (consumeEvent) {
-                    tickle();
-                }
-        }
-        return consumeEvent;
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mFadingEnabled) {
-            setBgAlpha(0);
-            fade(true);
-        }
-        getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
-        getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
-        if (mHostCallback != null) {
-            mHostCallback.onHostResume();
-        }
-    }
-
-    void startFadeTimer() {
-        sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
-        sHandler.sendMessageDelayed(sHandler.obtainMessage(START_FADE_OUT, mFragmentReference),
-                mShowTimeMs);
-    }
-
-    private static ValueAnimator loadAnimator(Context context, int resId) {
-        ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
-        animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
-        return animator;
-    }
-
-    private void loadBgAnimator() {
-        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                setBgAlpha((Integer) arg0.getAnimatedValue());
-            }
-        };
-
-        Context context = getContext();
-        mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
-        mBgFadeInAnimator.addUpdateListener(listener);
-        mBgFadeInAnimator.addListener(mFadeListener);
-
-        mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
-        mBgFadeOutAnimator.addUpdateListener(listener);
-        mBgFadeOutAnimator.addListener(mFadeListener);
-    }
-
-    private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
-    private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
-
-    View getControlRowView() {
-        if (getVerticalGridView() == null) {
-            return null;
-        }
-        RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
-        if (vh == null) {
-            return null;
-        }
-        return vh.itemView;
-    }
-
-    private void loadControlRowAnimator() {
-        final AnimatorListener listener = new AnimatorListener() {
-            @Override
-            void getViews(ArrayList<View> views) {
-                View view = getControlRowView();
-                if (view != null) {
-                    views.add(view);
-                }
-            }
-        };
-        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                View view = getControlRowView();
-                if (view != null) {
-                    final float fraction = (Float) arg0.getAnimatedValue();
-                    if (DEBUG) Log.v(TAG, "fraction " + fraction);
-                    view.setAlpha(fraction);
-                    view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
-                }
-            }
-        };
-
-        Context context = getContext();
-        mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
-        mControlRowFadeInAnimator.addUpdateListener(updateListener);
-        mControlRowFadeInAnimator.addListener(listener);
-        mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
-        mControlRowFadeOutAnimator = loadAnimator(context,
-                R.animator.lb_playback_controls_fade_out);
-        mControlRowFadeOutAnimator.addUpdateListener(updateListener);
-        mControlRowFadeOutAnimator.addListener(listener);
-        mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
-    }
-
-    private void loadOtherRowAnimator() {
-        final AnimatorListener listener = new AnimatorListener() {
-            @Override
-            void getViews(ArrayList<View> views) {
-                if (getVerticalGridView() == null) {
-                    return;
-                }
-                final int count = getVerticalGridView().getChildCount();
-                for (int i = 0; i < count; i++) {
-                    View view = getVerticalGridView().getChildAt(i);
-                    if (view != null) {
-                        views.add(view);
-                    }
-                }
-            }
-        };
-        final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                if (getVerticalGridView() == null) {
-                    return;
-                }
-                final float fraction = (Float) arg0.getAnimatedValue();
-                for (View view : listener.mViews) {
-                    if (getVerticalGridView().getChildPosition(view) > 0) {
-                        view.setAlpha(fraction);
-                        view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
-                    }
-                }
-            }
-        };
-
-        Context context = getContext();
-        mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
-        mOtherRowFadeInAnimator.addListener(listener);
-        mOtherRowFadeInAnimator.addUpdateListener(updateListener);
-        mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
-        mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
-        mOtherRowFadeOutAnimator.addListener(listener);
-        mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
-        mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
-    }
-
-    private void loadDescriptionAnimator() {
-        AnimatorUpdateListener listener = new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator arg0) {
-                if (getVerticalGridView() == null) {
-                    return;
-                }
-                ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
-                        getVerticalGridView().findViewHolderForPosition(0);
-                if (adapterVh != null && adapterVh.getViewHolder()
-                        instanceof PlaybackControlsRowPresenter.ViewHolder) {
-                    final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
-                            adapterVh.getViewHolder()).mDescriptionViewHolder;
-                    if (vh != null) {
-                        vh.view.setAlpha((Float) arg0.getAnimatedValue());
-                    }
-                }
-            }
-        };
-
-        Context context = getContext();
-        mDescriptionFadeInAnimator = loadAnimator(context,
-                R.animator.lb_playback_description_fade_in);
-        mDescriptionFadeInAnimator.addUpdateListener(listener);
-        mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
-        mDescriptionFadeOutAnimator = loadAnimator(context,
-                R.animator.lb_playback_description_fade_out);
-        mDescriptionFadeOutAnimator.addUpdateListener(listener);
-    }
-
-    void fade(boolean fadeIn) {
-        if (DEBUG) Log.v(TAG, "fade " + fadeIn);
-        if (getView() == null) {
-            return;
-        }
-        if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
-            if (DEBUG) Log.v(TAG, "requested fade in progress");
-            return;
-        }
-        if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
-            if (DEBUG) Log.v(TAG, "fade is no-op");
-            return;
-        }
-
-        mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0
-                ? mMajorFadeTranslateY : mMinorFadeTranslateY;
-
-        if (mFadingStatus == IDLE) {
-            if (fadeIn) {
-                mBgFadeInAnimator.start();
-                mControlRowFadeInAnimator.start();
-                mOtherRowFadeInAnimator.start();
-                mDescriptionFadeInAnimator.start();
-            } else {
-                mBgFadeOutAnimator.start();
-                mControlRowFadeOutAnimator.start();
-                mOtherRowFadeOutAnimator.start();
-                mDescriptionFadeOutAnimator.start();
-            }
-        } else {
-            if (fadeIn) {
-                mBgFadeOutAnimator.reverse();
-                mControlRowFadeOutAnimator.reverse();
-                mOtherRowFadeOutAnimator.reverse();
-                mDescriptionFadeOutAnimator.reverse();
-            } else {
-                mBgFadeInAnimator.reverse();
-                mControlRowFadeInAnimator.reverse();
-                mOtherRowFadeInAnimator.reverse();
-                mDescriptionFadeInAnimator.reverse();
-            }
-        }
-        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
-                : R.string.lb_playback_controls_hidden));
-
-        // If fading in while control row is focused, set initial translationY so
-        // views slide in from below.
-        if (fadeIn && mFadingStatus == IDLE) {
-            final int count = getVerticalGridView().getChildCount();
-            for (int i = 0; i < count; i++) {
-                getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
-            }
-        }
-
-        mFadingStatus = fadeIn ? IN : OUT;
-    }
-
-    /**
-     * Sets the list of rows for the fragment.
-     */
-    @Override
-    public void setAdapter(ObjectAdapter adapter) {
-        if (getAdapter() != null) {
-            getAdapter().unregisterObserver(mObserver);
-        }
-        super.setAdapter(adapter);
-        if (adapter != null) {
-            adapter.registerObserver(mObserver);
-        }
-    }
-
-    @Override
-    protected void setupPresenter(Presenter rowPresenter) {
-        if (rowPresenter instanceof PlaybackRowPresenter) {
-            if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
-                ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
-                ItemAlignmentFacet.ItemAlignmentDef def =
-                        new ItemAlignmentFacet.ItemAlignmentDef();
-                def.setItemAlignmentOffset(0);
-                def.setItemAlignmentOffsetPercent(100);
-                itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
-                        {def});
-                rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
-            }
-        } else {
-            super.setupPresenter(rowPresenter);
-        }
-    }
-
-    @Override
-    void setVerticalGridViewLayout(VerticalGridView listview) {
-        if (listview == null) {
-            return;
-        }
-
-        // we set the base line of alignment to -paddingBottom
-        listview.setWindowAlignmentOffset(-mPaddingBottom);
-        listview.setWindowAlignmentOffsetPercent(
-                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
-
-        // align other rows that arent the last to center of screen, since our baseline is
-        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
-        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
-        listview.setItemAlignmentOffsetPercent(50);
-
-        // Push last row to the bottom padding
-        // Padding affects alignment when last row is focused
-        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
-                listview.getPaddingRight(), mPaddingBottom);
-        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mOtherRowsCenterToBottom = getResources()
-                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
-        mPaddingBottom =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
-        mBgDarkColor =
-                getResources().getColor(R.color.lb_playback_controls_background_dark);
-        mBgLightColor =
-                getResources().getColor(R.color.lb_playback_controls_background_light);
-        mShowTimeMs =
-                getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
-        mMajorFadeTranslateY =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
-        mMinorFadeTranslateY =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
-
-        loadBgAnimator();
-        loadControlRowAnimator();
-        loadOtherRowAnimator();
-        loadDescriptionAnimator();
-    }
-
-    /**
-     * Sets the background type.
-     *
-     * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
-     */
-    public void setBackgroundType(int type) {
-        switch (type) {
-        case BG_LIGHT:
-        case BG_DARK:
-        case BG_NONE:
-            if (type != mBackgroundType) {
-                mBackgroundType = type;
-                updateBackground();
-            }
-            break;
-        default:
-            throw new IllegalArgumentException("Invalid background type");
-        }
-    }
-
-    /**
-     * Returns the background type.
-     */
-    public int getBackgroundType() {
-        return mBackgroundType;
-    }
-
-    private void updateBackground() {
-        if (mRootView != null) {
-            int color = mBgDarkColor;
-            switch (mBackgroundType) {
-                case BG_DARK: break;
-                case BG_LIGHT: color = mBgLightColor; break;
-                case BG_NONE: color = Color.TRANSPARENT; break;
-            }
-            mRootView.setBackground(new ColorDrawable(color));
-        }
-    }
-
-    void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
-        // Add extra space between rows 0 and 1
-        if (vh == null && getVerticalGridView() != null) {
-            vh = (ItemBridgeAdapter.ViewHolder)
-                    getVerticalGridView().findViewHolderForPosition(0);
-        }
-        if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
-            final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
-            ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
-                    (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
-                    adapterSize > 1);
-        }
-    }
-
-    private final ItemBridgeAdapter.AdapterListener mAdapterListener =
-            new ItemBridgeAdapter.AdapterListener() {
-        @Override
-        public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
-            if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
-            if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
-                if (DEBUG) Log.v(TAG, "setting alpha to 0");
-                vh.getViewHolder().view.setAlpha(0);
-            }
-            if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) {
-                resetControlsToPrimaryActions(vh);
-            }
-        }
-        @Override
-        public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
-            if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
-            // Reset animation state
-            vh.getViewHolder().view.setAlpha(1f);
-            vh.getViewHolder().view.setTranslationY(0);
-            if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
-                Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder)
-                        vh.getViewHolder()).mDescriptionViewHolder;
-                if (descriptionVh != null) {
-                    descriptionVh.view.setAlpha(1f);
-                }
-            }
-        }
-        @Override
-        public void onBind(ItemBridgeAdapter.ViewHolder vh) {
-            if (vh.getPosition() == 0) {
-                updateControlsBottomSpace(vh);
-            }
-        }
-    };
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        mRootView = super.onCreateView(inflater, container, savedInstanceState);
-        mBgAlpha = 255;
-        updateBackground();
-        getRowsSupportFragment().setExternalAdapterListener(mAdapterListener);
-        return mRootView;
-    }
-
-    @Override
-    public void onDestroyView() {
-        mRootView = null;
-        if (mHostCallback != null) {
-            mHostCallback.onHostDestroy();
-        }
-        super.onDestroyView();
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        // Workaround problem VideoView forcing itself to focused, let controls take focus.
-        getRowsSupportFragment().getView().requestFocus();
-        if (mHostCallback != null) {
-            mHostCallback.onHostStart();
-        }
-    }
-
-    private final DataObserver mObserver = new DataObserver() {
-        @Override
-        public void onChanged() {
-            updateControlsBottomSpace(null);
-        }
-    };
-
-    static abstract class AnimatorListener implements Animator.AnimatorListener {
-        ArrayList<View> mViews = new ArrayList<View>();
-        ArrayList<Integer> mLayerType = new ArrayList<Integer>();
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-        }
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-        }
-        @Override
-        public void onAnimationStart(Animator animation) {
-            getViews(mViews);
-            for (View view : mViews) {
-                mLayerType.add(view.getLayerType());
-                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            }
-        }
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            for (int i = 0; i < mViews.size(); i++) {
-                mViews.get(i).setLayerType(mLayerType.get(i), null);
-            }
-            mLayerType.clear();
-            mViews.clear();
-        }
-        abstract void getViews(ArrayList<View> views);
-
-    };
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
index 82cfa79..000db3c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
@@ -32,7 +32,7 @@
 /**
  * A PlaybackControlsRowPresenter renders a {@link PlaybackControlsRow} to display a
  * series of playback control buttons. Typically this row will be the first row in a fragment
- * such as the {@link android.support.v17.leanback.app.PlaybackOverlayFragment}.
+ * such as the {@link android.support.v17.leanback.app.PlaybackFragment}.
  *
  * <p>The detailed description is rendered using a {@link Presenter} passed in
  * {@link #PlaybackControlsRowPresenter(Presenter)}.  Typically this will be an instance of
diff --git a/v17/leanback/tests/generatev4.py b/v17/leanback/tests/generatev4.py
index 9e4f935..d87ff6f 100755
--- a/v17/leanback/tests/generatev4.py
+++ b/v17/leanback/tests/generatev4.py
@@ -166,18 +166,3 @@
 file.close()
 outfile.close()
 
-####### generate glue support test #######
-
-print "copy PlaybackControlGlueTest to PlaybackControlSupportGlueTest"
-file = open('java/android/support/v17/leanback/app/PlaybackControlGlueTest.java', 'r')
-outfile = open('java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java', 'w')
-outfile.write("// CHECKSTYLE:OFF Generated code\n")
-outfile.write("/* This file is auto-generated from PlaybackControlGlueTest.java.  DO NOT MODIFY. */\n\n")
-for line in file:
-    line = line.replace('PlaybackControlGlue', 'PlaybackControlSupportGlue')
-    line = line.replace('PlaybackOverlayFragment', 'PlaybackOverlaySupportFragment')
-    line = line.replace('PlaybackGlueHostOld', 'PlaybackSupportGlueHostOld')
-    outfile.write(line)
-file.close()
-outfile.close()
-
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
deleted file mode 100644
index 70c8795..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v17.leanback.app;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class PlaybackControlGlueTest {
-
-
-    static class PlayControlGlueImpl extends PlaybackControlGlue {
-        int mSpeedId = PLAYBACK_SPEED_PAUSED;
-        // number of times onRowChanged callback is called
-        int mOnRowChangedCallCount = 0;
-
-        PlayControlGlueImpl(Context context, int[] seekSpeeds) {
-            super(context, seekSpeeds);
-        }
-
-        PlayControlGlueImpl(Context context, int[] ffSpeeds, int[] rwSpeeds) {
-            super(context, ffSpeeds, rwSpeeds);
-        }
-
-        PlayControlGlueImpl(Context context, PlaybackOverlayFragment fragment,
-                                   int[] seekSpeeds) {
-            super(context, fragment, seekSpeeds);
-        }
-
-        @Override
-        public boolean hasValidMedia() {
-            return true;
-        }
-
-        @Override
-        public boolean isMediaPlaying() {
-            return mSpeedId == PLAYBACK_SPEED_NORMAL;
-        }
-
-        @Override
-        public CharSequence getMediaTitle() {
-            return "DUMP TITLE";
-        }
-
-        @Override
-        public CharSequence getMediaSubtitle() {
-            return "DUMP SUBTITLE";
-        }
-
-        @Override
-        public int getMediaDuration() {
-            return 50000;
-        }
-
-        @Override
-        public Drawable getMediaArt() {
-            return null;
-        }
-
-        @Override
-        public long getSupportedActions() {
-            return ACTION_REWIND | ACTION_FAST_FORWARD | ACTION_PLAY_PAUSE;
-        }
-
-        @Override
-        public int getCurrentSpeedId() {
-            return mSpeedId;
-        }
-
-        @Override
-        public int getCurrentPosition() {
-            return 5000;
-        }
-
-        @Override
-        protected void startPlayback(int speed) {
-            mSpeedId = speed;
-        }
-
-        @Override
-        protected void pausePlayback() {
-            mSpeedId = PLAYBACK_SPEED_PAUSED;
-        }
-
-        @Override
-        protected void skipToNext() {
-        }
-
-        @Override
-        protected void skipToPrevious() {
-        }
-
-        @Override
-        protected void onRowChanged(PlaybackControlsRow row) {
-            mOnRowChangedCallCount++;
-        }
-
-        public void notifyMetaDataChanged() {
-            onMetadataChanged();
-            onStateChanged();
-        }
-
-        public int getOnRowChangedCallCount() {
-            return mOnRowChangedCallCount;
-        }
-    }
-
-    Context context;
-    PlaybackControlGlue glue;
-
-    @Before
-    public void setUp() {
-        context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        try {
-            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-                @Override
-                public void run() {
-                    glue = new PlayControlGlueImpl(context, new int[]{
-                            PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
-                            PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
-                            PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
-                    });
-                }
-            });
-        } catch (Throwable throwable) {
-            Assert.fail(throwable.getMessage());
-        }
-    }
-
-    @Test
-    public void testFastForwardToMaxThenReset() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_REWIND);
-
-        assertFalse(glue.isMediaPlaying());
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // click multiple times to reach PLAYBACK_SPEED_FAST_L2
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        assertEquals(1, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
-        assertEquals(2, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(3, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(3, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // press playPause again put it back to play
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-    }
-
-    @Test
-    public void testFastRewindToMaxThenReset() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_REWIND);
-
-        assertFalse(glue.isMediaPlaying());
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // click multiple times to reach PLAYBACK_SPEED_FAST_L2
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(1, rewind.getIndex());
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(2, rewind.getIndex());
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(3, rewind.getIndex());
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(3, rewind.getIndex());
-
-        // press playPause again put it back to play
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-    }
-
-    @Test
-    public void testFastForwardAbortKeyCodes() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_REWIND);
-
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // Testing keycodes that will not abort seek
-        final int[] noAbortSeekKeyCodes = new int[] {
-                KeyEvent.KEYCODE_DPAD_CENTER,
-                KeyEvent.KEYCODE_ENTER
-        };
-        for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(fastForward);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(1, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
-            glue.onKey(null, noAbortSeekKeyCodes[i], kv);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            glue.onActionClicked(playPause);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        }
-
-        // Testing abortSeekKeyCodes
-        final int[] abortSeekKeyCodes = new int[] {
-            KeyEvent.KEYCODE_DPAD_UP,
-            KeyEvent.KEYCODE_DPAD_DOWN,
-            KeyEvent.KEYCODE_DPAD_RIGHT,
-            KeyEvent.KEYCODE_DPAD_LEFT,
-            KeyEvent.KEYCODE_BACK,
-            KeyEvent.KEYCODE_ESCAPE
-        };
-        for (int i = 0; i < abortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(fastForward);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(1, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
-            glue.onKey(null, abortSeekKeyCodes[i], kv);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-        }
-    }
-
-    @Test
-    public void testRewindAbortKeyCodes() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_REWIND);
-
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // Testing keycodes that will not abort seek
-        final int[] noAbortSeekKeyCodes = new int[] {
-                KeyEvent.KEYCODE_DPAD_CENTER,
-                KeyEvent.KEYCODE_ENTER
-        };
-        for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(rewind);
-            assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(1, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
-            glue.onKey(null, noAbortSeekKeyCodes[i], kv);
-            assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            glue.onActionClicked(playPause);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        }
-
-        // Testing abortSeekKeyCodes
-        final int[] abortSeekKeyCodes = new int[] {
-                KeyEvent.KEYCODE_DPAD_UP,
-                KeyEvent.KEYCODE_DPAD_DOWN,
-                KeyEvent.KEYCODE_DPAD_RIGHT,
-                KeyEvent.KEYCODE_DPAD_LEFT,
-                KeyEvent.KEYCODE_BACK,
-                KeyEvent.KEYCODE_ESCAPE
-        };
-        for (int i = 0; i < abortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(rewind);
-            assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(1, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
-            glue.onKey(null, abortSeekKeyCodes[i], kv);
-            assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-        }
-    }
-
-    @Test
-    public void testMediaPauseButtonOnFF() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PAUSE));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPauseButtonOnPlay() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PAUSE));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPauseButtonOnPause() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PAUSE));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayButtonOnFF() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayButtonOnPlay() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayButtonOnPause() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayPauseButtonOnFF() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayPauseButtonOnPlay() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayPauseButtonOnPause() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testOnItemClickedListener() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        final PlaybackOverlayFragment[] fragmentResult = new PlaybackOverlayFragment[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                fragmentResult[0] = new PlaybackOverlayFragment();
-            }
-        });
-        PlaybackOverlayFragment fragment = fragmentResult[0];
-        glue.setHost(new PlaybackControlGlue.PlaybackGlueHostOld(fragment));
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-        OnItemViewClickedListener listener = Mockito.mock(OnItemViewClickedListener.class);
-        glue.setOnItemViewClickedListener(listener);
-
-        // create fake row ViewHolder and fade item ViewHolder
-        View rowView = new View(context);
-        View view = new View(context);
-        PlaybackRowPresenter.ViewHolder rowVh = new PlaybackRowPresenter.ViewHolder(rowView);
-        Presenter.ViewHolder vh = new Presenter.ViewHolder(view);
-
-        // Initially media is paused
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-
-        // simulate a click inside PlaybackOverlayFragment's PlaybackRow.
-        fragment.getOnItemViewClickedListener().onItemClicked(vh, playPause, rowVh, row);
-        verify(listener, times(0)).onItemClicked(vh, playPause, rowVh, row);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-
-        // simulate a click on object other than PlaybackRow.
-        Object regularItem = new Object();
-        Row regularRow = new Row();
-        RowPresenter.ViewHolder regularRowViewHolder = new RowPresenter.ViewHolder(rowView);
-        Presenter.ViewHolder regularViewHOlder = new Presenter.ViewHolder(view);
-        fragment.getOnItemViewClickedListener().onItemClicked(regularViewHOlder, regularItem,
-                regularRowViewHolder, regularRow);
-        verify(listener, times(1)).onItemClicked(regularViewHOlder, regularItem,
-                regularRowViewHolder, regularRow);
-        assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testOnRowChangedCallback() throws Exception {
-        final PlaybackOverlayFragment[] fragmentResult = new
-                PlaybackOverlayFragment[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                fragmentResult[0] = new PlaybackOverlayFragment();
-            }
-        });
-        PlaybackOverlayFragment fragment = fragmentResult[0];
-        PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
-                new int[]{
-                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
-                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
-                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
-                });
-
-        // before any controls row is created the count is zero
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
-        playbackGlue.createControlsRowAndPresenter();
-        // after a controls row is created, onRowChanged() call back is called once
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-        playbackGlue.notifyMetaDataChanged();
-        // onMetaDataChanged() calls updateRowMetadata which ends up calling
-        // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-    }
-
-
-    @Test
-    public void testWithoutValidMedia() throws Exception {
-        final PlaybackOverlayFragment[] fragmentResult = new
-                PlaybackOverlayFragment[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                fragmentResult[0] = new PlaybackOverlayFragment();
-            }
-        });
-        final boolean[] hasValidMedia = new boolean[] {false};
-        PlaybackOverlayFragment fragment = fragmentResult[0];
-        PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
-                new int[]{
-                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
-                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
-                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
-                }) {
-            @Override
-            public boolean hasValidMedia() {
-                return hasValidMedia[0];
-            }
-        };
-
-        // before any controls row is created the count is zero
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
-        playbackGlue.createControlsRowAndPresenter();
-        // after a controls row is created, onRowChanged() call back is called once
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
-        // enven hasValidMedia() is false, we should still have three buttons.
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-
-        hasValidMedia[0] = true;
-        playbackGlue.notifyMetaDataChanged();
-        // onMetaDataChanged() calls updateRowMetadata which ends up calling
-        // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-    }
-
-}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
deleted file mode 100644
index 37f5754..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
+++ /dev/null
@@ -1,652 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackControlGlueTest.java.  DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v17.leanback.app;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class PlaybackControlSupportGlueTest {
-
-
-    static class PlayControlGlueImpl extends PlaybackControlSupportGlue {
-        int mSpeedId = PLAYBACK_SPEED_PAUSED;
-        // number of times onRowChanged callback is called
-        int mOnRowChangedCallCount = 0;
-
-        PlayControlGlueImpl(Context context, int[] seekSpeeds) {
-            super(context, seekSpeeds);
-        }
-
-        PlayControlGlueImpl(Context context, int[] ffSpeeds, int[] rwSpeeds) {
-            super(context, ffSpeeds, rwSpeeds);
-        }
-
-        PlayControlGlueImpl(Context context, PlaybackOverlaySupportFragment fragment,
-                                   int[] seekSpeeds) {
-            super(context, fragment, seekSpeeds);
-        }
-
-        @Override
-        public boolean hasValidMedia() {
-            return true;
-        }
-
-        @Override
-        public boolean isMediaPlaying() {
-            return mSpeedId == PLAYBACK_SPEED_NORMAL;
-        }
-
-        @Override
-        public CharSequence getMediaTitle() {
-            return "DUMP TITLE";
-        }
-
-        @Override
-        public CharSequence getMediaSubtitle() {
-            return "DUMP SUBTITLE";
-        }
-
-        @Override
-        public int getMediaDuration() {
-            return 50000;
-        }
-
-        @Override
-        public Drawable getMediaArt() {
-            return null;
-        }
-
-        @Override
-        public long getSupportedActions() {
-            return ACTION_REWIND | ACTION_FAST_FORWARD | ACTION_PLAY_PAUSE;
-        }
-
-        @Override
-        public int getCurrentSpeedId() {
-            return mSpeedId;
-        }
-
-        @Override
-        public int getCurrentPosition() {
-            return 5000;
-        }
-
-        @Override
-        protected void startPlayback(int speed) {
-            mSpeedId = speed;
-        }
-
-        @Override
-        protected void pausePlayback() {
-            mSpeedId = PLAYBACK_SPEED_PAUSED;
-        }
-
-        @Override
-        protected void skipToNext() {
-        }
-
-        @Override
-        protected void skipToPrevious() {
-        }
-
-        @Override
-        protected void onRowChanged(PlaybackControlsRow row) {
-            mOnRowChangedCallCount++;
-        }
-
-        public void notifyMetaDataChanged() {
-            onMetadataChanged();
-            onStateChanged();
-        }
-
-        public int getOnRowChangedCallCount() {
-            return mOnRowChangedCallCount;
-        }
-    }
-
-    Context context;
-    PlaybackControlSupportGlue glue;
-
-    @Before
-    public void setUp() {
-        context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        try {
-            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-                @Override
-                public void run() {
-                    glue = new PlayControlGlueImpl(context, new int[]{
-                            PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
-                            PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
-                            PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
-                    });
-                }
-            });
-        } catch (Throwable throwable) {
-            Assert.fail(throwable.getMessage());
-        }
-    }
-
-    @Test
-    public void testFastForwardToMaxThenReset() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
-        assertFalse(glue.isMediaPlaying());
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // click multiple times to reach PLAYBACK_SPEED_FAST_L2
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        assertEquals(1, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
-        assertEquals(2, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(3, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(3, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // press playPause again put it back to play
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-    }
-
-    @Test
-    public void testFastRewindToMaxThenReset() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
-        assertFalse(glue.isMediaPlaying());
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // click multiple times to reach PLAYBACK_SPEED_FAST_L2
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(1, rewind.getIndex());
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(2, rewind.getIndex());
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(3, rewind.getIndex());
-        glue.onActionClicked(rewind);
-        assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(3, rewind.getIndex());
-
-        // press playPause again put it back to play
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-    }
-
-    @Test
-    public void testFastForwardAbortKeyCodes() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // Testing keycodes that will not abort seek
-        final int[] noAbortSeekKeyCodes = new int[] {
-                KeyEvent.KEYCODE_DPAD_CENTER,
-                KeyEvent.KEYCODE_ENTER
-        };
-        for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(fastForward);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(1, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
-            glue.onKey(null, noAbortSeekKeyCodes[i], kv);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            glue.onActionClicked(playPause);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        }
-
-        // Testing abortSeekKeyCodes
-        final int[] abortSeekKeyCodes = new int[] {
-            KeyEvent.KEYCODE_DPAD_UP,
-            KeyEvent.KEYCODE_DPAD_DOWN,
-            KeyEvent.KEYCODE_DPAD_RIGHT,
-            KeyEvent.KEYCODE_DPAD_LEFT,
-            KeyEvent.KEYCODE_BACK,
-            KeyEvent.KEYCODE_ESCAPE
-        };
-        for (int i = 0; i < abortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(fastForward);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(1, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
-            glue.onKey(null, abortSeekKeyCodes[i], kv);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-        }
-    }
-
-    @Test
-    public void testRewindAbortKeyCodes() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-        PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
-        glue.onActionClicked(playPause);
-        assertTrue(glue.isMediaPlaying());
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        assertEquals(0, fastForward.getIndex());
-        assertEquals(0, rewind.getIndex());
-
-        // Testing keycodes that will not abort seek
-        final int[] noAbortSeekKeyCodes = new int[] {
-                KeyEvent.KEYCODE_DPAD_CENTER,
-                KeyEvent.KEYCODE_ENTER
-        };
-        for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(rewind);
-            assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(1, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
-            glue.onKey(null, noAbortSeekKeyCodes[i], kv);
-            assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            glue.onActionClicked(playPause);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        }
-
-        // Testing abortSeekKeyCodes
-        final int[] abortSeekKeyCodes = new int[] {
-                KeyEvent.KEYCODE_DPAD_UP,
-                KeyEvent.KEYCODE_DPAD_DOWN,
-                KeyEvent.KEYCODE_DPAD_RIGHT,
-                KeyEvent.KEYCODE_DPAD_LEFT,
-                KeyEvent.KEYCODE_BACK,
-                KeyEvent.KEYCODE_ESCAPE
-        };
-        for (int i = 0; i < abortSeekKeyCodes.length; i++) {
-            glue.onActionClicked(rewind);
-            assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(1, rewind.getIndex());
-            KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
-            glue.onKey(null, abortSeekKeyCodes[i], kv);
-            assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-            assertEquals(0, fastForward.getIndex());
-            assertEquals(0, rewind.getIndex());
-        }
-    }
-
-    @Test
-    public void testMediaPauseButtonOnFF() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PAUSE));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPauseButtonOnPlay() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PAUSE));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPauseButtonOnPause() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PAUSE));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayButtonOnFF() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayButtonOnPlay() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayButtonOnPause() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayPauseButtonOnFF() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(fastForward);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayPauseButtonOnPlay() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testMediaPlayPauseButtonOnPause() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
-        glue.onActionClicked(playPause);
-        glue.onActionClicked(playPause);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-        glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testOnItemClickedListener() {
-        PlaybackControlsRow row = new PlaybackControlsRow();
-        final PlaybackOverlaySupportFragment[] fragmentResult = new PlaybackOverlaySupportFragment[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                fragmentResult[0] = new PlaybackOverlaySupportFragment();
-            }
-        });
-        PlaybackOverlaySupportFragment fragment = fragmentResult[0];
-        glue.setHost(new PlaybackControlSupportGlue.PlaybackSupportGlueHostOld(fragment));
-        glue.setControlsRow(row);
-        SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
-                row.getPrimaryActionsAdapter();
-        PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
-                .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-        OnItemViewClickedListener listener = Mockito.mock(OnItemViewClickedListener.class);
-        glue.setOnItemViewClickedListener(listener);
-
-        // create fake row ViewHolder and fade item ViewHolder
-        View rowView = new View(context);
-        View view = new View(context);
-        PlaybackRowPresenter.ViewHolder rowVh = new PlaybackRowPresenter.ViewHolder(rowView);
-        Presenter.ViewHolder vh = new Presenter.ViewHolder(view);
-
-        // Initially media is paused
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-
-        // simulate a click inside PlaybackOverlaySupportFragment's PlaybackRow.
-        fragment.getOnItemViewClickedListener().onItemClicked(vh, playPause, rowVh, row);
-        verify(listener, times(0)).onItemClicked(vh, playPause, rowVh, row);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-
-        // simulate a click on object other than PlaybackRow.
-        Object regularItem = new Object();
-        Row regularRow = new Row();
-        RowPresenter.ViewHolder regularRowViewHolder = new RowPresenter.ViewHolder(rowView);
-        Presenter.ViewHolder regularViewHOlder = new Presenter.ViewHolder(view);
-        fragment.getOnItemViewClickedListener().onItemClicked(regularViewHOlder, regularItem,
-                regularRowViewHolder, regularRow);
-        verify(listener, times(1)).onItemClicked(regularViewHOlder, regularItem,
-                regularRowViewHolder, regularRow);
-        assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-    }
-
-    @Test
-    public void testOnRowChangedCallback() throws Exception {
-        final PlaybackOverlaySupportFragment[] fragmentResult = new
-                PlaybackOverlaySupportFragment[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                fragmentResult[0] = new PlaybackOverlaySupportFragment();
-            }
-        });
-        PlaybackOverlaySupportFragment fragment = fragmentResult[0];
-        PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
-                new int[]{
-                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
-                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
-                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
-                });
-
-        // before any controls row is created the count is zero
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
-        playbackGlue.createControlsRowAndPresenter();
-        // after a controls row is created, onRowChanged() call back is called once
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-        playbackGlue.notifyMetaDataChanged();
-        // onMetaDataChanged() calls updateRowMetadata which ends up calling
-        // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-    }
-
-
-    @Test
-    public void testWithoutValidMedia() throws Exception {
-        final PlaybackOverlaySupportFragment[] fragmentResult = new
-                PlaybackOverlaySupportFragment[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                fragmentResult[0] = new PlaybackOverlaySupportFragment();
-            }
-        });
-        final boolean[] hasValidMedia = new boolean[] {false};
-        PlaybackOverlaySupportFragment fragment = fragmentResult[0];
-        PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
-                new int[]{
-                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
-                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
-                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
-                }) {
-            @Override
-            public boolean hasValidMedia() {
-                return hasValidMedia[0];
-            }
-        };
-
-        // before any controls row is created the count is zero
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
-        playbackGlue.createControlsRowAndPresenter();
-        // after a controls row is created, onRowChanged() call back is called once
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
-        // enven hasValidMedia() is false, we should still have three buttons.
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-
-        hasValidMedia[0] = true;
-        playbackGlue.notifyMetaDataChanged();
-        // onMetaDataChanged() calls updateRowMetadata which ends up calling
-        // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
-        assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
-        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-    }
-
-}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
deleted file mode 100644
index f21bd04..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.support.v17.leanback.app;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.MediumTest;
-import android.support.test.filters.Suppress;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v17.leanback.test.R;
-import android.view.View;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class PlaybackOverlayFragmentTest extends SingleFragmentTestBase {
-
-    @Test
-    public void workaroundVideoViewStealFocus() {
-        SingleFragmentTestActivity activity =
-                launchAndWaitActivity(PlaybackOverlayTestFragment.class,
-                new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
-        PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
-                activity.getTestFragment();
-
-        assertFalse(activity.findViewById(R.id.videoView).hasFocus());
-        assertTrue(fragment.getView().hasFocus());
-    }
-
-    @FlakyTest
-    @Suppress
-    @Test
-    public void alignmentRowToBottom() throws Throwable {
-        SingleFragmentTestActivity activity =
-                launchAndWaitActivity(PlaybackOverlayTestFragment.class,
-                new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
-        final PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
-                activity.getTestFragment();
-
-        assertTrue(fragment.getAdapter().size() > 2);
-
-        View playRow = fragment.getVerticalGridView().getChildAt(0);
-        assertTrue(playRow.hasFocus());
-        assertEquals(playRow.getResources().getDimensionPixelSize(
-                R.dimen.lb_playback_controls_padding_bottom),
-                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
-
-        activityTestRule.runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                fragment.getVerticalGridView().setSelectedPositionSmooth(
-                        fragment.getAdapter().size() - 1);
-            }
-        });
-        waitForScrollIdle(fragment.getVerticalGridView());
-
-        View lastRow = fragment.getVerticalGridView().getChildAt(
-                fragment.getVerticalGridView().getChildCount() - 1);
-        assertEquals(fragment.getAdapter().size() - 1,
-                fragment.getVerticalGridView().getChildAdapterPosition(lastRow));
-        assertTrue(lastRow.hasFocus());
-        assertEquals(lastRow.getResources().getDimensionPixelSize(
-                R.dimen.lb_playback_controls_padding_bottom),
-                fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
-    }
-
-}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
deleted file mode 100644
index 82e37d3..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.support.v17.leanback.app;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v17.leanback.test.R;
-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.ControlButtonPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.OnItemViewSelectedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Toast;
-
-public class PlaybackOverlayTestFragment extends PlaybackOverlayFragment {
-    private static final String TAG = "leanback.PlaybackControlsFragment";
-
-    /**
-     * Change this to choose a different overlay background.
-     */
-    private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;
-
-    /**
-     * Change the number of related content rows.
-     */
-    private static final int RELATED_CONTENT_ROWS = 3;
-
-    /**
-     * Change this to select hidden
-     */
-    private static final boolean SECONDARY_HIDDEN = false;
-
-    private static final int ROW_CONTROLS = 0;
-
-    private PlaybackControlHelper mGlue;
-    private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
-
-    private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
-        @Override
-        public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
-                                  RowPresenter.ViewHolder rowViewHolder, Row row) {
-            Log.i(TAG, "onItemClicked: " + item + " row " + row);
-            if (item instanceof Action) {
-                mGlue.onActionClicked((Action) item);
-            }
-        }
-    };
-
-    private OnItemViewSelectedListener mOnItemViewSelectedListener =
-            new OnItemViewSelectedListener() {
-        @Override
-        public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
-                                   RowPresenter.ViewHolder rowViewHolder, Row row) {
-            Log.i(TAG, "onItemSelected: " + item + " row " + row);
-        }
-    };
-
-    @Override
-    public SparseArrayObjectAdapter getAdapter() {
-        return (SparseArrayObjectAdapter) super.getAdapter();
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        Log.i(TAG, "onCreate");
-        super.onCreate(savedInstanceState);
-
-        setBackgroundType(BACKGROUND_TYPE);
-        setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-
-        createComponents(getActivity());
-    }
-
-    private void createComponents(Context context) {
-        mGlue = new PlaybackControlHelper(context, this) {
-            @Override
-            public int getUpdatePeriod() {
-                long totalTime = getControlsRow().getDuration();
-                if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
-                    return 1000;
-                }
-                return 16;
-            }
-
-            @Override
-            protected void onRowChanged(PlaybackControlsRow row) {
-                if (getAdapter() == null) {
-                    return;
-                }
-                int index = getAdapter().indexOf(row);
-                if (index >= 0) {
-                    getAdapter().notifyArrayItemRangeChanged(index, 1);
-                }
-            }
-
-            @Override
-            public void onActionClicked(Action action) {
-                if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
-                    return;
-                }
-                super.onActionClicked(action);
-            }
-        };
-
-        mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
-
-        mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
-        mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
-        ClassPresenterSelector selector = new ClassPresenterSelector();
-        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
-        selector.addClassPresenter(PlaybackControlsRow.class, mPlaybackControlsRowPresenter);
-
-        setAdapter(new SparseArrayObjectAdapter(selector));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
-
-        // Add related content rows
-        for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
-            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
-            listRowAdapter.add("Some related content");
-            listRowAdapter.add("Other related content");
-            HeaderItem header = new HeaderItem(i, "Row " + i);
-            getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
-        }
-
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        mGlue.setFadingEnabled(true);
-    }
-
-    abstract static class PlaybackControlHelper extends PlaybackControlGlue {
-        /**
-         * Change the location of the thumbs up/down controls
-         */
-        private static final boolean THUMBS_PRIMARY = true;
-
-        private static final String FAUX_TITLE = "A short song of silence";
-        private static final String FAUX_SUBTITLE = "2014";
-        private static final int FAUX_DURATION = 33 * 1000;
-
-        // These should match the playback service FF behavior
-        private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
-
-        private boolean mIsPlaying;
-        private int mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
-        private long mStartTime;
-        private long mStartPosition = 0;
-
-        private PlaybackControlsRow.RepeatAction mRepeatAction;
-        private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
-        private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
-        private PlaybackControlsRow.PictureInPictureAction mPipAction;
-        private static Handler mHandler = new Handler();
-
-        private final Runnable mUpdateProgressRunnable = new Runnable() {
-            @Override
-            public void run() {
-                updateProgress();
-                mHandler.postDelayed(this, getUpdatePeriod());
-            }
-        };
-
-        PlaybackControlHelper(Context context, PlaybackOverlayFragment fragment) {
-            super(context, fragment, sFastForwardSpeeds);
-            mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
-            mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
-            mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
-            mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
-            mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
-            mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
-        }
-
-        @Override
-        public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
-            PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
-
-            ArrayObjectAdapter adapter = new ArrayObjectAdapter(
-                    new ControlButtonPresenterSelector());
-            getControlsRow().setSecondaryActionsAdapter(adapter);
-            if (!THUMBS_PRIMARY) {
-                adapter.add(mThumbsDownAction);
-            }
-            if (android.os.Build.VERSION.SDK_INT > 23) {
-                adapter.add(mPipAction);
-            }
-            adapter.add(mRepeatAction);
-            if (!THUMBS_PRIMARY) {
-                adapter.add(mThumbsUpAction);
-            }
-
-            return presenter;
-        }
-
-        @Override
-        protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
-                PresenterSelector presenterSelector) {
-            SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
-            if (THUMBS_PRIMARY) {
-                adapter.set(PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
-                adapter.set(PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
-            }
-            return adapter;
-        }
-
-        @Override
-        public void onActionClicked(Action action) {
-            if (shouldDispatchAction(action)) {
-                dispatchAction(action);
-                return;
-            }
-            super.onActionClicked(action);
-        }
-
-        @Override
-        public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
-            if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
-                Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
-                if (shouldDispatchAction(action)) {
-                    dispatchAction(action);
-                    return true;
-                }
-            }
-            return super.onKey(view, keyCode, keyEvent);
-        }
-
-        private boolean shouldDispatchAction(Action action) {
-            return action == mRepeatAction || action == mThumbsUpAction
-                    || action == mThumbsDownAction;
-        }
-
-        private void dispatchAction(Action action) {
-            Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
-            PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
-            multiAction.nextIndex();
-            notifyActionChanged(multiAction);
-        }
-
-        private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
-            int index;
-            index = getPrimaryActionsAdapter().indexOf(action);
-            if (index >= 0) {
-                getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
-            } else {
-                index = getSecondaryActionsAdapter().indexOf(action);
-                if (index >= 0) {
-                    getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
-                }
-            }
-        }
-
-        private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
-            return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
-        }
-
-        private ArrayObjectAdapter getSecondaryActionsAdapter() {
-            return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
-        }
-
-        @Override
-        public boolean hasValidMedia() {
-            return true;
-        }
-
-        @Override
-        public boolean isMediaPlaying() {
-            return mIsPlaying;
-        }
-
-        @Override
-        public CharSequence getMediaTitle() {
-            return FAUX_TITLE;
-        }
-
-        @Override
-        public CharSequence getMediaSubtitle() {
-            return FAUX_SUBTITLE;
-        }
-
-        @Override
-        public int getMediaDuration() {
-            return FAUX_DURATION;
-        }
-
-        @Override
-        public Drawable getMediaArt() {
-            return null;
-        }
-
-        @Override
-        public long getSupportedActions() {
-            return PlaybackControlGlue.ACTION_PLAY_PAUSE
-                   | PlaybackControlGlue.ACTION_FAST_FORWARD
-                   | PlaybackControlGlue.ACTION_REWIND;
-        }
-
-        @Override
-        public int getCurrentSpeedId() {
-            return mSpeed;
-        }
-
-        @Override
-        public int getCurrentPosition() {
-            int speed;
-            if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
-                speed = 0;
-            } else if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_NORMAL) {
-                speed = 1;
-            } else if (mSpeed >= PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
-                int index = mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
-                speed = getFastForwardSpeeds()[index];
-            } else if (mSpeed <= -PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
-                int index = -mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
-                speed = -getRewindSpeeds()[index];
-            } else {
-                return -1;
-            }
-            long position = mStartPosition + (System.currentTimeMillis() - mStartTime) * speed;
-            if (position > getMediaDuration()) {
-                position = getMediaDuration();
-                onPlaybackComplete(true);
-            } else if (position < 0) {
-                position = 0;
-                onPlaybackComplete(false);
-            }
-            return (int) position;
-        }
-
-        void onPlaybackComplete(final boolean ended) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
-                        pausePlayback();
-                    } else {
-                        startPlayback(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL);
-                    }
-                    mStartPosition = 0;
-                    onStateChanged();
-                }
-            });
-        }
-
-        @Override
-        protected void startPlayback(int speed) {
-            if (speed == mSpeed) {
-                return;
-            }
-            mStartPosition = getCurrentPosition();
-            mSpeed = speed;
-            mIsPlaying = true;
-            mStartTime = System.currentTimeMillis();
-        }
-
-        @Override
-        protected void pausePlayback() {
-            if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
-                return;
-            }
-            mStartPosition = getCurrentPosition();
-            mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
-            mIsPlaying = false;
-        }
-
-        @Override
-        protected void skipToNext() {
-            // Not supported
-        }
-
-        @Override
-        protected void skipToPrevious() {
-            // Not supported
-        }
-
-        @Override
-        public void enableProgressUpdating(boolean enable) {
-            mHandler.removeCallbacks(mUpdateProgressRunnable);
-            if (enable) {
-                mUpdateProgressRunnable.run();
-            }
-        }
-    }
-}
