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

Commit 82a0ba84 authored by chaviw's avatar chaviw
Browse files

Clear all options from Task when any ActivityRecord consumes the options.

Multiple ActivityRecords can get the same options if they are in some state of
being launched. If the Task starts and already has ActivityRecords in the Task,
they will also get the new options. It's pretty difficult to prevent that since
they are being moved to the front, even though another activity will launch on
top. Instead, just clear all ActivityRecord's options in the same Task so only
one is ever consumed.

Fixes: 74611027
Test: Launch activity then background. Open second activity from
notification. When pressing back, window animation should start.
Test: Launch activity, press home, launch same activity. Starting
animation occurs on the second launch.
Test: testsApplyOptionsLocked

Change-Id: I72119772851102cbb71d59527c5f0256b575752b
parent 0d562bf8
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -1540,7 +1540,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
                    Slog.e(TAG, "applyOptionsLocked: Unknown animationType=" + animationType);
                    break;
            }
            pendingOptions = null;

            if (task == null) {
                clearOptionsLocked(false /* withAbort */);
            } else {
                // This will clear the options for all the ActivityRecords for this Task.
                task.clearAllPendingOptions();
            }
        }
    }

@@ -1549,10 +1555,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    }

    void clearOptionsLocked() {
        if (pendingOptions != null) {
        clearOptionsLocked(true /* withAbort */);
    }

    void clearOptionsLocked(boolean withAbort) {
        if (withAbort && pendingOptions != null) {
            pendingOptions.abort();
            pendingOptions = null;
        }
        pendingOptions = null;
    }

    ActivityOptions takeOptionsLocked() {
+7 −1
Original line number Diff line number Diff line
@@ -944,7 +944,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
    }

    @Override
    protected ConfigurationContainer getChildAt(int index) {
    protected ActivityRecord getChildAt(int index) {
        return mActivities.get(index);
    }

@@ -1898,6 +1898,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
        }
    }

    void clearAllPendingOptions() {
        for (int i = getChildCount() - 1; i >= 0; i--) {
            getChildAt(i).clearOptionsLocked(false /* withAbort */);
        }
    }

    void dump(PrintWriter pw, String prefix) {
        pw.print(prefix); pw.print("userId="); pw.print(userId);
                pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
+33 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;

import static junit.framework.TestCase.assertNotNull;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -45,6 +47,8 @@ import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityOptions;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.PauseActivityItem;
import android.graphics.Rect;
@@ -201,6 +205,35 @@ public class ActivityRecordTests extends ActivityTestsBase {
                false /*activityResizeable*/, true /*expected*/);
    }

    @Test
    public void testsApplyOptionsLocked() {
        ActivityOptions activityOptions = ActivityOptions.makeBasic();

        // Set and apply options for ActivityRecord. Pending options should be cleared
        mActivity.updateOptionsLocked(activityOptions);
        mActivity.applyOptionsLocked();
        assertNull(mActivity.pendingOptions);

        // Set options for two ActivityRecords in same Task. Apply one ActivityRecord options.
        // Pending options should be cleared for both ActivityRecords
        ActivityRecord activity2 = new ActivityBuilder(mService).setTask(mTask).build();
        activity2.updateOptionsLocked(activityOptions);
        mActivity.updateOptionsLocked(activityOptions);
        mActivity.applyOptionsLocked();
        assertNull(mActivity.pendingOptions);
        assertNull(activity2.pendingOptions);

        // Set options for two ActivityRecords in separate Tasks. Apply one ActivityRecord options.
        // Pending options should be cleared for only ActivityRecord that was applied
        TaskRecord task2 = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
        activity2 = new ActivityBuilder(mService).setTask(task2).build();
        activity2.updateOptionsLocked(activityOptions);
        mActivity.updateOptionsLocked(activityOptions);
        mActivity.applyOptionsLocked();
        assertNull(mActivity.pendingOptions);
        assertNotNull(activity2.pendingOptions);
    }

    private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable,
            boolean activityResizeable, boolean expected) {
        mService.mSupportsMultiWindow = true;