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

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

Boost the surface layer of the dimmed TaskFragment

The surface layer of the dimmed TaskFragment is boosted to be above
the adjacent TaskFragment when the dimming is applied on across the
two TaskFragments.

Bug: 317289837
Test: TaskTests
Change-Id: I7493e99e3252ca23ee57df45d27383f996aee48d
parent a6c11721
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -3698,6 +3698,16 @@ class Task extends TaskFragment {
                }
                wc.assignLayer(t, layer++);

                // Boost the adjacent TaskFragment for dimmer if needed.
                final TaskFragment taskFragment = wc.asTaskFragment();
                if (taskFragment != null && taskFragment.isEmbedded()
                        && taskFragment.isVisibleRequested()) {
                    final TaskFragment adjacentTf = taskFragment.getAdjacentTaskFragment();
                    if (adjacentTf != null && adjacentTf.shouldBoostDimmer()) {
                        adjacentTf.assignLayer(t, layer++);
                    }
                }

                // Place the decor surface just above the owner TaskFragment.
                if (mDecorSurfaceContainer != null && !decorSurfacePlaced
                        && wc == mDecorSurfaceContainer.mOwnerTaskFragment) {
+25 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.UserHandle.USER_NULL;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_NONE;
@@ -2995,6 +2996,30 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        }, false /* traverseTopToBottom */);
    }

    boolean shouldBoostDimmer() {
        if (asTask() != null || !isDimmingOnParentTask()) {
            // early return if not embedded or should not dim on parent Task.
            return false;
        }

        final TaskFragment adjacentTf = getAdjacentTaskFragment();
        if (adjacentTf == null) {
            // early return if no adjacent TF.
            return false;
        }

        if (getParent().mChildren.indexOf(adjacentTf) < getParent().mChildren.indexOf(this)) {
            // early return if this TF already has higher z-ordering.
            return false;
        }

        // boost if there's an Activity window that has FLAG_DIM_BEHIND flag.
        return forAllWindows(
                (w) -> (w.mAttrs.flags & FLAG_DIM_BEHIND) != 0 && w.mActivityRecord != null
                        && w.mActivityRecord.isEmbedded() && (w.mActivityRecord.isVisibleRequested()
                        || w.mActivityRecord.isVisible()), true);
    }

    @Override
    Dimmer getDimmer() {
        // If this is in an embedded TaskFragment and we want the dim applies on the TaskFragment.
+6 −1
Original line number Diff line number Diff line
@@ -1797,7 +1797,12 @@ public class WindowManagerService extends IWindowManager.Stub

            // Don't do layout here, the window must call
            // relayout to be displayed, so we'll do it there.
            if (win.mActivityRecord != null && win.mActivityRecord.isEmbedded()) {
                // Assign child layers from the parent Task if the Activity is embedded.
                win.getTask().assignChildLayers();
            } else {
                win.getParent().assignChildLayers();
            }

            if (focusChanged) {
                displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus,
+24 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK;
import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;

import static com.google.common.truth.Truth.assertThat;
@@ -1619,6 +1620,29 @@ public class TaskTests extends WindowTestsBase {
        assertFalse(task.isDragResizing());
    }

    @Test
    public void testBoostDimmingTaskFragmentOnTask() {
        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
        final Task task = createTask(mDisplayContent);
        final TaskFragment primary = createTaskFragmentWithEmbeddedActivity(task, organizer);
        final TaskFragment secondary = createTaskFragmentWithEmbeddedActivity(task, organizer);
        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);

        primary.mVisibleRequested = true;
        secondary.mVisibleRequested = true;
        primary.setAdjacentTaskFragment(secondary);
        secondary.setAdjacentTaskFragment(primary);
        primary.setEmbeddedDimArea(EMBEDDED_DIM_AREA_PARENT_TASK);
        doReturn(true).when(primary).shouldBoostDimmer();
        task.assignChildLayers(t);

        // The layers are initially assigned via the hierarchy, but the primary will be boosted and
        // assigned again to above of the secondary.
        verify(primary).assignLayer(t, 0);
        verify(secondary).assignLayer(t, 1);
        verify(primary).assignLayer(t, 2);
    }

    @Test
    public void testMoveOrCreateDecorSurface() {
        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);