From c48483db9e33c3ed9efdf04734b15aa52430299c Mon Sep 17 00:00:00 2001 From: Chris Li Date: Tue, 12 Apr 2022 13:11:17 +0800 Subject: [PATCH] Fix untrusted embedding visibility in multi windowing mode Before, we search overlay within the same root Task, which can be other task in split. Now, we only search within the same leaf Task. Bug: 197364677 Test: atest WmTests:TaskFragmentTest Change-Id: I64dfdf322a15cfd80f169d0ddfc6e9bbf94d2a03 --- .../com/android/server/wm/ActivityRecord.java | 4 +- .../android/server/wm/TaskFragmentTest.java | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 314864e2f917f..c5251296b91ea 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5553,7 +5553,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * this activity when embedded in untrusted mode. */ boolean hasOverlayOverUntrustedModeEmbedded() { - if (!isEmbeddedInUntrustedMode() || getRootTask() == null) { + if (!isEmbeddedInUntrustedMode() || getTask() == null) { // The activity is not embedded in untrusted mode. return false; } @@ -5561,7 +5561,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // 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. - final ActivityRecord differentUidOverlayActivity = getRootTask().getActivity( + final ActivityRecord differentUidOverlayActivity = getTask().getActivity( a -> a.getUid() != getUid(), this /* boundary */, false /* includeBoundary */, false /* traverseTopToBottom */); return differentUidOverlayActivity != null; diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java index 971826dd09b68..2101b6e767c89 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java @@ -16,6 +16,9 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; + import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; @@ -202,4 +205,56 @@ public class TaskFragmentTest extends WindowTestsBase { assertTrue(primaryActivity.supportsEnterPipOnTaskSwitch); assertFalse(secondaryActivity.supportsEnterPipOnTaskSwitch); } + + @Test + public void testActivityHasOverlayOverUntrustedModeEmbedded() { + final Task rootTask = createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, + ACTIVITY_TYPE_STANDARD); + final Task leafTask0 = new TaskBuilder(mSupervisor) + .setParentTaskFragment(rootTask) + .build(); + final TaskFragment organizedTf = new TaskFragmentBuilder(mAtm) + .createActivityCount(2) + .setParentTask(leafTask0) + .setFragmentToken(new Binder()) + .setOrganizer(mOrganizer) + .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. + 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); + + assertTrue(activity0.hasOverlayOverUntrustedModeEmbedded()); + assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded()); + + // Both activities are trusted embedded. + // None of the two has overlay over untrusted mode embedded. + activity0.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID; + + assertFalse(activity0.hasOverlayOverUntrustedModeEmbedded()); + assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded()); + + // Bottom activity is trusted embedding. Top activity is untrusted embedded. + // None of the two has overlay over untrusted mode embedded. + activity1.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID + 1; + + assertFalse(activity0.hasOverlayOverUntrustedModeEmbedded()); + assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded()); + + // There is an activity in a different leaf task on top of activity0 and activity1. + // None of the two has overlay over untrusted mode embedded because it is not the same Task. + final Task leafTask1 = new TaskBuilder(mSupervisor) + .setParentTaskFragment(rootTask) + .setOnTop(true) + .setCreateActivity(true) + .build(); + final ActivityRecord activity2 = leafTask1.getTopMostActivity(); + activity2.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID + 2; + + assertFalse(activity0.hasOverlayOverUntrustedModeEmbedded()); + assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded()); + } }