PIP: Make PIPed activity to be focused from Recents

This makes PIPed activity to look like part of the Recents.

Bug: 26946155
Change-Id: Ic0ac441e57af5594c06701fa9d30400f0f7cc5a5
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index f24f67d..a3a3112 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -31,4 +31,8 @@
          is located in center. -->
     <string translatable="false" name="config_centeredPictureInPictureBounds">"596 280 1324 690"</string>
 
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+         when the PIP is shown with Recents. -->
+    <string translatable="false" name="config_pictureInPictureBoundsInRecents">"1480 123 1760 303"</string>
+
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 54f9093..9552820 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2444,6 +2444,10 @@
          is located in center. -->
     <string translatable="false" name="config_centeredPictureInPictureBounds">"0 0 300 300"</string>
 
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+         when the PIP is shown with Recents. -->
+    <string translatable="false" name="config_pictureInPictureBoundsInRecents">"0 0 100 100"</string>
+
     <!-- Controls the snap mode for the docked stack divider
              0 - 3 snap targets: left/top has 16:9 ratio, 1:1, and right/bottom has 16:9 ratio
              1 - 3 snap targets: fixed ratio, 1:1, (1 - fixed ratio)
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3c81028..ff247b5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -306,6 +306,7 @@
   <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="string" name="config_defaultPictureInPictureBounds" />
   <java-symbol type="string" name="config_centeredPictureInPictureBounds" />
+  <java-symbol type="string" name="config_pictureInPictureBoundsInRecents" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
diff --git a/packages/SystemUI/res/drawable/ic_fullscreen_white_24dp.xml b/packages/SystemUI/res/drawable/ic_fullscreen_white_24dp.xml
new file mode 100644
index 0000000..7ddb40c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_fullscreen_white_24dp.xml
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:pathData="M0 0h24v24H0z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_pause_white_24dp.xml b/packages/SystemUI/res/drawable/ic_pause_white_24dp.xml
new file mode 100644
index 0000000..d9a4f7b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_pause_white_24dp.xml
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_play_arrow_white_24dp.xml b/packages/SystemUI/res/drawable/ic_play_arrow_white_24dp.xml
new file mode 100644
index 0000000..b8fa99e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_play_arrow_white_24dp.xml
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M8 5v14l11-7z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
diff --git a/packages/SystemUI/res/layout/recents_on_tv.xml b/packages/SystemUI/res/layout/recents_on_tv.xml
index b4543bd..94b099e 100644
--- a/packages/SystemUI/res/layout/recents_on_tv.xml
+++ b/packages/SystemUI/res/layout/recents_on_tv.xml
@@ -28,10 +28,26 @@
         android:clipChildren="false"
         android:clipToPadding="false"
         android:descendantFocusability="beforeDescendants"
+        android:layout_gravity="center"
         android:gravity="center"
         android:paddingStart="@dimen/recents_tv_grid_row_padding"
         android:paddingEnd="@dimen/recents_tv_grid_row_padding"
-        android:focusable="true"/>
+        android:focusable="true" />
 
+    <View
+        android:id="@+id/pip_shade"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible"
+        android:background="#76000000"/>
+
+    <!-- Placeholder view to handle key events for PIP when it's focused.
+         Size and positions will be adjusted to comply with
+         config_pictureInPictureBoundsInRecents -->
+    <View
+        android:id="@+id/pip"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:visibility="invisible"
+        android:focusable="true" />
 </com.android.systemui.recents.tv.views.RecentsTvView>
-
diff --git a/packages/SystemUI/res/layout/tv_pip_overlay.xml b/packages/SystemUI/res/layout/tv_pip_overlay.xml
index 6d9c48d..ebd362c 100644
--- a/packages/SystemUI/res/layout/tv_pip_overlay.xml
+++ b/packages/SystemUI/res/layout/tv_pip_overlay.xml
@@ -17,13 +17,38 @@
 */
 -->
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/guide_overlay"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_gravity="bottom"
-    android:padding="3dp"
-    android:textSize="13sp"
-    android:textColor="#111111"
-    android:background="#99EEEEEE"
-    android:text="@string/pip_hold_home" />
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/guide_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:padding="3dp"
+        android:textSize="13sp"
+        android:textColor="#111111"
+        android:background="#99EEEEEE"
+        android:text="@string/pip_hold_home" />
+    <LinearLayout
+        android:id="@+id/guide_buttons"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:orientation="horizontal">
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_fullscreen_white_24dp" />
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_pause_white_24dp" />
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_close_white" />
+    </LinearLayout>
+</RelativeLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 8b4474f..4b29c29 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -998,20 +998,4 @@
             e.printStackTrace();
         }
     }
-    
-    public void focusPinnedStack() {
-        try {
-            mIam.setFocusedStack(PINNED_STACK_ID);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void focusHomeStack() {
-        try {
-            mIam.setFocusedStack(HOME_STACK_ID);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-    }
 }
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 f3201d0..9450287 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -18,6 +18,7 @@
 import android.app.Activity;
 import android.app.ActivityOptions;
 import android.content.Intent;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Log;
@@ -25,6 +26,7 @@
 import android.view.View;
 import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.view.WindowManager;
+import android.widget.FrameLayout.LayoutParams;
 
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -58,6 +60,7 @@
 import com.android.systemui.tv.pip.PipManager;
 
 import java.util.ArrayList;
+
 /**
  * The main TV recents activity started by the RecentsImpl.
  */
@@ -73,9 +76,28 @@
     private boolean mIgnoreAltTabRelease;
 
     private RecentsTvView mRecentsView;
+    private View mPipView;
+    private View mPipShadeView;
     private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
     private FinishRecentsRunnable mFinishLaunchHomeRunnable;
 
+    private PipManager mPipManager;
+    private PipManager.Listener mPipListener = new PipManager.Listener() {
+        @Override
+        public void onPipActivityClosed() {
+            mPipView.setVisibility(View.GONE);
+            mPipShadeView.setVisibility(View.GONE);
+        }
+
+        @Override
+        public void onShowPipMenu() { }
+
+        @Override
+        public void onMoveToFullscreen() { }
+
+        @Override
+        public void onPipResizeAboutToStart() { }
+    };
 
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
@@ -212,6 +234,7 @@
             finish();
             return;
         }
+        mPipManager = PipManager.getInstance();
 
         // Register this activity with the event bus
         EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
@@ -226,7 +249,8 @@
         mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-
+        mPipView = findViewById(R.id.pip);
+        mPipShadeView = findViewById(R.id.pip_shade);
         getWindow().getAttributes().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 
@@ -265,6 +289,38 @@
         // Notify that recents is now visible
         SystemServicesProxy ssp = Recents.getSystemServices();
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, true));
+
+        if (mPipManager.isPipShown()) {
+            // Place mPipView at the PIP bounds for fine tuned focus handling.
+            Rect pipBounds = mPipManager.getPipBounds();
+            LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
+            lp.width = pipBounds.width();
+            lp.height = pipBounds.height();
+            lp.leftMargin = pipBounds.left;
+            lp.topMargin = pipBounds.top;
+            mPipView.setLayoutParams(lp);
+
+            mPipView.setVisibility(View.VISIBLE);
+            mPipView.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mPipManager.resizePinnedStack(PipManager.STATE_PIP_MENU);
+                }
+            });
+            mPipView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+                @Override
+                public void onFocusChange(View v, boolean hasFocus) {
+                    mPipManager.onPipViewFocusChangedInRecents(hasFocus);
+                    mPipShadeView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
+                }
+            });
+            mPipManager.addListener(mPipListener);
+        } else {
+            mPipView.setVisibility(View.GONE);
+        }
+        mPipManager.onRecentsStarted();
+        // Give focus to the recents row whenever its visible to an user.
+        mRecentsView.requestFocus();
     }
 
     @Override
@@ -277,6 +333,8 @@
     protected void onStop() {
         super.onStop();
 
+        mPipManager.onRecentsStopped();
+        mPipManager.removeListener(mPipListener);
         mIgnoreAltTabRelease = false;
         // Notify that recents is now hidden
         SystemServicesProxy ssp = Recents.getSystemServices();
@@ -316,18 +374,6 @@
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_UP: {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                PipManager.getInstance().resizePinnedStack(PipManager.STATE_PIP_MENU);
-                ssp.focusPinnedStack();
-                return true;
-            }
-            case KeyEvent.KEYCODE_DPAD_DOWN: {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                PipManager.getInstance().resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
-                ssp.focusHomeStack();
-                return true;
-            }
             case KeyEvent.KEYCODE_DEL:
             case KeyEvent.KEYCODE_FORWARD_DEL: {
                 EventBus.getDefault().send(new DismissFocusedTaskViewEvent());
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 b175855..8e768a2 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
@@ -200,19 +200,6 @@
         EventBus.getDefault().unregister(this);
     }
 
-    /**
-     * This is called with the full size of the window since we are handling our own insets.
-     */
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (mTaskStackHorizontalView != null && mTaskStackHorizontalView.getVisibility() != GONE) {
-            mTaskStackHorizontalView.layout(left, top, left + getMeasuredWidth(), top + getMeasuredHeight());
-        }
-
-        // Layout the empty view
-        mEmptyView.layout(left, top, right, bottom);
-    }
-
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         mSystemInsets.set(insets.getSystemWindowInsets());
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 0089fa9..ec49256 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -65,17 +65,25 @@
     public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH = 0x2;
     private int mSuspendPipResizingReason;
 
+    private static final float SCALE_FACTOR = 1.1f;
+
     private Context mContext;
     private IActivityManager mActivityManager;
     private int mState = STATE_NO_PIP;
     private final Handler mHandler = new Handler();
     private List<Listener> mListeners = new ArrayList<>();
-    private Rect mPipBound;
-    private Rect mMenuModePipBound;
+    private Rect mCurrentPipBounds;
+    private Rect mPipBounds;
+    private Rect mMenuModePipBounds;
+    private Rect mRecentsPipBounds;
+    private Rect mRecentsFocusedPipBounds;
     private boolean mInitialized;
     private int mPipTaskId = TASK_ID_NO_PIP;
     private boolean mOnboardingShown;
 
+    private boolean mIsRecentsShown;
+    private boolean mIsPipFocusedInRecent;
+
     private final Runnable mOnActivityPinnedRunnable = new Runnable() {
         @Override
         public void run() {
@@ -83,7 +91,7 @@
             try {
                 stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
                 if (stackInfo == null) {
-                    Log.w(TAG, "There is no pinned stack");
+                    Log.w(TAG, "Cannot find pinned stack");
                     return;
                 }
             } catch (RemoteException e) {
@@ -94,6 +102,7 @@
             mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
             // Set state to overlay so we show it when the pinned stack animation ends.
             mState = STATE_PIP_OVERLAY;
+            mCurrentPipBounds = mPipBounds;
             launchPipOnboardingActivityIfNeeded();
         }
     };
@@ -133,10 +142,13 @@
     private final Runnable mOnPinnedStackAnimationEnded = new Runnable() {
         @Override
         public void run() {
-            if (mState == STATE_PIP_OVERLAY) {
-                showPipOverlay();
-            } else if (mState == STATE_PIP_MENU) {
-                showPipMenu();
+            switch (mState) {
+                case STATE_PIP_OVERLAY:
+                    showPipOverlay();
+                    break;
+                case STATE_PIP_MENU:
+                    showPipMenu();
+                    break;
             }
         }
     };
@@ -177,10 +189,18 @@
         mInitialized = true;
         mContext = context;
         Resources res = context.getResources();
-        mPipBound = Rect.unflattenFromString(res.getString(
+        mPipBounds = Rect.unflattenFromString(res.getString(
                 com.android.internal.R.string.config_defaultPictureInPictureBounds));
-        mMenuModePipBound = Rect.unflattenFromString(res.getString(
+        mMenuModePipBounds = Rect.unflattenFromString(res.getString(
                 com.android.internal.R.string.config_centeredPictureInPictureBounds));
+        mRecentsPipBounds = Rect.unflattenFromString(res.getString(
+                com.android.internal.R.string.config_pictureInPictureBoundsInRecents));
+        float scaleBy = (SCALE_FACTOR - 1.0f) / 2;
+        mRecentsFocusedPipBounds = new Rect(
+                (int) (mRecentsPipBounds.left - scaleBy * mRecentsPipBounds.width()),
+                (int) (mRecentsPipBounds.top - scaleBy * mRecentsPipBounds.height()),
+                (int) (mRecentsPipBounds.right + scaleBy * mRecentsPipBounds.width()),
+                (int) (mRecentsPipBounds.bottom + scaleBy * mRecentsPipBounds.height()));
 
         mActivityManager = ActivityManagerNative.getDefault();
         TaskStackListener taskStackListener = new TaskStackListener();
@@ -203,7 +223,7 @@
      */
     public void requestTvPictureInPicture() {
         if (DEBUG) Log.d(TAG, "requestTvPictureInPicture()");
-        if (!hasPipTasks()) {
+        if (!isPipShown()) {
             startPip();
         } else if (mState == STATE_PIP_OVERLAY) {
             resizePinnedStack(STATE_PIP_MENU);
@@ -212,7 +232,7 @@
 
     private void startPip() {
         try {
-            mActivityManager.moveTopActivityToPinnedStack(FULLSCREEN_WORKSPACE_STACK_ID, mPipBound);
+            mActivityManager.moveTopActivityToPinnedStack(FULLSCREEN_WORKSPACE_STACK_ID, mPipBounds);
         } catch (RemoteException|IllegalArgumentException e) {
             Log.e(TAG, "moveTopActivityToPinnedStack failed", e);
         }
@@ -235,6 +255,9 @@
                 Log.e(TAG, "removeStack failed", e);
             }
         }
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onPipActivityClosed();
+        }
     }
 
     /**
@@ -295,37 +318,100 @@
     public void resizePinnedStack(int state) {
         if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state);
         mState = state;
-        Rect bounds;
         for (int i = mListeners.size() - 1; i >= 0; --i) {
             mListeners.get(i).onPipResizeAboutToStart();
         }
-        switch (mState) {
-            case STATE_PIP_MENU:
-                bounds = mMenuModePipBound;
-                break;
-            case STATE_NO_PIP:
-                bounds = null;
-                break;
-            default:
-                bounds = mPipBound;
-                break;
-        }
-
         if (mSuspendPipResizingReason != 0) {
             if (DEBUG) Log.d(TAG,
                     "resizePinnedStack() deferring mSuspendPipResizingReason=" +
                             mSuspendPipResizingReason);
             return;
         }
-
+        switch (mState) {
+            case STATE_NO_PIP:
+                mCurrentPipBounds = null;
+                break;
+            case STATE_PIP_MENU:
+                mCurrentPipBounds = mMenuModePipBounds;
+                break;
+            case STATE_PIP_OVERLAY:
+                if (mIsRecentsShown) {
+                    if (mIsPipFocusedInRecent) {
+                        mCurrentPipBounds = mRecentsFocusedPipBounds;
+                    } else {
+                        mCurrentPipBounds = mRecentsPipBounds;
+                    }
+                } else {
+                    mCurrentPipBounds = mPipBounds;
+                }
+                break;
+            default:
+                mCurrentPipBounds = mPipBounds;
+                break;
+        }
         try {
-            mActivityManager.resizeStack(PINNED_STACK_ID, bounds, true, true, true);
+            mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds, true, true, true);
         } catch (RemoteException e) {
             Log.e(TAG, "showPipMenu failed", e);
         }
     }
 
     /**
+     * Returns the current PIP bound for activities to sync their UI with PIP.
+     */
+    public Rect getPipBounds() {
+        return mCurrentPipBounds;
+    }
+
+    /**
+     * Called when Recents is started.
+     * PIPed activity will be resized accordingly and overlay will show available buttons.
+     */
+    public void onRecentsStarted() {
+        mIsRecentsShown = true;
+        mIsPipFocusedInRecent = false;
+        if (mState == STATE_NO_PIP) {
+            return;
+        }
+        resizePinnedStack(STATE_PIP_OVERLAY);
+    }
+
+    /**
+     * Called when Recents is stopped.
+     * PIPed activity will be resized accordingly and overlay will hide available buttons.
+     */
+    public void onRecentsStopped() {
+        mIsRecentsShown = false;
+        mIsPipFocusedInRecent = false;
+        if (mState == STATE_NO_PIP) {
+            return;
+        }
+        resizePinnedStack(STATE_PIP_OVERLAY);
+    }
+
+    /**
+     * Returns {@code true} if recents is shown.
+     */
+    boolean isRecentsShown() {
+        return mIsRecentsShown;
+    }
+
+    /**
+     * Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
+     * is focused.
+     * This only resizes pinned stack so it looks like it's in Recents.
+     * This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
+     */
+    public void onPipViewFocusChangedInRecents(boolean hasFocus) {
+        mIsPipFocusedInRecent = hasFocus;
+        if (mState != STATE_PIP_OVERLAY) {
+            Log.w(TAG, "There is no pinned stack to handle focus change.");
+            return;
+        }
+        resizePinnedStack(STATE_PIP_OVERLAY);
+    }
+
+    /**
      * Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned
      * stack to the centered PIP bound {@link com.android.internal.R.string
      * .config_centeredPictureInPictureBounds}.
@@ -362,6 +448,13 @@
         }
     }
 
+    /**
+     * Returns {@code true} if PIP is shown.
+     */
+    public boolean isPipShown() {
+        return hasPipTasks();
+    }
+
     private boolean hasPipTasks() {
         try {
             StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
index 7b1764f..6f24691 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
@@ -35,6 +35,7 @@
     private final PipManager mPipManager = PipManager.getInstance();
     private final Handler mHandler = new Handler();
     private View mGuideOverlayView;
+    private View mGuideButtonsView;
     private final Runnable mHideGuideOverlayRunnable = new Runnable() {
         public void run() {
             mGuideOverlayView.setVisibility(View.INVISIBLE);
@@ -46,13 +47,21 @@
         super.onCreate(bundle);
         setContentView(R.layout.tv_pip_overlay);
         mGuideOverlayView = findViewById(R.id.guide_overlay);
+        mGuideButtonsView = findViewById(R.id.guide_buttons);
         mPipManager.addListener(this);
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        mGuideOverlayView.setVisibility(View.VISIBLE);
+        // TODO: Implement animation for this
+        if (!mPipManager.isRecentsShown()) {
+            mGuideOverlayView.setVisibility(View.VISIBLE);
+            mGuideButtonsView.setVisibility(View.INVISIBLE);
+        } else {
+            mGuideOverlayView.setVisibility(View.INVISIBLE);
+            mGuideButtonsView.setVisibility(View.VISIBLE);
+        }
         mHandler.removeCallbacks(mHideGuideOverlayRunnable);
         mHandler.postDelayed(mHideGuideOverlayRunnable, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
     }