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

Commit 80f15bd5 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Remove AnimatingActivityRegistry" into main

parents 14b7c134 4d5d80e3
Loading
Loading
Loading
Loading
+0 −34
Original line number Diff line number Diff line
@@ -657,8 +657,6 @@ final class ActivityRecord extends WindowToken {

    private RemoteAnimationDefinition mRemoteAnimationDefinition;

    AnimatingActivityRegistry mAnimatingActivityRegistry;

    // Set to the previous Task parent of the ActivityRecord when it is reparented to a new Task
    // due to picture-in-picture. This gets cleared whenever this activity or the Task
    // it references to gets removed. This should also be cleared when we move out of pip.
@@ -1579,9 +1577,6 @@ final class ActivityRecord extends WindowToken {
            }
        }
        final Task rootTask = getRootTask();

        updateAnimatingActivityRegistry();

        if (task == mLastParentBeforePip && task != null) {
            // Notify the TaskFragmentOrganizer that the activity is reparented back from pip.
            mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController
@@ -1683,20 +1678,6 @@ final class ActivityRecord extends WindowToken {
        return !organizedTaskFragment.isAllowedToEmbedActivityInTrustedMode(this);
    }

    void updateAnimatingActivityRegistry() {
        final Task rootTask = getRootTask();
        final AnimatingActivityRegistry registry = rootTask != null
                ? rootTask.getAnimatingActivityRegistry()
                : null;

        // If we reparent, make sure to remove ourselves from the old animation registry.
        if (mAnimatingActivityRegistry != null && mAnimatingActivityRegistry != registry) {
            mAnimatingActivityRegistry.notifyFinished(this);
        }

        mAnimatingActivityRegistry = registry;
    }

    boolean canAutoEnterPip() {
        // beforeStopping=false since the actual pip-ing will take place after startPausing()
        final boolean activityCanPip = checkEnterPictureInPictureState(
@@ -7534,13 +7515,6 @@ final class ActivityRecord extends WindowToken {
        return boundsLayer;
    }

    @Override
    public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
        return mAnimatingActivityRegistry != null
                && mAnimatingActivityRegistry.notifyAboutToFinish(
                this, endDeferFinishCallback);
    }

    @Override
    boolean isWaitingForTransitionStart() {
        final DisplayContent dc = getDisplayContent();
@@ -7562,10 +7536,6 @@ final class ActivityRecord extends WindowToken {

    @Override
    public void onLeashAnimationStarting(Transaction t, SurfaceControl leash) {
        if (mAnimatingActivityRegistry != null) {
            mAnimatingActivityRegistry.notifyStarting(this);
        }

        if (mNeedsLetterboxedAnimation) {
            updateLetterboxSurfaceIfNeeded(findMainWindow(), t);
            mNeedsAnimationBoundsLayer = true;
@@ -7732,10 +7702,6 @@ final class ActivityRecord extends WindowToken {
            mNeedsLetterboxedAnimation = false;
            updateLetterboxSurfaceIfNeeded(findMainWindow(), t);
        }

        if (mAnimatingActivityRegistry != null) {
            mAnimatingActivityRegistry.notifyFinished(this);
        }
    }

    @Override
+0 −120
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.wm;

import android.util.ArrayMap;
import android.util.ArraySet;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Keeps track of all {@link ActivityRecord} that are animating and makes sure all animations are
 * finished at the same time such that we don't run into issues with z-ordering: An activity A
 * that has a shorter animation that is above another activity B with a longer animation in the same
 * task, the animation layer would put the B on top of A, but from the hierarchy, A needs to be on
 * top of B. Thus, we defer reparenting A to the original hierarchy such that it stays on top of B
 * until B finishes animating.
 */
class AnimatingActivityRegistry {

    private ArraySet<ActivityRecord> mAnimatingActivities = new ArraySet<>();
    private ArrayMap<ActivityRecord, Runnable> mFinishedTokens = new ArrayMap<>();

    private ArrayList<Runnable> mTmpRunnableList = new ArrayList<>();

    private boolean mEndingDeferredFinish;

    /**
     * Notifies that an {@link ActivityRecord} has started animating.
     */
    void notifyStarting(ActivityRecord token) {
        mAnimatingActivities.add(token);
    }

    /**
     * Notifies that an {@link ActivityRecord} has finished animating.
     */
    void notifyFinished(ActivityRecord activity) {
        mAnimatingActivities.remove(activity);
        mFinishedTokens.remove(activity);

        // If we were the last activity, make sure the end all deferred finishes.
        if (mAnimatingActivities.isEmpty()) {
            endDeferringFinished();
        }
    }

    /**
     * Called when an {@link ActivityRecord} is about to finish animating.
     *
     * @param endDeferFinishCallback Callback to run when defer finish should be ended.
     * @return {@code true} if finishing the animation should be deferred, {@code false} otherwise.
     */
    boolean notifyAboutToFinish(ActivityRecord activity, Runnable endDeferFinishCallback) {
        final boolean removed = mAnimatingActivities.remove(activity);
        if (!removed) {
            return false;
        }

        if (mAnimatingActivities.isEmpty()) {

            // If no animations are animating anymore, finish all others.
            endDeferringFinished();
            return false;
        } else {

            // Otherwise let's put it into the pending list of to be finished animations.
            mFinishedTokens.put(activity, endDeferFinishCallback);
            return true;
        }
    }

    private void endDeferringFinished() {

        // Don't start recursing. Running the finished listener invokes notifyFinished, which may
        // invoked us again.
        if (mEndingDeferredFinish) {
            return;
        }
        try {
            mEndingDeferredFinish = true;

            // Copy it into a separate temp list to avoid modifying the collection while iterating
            // as calling the callback may call back into notifyFinished.
            for (int i = mFinishedTokens.size() - 1; i >= 0; i--) {
                mTmpRunnableList.add(mFinishedTokens.valueAt(i));
            }
            mFinishedTokens.clear();
            for (int i = mTmpRunnableList.size() - 1; i >= 0; i--) {
                mTmpRunnableList.get(i).run();
            }
            mTmpRunnableList.clear();
        } finally {
            mEndingDeferredFinish = false;
        }
    }

    void dump(PrintWriter pw, String header, String prefix) {
        if (!mAnimatingActivities.isEmpty() || !mFinishedTokens.isEmpty()) {
            pw.print(prefix); pw.println(header);
            prefix = prefix + "  ";
            pw.print(prefix); pw.print("mAnimatingActivities="); pw.println(mAnimatingActivities);
            pw.print(prefix); pw.print("mFinishedTokens="); pw.println(mFinishedTokens);
        }
    }
}
+0 −9
Original line number Diff line number Diff line
@@ -109,15 +109,6 @@ public interface AnimationAdapter {
     * Gets called when the animation is about to finish and gives the client the opportunity to
     * defer finishing the animation, i.e. it keeps the leash around until the client calls
     * endDeferFinishCallback.
     * <p>
     * This has the same effect as
     * {@link com.android.server.wm.SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)}
     * . The later will be evaluated first and has precedence over this method if it returns true,
     * which means that if the {@link com.android.server.wm.SurfaceAnimator.Animatable} requests to
     * defer its finish, this method won't be called so this adapter will never have access to the
     * finish callback. On the other hand, if the
     * {@link com.android.server.wm.SurfaceAnimator.Animatable}, doesn't request to defer, this
     * {@link AnimationAdapter} is responsible for ending the animation.
     *
     * @param endDeferFinishCallback The callback to call when defer finishing should be ended.
     * @return Whether the client would like to defer the animation finish.
+1 −22
Original line number Diff line number Diff line
@@ -132,10 +132,7 @@ public class SurfaceAnimator {
                        animationFinishCallback.onAnimationFinished(type, anim);
                    }
                };
                // If both the Animatable and AnimationAdapter requests to be deferred, only the
                // first one will be called.
                if (!(mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)
                        || anim.shouldDeferAnimationFinish(resetAndInvokeFinish))) {
                if (!anim.shouldDeferAnimationFinish(resetAndInvokeFinish)) {
                    resetAndInvokeFinish.run();
                }
                mAnimationFinished = true;
@@ -639,23 +636,5 @@ public class SurfaceAnimator {
         * @return The height of the surface to be animated.
         */
        int getSurfaceHeight();

        /**
         * Gets called when the animation is about to finish and gives the client the opportunity to
         * defer finishing the animation, i.e. it keeps the leash around until the client calls
         * {@link #cancelAnimation}.
         * <p>
         * {@link AnimationAdapter} has a similar method which is called only if this method returns
         * false. This mean that if both this {@link Animatable} and the {@link AnimationAdapter}
         * request to be deferred, this method is the sole responsible to call
         * endDeferFinishCallback. On the other hand, the animation finish might still be deferred
         * if this method return false and the one from the {@link AnimationAdapter} returns true.
         *
         * @param endDeferFinishCallback The callback to call when defer finishing should be ended.
         * @return Whether the client would like to defer the animation finish.
         */
        default boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
            return false;
        }
    }
}
+0 −17
Original line number Diff line number Diff line
@@ -508,9 +508,6 @@ class Task extends TaskFragment {
     */
    boolean mAllowForceResizeOverride = true;

    private final AnimatingActivityRegistry mAnimatingActivityRegistry =
            new AnimatingActivityRegistry();

    private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_TASK_MSG + 1;

    private final Handler mHandler;
@@ -1174,9 +1171,6 @@ class Task extends TaskFragment {
        }

        mRootWindowContainer.updateUIDsPresentOnDisplay();

        // Ensure all animations are finished at same time in split-screen mode.
        forAllActivities(ActivityRecord::updateAnimatingActivityRegistry);
    }

    @Override
@@ -3335,13 +3329,6 @@ class Task extends TaskFragment {
        mLastSurfaceShowing = show;
    }

    @Override
    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
        super.dump(pw, prefix, dumpAll);
        mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix);
    }


    /**
     * Fills in a {@link TaskInfo} with information from this task. Note that the base intent in the
     * task info will not include any extras or clip data.
@@ -6303,10 +6290,6 @@ class Task extends TaskFragment {
        return mDisplayContent.getDisplayInfo();
    }

    AnimatingActivityRegistry getAnimatingActivityRegistry() {
        return mAnimatingActivityRegistry;
    }

    private Rect getRawBounds() {
        return super.getBounds();
    }
Loading