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

Commit 7b82b326 authored by Charles Chen's avatar Charles Chen
Browse files

Fix untrusted activity not shown when pinned

Before, we only check if the activity on top of untrusted activity
is in different UID and non-finishing, but it doesn't cover the case
that the untrusted activity is in the primary split container, while
the top activity of the secondary split is in the same process of
the host task.

This CL also checks if the activity above the untrusted activity
occludes the untrusted activity to fix the issue.

Test: atest TaskFragmentTest
Fixes: 343308303
Flag: EXEMPT bugfix
Change-Id: I8a94207f4b5a69aadcffa13266e32fd18d54b150
parent bcc59ec1
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -6223,12 +6223,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            return false;
        }
        // Check if there are any activities with different UID over the activity that is embedded
        // in untrusted mode. Traverse bottom to top with boundary so that it will only check
        // activities above this activity.
        // Check if there are any activities with different UID occluding partially the activity
        // that is embedded in untrusted mode. Traverse bottom to top with boundary so that it will
        // only check activities above this activity.
        final ActivityRecord differentUidOverlayActivity = getTask().getActivity(
                a -> !a.finishing && a.getUid() != getUid(), this /* boundary */,
                false /* includeBoundary */, false /* traverseTopToBottom */);
                a -> !a.finishing && a.getUid() != getUid() && Rect.intersects(a.getBounds(),
                        getBounds()), this /* boundary */, false /* includeBoundary */,
                false /* traverseTopToBottom */);
        return differentUidOverlayActivity != null;
    }
+44 −2
Original line number Diff line number Diff line
@@ -474,8 +474,8 @@ public class TaskFragmentTest extends WindowTestsBase {
                .build();
        final ActivityRecord activity0 = organizedTf.getBottomMostActivity();
        final ActivityRecord activity1 = organizedTf.getTopMostActivity();
        // Bottom activity is untrusted embedding. Top activity is trusted embedded.
        // Activity0 has overlay over untrusted mode embedded.
        // Bottom activity is untrusted embedding. Top activity is trusted embedded and occludes
        // the bottom activity. Activity0 has overlay over untrusted mode embedded.
        activity0.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID + 1;
        activity1.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID;
        doReturn(true).when(organizedTf).isAllowedToEmbedActivityInUntrustedMode(activity0);
@@ -511,6 +511,48 @@ public class TaskFragmentTest extends WindowTestsBase {
        assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());
    }

    @Test
    public void testActivityHasOverlayOverUntrustedModeEmbeddedWithAdjacentTaskFragments() {
        final Task rootTask = createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW,
                ACTIVITY_TYPE_STANDARD);
        final Rect taskBounds = rootTask.getBounds();
        final TaskFragment organizedTf0 = new TaskFragmentBuilder(mAtm)
                .createActivityCount(1)
                .setParentTask(rootTask)
                .setFragmentToken(new Binder())
                .setOrganizer(mOrganizer)
                .setBounds(new Rect(taskBounds.left, taskBounds.top,
                        taskBounds.left + taskBounds.width() / 2, taskBounds.bottom))
                .build();
        final TaskFragment organizedTf1 = new TaskFragmentBuilder(mAtm)
                .createActivityCount(1)
                .setParentTask(rootTask)
                .setFragmentToken(new Binder())
                .setOrganizer(mOrganizer)
                .setBounds(new Rect(taskBounds.left + taskBounds.width() / 2, taskBounds.top,
                        taskBounds.right, taskBounds.bottom))
                .build();
        final ActivityRecord activity0 = organizedTf0.getTopMostActivity();
        final ActivityRecord activity1 = organizedTf1.getTopMostActivity();

        activity0.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID + 1;
        activity1.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID;
        doReturn(true).when(organizedTf0).isAllowedToEmbedActivityInUntrustedMode(activity0);

        assertFalse("Activity0 doesn't have overlay because it's not occluded by activity1",
                activity0.hasOverlayOverUntrustedModeEmbedded());
        assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());

        // Expand organizedTf1 bounds slightly.
        final Rect tfBounds1 = organizedTf1.getBounds();
        organizedTf1.setBounds(tfBounds1.left - 5, tfBounds1.top, taskBounds.right + 5,
                tfBounds1.bottom);

        assertTrue("Activity0 has overlay because it's occluded partially by activity1",
                activity0.hasOverlayOverUntrustedModeEmbedded());
        assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());
    }

    @Test
    public void testIsAllowedToBeEmbeddedInTrustedMode() {
        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)