Close picture-in-picture when a fullscreen app starts to play a video

Bug: 26549507
Change-Id: I27e8f7b1847bf0e34e7c47bf6303c425c3eb9127
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6ec757d..c1f97a8 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -152,6 +152,9 @@
     <!-- Needed for passing extras with intent ACTION_SHOW_ADMIN_SUPPORT_DETAILS -->
     <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
 
+    <!-- TV picture-in-picture -->
+    <uses-permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
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 2aac69a..3d91d62 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -29,6 +29,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -37,6 +38,9 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+
 /**
  * Manages the picture-in-picture (PIP) UI and states.
  */
@@ -46,10 +50,15 @@
 
     private static PipManager sPipManager;
 
+    private static final int MAX_RUNNING_TASKS_COUNT = 10;
+
     private static final int STATE_NO_PIP = 0;
     private static final int STATE_PIP_OVERLAY = 1;
     private static final int STATE_PIP_MENU = 2;
 
+    private static final int TASK_ID_NO_PIP = -1;
+    private static final int INVALID_RESOURCE_TYPE = -1;
+
     private Context mContext;
     private IActivityManager mActivityManager;
     private int mState = STATE_NO_PIP;
@@ -58,6 +67,8 @@
     private Rect mPipBound;
     private Rect mMenuModePipBound;
     private boolean mInitialized;
+    private int mPipTaskId = TASK_ID_NO_PIP;
+
     private final Runnable mOnActivityPinnedRunnable = new Runnable() {
         @Override
         public void run() {
@@ -74,6 +85,7 @@
             }
             if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
             mState = STATE_PIP_OVERLAY;
+            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
             launchPipOverlayActivity();
         }
     };
@@ -86,15 +98,27 @@
         }
     };
 
-    private final BroadcastReceiver mPipButtonReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Log.d(TAG, "PIP button pressed");
-            if (!hasPipTasks()) {
-                startPip();
-            } else if (mState == STATE_PIP_OVERLAY) {
-                showPipMenu();
+            String action = intent.getAction();
+            if (Intent.ACTION_PICTURE_IN_PICTURE_BUTTON.equals(action)) {
+                if (DEBUG) Log.d(TAG, "PIP button pressed");
+                if (!hasPipTasks()) {
+                    startPip();
+                } else if (mState == STATE_PIP_OVERLAY) {
+                    showPipMenu();
+                }
+            } else if (Intent.ACTION_MEDIA_RESOURCE_GRANTED.equals(action)) {
+                String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+                int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE,
+                        INVALID_RESOURCE_TYPE);
+                if (mState != STATE_NO_PIP && packageNames != null && packageNames.length > 0
+                        && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) {
+                    handleMediaResourceGranted(packageNames);
+                }
             }
+
         }
     };
 
@@ -125,7 +149,8 @@
         }
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PICTURE_IN_PICTURE_BUTTON);
-        mContext.registerReceiver(mPipButtonReceiver, intentFilter);
+        intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
     }
 
     private void startPip() {
@@ -142,6 +167,7 @@
      */
     public void closePip() {
         mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
         StackInfo stackInfo = null;
         try {
             stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
@@ -166,6 +192,7 @@
      */
     public void movePipToFullscreen() {
         mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
         for (int i = mListeners.size() - 1; i >= 0; --i) {
             mListeners.get(i).onMoveToFullscreen();
         }
@@ -251,6 +278,45 @@
         }
     }
 
+    private void handleMediaResourceGranted(String[] packageNames) {
+        StackInfo fullscreenStack = null;
+        try {
+            fullscreenStack = mActivityManager.getStackInfo(FULLSCREEN_WORKSPACE_STACK_ID);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getStackInfo failed", e);
+        }
+        if (fullscreenStack == null) {
+            return;
+        }
+        int fullscreenTopTaskId = fullscreenStack.taskIds[fullscreenStack.taskIds.length - 1];
+        List<RunningTaskInfo> tasks = null;
+        try {
+            tasks = mActivityManager.getTasks(MAX_RUNNING_TASKS_COUNT, 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getTasks failed", e);
+        }
+        if (tasks == null) {
+            return;
+        }
+        boolean wasGrantedInFullscreen = false;
+        boolean wasGrantedInPip = false;
+        for (int i = tasks.size() - 1; i >= 0; --i) {
+            RunningTaskInfo task = tasks.get(i);
+            for (int j = packageNames.length - 1; j >= 0; --j) {
+                if (task.topActivity.getPackageName().equals(packageNames[j])) {
+                    if (task.id == fullscreenTopTaskId) {
+                        wasGrantedInFullscreen = true;
+                    } else if (task.id == mPipTaskId) {
+                        wasGrantedInPip= true;
+                    }
+                }
+            }
+        }
+        if (wasGrantedInFullscreen && !wasGrantedInPip) {
+            closePip();
+        }
+    }
+
     private class TaskStackListener extends ITaskStackListener.Stub {
         @Override
         public void onTaskStackChanged() throws RemoteException {