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

Commit 570308d9 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Reduce lock contention of setting running shell remote transition

When the transition is ready on shell side, the core may be still
running surface placement. Then it may easily meet lock contention
when setting the animating state for the animation player process.

This change moves the animation delegate to TransitionController.
It can recognize the delegate process if the remote animation is
specified from ActivityOptions. So when shell is calling
setRunningRemoteTransitionDelegate, it can just check if the process
is handled without entering WM lock.

The case of using TransitionFilter may still encounter contention
the remote registrations only exist on shell side.

Also add a quick check at shell side to skip the IPC if the app
thread of remote animation is null. Such as when launching from
quick settings that the remote is actual the local process.

Bug: 235323163
Test: atest TransitionTests#testRunningRemoteTransition

Change-Id: I137fcdff3cb5658aad5f7452c33bbc8d70f42398
parent 619befaa
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -67,7 +67,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.app.WindowConfiguration;
import android.content.Context;
@@ -453,14 +452,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                                finishedCallback.onAnimationFinished();
                            }
                        };
                Transitions.setRunningRemoteTransitionDelegate(adapter.getCallingApplication());
                try {
                    try {
                        ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
                                adapter.getCallingApplication());
                    } catch (SecurityException e) {
                        Slog.e(TAG, "Unable to boost animation thread. This should only happen"
                                + " during unit tests");
                    }
                    adapter.getRunner().onAnimationStart(transit, apps, wallpapers,
                            augmentedNonApps, wrapCallback);
                } catch (RemoteException e) {
+1 −9
Original line number Diff line number Diff line
@@ -18,11 +18,9 @@ package com.android.wm.shell.transition;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
import android.view.SurfaceControl;
import android.window.IRemoteTransition;
import android.window.IRemoteTransitionFinishedCallback;
@@ -87,17 +85,11 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
                });
            }
        };
        Transitions.setRunningRemoteTransitionDelegate(mRemote.getAppThread());
        try {
            if (mRemote.asBinder() != null) {
                mRemote.asBinder().linkToDeath(remoteDied, 0 /* flags */);
            }
            try {
                ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
                        mRemote.getAppThread());
            } catch (SecurityException e) {
                Slog.e(Transitions.TAG, "Unable to boost animation thread. This should only happen"
                        + " during unit tests");
            }
            mRemote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
            // assume that remote will apply the start transaction.
            startTransaction.clear();
+1 −8
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.wm.shell.transition;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -129,15 +128,9 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
                });
            }
        };
        Transitions.setRunningRemoteTransitionDelegate(remote.getAppThread());
        try {
            handleDeath(remote.asBinder(), finishCallback);
            try {
                ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
                        remote.getAppThread());
            } catch (SecurityException e) {
                Log.e(Transitions.TAG, "Unable to boost animation thread. This should only happen"
                        + " during unit tests");
            }
            remote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
            // assume that remote will apply the start transaction.
            startTransaction.clear();
+15 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTas

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.app.IApplicationThread;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -228,6 +230,19 @@ public class Transitions implements RemoteCallable<Transitions> {
        mRemoteTransitionHandler.removeFiltered(remoteTransition);
    }

    /** Boosts the process priority of remote animation player. */
    public static void setRunningRemoteTransitionDelegate(IApplicationThread appThread) {
        if (appThread == null) return;
        try {
            ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(appThread);
        } catch (SecurityException e) {
            Log.e(TAG, "Unable to boost animation process. This should only happen"
                    + " during unit tests");
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Runs the given {@code runnable} when the last active transition has finished, or immediately
     * if there are currently no active transitions.
+0 −3
Original line number Diff line number Diff line
@@ -1659,9 +1659,6 @@ class ActivityStarter {
                && transitionController.getTransitionPlayer() != null)
                ? transitionController.createTransition(TRANSIT_OPEN) : null;
        RemoteTransition remoteTransition = r.takeRemoteTransition();
        if (newTransition != null && remoteTransition != null) {
            newTransition.setRemoteTransition(remoteTransition);
        }
        transitionController.collect(r);
        try {
            mService.deferWindowLayout();
Loading