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

Commit c48958ab authored by Rob Carr's avatar Rob Carr Committed by Automerger Merge Worker
Browse files

Merge "TaskOrganizer: Wait for apps to draw." into rvc-dev am: 428309a9 am:...

Merge "TaskOrganizer: Wait for apps to draw." into rvc-dev am: 428309a9 am: 3494c353 am: bd4d46d5

Change-Id: I130196b9c7e9f545582664f302331184e24169a1
parents 14b39436 bd4d46d5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5201,7 +5201,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
        finishLaunchTickingLocked();
        if (task != null) {
            task.hasBeenVisible = true;
            task.setHasBeenVisible(true);
        }
    }

+39 −6
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ class Task extends WindowContainer<WindowContainer> {
    boolean autoRemoveRecents;  // If true, we should automatically remove the task from
                                // recents when activity finishes
    boolean askedCompatMode;// Have asked the user about compat mode for this task.
    boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
    private boolean mHasBeenVisible; // Set if any activities in the task have been visible

    String stringName;      // caching of toString() result.
    boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
@@ -483,6 +483,10 @@ class Task extends WindowContainer<WindowContainer> {
     */
    ITaskOrganizer mTaskOrganizer;
    private int mLastTaskOrganizerWindowingMode = -1;
    /**
     * Prevent duplicate calls to onTaskAppeared.
     */
    boolean mTaskAppearedSent;

    /**
     * Last Picture-in-Picture params applicable to the task. Updated when the app
@@ -1517,7 +1521,7 @@ class Task extends WindowContainer<WindowContainer> {
        // We will automatically remove the task either if it has explicitly asked for
        // this, or it is empty and has never contained an activity that got shown to
        // the user.
        return autoRemoveRecents || (!hasChild() && !hasBeenVisible);
        return autoRemoveRecents || (!hasChild() && !getHasBeenVisible());
    }

    /**
@@ -2030,7 +2034,7 @@ class Task extends WindowContainer<WindowContainer> {
    }

    private void saveLaunchingStateIfNeeded(DisplayContent display) {
        if (!hasBeenVisible) {
        if (!getHasBeenVisible()) {
            // Not ever visible to user.
            return;
        }
@@ -3558,7 +3562,7 @@ class Task extends WindowContainer<WindowContainer> {
            pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
        }
        pw.print(prefix); pw.print("taskId=" + mTaskId); pw.println(" stackId=" + getRootTaskId());
        pw.print(prefix + "hasBeenVisible=" + hasBeenVisible);
        pw.print(prefix + "mHasBeenVisible=" + getHasBeenVisible());
        pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode));
        pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture);
        pw.print(" isResizeable=" + isResizeable());
@@ -4087,14 +4091,42 @@ class Task extends WindowContainer<WindowContainer> {
        super.reparentSurfaceControl(t, newParent);
    }

    void setHasBeenVisible(boolean hasBeenVisible) {
        mHasBeenVisible = hasBeenVisible;
        if (hasBeenVisible) {
            sendTaskAppeared();
            if (!isRootTask()) {
                getRootTask().setHasBeenVisible(true);
            }
        }
    }

    boolean getHasBeenVisible() {
        return mHasBeenVisible;
    }

    /** In the case that these three conditions are true, we want to send the Task to
     * the organizer:
     *     1. We have a SurfaceControl
     *     2. An organizer has been set
     *     3. We have finished drawing
     * Any time any of these conditions are updated, the updating code should call
     * sendTaskAppeared.
     */
    private boolean taskAppearedReady() {
        return mSurfaceControl != null && mTaskOrganizer != null && getHasBeenVisible();
    }

    private void sendTaskAppeared() {
        if (mSurfaceControl != null && mTaskOrganizer != null) {
        if (taskAppearedReady() && !mTaskAppearedSent) {
            mTaskAppearedSent = true;
            mAtmService.mTaskOrganizerController.onTaskAppeared(mTaskOrganizer, this);
        }
    }

    private void sendTaskVanished() {
        if (mTaskOrganizer != null) {
        if (mTaskOrganizer != null && mTaskAppearedSent) {
            mTaskAppearedSent = false;
            mAtmService.mTaskOrganizerController.onTaskVanished(mTaskOrganizer, this);
        }
   }
@@ -4113,6 +4145,7 @@ class Task extends WindowContainer<WindowContainer> {

    void taskOrganizerUnregistered() {
        mTaskOrganizer = null;
        mTaskAppearedSent = false;
        mLastTaskOrganizerWindowingMode = -1;
        onTaskOrganizerChanged();
        if (mCreatedByOrganizer) {
+3 −3
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase {
                .build();
        mTestTask.mUserId = TEST_USER_ID;
        mTestTask.mLastNonFullscreenBounds = TEST_BOUNDS;
        mTestTask.hasBeenVisible = true;
        mTestTask.setHasBeenVisible(true);

        mTaskWithDifferentComponent = new TaskBuilder(mSupervisor)
                .setComponent(ALTERNATIVE_COMPONENT).build();
@@ -346,7 +346,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase {
                .build();
        anotherTaskOfTheSameUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
        anotherTaskOfTheSameUser.setBounds(200, 300, 400, 500);
        anotherTaskOfTheSameUser.hasBeenVisible = true;
        anotherTaskOfTheSameUser.setHasBeenVisible(true);
        mTarget.saveTask(anotherTaskOfTheSameUser);

        stack = mTestDisplay.createStack(TEST_WINDOWING_MODE,
@@ -358,7 +358,7 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase {
                .build();
        anotherTaskOfDifferentUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
        anotherTaskOfDifferentUser.setBounds(300, 400, 500, 600);
        anotherTaskOfDifferentUser.hasBeenVisible = true;
        anotherTaskOfDifferentUser.setHasBeenVisible(true);
        mTarget.saveTask(anotherTaskOfDifferentUser);

        mTarget.onCleanupUser(TEST_USER_ID);
+103 −31
Original line number Diff line number Diff line
@@ -96,10 +96,28 @@ public class TaskOrganizerTests extends WindowTestsBase {
        return registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
    }

    Task createTask(ActivityStack stack, boolean fakeDraw) {
        final Task task = createTaskInStack(stack, 0);

        if (fakeDraw) {
            task.setHasBeenVisible(true);
        }
        return task;
    }

    Task createTask(ActivityStack stack) {
        // Fake draw notifications for most of our tests.
        return createTask(stack, true);
    }

    ActivityStack createStack() {
        return createTaskStackOnDisplay(mDisplayContent);
    }

    @Test
    public void testAppearVanish() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ITaskOrganizer organizer = registerMockOrganizer();

        task.setTaskOrganizer(organizer);
@@ -109,10 +127,43 @@ public class TaskOrganizerTests extends WindowTestsBase {
        verify(organizer).onTaskVanished(any());
    }

    @Test
    public void testAppearWaitsForVisibility() throws RemoteException {
        final ActivityStack stack = createStack();
        final Task task = createTask(stack, false);
        final ITaskOrganizer organizer = registerMockOrganizer();

        task.setTaskOrganizer(organizer);

        verify(organizer, never()).onTaskAppeared(any());
        task.setHasBeenVisible(true);
        assertTrue(stack.getHasBeenVisible());

        verify(organizer).onTaskAppeared(any());

        task.removeImmediately();
        verify(organizer).onTaskVanished(any());
    }

    @Test
    public void testNoVanishedIfNoAppear() throws RemoteException {
        final ActivityStack stack = createStack();
        final Task task = createTask(stack, false /* hasBeenVisible */);
        final ITaskOrganizer organizer = registerMockOrganizer();

        // In this test we skip making the Task visible, and verify
        // that even though a TaskOrganizer is set remove doesn't emit
        // a vanish callback, because we never emitted appear.
        task.setTaskOrganizer(organizer);
        verify(organizer, never()).onTaskAppeared(any());
        task.removeImmediately();
        verify(organizer, never()).onTaskVanished(any());
    }

    @Test
    public void testSwapOrganizer() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
        final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);

@@ -125,8 +176,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testSwapWindowingModes() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);
        final ITaskOrganizer organizer2 = registerMockOrganizer(WINDOWING_MODE_PINNED);

@@ -139,8 +190,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testClearOrganizer() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ITaskOrganizer organizer = registerMockOrganizer();

        stack.setTaskOrganizer(organizer);
@@ -154,8 +205,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testUnregisterOrganizer() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ITaskOrganizer organizer = registerMockOrganizer();

        stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
@@ -169,12 +220,12 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testUnregisterOrganizerReturnsRegistrationToPrevious() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
        final Task task2 = createTaskInStack(stack2, 0 /* userId */);
        final ActivityStack stack3 = createTaskStackOnDisplay(mDisplayContent);
        final Task task3 = createTaskInStack(stack3, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ActivityStack stack2 = createStack();
        final Task task2 = createTask(stack2);
        final ActivityStack stack3 = createStack();
        final Task task3 = createTask(stack3);
        final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_MULTI_WINDOW);

        // First organizer is registered, verify a task appears when changing windowing mode
@@ -202,9 +253,9 @@ public class TaskOrganizerTests extends WindowTestsBase {
    public void testRegisterTaskOrganizerStackWindowingModeChanges() throws RemoteException {
        final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED);

        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final Task task2 = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final Task task2 = createTask(stack);
        stack.setWindowingMode(WINDOWING_MODE_PINNED);
        verify(organizer, times(1)).onTaskAppeared(any());

@@ -214,8 +265,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testRegisterTaskOrganizerWithExistingTasks() throws RemoteException {
        final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stack, 0 /* userId */);
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        stack.setWindowingMode(WINDOWING_MODE_PINNED);

        final ITaskOrganizer organizer = registerMockOrganizer(WINDOWING_MODE_PINNED);
@@ -560,8 +611,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testTrivialBLASTCallback() throws RemoteException {
        final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stackController1, 0 /* userId */);
        final ActivityStack stackController1 = createStack();
        final Task task = createTask(stackController1);
        final ITaskOrganizer organizer = registerMockOrganizer();

        spyOn(task);
@@ -582,8 +633,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testOverlappingBLASTCallback() throws RemoteException {
        final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stackController1, 0 /* userId */);
        final ActivityStack stackController1 = createStack();
        final Task task = createTask(stackController1);
        final ITaskOrganizer organizer = registerMockOrganizer();

        spyOn(task);
@@ -611,8 +662,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testBLASTCallbackWithWindow() {
        final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stackController1, 0 /* userId */);
        final ActivityStack stackController1 = createStack();
        final Task task = createTask(stackController1);
        final ITaskOrganizer organizer = registerMockOrganizer();
        final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
        makeWindowVisible(w);
@@ -635,8 +686,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testBLASTCallbackWithInvisibleWindow() {
        final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stackController1, 0 /* userId */);
        final ActivityStack stackController1 = createStack();
        final Task task = createTask(stackController1);
        final ITaskOrganizer organizer = registerMockOrganizer();
        final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");

@@ -657,8 +708,8 @@ public class TaskOrganizerTests extends WindowTestsBase {

    @Test
    public void testBLASTCallbackWithChildWindow() {
        final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(stackController1, 0 /* userId */);
        final ActivityStack stackController1 = createStack();
        final Task task = createTask(stackController1);
        final ITaskOrganizer organizer = registerMockOrganizer();
        final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
        final WindowState child = createWindow(w, TYPE_APPLICATION, "Other Window");
@@ -708,6 +759,8 @@ public class TaskOrganizerTests extends WindowTestsBase {
        record.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
        spyOn(record);
        doReturn(true).when(record).checkEnterPictureInPictureState(any(), anyBoolean());

        record.getRootTask().setHasBeenVisible(true);
        return record;
    }

@@ -755,4 +808,23 @@ public class TaskOrganizerTests extends WindowTestsBase {
        assertEquals(3, ratio.getNumerator());
        assertEquals(4, ratio.getDenominator());
    }

    @Test
    public void testPreventDuplicateAppear() throws RemoteException {
        final ActivityStack stack = createStack();
        final Task task = createTask(stack);
        final ITaskOrganizer organizer = registerMockOrganizer();

        task.setTaskOrganizer(organizer);
        // setHasBeenVisible was already called once by the set-up code.
        task.setHasBeenVisible(true);
        verify(organizer, times(1)).onTaskAppeared(any());

        task.taskOrganizerUnregistered();
        task.setTaskOrganizer(organizer);
        verify(organizer, times(2)).onTaskAppeared(any());

        task.removeImmediately();
        verify(organizer).onTaskVanished(any());
    }
}
+8 −8
Original line number Diff line number Diff line
@@ -874,11 +874,11 @@ public class TaskRecordTests extends ActivityTestsBase {
        spyOn(persister);

        final Task task = getTestTask();
        task.hasBeenVisible = false;
        task.setHasBeenVisible(false);
        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
        task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN);

        task.hasBeenVisible = true;
        task.setHasBeenVisible(true);
        task.onConfigurationChanged(task.getParent().getConfiguration());

        verify(persister).saveTask(task, task.getDisplayContent());
@@ -890,7 +890,7 @@ public class TaskRecordTests extends ActivityTestsBase {
        spyOn(persister);

        final Task task = getTestTask();
        task.hasBeenVisible = false;
        task.setHasBeenVisible(false);
        task.getDisplayContent().setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
        task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
        final DisplayContent oldDisplay = task.getDisplayContent();
@@ -900,7 +900,7 @@ public class TaskRecordTests extends ActivityTestsBase {
        persister.getLaunchParams(task, null, params);
        assertEquals(WINDOWING_MODE_UNDEFINED, params.mWindowingMode);

        task.hasBeenVisible = true;
        task.setHasBeenVisible(true);
        task.removeImmediately();

        verify(persister).saveTask(task, oldDisplay);
@@ -915,10 +915,10 @@ public class TaskRecordTests extends ActivityTestsBase {
        spyOn(persister);

        final Task task = getTestTask();
        task.hasBeenVisible = false;
        task.setHasBeenVisible(false);
        task.getStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN);

        task.hasBeenVisible = true;
        task.setHasBeenVisible(true);
        task.onConfigurationChanged(task.getParent().getConfiguration());

        verify(persister, never()).saveTask(same(task), any());
@@ -930,11 +930,11 @@ public class TaskRecordTests extends ActivityTestsBase {
        spyOn(persister);

        final Task task = getTestTask();
        task.hasBeenVisible = false;
        task.setHasBeenVisible(false);
        task.getDisplayContent().setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
        task.getStack().setWindowingMode(WINDOWING_MODE_PINNED);

        task.hasBeenVisible = true;
        task.setHasBeenVisible(true);
        task.onConfigurationChanged(task.getParent().getConfiguration());

        verify(persister, never()).saveTask(same(task), any());