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

Commit 9debeecb authored by wilsonshih's avatar wilsonshih
Browse files

Do not prepare animation if no corresponding animator registered.

If there is no animator can play the corresponding animation, then core
does need to prepare the animation at all.

Flag: EXEMPT bugfix
Bug: 363922376
Test: set default home to 3rd-party launcher, launch app then trigger
back gesture.

Change-Id: I7312cb2795bae47d8920c1e9937bb61cd83f2c11
parent 61dfb4a0
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package android.window;

import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

/**
 * Object that describes how to run a remote back animation.
 *
@@ -26,6 +29,7 @@ import android.os.Parcelable;
 */
public class BackAnimationAdapter implements Parcelable {
    private final IBackAnimationRunner mRunner;
    private int[] mSupportedAnimators;

    public BackAnimationAdapter(IBackAnimationRunner runner) {
        mRunner = runner;
@@ -33,12 +37,23 @@ public class BackAnimationAdapter implements Parcelable {

    public BackAnimationAdapter(Parcel in) {
        mRunner = IBackAnimationRunner.Stub.asInterface(in.readStrongBinder());
        mSupportedAnimators = new int[in.readInt()];
        in.readIntArray(mSupportedAnimators);
    }

    public IBackAnimationRunner getRunner() {
        return mRunner;
    }

    /** Update the latest animators in the system. */
    public void updateSupportedAnimators(@NonNull ArrayList<Integer> animators) {
        final int size = animators.size();
        mSupportedAnimators = new int[size];
        for (int i = size - 1; i >= 0; --i) {
            mSupportedAnimators[i] = animators.get(i);
        }
    }

    @Override
    public int describeContents() {
        return 0;
@@ -47,6 +62,8 @@ public class BackAnimationAdapter implements Parcelable {
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStrongInterface(mRunner);
        dest.writeInt(mSupportedAnimators.length);
        dest.writeIntArray(mSupportedAnimators);
    }

    public static final @android.annotation.NonNull Creator<BackAnimationAdapter> CREATOR =
@@ -59,4 +76,19 @@ public class BackAnimationAdapter implements Parcelable {
            return new BackAnimationAdapter[size];
        }
    };

    /**
     * Check if the back type is animatable.
     */
    public boolean isAnimatable(@BackNavigationInfo.BackTargetType int backType) {
        if (mSupportedAnimators == null) {
            return false;
        }
        for (int i = mSupportedAnimators.length - 1; i >= 0; --i) {
            if (backType == mSupportedAnimators[i]) {
                return true;
            }
        }
        return false;
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -573,8 +573,14 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
    private void startBackNavigation(@NonNull BackTouchTracker touchTracker) {
        try {
            startLatencyTracking();
            final BackAnimationAdapter adapter = mEnableAnimations.get()
                    ? mBackAnimationAdapter : null;
            if (adapter != null && mShellBackAnimationRegistry.hasSupportedAnimatorsChanged()) {
                adapter.updateSupportedAnimators(
                        mShellBackAnimationRegistry.getSupportedAnimators());
            }
            mBackNavigationInfo = mActivityTaskManager.startBackNavigation(
                    mNavigationObserver, mEnableAnimations.get() ? mBackAnimationAdapter : null);
                    mNavigationObserver, adapter);
            onBackNavigationInfoReceived(mBackNavigationInfo, touchTracker);
        } catch (RemoteException remoteException) {
            Log.e(TAG, "Failed to initAnimation", remoteException);
+24 −1
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.util.Log;
import android.util.SparseArray;
import android.window.BackNavigationInfo;

import java.util.ArrayList;

/** Registry for all types of default back animations */
public class ShellBackAnimationRegistry {
    private static final String TAG = "ShellBackPreview";
@@ -31,6 +33,8 @@ public class ShellBackAnimationRegistry {
    private ShellBackAnimation mDefaultCrossActivityAnimation;
    private final ShellBackAnimation mCustomizeActivityAnimation;
    private final ShellBackAnimation mCrossTaskAnimation;
    private boolean mSupportedAnimatorsChanged = false;
    private final ArrayList<Integer> mSupportedAnimators = new ArrayList<>();

    public ShellBackAnimationRegistry(
            @ShellBackAnimation.CrossActivity @Nullable ShellBackAnimation crossActivityAnimation,
@@ -60,7 +64,7 @@ public class ShellBackAnimationRegistry {
        mDefaultCrossActivityAnimation = crossActivityAnimation;
        mCustomizeActivityAnimation = customizeActivityAnimation;
        mCrossTaskAnimation = crossTaskAnimation;

        updateSupportedAnimators();
        // TODO(b/236760237): register dialog close animation when it's completed.
    }

@@ -71,6 +75,7 @@ public class ShellBackAnimationRegistry {
        if (BackNavigationInfo.TYPE_CROSS_ACTIVITY == type) {
            mDefaultCrossActivityAnimation = null;
        }
        updateSupportedAnimators();
    }

    void unregisterAnimation(@BackNavigationInfo.BackTargetType int type) {
@@ -79,6 +84,24 @@ public class ShellBackAnimationRegistry {
        if (BackNavigationInfo.TYPE_CROSS_ACTIVITY == type) {
            mDefaultCrossActivityAnimation = null;
        }
        updateSupportedAnimators();
    }

    private void updateSupportedAnimators() {
        mSupportedAnimators.clear();
        for (int i = mAnimationDefinition.size() - 1; i >= 0; --i) {
            mSupportedAnimators.add(mAnimationDefinition.keyAt(i));
        }
        mSupportedAnimatorsChanged = true;
    }

    boolean hasSupportedAnimatorsChanged() {
        return mSupportedAnimatorsChanged;
    }

    ArrayList<Integer> getSupportedAnimators() {
        mSupportedAnimatorsChanged = false;
        return mSupportedAnimators;
    }

    /**
+1 −2
Original line number Diff line number Diff line
@@ -339,13 +339,12 @@ class BackNavigationController {
                    removedWindowContainer,
                    BackNavigationInfo.typeToString(backType));

            // For now, we only animate when going home, cross task or cross-activity.
            boolean prepareAnimation =
                    (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
                                    || backType == BackNavigationInfo.TYPE_CROSS_TASK
                                    || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY
                                    || backType == BackNavigationInfo.TYPE_DIALOG_CLOSE)
                            && adapter != null;
                            && (adapter != null && adapter.isAnimatable(backType));

            if (prepareAnimation) {
                final AnimationHandler.ScheduleAnimationBuilder builder =
+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ public class BackNavigationControllerTests extends WindowTestsBase {
        mWindowManagerInternal = mock(WindowManagerInternal.class);
        LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
        mBackAnimationAdapter = mock(BackAnimationAdapter.class);
        doReturn(true).when(mBackAnimationAdapter).isAnimatable(anyInt());
        mNavigationMonitor = mock(BackNavigationController.NavigationMonitor.class);
        mRootHomeTask = initHomeActivity();
    }