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

Commit fd5539ea authored by Louis Chang's avatar Louis Chang
Browse files

Report task profile locked for leaf tasks only

A root task (ActivityStack) was reported to the TaskStackListener
(sysui) that the task had been put in a locked state. So, the task
was requested by sysui to be used as the launching task while
starting activity and was failed.

Also fix an issue that activities could be removed if the task has
overlay activities.

Bug: 148214416
Test: atest ActivityRecordTests
Change-Id: If76ef668158a97d50c0d541319402c0bbdae2184
parent c250524f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -3323,6 +3323,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
     * @return {@code true} if the top activity looks like it belongs to {@param userId}.
     */
    private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
        // TODO(b/80414790): having utilities to loop for all leaf tasks from caller vs. checking
        //  leaf tasks here.
        if (!task.isLeafTask()) {
            // No op if not a leaf task since we don't want to report root tasks to
            // TaskStackListeners.
            return;
        }

        // To handle the case that work app is in the task but just is not the top one.
        final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
        final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
+25 −13
Original line number Diff line number Diff line
@@ -79,11 +79,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.ActivityTaskManagerService.TAG_STACK;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS;
import static com.android.server.wm.TaskProto.FILLS_PARENT;
import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
@@ -125,7 +120,6 @@ import android.provider.Settings;
import android.service.voice.IVoiceInteractionSession;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
import android.view.ITaskOrganizer;
import android.view.RemoteAnimationTarget;
@@ -1433,18 +1427,27 @@ class Task extends WindowContainer<WindowContainer> {
    }

    /**
     * @return whether or not there are ONLY task overlay activities in the stack.
     * @return whether or not there are ONLY task overlay activities in the task.
     *         If {@param includeFinishing} is set, then don't ignore finishing activities in the
     *         check. If there are no task overlay activities, this call returns false.
     */
    boolean onlyHasTaskOverlayActivities(boolean includeFinishing) {
        if (getChildCount() == 0) {
        int count = 0;
        for (int i = getChildCount() - 1; i >= 0; i--) {
            final ActivityRecord r = getChildAt(i).asActivityRecord();
            if (r == null) {
                // Has a child that is other than Activity.
                return false;
            }
            if (!includeFinishing && r.finishing) {
                continue;
            }
            if (!r.isTaskOverlay()) {
                return false;
            }
        if (includeFinishing) {
            return getActivity((r) -> r.isTaskOverlay()) != null;
            count++;
        }
        return getActivity((r) -> !r.finishing && r.isTaskOverlay()) != null;
        return count > 0;
    }

    private boolean autoRemoveFromRecents() {
@@ -2371,6 +2374,15 @@ class Task extends WindowContainer<WindowContainer> {
        return getRootTask() == this;
    }

    boolean isLeafTask() {
        for (int i = mChildren.size() - 1; i >= 0; --i) {
            if (mChildren.get(i).asTask() != null) {
                return false;
            }
        }
        return true;
    }

    int getDescendantTaskCount() {
        final int[] currentCount = {0};
        final PooledConsumer c = PooledLambda.obtainConsumer((t, count) -> { count[0]++; },
+14 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -139,6 +140,19 @@ public class ActivityRecordTests extends ActivityTestsBase {
        assertNull(mService.mRootWindowContainer.getStack(mStack.mTaskId));
    }

    @Test
    public void testRemoveChildWithOverlayActivity() {
        final ActivityRecord overlayActivity =
                new ActivityBuilder(mService).setTask(mTask).build();
        overlayActivity.setTaskOverlay(true);
        final ActivityRecord overlayActivity2 =
                new ActivityBuilder(mService).setTask(mTask).build();
        overlayActivity2.setTaskOverlay(true);

        mTask.removeChild(overlayActivity2, "test");
        verify(mSupervisor, never()).removeTask(any(), anyBoolean(), anyBoolean(), any());
    }

    @Test
    public void testNoCleanupMovingActivityInSameStack() {
        final Task newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();