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

Commit eefcd546 authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge "Add #onPictureInPictureRequested to Activity and ATM"

parents 11d07a8b 06bc3233
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3812,6 +3812,7 @@ package android.app {
    method public void onPerformDirectAction(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.os.Bundle>);
    method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
    method @Deprecated public void onPictureInPictureModeChanged(boolean);
    method public void onPictureInPictureRequested();
    method @CallSuper protected void onPostCreate(@Nullable android.os.Bundle);
    method public void onPostCreate(@Nullable android.os.Bundle, @Nullable android.os.PersistableBundle);
    method @CallSuper protected void onPostResume();
@@ -5102,6 +5103,7 @@ package android.app {
    method public void callActivityOnDestroy(android.app.Activity);
    method public void callActivityOnNewIntent(android.app.Activity, android.content.Intent);
    method public void callActivityOnPause(android.app.Activity);
    method public void callActivityOnPictureInPictureRequested(@NonNull android.app.Activity);
    method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle);
    method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle, @Nullable android.os.PersistableBundle);
    method public void callActivityOnRestart(android.app.Activity);
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ package android.app {
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean moveTopActivityToPinnedStack(int, android.graphics.Rect);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksWithActivityTypes(int[]) throws java.lang.SecurityException;
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void requestPictureInPictureMode(@NonNull android.os.IBinder);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeDockedStack(android.graphics.Rect, android.graphics.Rect);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizePinnedStack(int, android.graphics.Rect, boolean);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeTask(int, android.graphics.Rect);
+11 −0
Original line number Diff line number Diff line
@@ -2837,6 +2837,17 @@ public class Activity extends ContextThemeWrapper
        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
    }

    /**
     * Called by the system when picture in picture mode should be entered if supported.
     */
    public void onPictureInPictureRequested() {
        // Previous recommendation was for apps to enter picture-in-picture in onUserLeaveHint()
        // which is sent after onPause(). This new method allows the system to request the app to
        // go into picture-in-picture decoupling it from life cycle events. For backwards
        // compatibility we schedule the life cycle events if the app didn't override this method.
        mMainThread.schedulePauseAndReturnToCurrentState(mToken);
    }

    void dispatchMovedToDisplay(int displayId, Configuration config) {
        updateDisplay(displayId);
        onMovedToDisplay(displayId, config);
+15 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -433,4 +434,18 @@ public class ActivityTaskManager {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Requests that an activity should enter picture-in-picture mode if possible.
     * @hide
     */
    @TestApi
    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
    public void requestPictureInPictureMode(@NonNull IBinder token) {
        try {
            getService().requestPictureInPictureMode(token);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
+67 −0
Original line number Diff line number Diff line
@@ -41,8 +41,10 @@ import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ActivityResultItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.ClientTransactionItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.PendingTransactionActions;
import android.app.servertransaction.PendingTransactionActions.StopInfo;
import android.app.servertransaction.ResumeActivityItem;
import android.app.servertransaction.TransactionExecutor;
import android.app.servertransaction.TransactionExecutorHelper;
import android.compat.annotation.UnsupportedAppUsage;
@@ -522,6 +524,8 @@ public final class ActivityThread extends ClientTransactionHandler {
        boolean startsNotResumed;
        public final boolean isForward;
        int pendingConfigChanges;
        // Whether we are in the process of performing on user leaving.
        boolean mIsUserLeaving;

        Window mPendingRemoveWindow;
        WindowManager mPendingRemoveWindowManager;
@@ -3763,6 +3767,66 @@ public final class ActivityThread extends ClientTransactionHandler {
        }
    }

    @Override
    public void handlePictureInPictureRequested(IBinder token) {
        final ActivityClientRecord r = mActivities.get(token);
        if (r == null) {
            Log.w(TAG, "Activity to request PIP to no longer exists");
            return;
        }

        r.activity.onPictureInPictureRequested();
    }

    /**
     * Cycle activity through onPause and onUserLeaveHint so that PIP is entered if supported, then
     * return to its previous state. This allows activities that rely on onUserLeaveHint instead of
     * onPictureInPictureRequested to enter picture-in-picture.
     */
    public void schedulePauseAndReturnToCurrentState(IBinder token) {
        final ActivityClientRecord r = mActivities.get(token);
        if (r == null) {
            Log.w(TAG, "Activity to request pause with user leaving hint to no longer exists");
            return;
        }

        if (r.mIsUserLeaving) {
            // The activity is about to perform user leaving, so there's no need to cycle ourselves.
            return;
        }

        final int prevState = r.getLifecycleState();
        if (prevState != ON_RESUME && prevState != ON_PAUSE) {
            return;
        }

        switch (prevState) {
            case ON_RESUME:
                // Schedule a PAUSE then return to RESUME.
                schedulePauseWithUserLeavingHint(r);
                scheduleResume(r);
                break;
            case ON_PAUSE:
                // Schedule a RESUME then return to PAUSE.
                scheduleResume(r);
                schedulePauseWithUserLeavingHint(r);
                break;
        }
    }

    private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) {
        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
        transaction.setLifecycleStateRequest(PauseActivityItem.obtain(r.activity.isFinishing(),
                /* userLeaving */ true, r.activity.mConfigChangeFlags, /* dontReport */ false));
        executeTransaction(transaction);
    }

    private void scheduleResume(ActivityClientRecord r) {
        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
        transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false));
        executeTransaction(transaction);
    }

    private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
        final ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
@@ -4483,6 +4547,7 @@ public final class ActivityThread extends ClientTransactionHandler {
        if (r != null) {
            if (userLeaving) {
                performUserLeavingActivity(r);
                r.mIsUserLeaving = false;
            }

            r.activity.mConfigChangeFlags |= configChanges;
@@ -4497,6 +4562,8 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    final void performUserLeavingActivity(ActivityClientRecord r) {
        r.mIsUserLeaving = true;
        mInstrumentation.callActivityOnPictureInPictureRequested(r.activity);
        mInstrumentation.callActivityOnUserLeaving(r.activity);
    }

Loading