Loading core/java/android/window/DisplayWindowPolicyController.java +30 −8 Original line number Diff line number Diff line Loading @@ -17,8 +17,10 @@ package android.window; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.view.Display.INVALID_DISPLAY; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.WindowConfiguration; import android.content.ComponentName; Loading Loading @@ -107,18 +109,38 @@ public abstract class DisplayWindowPolicyController { } /** * Returns {@code true} if the given activities can be displayed on this virtual display and * the windowing mode is supported. * Returns {@code true} if all of the given activities can be launched on this virtual display * in the configuration defined by the rest of the arguments. * * @see #canContainActivity */ public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { for (int i = 0; i < activities.size(); i++) { if (!canContainActivity(activities.get(i), windowingMode, /*launchingFromDisplayId=*/ INVALID_DISPLAY, /*isNewTask=*/ false)) { return false; } } return true; } /** * Returns {@code true} if the given activity can be launched on this virtual display in the * configuration defined by the rest of the arguments. If the given intent would be intercepted * by the display owner then this means that the activity cannot be launched. */ public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode); public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask); /** * Returns {@code true} if the given new task can be launched on this virtual display. * Returns {@code true} if the given activity can be launched on this virtual display in the * configuration defined by the rest of the arguments. */ public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask); protected abstract boolean canContainActivity(@NonNull ActivityInfo activityInfo, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask); /** * Called when an Activity window is layouted with the new changes where contains the Loading services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +54 −89 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.companion.virtual; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; Loading Loading @@ -46,7 +47,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.BlockedAppStreamingActivity; import java.util.List; import java.util.Set; Loading Loading @@ -219,28 +219,37 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } @Override public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { if (!isWindowingModeSupported(windowingMode)) { public boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId, isNewTask)) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } // Can't display all the activities if any of them don't want to be displayed. final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, aInfo); if (mIntentListenerCallback != null && intent != null && mIntentListenerCallback.shouldInterceptIntent(intent)) { Slog.d(TAG, "Virtual device intercepting intent"); return false; } } return true; } @Override public boolean canActivityBeLaunched(ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { public boolean canContainActivity(@NonNull ActivityInfo activityInfo, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (!isWindowingModeSupported(windowingMode)) { Slog.d(TAG, "Virtual device doesn't support windowing mode " + windowingMode); return false; } if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { Slog.d(TAG, "Virtual device requires android:canDisplayOnRemoteDevices=true"); return false; } final UserHandle activityUser = UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); if (!mAllowedUsers.contains(activityUser)) { Slog.d(TAG, "Virtual device launch disallowed from user " + activityUser); return false; } Loading @@ -249,40 +258,36 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController // The error dialog alerting users that streaming is blocked is always allowed. return true; } if (!canContainActivity(activityInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); if (!activityMatchesDisplayCategory(activityInfo)) { Slog.d(TAG, "The activity's required display category '" + activityInfo.requiredDisplayCategory + "' not found on virtual display with the following categories: " + mDisplayCategories); return false; } if (launchingFromDisplayId == Display.DEFAULT_DISPLAY) { return true; } if (isNewTask && !mBlockedCrossTaskNavigations.isEmpty() && mBlockedCrossTaskNavigations.contains(activityComponent)) { Slog.d(TAG, "Virtual device blocking cross task navigation of " + activityComponent); mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); if ((mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED && mBlockedActivities.contains(activityComponent)) || (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED && !mAllowedActivities.contains(activityComponent))) { Slog.d(TAG, "Virtual device launch disallowed by policy: " + activityComponent); return false; } if (isNewTask && !mAllowedCrossTaskNavigations.isEmpty() && !mAllowedCrossTaskNavigations.contains(activityComponent)) { Slog.d(TAG, "Virtual device not allowing cross task navigation of " if (isNewTask && launchingFromDisplayId != DEFAULT_DISPLAY) { if ((!mBlockedCrossTaskNavigations.isEmpty() && mBlockedCrossTaskNavigations.contains(activityComponent)) || ((!mAllowedCrossTaskNavigations.isEmpty() && !mAllowedCrossTaskNavigations.contains(activityComponent)))) { Slog.d(TAG, "Virtual device cross task navigation disallowed by policy: " + activityComponent); mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } if (mIntentListenerCallback != null && intent != null && mIntentListenerCallback.shouldInterceptIntent(intent)) { Slog.d(TAG, "Virtual device has intercepted intent"); return false; } return true; } @Override @SuppressWarnings("AndroidFrameworkRequiresPermission") public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { // The callback is fired only when windowFlags are changed. To let VirtualDevice owner Loading @@ -293,10 +298,17 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController activityInfo.applicationInfo.uid)); } if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) { if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE, activityInfo.packageName, UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid))) { // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. if ((windowFlags & FLAG_SECURE) != 0 || (systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } } return true; } Loading Loading @@ -368,53 +380,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { return false; } ComponentName activityComponent = activityInfo.getComponentName(); if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) { // The error dialog alerting users that streaming is blocked is always allowed. Need to // run before the clauses below to ensure error dialog always shows up. return true; } if (!activityMatchesDisplayCategory(activityInfo)) { Slog.d(TAG, String.format( "The activity's required display category: %s is not found on virtual display" + " with the following categories: %s", activityInfo.requiredDisplayCategory, mDisplayCategories.toString())); return false; } final UserHandle activityUser = UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); if (!mAllowedUsers.contains(activityUser)) { Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser); return false; } if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED && mBlockedActivities.contains(activityComponent)) { Slog.d(TAG, "Virtual device blocking launch of " + activityComponent); return false; } if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED && !mAllowedActivities.contains(activityComponent)) { Slog.d(TAG, activityComponent + " is not in the allowed list."); return false; } if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE, activityInfo.packageName, activityUser)) { // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. if ((windowFlags & FLAG_SECURE) != 0) { return false; } if ((systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { return false; } } return true; } @VisibleForTesting int getRunningAppsChangedListenersSizeForTesting() { synchronized (mGenericWindowPolicyControllerLock) { Loading services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java +20 −20 Original line number Diff line number Diff line Loading @@ -68,19 +68,15 @@ class DisplayWindowPolicyControllerHelper { } /** * @see DisplayWindowPolicyController#canContainActivities(List, int) * @see DisplayWindowPolicyController#canContainActivities */ public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { if (mDisplayWindowPolicyController == null) { for (int i = activities.size() - 1; i >= 0; i--) { final ActivityInfo aInfo = activities.get(i); if (aInfo.requiredDisplayCategory != null) { Slog.e(TAG, String.format("Activity with requiredDisplayCategory='%s' cannot be" + " displayed on display %d because that display does" + " not have a matching category", aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); for (int i = 0; i < activities.size(); ++i) { // Missing controller means that this display has no categories for activity launch // restriction. if (hasDisplayCategory(activities.get(i))) { return false; } } Loading @@ -90,26 +86,31 @@ class DisplayWindowPolicyControllerHelper { } /** * @see DisplayWindowPolicyController#canActivityBeLaunched(ActivityInfo, int, int, boolean) * @see DisplayWindowPolicyController#canActivityBeLaunched */ public boolean canActivityBeLaunched(ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (mDisplayWindowPolicyController == null) { if (activityInfo.requiredDisplayCategory != null) { Slog.e(TAG, String.format("Activity with requiredDisplayCategory='%s' cannot be" + " launched on display %d because that display does" + " not have a matching category", activityInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); return false; } return true; // Missing controller means that this display has no categories for activity launch // restriction. return !hasDisplayCategory(activityInfo); } return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, intent, windowingMode, launchingFromDisplayId, isNewTask); } private boolean hasDisplayCategory(ActivityInfo aInfo) { if (aInfo.requiredDisplayCategory != null) { Slog.d(TAG, String.format("Checking activity launch with requiredDisplayCategory='%s' on" + " display %d, which doesn't have a matching category.", aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); return true; } return false; } /** * @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int) */ Loading Loading @@ -199,7 +200,6 @@ class DisplayWindowPolicyControllerHelper { return mDisplayWindowPolicyController.isEnteringPipAllowed(uid); } void dump(String prefix, PrintWriter pw) { if (mDisplayWindowPolicyController != null) { pw.println(); Loading services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +37 −31 File changed.Preview size limit exceeded, changes collapsed. Show changes services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java +10 −13 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; import java.util.Set; /** Loading Loading @@ -106,7 +105,6 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { assertEquals(uidAmount, mDwpc.mRunningUids.size()); assertTrue(mDwpc.mRunningUids.contains(TEST_USER_0_ID) == expectedUid0); assertTrue(mDwpc.mRunningUids.contains(TEST_USER_1_ID) == expectedUid1); } private ActivityRecord launchActivityOnDisplay(DisplayContent display, int uid) { Loading Loading @@ -197,6 +195,11 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { @Test public void testCanActivityBeLaunched_requiredDisplayCategory() { doReturn(null).when(mWm.mDisplayManagerInternal) .getDisplayWindowPolicyController(anyInt()); mSecondaryDisplay = createNewDisplay(); assertFalse(mSecondaryDisplay.mDwpcHelper.hasController()); ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm, mSupervisor, mock(ActivityStartInterceptor.class)); final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build(); Loading Loading @@ -233,20 +236,14 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { public boolean canActivityBeLaunched(@NonNull ActivityInfo activity, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { return false; return canContainActivity(activity, windowingMode, launchingFromDisplayId, isNewTask); } @Override public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if (aInfo.getComponentName().equals(DISALLOWED_ACTIVITY)) { return false; } } return true; protected boolean canContainActivity(@NonNull ActivityInfo activity, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { return !activity.getComponentName().equals(DISALLOWED_ACTIVITY); } @Override Loading Loading
core/java/android/window/DisplayWindowPolicyController.java +30 −8 Original line number Diff line number Diff line Loading @@ -17,8 +17,10 @@ package android.window; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.view.Display.INVALID_DISPLAY; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.WindowConfiguration; import android.content.ComponentName; Loading Loading @@ -107,18 +109,38 @@ public abstract class DisplayWindowPolicyController { } /** * Returns {@code true} if the given activities can be displayed on this virtual display and * the windowing mode is supported. * Returns {@code true} if all of the given activities can be launched on this virtual display * in the configuration defined by the rest of the arguments. * * @see #canContainActivity */ public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { for (int i = 0; i < activities.size(); i++) { if (!canContainActivity(activities.get(i), windowingMode, /*launchingFromDisplayId=*/ INVALID_DISPLAY, /*isNewTask=*/ false)) { return false; } } return true; } /** * Returns {@code true} if the given activity can be launched on this virtual display in the * configuration defined by the rest of the arguments. If the given intent would be intercepted * by the display owner then this means that the activity cannot be launched. */ public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode); public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask); /** * Returns {@code true} if the given new task can be launched on this virtual display. * Returns {@code true} if the given activity can be launched on this virtual display in the * configuration defined by the rest of the arguments. */ public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask); protected abstract boolean canContainActivity(@NonNull ActivityInfo activityInfo, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask); /** * Called when an Activity window is layouted with the new changes where contains the Loading
services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +54 −89 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.companion.virtual; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; Loading Loading @@ -46,7 +47,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.BlockedAppStreamingActivity; import java.util.List; import java.util.Set; Loading Loading @@ -219,28 +219,37 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } @Override public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { if (!isWindowingModeSupported(windowingMode)) { public boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId, isNewTask)) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } // Can't display all the activities if any of them don't want to be displayed. final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, aInfo); if (mIntentListenerCallback != null && intent != null && mIntentListenerCallback.shouldInterceptIntent(intent)) { Slog.d(TAG, "Virtual device intercepting intent"); return false; } } return true; } @Override public boolean canActivityBeLaunched(ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { public boolean canContainActivity(@NonNull ActivityInfo activityInfo, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (!isWindowingModeSupported(windowingMode)) { Slog.d(TAG, "Virtual device doesn't support windowing mode " + windowingMode); return false; } if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { Slog.d(TAG, "Virtual device requires android:canDisplayOnRemoteDevices=true"); return false; } final UserHandle activityUser = UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); if (!mAllowedUsers.contains(activityUser)) { Slog.d(TAG, "Virtual device launch disallowed from user " + activityUser); return false; } Loading @@ -249,40 +258,36 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController // The error dialog alerting users that streaming is blocked is always allowed. return true; } if (!canContainActivity(activityInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); if (!activityMatchesDisplayCategory(activityInfo)) { Slog.d(TAG, "The activity's required display category '" + activityInfo.requiredDisplayCategory + "' not found on virtual display with the following categories: " + mDisplayCategories); return false; } if (launchingFromDisplayId == Display.DEFAULT_DISPLAY) { return true; } if (isNewTask && !mBlockedCrossTaskNavigations.isEmpty() && mBlockedCrossTaskNavigations.contains(activityComponent)) { Slog.d(TAG, "Virtual device blocking cross task navigation of " + activityComponent); mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); if ((mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED && mBlockedActivities.contains(activityComponent)) || (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED && !mAllowedActivities.contains(activityComponent))) { Slog.d(TAG, "Virtual device launch disallowed by policy: " + activityComponent); return false; } if (isNewTask && !mAllowedCrossTaskNavigations.isEmpty() && !mAllowedCrossTaskNavigations.contains(activityComponent)) { Slog.d(TAG, "Virtual device not allowing cross task navigation of " if (isNewTask && launchingFromDisplayId != DEFAULT_DISPLAY) { if ((!mBlockedCrossTaskNavigations.isEmpty() && mBlockedCrossTaskNavigations.contains(activityComponent)) || ((!mAllowedCrossTaskNavigations.isEmpty() && !mAllowedCrossTaskNavigations.contains(activityComponent)))) { Slog.d(TAG, "Virtual device cross task navigation disallowed by policy: " + activityComponent); mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } if (mIntentListenerCallback != null && intent != null && mIntentListenerCallback.shouldInterceptIntent(intent)) { Slog.d(TAG, "Virtual device has intercepted intent"); return false; } return true; } @Override @SuppressWarnings("AndroidFrameworkRequiresPermission") public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { // The callback is fired only when windowFlags are changed. To let VirtualDevice owner Loading @@ -293,10 +298,17 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController activityInfo.applicationInfo.uid)); } if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) { if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE, activityInfo.packageName, UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid))) { // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. if ((windowFlags & FLAG_SECURE) != 0 || (systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } } return true; } Loading Loading @@ -368,53 +380,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { return false; } ComponentName activityComponent = activityInfo.getComponentName(); if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) { // The error dialog alerting users that streaming is blocked is always allowed. Need to // run before the clauses below to ensure error dialog always shows up. return true; } if (!activityMatchesDisplayCategory(activityInfo)) { Slog.d(TAG, String.format( "The activity's required display category: %s is not found on virtual display" + " with the following categories: %s", activityInfo.requiredDisplayCategory, mDisplayCategories.toString())); return false; } final UserHandle activityUser = UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); if (!mAllowedUsers.contains(activityUser)) { Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser); return false; } if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED && mBlockedActivities.contains(activityComponent)) { Slog.d(TAG, "Virtual device blocking launch of " + activityComponent); return false; } if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED && !mAllowedActivities.contains(activityComponent)) { Slog.d(TAG, activityComponent + " is not in the allowed list."); return false; } if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE, activityInfo.packageName, activityUser)) { // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. if ((windowFlags & FLAG_SECURE) != 0) { return false; } if ((systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { return false; } } return true; } @VisibleForTesting int getRunningAppsChangedListenersSizeForTesting() { synchronized (mGenericWindowPolicyControllerLock) { Loading
services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java +20 −20 Original line number Diff line number Diff line Loading @@ -68,19 +68,15 @@ class DisplayWindowPolicyControllerHelper { } /** * @see DisplayWindowPolicyController#canContainActivities(List, int) * @see DisplayWindowPolicyController#canContainActivities */ public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { if (mDisplayWindowPolicyController == null) { for (int i = activities.size() - 1; i >= 0; i--) { final ActivityInfo aInfo = activities.get(i); if (aInfo.requiredDisplayCategory != null) { Slog.e(TAG, String.format("Activity with requiredDisplayCategory='%s' cannot be" + " displayed on display %d because that display does" + " not have a matching category", aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); for (int i = 0; i < activities.size(); ++i) { // Missing controller means that this display has no categories for activity launch // restriction. if (hasDisplayCategory(activities.get(i))) { return false; } } Loading @@ -90,26 +86,31 @@ class DisplayWindowPolicyControllerHelper { } /** * @see DisplayWindowPolicyController#canActivityBeLaunched(ActivityInfo, int, int, boolean) * @see DisplayWindowPolicyController#canActivityBeLaunched */ public boolean canActivityBeLaunched(ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (mDisplayWindowPolicyController == null) { if (activityInfo.requiredDisplayCategory != null) { Slog.e(TAG, String.format("Activity with requiredDisplayCategory='%s' cannot be" + " launched on display %d because that display does" + " not have a matching category", activityInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); return false; } return true; // Missing controller means that this display has no categories for activity launch // restriction. return !hasDisplayCategory(activityInfo); } return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, intent, windowingMode, launchingFromDisplayId, isNewTask); } private boolean hasDisplayCategory(ActivityInfo aInfo) { if (aInfo.requiredDisplayCategory != null) { Slog.d(TAG, String.format("Checking activity launch with requiredDisplayCategory='%s' on" + " display %d, which doesn't have a matching category.", aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); return true; } return false; } /** * @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int) */ Loading Loading @@ -199,7 +200,6 @@ class DisplayWindowPolicyControllerHelper { return mDisplayWindowPolicyController.isEnteringPipAllowed(uid); } void dump(String prefix, PrintWriter pw) { if (mDisplayWindowPolicyController != null) { pw.println(); Loading
services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +37 −31 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java +10 −13 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; import java.util.Set; /** Loading Loading @@ -106,7 +105,6 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { assertEquals(uidAmount, mDwpc.mRunningUids.size()); assertTrue(mDwpc.mRunningUids.contains(TEST_USER_0_ID) == expectedUid0); assertTrue(mDwpc.mRunningUids.contains(TEST_USER_1_ID) == expectedUid1); } private ActivityRecord launchActivityOnDisplay(DisplayContent display, int uid) { Loading Loading @@ -197,6 +195,11 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { @Test public void testCanActivityBeLaunched_requiredDisplayCategory() { doReturn(null).when(mWm.mDisplayManagerInternal) .getDisplayWindowPolicyController(anyInt()); mSecondaryDisplay = createNewDisplay(); assertFalse(mSecondaryDisplay.mDwpcHelper.hasController()); ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm, mSupervisor, mock(ActivityStartInterceptor.class)); final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build(); Loading Loading @@ -233,20 +236,14 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { public boolean canActivityBeLaunched(@NonNull ActivityInfo activity, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { return false; return canContainActivity(activity, windowingMode, launchingFromDisplayId, isNewTask); } @Override public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if (aInfo.getComponentName().equals(DISALLOWED_ACTIVITY)) { return false; } } return true; protected boolean canContainActivity(@NonNull ActivityInfo activity, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { return !activity.getComponentName().equals(DISALLOWED_ACTIVITY); } @Override Loading