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

Commit cb5cd880 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Apply right animation style on closing translucent task

It should use R.anim.activity_translucent_close_exit instead of
R.anim.task_close_exit.
This is similar to I97c5220b9fe3fde33e1426c8fc2598410fad3735.

Also ignore visibleIgnoringKeyguard when resolving FLAG_TRANSLUCENT
for transition. Otherwise a closing opaque activity may be misjudged
as translucent. This aligns the same behavior as legacy
AppTransitionController#getTransitCompatType that only
checks fillsParent().

Fix: 278786253
Test: TransitionTests
Test: Close a translucent task.
      It should not be x-axis task animation.
Change-Id: Idb3a78d00ece7b5ec0d3e2d4c2957f489c816b03
parent dfc317e1
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -122,14 +122,14 @@ public class TransitionAnimationHelper {
                    ? R.styleable.WindowAnimation_taskToFrontEnterAnimation
                    : R.styleable.WindowAnimation_taskToFrontExitAnimation;
        } else if (type == TRANSIT_CLOSE) {
            if (isTask) {
            if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
                translucent = true;
            }
            if (isTask && !translucent) {
                animAttr = enter
                        ? R.styleable.WindowAnimation_taskCloseEnterAnimation
                        : R.styleable.WindowAnimation_taskCloseExitAnimation;
            } else {
                if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
                    translucent = true;
                }
                animAttr = enter
                        ? R.styleable.WindowAnimation_activityCloseEnterAnimation
                        : R.styleable.WindowAnimation_activityCloseExitAnimation;
+35 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ import static com.android.server.wm.Task.TAG_CLEANUP;
import static com.android.server.wm.WindowContainer.POSITION_TOP;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -261,6 +262,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
    /** Helper for {@link Task#fillTaskInfo}. */
    final TaskInfoHelper mTaskInfoHelper = new TaskInfoHelper();

    final OpaqueActivityHelper mOpaqueActivityHelper = new OpaqueActivityHelper();

    private final ActivityTaskSupervisorHandler mHandler;
    final Looper mLooper;

@@ -2906,6 +2909,38 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        }
    }

    /** The helper to get the top opaque activity of a container. */
    static class OpaqueActivityHelper implements Predicate<ActivityRecord> {
        private ActivityRecord mStarting;
        private boolean mIncludeInvisibleAndFinishing;

        ActivityRecord getOpaqueActivity(@NonNull WindowContainer<?> container) {
            mIncludeInvisibleAndFinishing = true;
            return container.getActivity(this,
                    true /* traverseTopToBottom */, null /* boundary */);
        }

        ActivityRecord getVisibleOpaqueActivity(@NonNull WindowContainer<?> container,
                @Nullable ActivityRecord starting) {
            mStarting = starting;
            mIncludeInvisibleAndFinishing = false;
            final ActivityRecord opaque = container.getActivity(this,
                    true /* traverseTopToBottom */, null /* boundary */);
            mStarting = null;
            return opaque;
        }

        @Override
        public boolean test(ActivityRecord r) {
            if (!mIncludeInvisibleAndFinishing && !r.visibleIgnoringKeyguard && r != mStarting) {
                // Ignore invisible activities that are not the currently starting activity
                // (about to be visible).
                return false;
            }
            return r.occludesParent(mIncludeInvisibleAndFinishing /* includingFinishing */);
        }
    }

    /**
     * Fills the info that needs to iterate all activities of task, such as the number of
     * non-finishing activities and collecting launch cookies.
+5 −26
Original line number Diff line number Diff line
@@ -102,8 +102,6 @@ import android.window.TaskFragmentOrganizerToken;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.am.HostingRecord;
import com.android.server.pm.pkg.AndroidPackage;

@@ -934,11 +932,10 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        if (!isAttached() || isForceHidden() || isForceTranslucent()) {
            return true;
        }
        final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity,
                PooledLambda.__(ActivityRecord.class), starting, false /* including*/);
        final ActivityRecord opaque = getActivity(p);
        p.recycle();
        return opaque == null;
        // A TaskFragment isn't translucent if it has at least one visible activity that occludes
        // this TaskFragment.
        return mTaskSupervisor.mOpaqueActivityHelper.getVisibleOpaqueActivity(this,
                starting) == null;
    }

    /**
@@ -951,25 +948,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
            return true;
        }
        // Including finishing Activity if the TaskFragment is becoming invisible in the transition.
        final boolean includingFinishing = !isVisibleRequested();
        final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity,
                PooledLambda.__(ActivityRecord.class), null /* starting */, includingFinishing);
        final ActivityRecord opaque = getActivity(p);
        p.recycle();
        return opaque == null;
    }

    private static boolean isOpaqueActivity(@NonNull ActivityRecord r,
            @Nullable ActivityRecord starting, boolean includingFinishing) {
        if (!r.visibleIgnoringKeyguard && r != starting) {
            // Also ignore invisible activities that are not the currently starting
            // activity (about to be visible).
            return false;
        }

        // TaskFragment isn't translucent if it has at least one fullscreen activity that is
        // visible.
        return r.occludesParent(includingFinishing);
        return mTaskSupervisor.mOpaqueActivityHelper.getOpaqueActivity(this) == null;
    }

    ActivityRecord getTopNonFinishingActivity() {
+0 −13
Original line number Diff line number Diff line
@@ -367,7 +367,6 @@ public class TransitionTests extends WindowTestsBase {
            final ActivityRecord act = createActivityRecord(tasks[i]);
            // alternate so that the transition doesn't get promoted to the display area
            act.setVisibleRequested((i % 2) == 0); // starts invisible
            act.visibleIgnoringKeyguard = (i % 2) == 0;
            if (i == showWallpaperTask) {
                doReturn(true).when(act).showWallpaper();
            }
@@ -754,10 +753,8 @@ public class TransitionTests extends WindowTestsBase {

        final ActivityRecord closing = createActivityRecord(oldTask);
        closing.setOccludesParent(true);
        closing.visibleIgnoringKeyguard = true;
        final ActivityRecord opening = createActivityRecord(newTask);
        opening.setOccludesParent(true);
        opening.visibleIgnoringKeyguard = true;
        // Start states.
        changes.put(newTask, new Transition.ChangeInfo(newTask, false /* vis */, true /* exChg */));
        changes.put(oldTask, new Transition.ChangeInfo(oldTask, true /* vis */, false /* exChg */));
@@ -795,10 +792,8 @@ public class TransitionTests extends WindowTestsBase {

        final ActivityRecord closing = createActivityRecord(oldTask);
        closing.setOccludesParent(true);
        closing.visibleIgnoringKeyguard = true;
        final ActivityRecord opening = createActivityRecord(newTask);
        opening.setOccludesParent(false);
        opening.visibleIgnoringKeyguard = true;
        // Start states.
        changes.put(newTask, new Transition.ChangeInfo(newTask, false /* vis */, true /* exChg */));
        changes.put(oldTask, new Transition.ChangeInfo(oldTask, true /* vis */, false /* exChg */));
@@ -837,10 +832,8 @@ public class TransitionTests extends WindowTestsBase {

        final ActivityRecord closing = closingTaskFragment.getTopMostActivity();
        closing.setOccludesParent(true);
        closing.visibleIgnoringKeyguard = true;
        final ActivityRecord opening = openingTaskFragment.getTopMostActivity();
        opening.setOccludesParent(true);
        opening.visibleIgnoringKeyguard = true;
        // Start states.
        changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment,
                false /* vis */, true /* exChg */));
@@ -881,10 +874,8 @@ public class TransitionTests extends WindowTestsBase {

        final ActivityRecord closing = closingTaskFragment.getTopMostActivity();
        closing.setOccludesParent(true);
        closing.visibleIgnoringKeyguard = true;
        final ActivityRecord opening = openingTaskFragment.getTopMostActivity();
        opening.setOccludesParent(false);
        opening.visibleIgnoringKeyguard = true;
        // Start states.
        changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment,
                false /* vis */, true /* exChg */));
@@ -925,10 +916,8 @@ public class TransitionTests extends WindowTestsBase {

        final ActivityRecord opening = openingTaskFragment.getTopMostActivity();
        opening.setOccludesParent(true);
        opening.visibleIgnoringKeyguard = true;
        final ActivityRecord closing = closingTaskFragment.getTopMostActivity();
        closing.setOccludesParent(true);
        closing.visibleIgnoringKeyguard = true;
        closing.finishing = true;
        // Start states.
        changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment,
@@ -970,10 +959,8 @@ public class TransitionTests extends WindowTestsBase {

        final ActivityRecord opening = openingTaskFragment.getTopMostActivity();
        opening.setOccludesParent(true);
        opening.visibleIgnoringKeyguard = true;
        final ActivityRecord closing = closingTaskFragment.getTopMostActivity();
        closing.setOccludesParent(false);
        closing.visibleIgnoringKeyguard = true;
        closing.finishing = true;
        // Start states.
        changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment,