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 116003f9..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 764b1696..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();
-            }
-        }
-    }
-}
