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

Commit b502690e authored by Winson Chung's avatar Winson Chung
Browse files

Updating Overview to work with PiP

- Ensure that an activity that is auto-entering PiP when hitting Overview
  does not show up in Overview. This is done by listening for the
  onActivityPinned() callback from the system, and remove the pinned task.
- Ensure that we show the PiP task in Overview after it is dismissed, while
  Overview is open. This is done by listening for the onActivityUnpinned()
  callback from the system and refreshing the task list similar to when
  the multi-window mode changes.
- When launching from a PiP activity, or launching back into Overview where
  the next task should be PiP, then ensure that we scroll the stack to the
  front so that the first task is fully visible.
- Fix two lingering Overview issues, when there are no handlers (ie. with
  dynamically registered handlers), ensure that we call pre/post dispatch
  callbacks (otherwise it could cause animated events not to work correctly).
  Also, ensure that we don't update the dummy stack view TaskStack without
  clearing the stack first, since we may be modifying the same stack
  that the activity consumed when starting.

Bug: 34185886
Bug: 38207296
Test: Launch PIP activity from hitting Overview in the various ways
      described above
Change-Id: I699e655106e6ed7206e163f9d3c15477bbfd52ef
parent e96d66db
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ oneway interface ITaskStackListener {
    void onTaskStackChanged();

    /** Called whenever an Activity is moved to the pinned stack from another stack. */
    void onActivityPinned(String packageName);
    void onActivityPinned(String packageName, int taskId);

    /** Called whenever an Activity is moved from the pinned stack to another stack. */
    void onActivityUnpinned();
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
    }

    @Override
    public void onActivityPinned(String packageName) throws RemoteException {
    public void onActivityPinned(String packageName, int taskId) throws RemoteException {
    }

    @Override
+26 −1
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.systemui.pip.phone;

import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.view.Display.DEFAULT_DISPLAY;

import android.app.ActivityManager;
import android.app.ActivityManager.StackInfo;
import android.app.IActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -33,6 +35,8 @@ import android.view.IWindowManager;
import android.view.WindowManagerGlobal;

import com.android.systemui.pip.BasePipManager;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.component.ExpandPipEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.statusbar.CommandQueue;
@@ -65,7 +69,7 @@ public class PipManager implements BasePipManager {
     */
    TaskStackListener mTaskStackListener = new TaskStackListener() {
        @Override
        public void onActivityPinned(String packageName) {
        public void onActivityPinned(String packageName, int taskId) {
            if (!checkCurrentUserId(false /* debug */)) {
                return;
            }
@@ -186,6 +190,7 @@ public class PipManager implements BasePipManager {
                mInputConsumerController);
        mNotificationController = new PipNotificationController(context, mActivityManager,
                mTouchHandler.getMotionHelper());
        EventBus.getDefault().register(this);
    }

    /**
@@ -195,6 +200,26 @@ public class PipManager implements BasePipManager {
        mTouchHandler.onConfigurationChanged();
    }

    /**
     * Expands the PIP.
     */
    public final void onBusEvent(ExpandPipEvent event) {
        if (event.clearThumbnailWindows) {
            try {
                StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
                if (stackInfo != null && stackInfo.taskIds != null) {
                    SystemServicesProxy ssp = SystemServicesProxy.getInstance(mContext);
                    for (int taskId : stackInfo.taskIds) {
                        ssp.cancelThumbnailTransition(taskId);
                    }
                }
            } catch (RemoteException e) {
                // Do nothing
            }
        }
        mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
    }

    /**
     * Sent from KEYCODE_WINDOW handler in PhoneWindowManager, to request the menu to be shown.
     */
+21 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ import android.widget.LinearLayout;

import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.component.HidePipMenuEvent;

import java.util.ArrayList;
import java.util.Collections;
@@ -231,6 +233,7 @@ public class PipMenuActivity extends Activity {
        super.onStop();

        cancelDelayedFinish();
        EventBus.getDefault().unregister(this);
    }

    @Override
@@ -290,6 +293,19 @@ public class PipMenuActivity extends Activity {
        // Do nothing
    }

    public final void onBusEvent(HidePipMenuEvent event) {
        if (mMenuState != MENU_STATE_NONE) {
            // If the menu is visible in either the closed or full state, then hide the menu and
            // trigger the animation trigger afterwards
            event.getAnimationTrigger().increment();
            hideMenu(() -> {
                mHandler.post(() -> {
                    event.getAnimationTrigger().decrement();
                });
            }, true /* notifyMenuVisibility */);
        }
    }

    private void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
            boolean allowMenuTimeout) {
        mAllowMenuTimeout = allowMenuTimeout;
@@ -374,11 +390,16 @@ public class PipMenuActivity extends Activity {
    private void updateFromIntent(Intent intent) {
        mToControllerMessenger = intent.getParcelableExtra(EXTRA_CONTROLLER_MESSENGER);
        notifyActivityCallback(mMessenger);

        // Register for HidePipMenuEvents once we notify the controller of this activity
        EventBus.getDefault().register(this);

        ParceledListSlice actions = intent.getParcelableExtra(EXTRA_ACTIONS);
        if (actions != null) {
            mActions.clear();
            mActions.addAll(actions.getList());
        }

        final int menuState = intent.getIntExtra(EXTRA_MENU_STATE, MENU_STATE_NONE);
        if (menuState != MENU_STATE_NONE) {
            Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
+19 −0
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ import android.util.Log;
import android.view.IWindowManager;

import com.android.systemui.pip.phone.PipMediaController.ActionListener;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.component.HidePipMenuEvent;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -119,6 +122,7 @@ public class PipMenuActivityController {
    // The dismiss fraction update is sent frequently, so use a temporary bundle for the message
    private Bundle mTmpDismissFractionData = new Bundle();

    private ReferenceCountedTrigger mOnAttachDecrementTrigger;
    private boolean mStartActivityRequested;
    private Messenger mToActivityMessenger;
    private Messenger mMessenger = new Messenger(new Handler() {
@@ -157,6 +161,10 @@ public class PipMenuActivityController {
                case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                    mToActivityMessenger = msg.replyTo;
                    mStartActivityRequested = false;
                    if (mOnAttachDecrementTrigger != null) {
                        mOnAttachDecrementTrigger.decrement();
                        mOnAttachDecrementTrigger = null;
                    }
                    // Mark the menu as invisible once the activity finishes as well
                    if (mToActivityMessenger == null) {
                        onMenuStateChanged(MENU_STATE_NONE, true /* resize */);
@@ -181,6 +189,8 @@ public class PipMenuActivityController {
        mActivityManager = activityManager;
        mMediaController = mediaController;
        mInputConsumerController = inputConsumerController;

        EventBus.getDefault().register(this);
    }

    public void onActivityPinned() {
@@ -435,6 +445,15 @@ public class PipMenuActivityController {
        mMenuState = menuState;
    }

    public final void onBusEvent(HidePipMenuEvent event) {
        if (mStartActivityRequested) {
            // If the menu has been start-requested, but not actually started, then we defer the
            // trigger callback until the menu has started and called back to the controller
            mOnAttachDecrementTrigger = event.getAnimationTrigger();
            mOnAttachDecrementTrigger.increment();
        }
    }

    public void dump(PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        pw.println(prefix + TAG);
Loading