Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c1e1544 authored by Youngsang Cho's avatar Youngsang Cho Committed by Android (Google) Code Review
Browse files

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

parents 670d54c8 ad8ceb03
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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"
+73 −7
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.res.Resources;
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 java.util.List;
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 @@ public class PipManager {

    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 @@ public class PipManager {
    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 @@ public class PipManager {
            }
            if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
            mState = STATE_PIP_OVERLAY;
            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
            launchPipOverlayActivity();
        }
    };
@@ -86,15 +98,27 @@ public class PipManager {
        }
    };

    private final BroadcastReceiver mPipButtonReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            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 @@ public class PipManager {
        }
        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 class PipManager {
     */
    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 class PipManager {
     */
    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 @@ public class PipManager {
        }
    }

    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 {