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

Commit fdd935b5 authored by wilsonshih's avatar wilsonshih Committed by Wei Sheng Shih
Browse files

Adjust cancel back navigation conditions.

There will cancel back navigation when navigation window lose focus,
for this change we also monitor when transition happens on navigation
target.

There are two shortcomings for monitor the navigation window lose
focus.
First is that it may cause misjudgment in multi-window mode. The
navigation window can be the one in split screen, but if another task
start a transition(e.g. start/finish activity), that should be
irrelevant to the navigation target, but that task could gain focus
for a short time. Another thing is that while back animating, the
window can lose focus if the close animation applys alpha = 0 to the
closing target, but that should be acceptable for animation.
So for window focus change, there can only used to monitor when the new
focus window is a stand alone winodw, or when the parent activity is
navigating.
And in order to cancel gesture for any change above window-level,
monitor if a new transition happens which contains the navigation
window.

Bug: 131727607
Test: atest BackAnimationControllerTest BackNavigationControllerTests
Test: manual, into split screen, start back animation on top task, and
start an activity from bottom task, verify the back animation won't be canceled.
Test: manual, during back-to-home animating, start another activity in
the same task, and verify shell should cancel the navigation.
Test: manual, verify ANR window can cancel back animation.
Test: manual, animation won't be canceled while playing a cross
activity animation with alpha=0.

Change-Id: Ia7acd041ec7afd3d94482f0950003fea499ce82b
parent dd76f4b3
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -65,12 +65,12 @@ import android.os.Debug;
import android.os.IBinder;
import android.os.IProgressListener;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
import android.os.StrictMode;
import android.os.WorkSource;
import android.service.voice.IVoiceInteractionSession;
import android.view.IRecentsAnimationRunner;
import android.view.IRemoteAnimationRunner;
import android.view.IWindowFocusObserver;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationAdapter;
import android.window.IWindowOrganizerController;
@@ -349,12 +349,13 @@ interface IActivityTaskManager {
    /**
     * Prepare the back navigation in the server. This setups the leashed for sysui to animate
     * the back gesture and returns the data needed for the animation.
     * @param focusObserver a remote callback to nofify shell when the focused window lost focus.
     * @param navigationObserver a remote callback to nofify shell when the focused window is gone,
                                 or an unexpected transition has happened on the navigation target.
     * @param adaptor a remote animation to be run for the back navigation plays the animation.
     * @return Returns the back navigation info.
     */
    android.window.BackNavigationInfo startBackNavigation(
            in IWindowFocusObserver focusObserver, in BackAnimationAdapter adaptor);
            in RemoteCallback navigationObserver, in BackAnimationAdapter adaptor);

    /**
     * registers a callback to be invoked when the screen is captured.
+17 −18
Original line number Diff line number Diff line
@@ -29,8 +29,9 @@ import android.content.Context;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -39,7 +40,6 @@ import android.provider.Settings.Global;
import android.util.Log;
import android.util.SparseArray;
import android.view.IRemoteAnimationRunner;
import android.view.IWindowFocusObserver;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -121,23 +121,22 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    private IOnBackInvokedCallback mActiveCallback;

    @VisibleForTesting
    final IWindowFocusObserver mFocusObserver = new IWindowFocusObserver.Stub() {
    final RemoteCallback mNavigationObserver = new RemoteCallback(
            new RemoteCallback.OnResultListener() {
                @Override
        public void focusGained(IBinder inputToken) { }
        @Override
        public void focusLost(IBinder inputToken) {
                public void onResult(@Nullable Bundle result) {
                    mShellExecutor.execute(() -> {
                        if (!mBackGestureStarted || mPostCommitAnimationInProgress) {
                    // If an uninterruptible animation is already in progress, we should ignore
                    // this due to it may cause focus lost. (alpha = 0)
                            // If an uninterruptible animation is already in progress, we should
                            // ignore this due to it may cause focus lost. (alpha = 0)
                            return;
                        }
                ProtoLog.i(WM_SHELL_BACK_PREVIEW, "Target window lost focus.");
                        ProtoLog.i(WM_SHELL_BACK_PREVIEW, "Navigation window gone.");
                        setTriggerBack(false);
                        onGestureFinished(false);
                    });
                }
    };
            });

    private final BackAnimationBackground mAnimationBackground;

@@ -351,7 +350,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont

        try {
            mBackNavigationInfo = mActivityTaskManager.startBackNavigation(
                    mFocusObserver, mEnableAnimations.get() ? mBackAnimationAdapter : null);
                    mNavigationObserver, mEnableAnimations.get() ? mBackAnimationAdapter : null);
            onBackNavigationInfoReceived(mBackNavigationInfo);
        } catch (RemoteException remoteException) {
            Log.e(TAG, "Failed to initAnimation", remoteException);
+1 −4
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
@@ -40,7 +39,6 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.provider.Settings;
@@ -341,8 +339,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
        mController.setTriggerBack(true);   // Fake trigger back

        // In case the focus has been changed.
        IBinder token = mock(IBinder.class);
        mController.mFocusObserver.focusLost(token);
        mController.mNavigationObserver.sendResult(null);
        mShellExecutor.flushAll();
        verify(mAnimatorCallback).onBackCancelled();

+3 −3
Original line number Diff line number Diff line
@@ -201,6 +201,7 @@ import android.os.Parcel;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
@@ -227,7 +228,6 @@ import android.util.SparseArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.IRecentsAnimationRunner;
import android.view.IWindowFocusObserver;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
@@ -1852,11 +1852,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    @Override
    public BackNavigationInfo startBackNavigation(
            IWindowFocusObserver observer, BackAnimationAdapter adapter) {
            RemoteCallback navigationObserver, BackAnimationAdapter adapter) {
        mAmInternal.enforceCallingPermission(START_TASKS_FROM_RECENTS,
                "startBackNavigation()");

        return mBackNavigationController.startBackNavigation(observer, adapter);
        return mBackNavigationController.startBackNavigation(navigationObserver, adapter);
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ public class AppTransitionController {

        ArraySet<ActivityRecord> tmpOpenApps = mDisplayContent.mOpeningApps;
        ArraySet<ActivityRecord> tmpCloseApps = mDisplayContent.mClosingApps;
        if (mDisplayContent.mAtmService.mBackNavigationController.isWaitBackTransition()) {
        if (mDisplayContent.mAtmService.mBackNavigationController.isMonitoringTransition()) {
            tmpOpenApps = new ArraySet<>(mDisplayContent.mOpeningApps);
            tmpCloseApps = new ArraySet<>(mDisplayContent.mClosingApps);
            if (mDisplayContent.mAtmService.mBackNavigationController
Loading