Allow virtual displays to launch activities if trusted
This CL updates ActivityStackSupervisor to allow virtual displays to launch Activities if they are trusted displays. Trusted virtual displays can only be created if the ADD_TRUSTED_DISPLAY permission is held. Bug: 162255799 Bug: 162042798 Test: atest WmTests:ActivityStackSupervisorTests Change-Id: I0ec3ef91e7ee2cbea34183d2607b31a4b0dd0fc3
This commit is contained in:
@@ -130,6 +130,7 @@ import android.util.MergedConfiguration;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -1090,9 +1091,9 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
|
||||
// Check if caller is already present on display
|
||||
final boolean uidPresentOnDisplay = displayContent.isUidPresent(callingUid);
|
||||
|
||||
final int displayOwnerUid = displayContent.mDisplay.getOwnerUid();
|
||||
if (displayContent.mDisplay.getType() == TYPE_VIRTUAL && displayOwnerUid != SYSTEM_UID) {
|
||||
// Limit launching on virtual displays, because their contents can be read from Surface
|
||||
final Display display = displayContent.mDisplay;
|
||||
if (!display.isTrusted()) {
|
||||
// Limit launching on untrusted displays because their contents can be read from Surface
|
||||
// by apps that created them.
|
||||
if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
|
||||
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
|
||||
@@ -1116,7 +1117,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
|
||||
}
|
||||
|
||||
// Check if the caller is the owner of the display.
|
||||
if (displayOwnerUid == callingUid) {
|
||||
if (display.getOwnerUid() == callingUid) {
|
||||
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
|
||||
+ " allow launch for owner of the display");
|
||||
return true;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<uses-permission android:name="android.permission.REORDER_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
|
||||
<uses-permission android:name="android.permission.STATUS_BAR" />
|
||||
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
|
||||
|
||||
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
|
||||
<application android:debuggable="true"
|
||||
|
||||
@@ -38,7 +38,13 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
|
||||
import android.app.WaitResult;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.media.ImageReader;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
@@ -173,4 +179,50 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskB.mTaskId) /* taskId */,
|
||||
eq(true) /* focused */);
|
||||
}
|
||||
|
||||
@Test
|
||||
/** Ensures that a trusted virtual display can launch arbitrary activities. */
|
||||
public void testTrustedVirtualDisplayCanLaunchActivities() {
|
||||
final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
|
||||
final Task stack = new StackBuilder(mRootWindowContainer)
|
||||
.setDisplay(newDisplay).build();
|
||||
final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
|
||||
VirtualDisplay virtualDisplay = createVirtualDisplay(true);
|
||||
final boolean allowed = mSupervisor.isCallerAllowedToLaunchOnDisplay(1234, 1234,
|
||||
virtualDisplay.getDisplay().getDisplayId(), unresizableActivity.info);
|
||||
|
||||
assertThat(allowed).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
/** Ensures that an untrusted virtual display cannot launch arbitrary activities. */
|
||||
public void testUntrustedVirtualDisplayCannotLaunchActivities() {
|
||||
final DisplayContent newDisplay = addNewDisplayContentAt(DisplayContent.POSITION_TOP);
|
||||
final Task stack = new StackBuilder(mRootWindowContainer)
|
||||
.setDisplay(newDisplay).build();
|
||||
final ActivityRecord unresizableActivity = stack.getTopNonFinishingActivity();
|
||||
VirtualDisplay virtualDisplay = createVirtualDisplay(false);
|
||||
final boolean allowed = mSupervisor.isCallerAllowedToLaunchOnDisplay(1234, 1234,
|
||||
virtualDisplay.getDisplay().getDisplayId(), unresizableActivity.info);
|
||||
|
||||
assertThat(allowed).isFalse();
|
||||
}
|
||||
|
||||
private VirtualDisplay createVirtualDisplay(boolean trusted) {
|
||||
final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
|
||||
final DisplayInfo displayInfo = new DisplayInfo();
|
||||
final Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
|
||||
defaultDisplay.getDisplayInfo(displayInfo);
|
||||
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
|
||||
if (trusted) {
|
||||
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
|
||||
}
|
||||
|
||||
final ImageReader imageReader = ImageReader.newInstance(
|
||||
displayInfo.logicalWidth, displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);
|
||||
|
||||
return dm.createVirtualDisplay("virtualDisplay", displayInfo.logicalWidth,
|
||||
displayInfo.logicalHeight,
|
||||
displayInfo.logicalDensityDpi, imageReader.getSurface(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user