Merge "PIP: Apply the latest Recents row animation when PIP control is focused" into nyc-dev
diff --git a/packages/SystemUI/res/drawable/tv_pip_close_button.xml b/packages/SystemUI/res/drawable/tv_pip_close_button.xml
index 86fda0d..186a4ba 100644
--- a/packages/SystemUI/res/drawable/tv_pip_close_button.xml
+++ b/packages/SystemUI/res/drawable/tv_pip_close_button.xml
@@ -19,8 +19,20 @@
     <item android:state_focused="true">
         <layer-list>
             <item android:drawable="@drawable/tv_pip_button_focused" />
-            <item android:drawable="@drawable/ic_close_white" />
+            <item android:drawable="@drawable/ic_close_white"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
         </layer-list>
     </item>
-    <item android:drawable="@drawable/ic_close_white" />
+    <item>
+        <layer-list>
+            <item android:drawable="@drawable/ic_close_white"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
+        </layer-list>
+    </item>
 </selector>
diff --git a/packages/SystemUI/res/drawable/tv_pip_full_button.xml b/packages/SystemUI/res/drawable/tv_pip_full_button.xml
index 332c669..c48dc828 100644
--- a/packages/SystemUI/res/drawable/tv_pip_full_button.xml
+++ b/packages/SystemUI/res/drawable/tv_pip_full_button.xml
@@ -19,8 +19,20 @@
     <item android:state_focused="true">
         <layer-list>
             <item android:drawable="@drawable/tv_pip_button_focused" />
-            <item android:drawable="@drawable/ic_fullscreen_white_24dp" />
+            <item android:drawable="@drawable/ic_fullscreen_white_24dp"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
         </layer-list>
     </item>
-    <item android:drawable="@drawable/ic_fullscreen_white_24dp" />
+    <item>
+        <layer-list>
+            <item android:drawable="@drawable/ic_fullscreen_white_24dp"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
+        </layer-list>
+    </item>
 </selector>
diff --git a/packages/SystemUI/res/drawable/tv_pip_pause_button.xml b/packages/SystemUI/res/drawable/tv_pip_pause_button.xml
index d277b07..bcc8973 100644
--- a/packages/SystemUI/res/drawable/tv_pip_pause_button.xml
+++ b/packages/SystemUI/res/drawable/tv_pip_pause_button.xml
@@ -19,8 +19,20 @@
     <item android:state_focused="true">
         <layer-list>
             <item android:drawable="@drawable/tv_pip_button_focused" />
-            <item android:drawable="@drawable/ic_pause_white_24dp" />
+            <item android:drawable="@drawable/ic_pause_white_24dp"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
         </layer-list>
     </item>
-    <item android:drawable="@drawable/ic_pause_white_24dp" />
+    <item>
+        <layer-list>
+            <item android:drawable="@drawable/ic_pause_white_24dp"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
+        </layer-list>
+    </item>
 </selector>
diff --git a/packages/SystemUI/res/drawable/tv_pip_play_button.xml b/packages/SystemUI/res/drawable/tv_pip_play_button.xml
index fecdc09..f77ea1d 100644
--- a/packages/SystemUI/res/drawable/tv_pip_play_button.xml
+++ b/packages/SystemUI/res/drawable/tv_pip_play_button.xml
@@ -19,8 +19,20 @@
     <item android:state_focused="true">
         <layer-list>
             <item android:drawable="@drawable/tv_pip_button_focused" />
-            <item android:drawable="@drawable/ic_play_arrow_white_24dp" />
+            <item android:drawable="@drawable/ic_play_arrow_white_24dp"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
         </layer-list>
     </item>
-    <item android:drawable="@drawable/ic_play_arrow_white_24dp" />
+    <item>
+        <layer-list>
+            <item android:drawable="@drawable/ic_play_arrow_white_24dp"
+                android:top="@dimen/tv_pip_button_icon_padding"
+                android:bottom="@dimen/tv_pip_button_icon_padding"
+                android:left="@dimen/tv_pip_button_icon_padding"
+                android:right="@dimen/tv_pip_button_icon_padding" />
+        </layer-list>
+    </item>
 </selector>
diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml
index 337513d..4e6a4b1 100644
--- a/packages/SystemUI/res/values/dimens_tv.xml
+++ b/packages/SystemUI/res/values/dimens_tv.xml
@@ -54,5 +54,7 @@
 
     <!-- Extra space around the PIP and its outline in PIP onboarding activity  -->
     <dimen name="tv_pip_bounds_space">3dp</dimen>
+    <!-- Extra space around the PIP control button icon to match with the focused circle -->
+    <dimen name="tv_pip_button_icon_padding">5dp</dimen>
 
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index 483f9e5..f9f851a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -53,7 +53,6 @@
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.tv.animations.FocusAnimationHolder;
 import com.android.systemui.recents.tv.views.RecentsTvView;
 import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -79,7 +78,6 @@
     private boolean mIgnoreAltTabRelease;
 
     private RecentsTvView mRecentsView;
-    private FocusAnimationHolder mRecentsFocusAnimationHolder;
     private View mPipView;
     private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
     private FinishRecentsRunnable mFinishLaunchHomeRunnable;
@@ -133,13 +131,7 @@
             new View.OnFocusChangeListener() {
                 @Override
                 public void onFocusChange(View v, boolean hasFocus) {
-                    if (hasFocus) {
-                        mRecentsFocusAnimationHolder.startFocusLoseAnimation();
-                        mPipRecentsOverlayManager.requestFocus(
-                                mTaskStackViewAdapter.getItemCount() > 0);
-                    } else {
-                        mRecentsFocusAnimationHolder.startFocusGainAnimation();
-                    }
+                    handlePipViewFocusChange(hasFocus);
                 }
             };
 
@@ -288,11 +280,10 @@
         mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-        mRecentsFocusAnimationHolder = new FocusAnimationHolder(mRecentsView);
 
         mPipView = findViewById(R.id.pip);
         // Place mPipView at the PIP bounds for fine tuned focus handling.
-        Rect pipBounds = mPipManager.getPipBounds();
+        Rect pipBounds = mPipManager.getRecentsFocusedPipBounds();
         LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
         lp.width = pipBounds.width();
         lp.height = pipBounds.height();
@@ -513,11 +504,30 @@
         if (mPipManager.isPipShown()) {
             mPipView.setVisibility(View.VISIBLE);
             mPipView.setOnFocusChangeListener(mPipViewFocusChangeListener);
-            mPipView.requestFocus();
+            if (mPipView.hasFocus()) {
+                // This can happen only if the activity is resumed. Ask for reset.
+                handlePipViewFocusChange(true);
+            } else {
+                mPipView.requestFocus();
+            }
         } else {
             mPipView.setVisibility(View.GONE);
             mPipRecentsOverlayManager.removePipRecentsOverlayView();
-            mRecentsFocusAnimationHolder.reset();
+        }
+    }
+
+    /**
+     * Handles the PIP view's focus change.
+     * This starts the relevant recents row animation
+     * and give focus to the recents overlay if needed.
+     */
+    private void handlePipViewFocusChange(boolean hasFocus) {
+        mRecentsView.startRecentsRowFocusAnimation(!hasFocus);
+        if (hasFocus) {
+            // When PIP view has focus, recents overlay view will takes the focus
+            // as if it's the part of the Recents UI.
+            mPipRecentsOverlayManager.requestFocus(
+                    mTaskStackViewAdapter.getItemCount() > 0);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/FocusAnimationHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/FocusAnimationHolder.java
deleted file mode 100644
index 864540c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/FocusAnimationHolder.java
+++ /dev/null
@@ -1,63 +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 com.android.systemui.recents.tv.animations;
-
-import android.content.res.Resources;
-import android.view.View;
-
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.tv.views.TaskCardView;
-
-/**
- * Collections of Recents row's animation depending on the PIP's focus.
- */
-public class FocusAnimationHolder {
-    private final float DIM_ALPHA = 0.5f;
-
-    private View mRecentsRowView;
-    private int mCardYDelta;
-    private long mDuration;
-
-    public FocusAnimationHolder(View recentsRowView) {
-        mRecentsRowView = recentsRowView;
-
-        Resources res = recentsRowView.getResources();
-        mCardYDelta = res.getDimensionPixelOffset(R.dimen.recents_tv_dismiss_shift_down);
-        mDuration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration);
-    }
-
-    public void startFocusGainAnimation() {
-        mRecentsRowView.animate()
-                .setDuration(mDuration)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .alpha(1f)
-                .translationY(0);
-    }
-
-    public void startFocusLoseAnimation() {
-        mRecentsRowView.animate()
-                .setDuration(mDuration)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .alpha(DIM_ALPHA)
-                .translationY(mCardYDelta);
-    }
-
-    public void reset() {
-        mRecentsRowView.setTransitionAlpha(1f);
-        mRecentsRowView.setTranslationY(0);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/RecentsRowFocusAnimationHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/RecentsRowFocusAnimationHolder.java
new file mode 100644
index 0000000..28abc34
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/RecentsRowFocusAnimationHolder.java
@@ -0,0 +1,76 @@
+/*
+ * 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 com.android.systemui.recents.tv.animations;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.res.Resources;
+import android.view.View;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+import com.android.systemui.recents.tv.views.TaskCardView;
+
+/**
+ * Recents row's focus animation with PIP controls.
+ */
+public class RecentsRowFocusAnimationHolder {
+    private static final float DIM_ALPHA = 0.5f;
+
+    private View mView;
+    private View mTitleView;
+
+    private AnimatorSet mFocusGainAnimatorSet;
+    private AnimatorSet mFocusLoseAnimatorSet;
+
+    public RecentsRowFocusAnimationHolder(View view, View titleView) {
+        mView = view;
+        mTitleView = titleView;
+
+        Resources res = view.getResources();
+        int duration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration);
+
+        mFocusGainAnimatorSet = new AnimatorSet();
+        mFocusGainAnimatorSet.playTogether(
+                ObjectAnimator.ofFloat(mView, "alpha", 1f),
+                ObjectAnimator.ofFloat(mTitleView, "alpha", 1f));
+        mFocusGainAnimatorSet.setDuration(duration);
+        mFocusGainAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+
+        mFocusLoseAnimatorSet = new AnimatorSet();
+        mFocusLoseAnimatorSet.playTogether(
+                ObjectAnimator.ofFloat(mView, "alpha", DIM_ALPHA),
+                ObjectAnimator.ofFloat(mTitleView, "alpha", 0f));
+        mFocusLoseAnimatorSet.setDuration(duration);
+        mFocusLoseAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+    }
+
+    /**
+     * Returns the Recents row's focus change animation.
+     */
+    public Animator getFocusChangeAnimator(boolean hasFocus) {
+        return hasFocus ? mFocusGainAnimatorSet : mFocusLoseAnimatorSet;
+    }
+
+    /**
+     * Resets the views to the initial state immediately.
+     */
+    public void reset() {
+        mView.setAlpha(1f);
+        mTitleView.setAlpha(1f);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index d966614..9da8eed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -37,6 +37,7 @@
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -52,6 +53,7 @@
     private TaskStack mStack;
     private TaskStackHorizontalGridView mTaskStackHorizontalView;
     private View mEmptyView;
+    private RecentsRowFocusAnimationHolder mEmptyViewFocusAnimationHolder;
     private boolean mAwaitingFirstLayout = true;
     private Rect mSystemInsets = new Rect();
     private RecentsTvTransitionHelper mTransitionHelper;
@@ -77,6 +79,8 @@
         LayoutInflater inflater = LayoutInflater.from(context);
         mEmptyView = inflater.inflate(R.layout.recents_empty, this, false);
         addView(mEmptyView);
+        mEmptyViewFocusAnimationHolder = new RecentsRowFocusAnimationHolder(mEmptyView, null);
+
         mHandler = new Handler();
         mTransitionHelper = new RecentsTvTransitionHelper(mContext, mHandler);
     }
@@ -94,7 +98,6 @@
             mTaskStackHorizontalView.setStack(stack);
         }
 
-
         if (stack.getStackTaskCount() > 0) {
             hideEmptyView();
         } else {
@@ -134,33 +137,40 @@
     public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
         if (mTaskStackHorizontalView != null) {
             // Iterate the stack views and try and find the given task.
-            List<TaskCardView> taskViews = mTaskStackHorizontalView.getTaskViews();
-            int taskViewCount = taskViews.size();
-            for (int j = 0; j < taskViewCount; j++) {
-                TaskCardView tv = taskViews.get(j);
-                if (tv.getTask() == task) {
-                    SystemServicesProxy ssp = Recents.getSystemServices();
-                    ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
-                    return true;
-                }
+            if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
+                SystemServicesProxy ssp = Recents.getSystemServices();
+                ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+                return true;
             }
         }
         return false;
     }
 
     /**
+     * Starts the focus change animation.
+     */
+    public void startRecentsRowFocusAnimation(boolean hasFocus) {
+        if (mEmptyView.getVisibility() == View.VISIBLE) {
+            mEmptyViewFocusAnimationHolder.getFocusChangeAnimator(hasFocus).start();
+        } else {
+            mTaskStackHorizontalView.startRecentsRowFocusAnimation(hasFocus);
+        }
+    }
+
+    /**
      * Hides the task stack and shows the empty view.
      */
     public void showEmptyView() {
         mEmptyView.setVisibility(View.VISIBLE);
-        mEmptyView.bringToFront();
+        mTaskStackHorizontalView.setVisibility(View.GONE);
     }
 
     /**
      * Shows the task stack and hides the empty view.
      */
     public void hideEmptyView() {
-        mEmptyView.setVisibility(View.INVISIBLE);
+        mEmptyView.setVisibility(View.GONE);
+        mTaskStackHorizontalView.setVisibility(View.VISIBLE);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index 3343aec..d605748 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -24,6 +24,7 @@
 import android.util.TypedValue;
 import android.view.Display;
 import android.view.KeyEvent;
+import android.view.View;
 import android.view.WindowManager;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -31,6 +32,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.recents.tv.animations.DismissAnimationsHolder;
+import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
 import com.android.systemui.recents.tv.animations.ViewFocusAnimator;
 import com.android.systemui.recents.model.Task;
 
@@ -44,6 +46,7 @@
 
     private ViewFocusAnimator mViewFocusAnimator;
     private DismissAnimationsHolder mDismissAnimationsHolder;
+    private RecentsRowFocusAnimationHolder mRecentsRowFocusAnimationHolder;
 
     public TaskCardView(Context context) {
         this(context, null);
@@ -65,6 +68,8 @@
         mTitleTextView = (TextView) findViewById(R.id.card_title_text);
         mBadgeView = (ImageView) findViewById(R.id.card_extra_badge);
         mDismissAnimationsHolder = new DismissAnimationsHolder(this);
+        View title = findViewById(R.id.card_info_field);
+        mRecentsRowFocusAnimationHolder = new RecentsRowFocusAnimationHolder(this, title);
     }
 
     public void init(Task task) {
@@ -193,6 +198,10 @@
         mDismissAnimationsHolder.startDismissAnimation(listener);
     }
 
+    public RecentsRowFocusAnimationHolder getRecentsRowFocusAnimationHolder() {
+        return mRecentsRowFocusAnimationHolder;
+    }
+
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
index 5eb9fda..603721a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
@@ -15,7 +15,11 @@
  */
 package com.android.systemui.recents.tv.views;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
 import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
 import android.support.v17.leanback.widget.HorizontalGridView;
 import android.util.AttributeSet;
 import android.view.View;
@@ -36,10 +40,19 @@
  * Horizontal Grid View Implementation to show the Task Stack for TV.
  */
 public class TaskStackHorizontalGridView extends HorizontalGridView implements TaskStackCallbacks {
-
+    private static final int ANIMATION_DELAY_MS = 50;
+    private static final int MSG_START_RECENT_ROW_FOCUS_ANIMATION = 100;
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_START_RECENT_ROW_FOCUS_ANIMATION) {
+                startRecentsRowFocusAnimation(msg.arg1 == 1);
+            }
+        }
+    };
     private TaskStack mStack;
-    private ArrayList<TaskCardView> mTaskViews = new ArrayList<>();
     private Task mFocusedTask;
+    private AnimatorSet mRecentsRowFocusAnimation;
 
     public TaskStackHorizontalGridView(Context context) {
         this(context, null);
@@ -62,10 +75,18 @@
         super.onDetachedFromWindow();
         EventBus.getDefault().unregister(this);
     }
+
     /**
      * Resets this view for reuse.
      */
     public void reset() {
+        for (int i = 0; i < getChildCount(); i++) {
+            ((TaskCardView) getChildAt(i)).getRecentsRowFocusAnimationHolder().reset();
+        }
+        if (mRecentsRowFocusAnimation != null && mRecentsRowFocusAnimation.isStarted()) {
+            mRecentsRowFocusAnimation.cancel();
+        }
+        mHandler.removeCallbacksAndMessages(null);
         requestLayout();
     }
 
@@ -119,10 +140,8 @@
      * @return Child view for given task
      */
     public TaskCardView getChildViewForTask(Task task) {
-        List<TaskCardView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskCardView tv = taskViews.get(i);
+        for (int i = 0; i < getChildCount(); i++) {
+            TaskCardView tv = (TaskCardView) getChildAt(i);
             if (tv.getTask() == task) {
                 return tv;
             }
@@ -130,12 +149,36 @@
         return null;
     }
 
-    public List<TaskCardView> getTaskViews() {
-        return mTaskViews;
+    /**
+     * Starts the focus change animation.
+     */
+    public void startRecentsRowFocusAnimation(final boolean hasFocus) {
+        if (getChildCount() == 0) {
+            // Animation request may happen before view is attached.
+            // Post again with small dealy so animation can be run again later.
+            if (getAdapter().getItemCount() > 0) {
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(
+                        MSG_START_RECENT_ROW_FOCUS_ANIMATION, hasFocus ? 1 : 0),
+                        ANIMATION_DELAY_MS);
+            }
+            return;
+        }
+        if (mRecentsRowFocusAnimation != null && mRecentsRowFocusAnimation.isStarted()) {
+            mRecentsRowFocusAnimation.cancel();
+        }
+        Animator animator = ((TaskCardView) getChildAt(0)).getRecentsRowFocusAnimationHolder()
+                .getFocusChangeAnimator(hasFocus);
+        mRecentsRowFocusAnimation = new AnimatorSet();
+        AnimatorSet.Builder builder = mRecentsRowFocusAnimation.play(animator);
+        for (int i = 1; i < getChildCount(); i++) {
+            builder.with(((TaskCardView) getChildAt(i)).getRecentsRowFocusAnimationHolder()
+                    .getFocusChangeAnimator(hasFocus));
+        }
+        mRecentsRowFocusAnimation.start();
     }
 
     @Override
-    public void onStackTaskAdded(TaskStack stack, Task newTask){
+    public void onStackTaskAdded(TaskStack stack, Task newTask) {
         getAdapter().notifyItemInserted(stack.getStackTasks().indexOf(newTask));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
index b90b727..47cd8e5 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
@@ -131,9 +131,9 @@
      * Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
      * is focused.
      * This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
-     * @param hasRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task)
+     * @param allowRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task)
      */
-    public void requestFocus(boolean hasRecentsFocusable) {
+    public void requestFocus(boolean allowRecentsFocusable) {
         if (!mIsRecentsShown || mIsPipFocusedInRecent) {
             return;
         }
@@ -143,7 +143,7 @@
         mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
         mPipControlsView.requestFocus();
         mPipControlsView.startFocusGainAnimation();
-        mRecentsView.setVisibility(hasRecentsFocusable ? View.VISIBLE : View.GONE);
+        mRecentsView.setVisibility(allowRecentsFocusable ? View.VISIBLE : View.GONE);
     }
 
     /**