Decide on navigation to task by policy in Virtual Device
Adds the implementation to allow or block navigation to a
new task in the policy controller for a virtual device. Will
only change behavior if the cross navigation allow or block
list is included and the navigation does not occur from
the default display.
Bug: 223915401
Test: atest WmTests:DisplayWindowPolicyControllerHelperTests
atest CtsVirtualDevicesTestCases
atest WmTests:ActivityStarterTests
Added test in ag/17503735
Change-Id: I3dfb9dd93c0edf4634320c52a3fc40c4bf473085
This commit is contained in:
@@ -109,6 +109,13 @@ public abstract class DisplayWindowPolicyController {
|
|||||||
public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities,
|
public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities,
|
||||||
@WindowConfiguration.WindowingMode int windowingMode);
|
@WindowConfiguration.WindowingMode int windowingMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the given new task can be launched on this virtual display.
|
||||||
|
*/
|
||||||
|
public abstract boolean canActivityBeLaunched(@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
|
* Called when an Activity window is layouted with the new changes where contains the
|
||||||
* window flags that we’re interested in.
|
* window flags that we’re interested in.
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final ArraySet<UserHandle> mAllowedUsers;
|
private final ArraySet<UserHandle> mAllowedUsers;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
private final ArraySet<ComponentName> mAllowedCrossTaskNavigations;
|
||||||
|
@Nullable
|
||||||
|
private final ArraySet<ComponentName> mBlockedCrossTaskNavigations;
|
||||||
|
@Nullable
|
||||||
private final ArraySet<ComponentName> mAllowedActivities;
|
private final ArraySet<ComponentName> mAllowedActivities;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final ArraySet<ComponentName> mBlockedActivities;
|
private final ArraySet<ComponentName> mBlockedActivities;
|
||||||
@@ -100,6 +104,10 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
|||||||
* @param windowFlags The window flags that this controller is interested in.
|
* @param windowFlags The window flags that this controller is interested in.
|
||||||
* @param systemWindowFlags The system window flags that this controller is interested in.
|
* @param systemWindowFlags The system window flags that this controller is interested in.
|
||||||
* @param allowedUsers The set of users that are allowed to stream in this display.
|
* @param allowedUsers The set of users that are allowed to stream in this display.
|
||||||
|
* @param allowedCrossTaskNavigations The set of components explicitly allowed to navigate
|
||||||
|
* across tasks on this device.
|
||||||
|
* @param blockedCrossTaskNavigations The set of components explicitly blocked from
|
||||||
|
* navigating across tasks on this device.
|
||||||
* @param allowedActivities The set of activities explicitly allowed to stream on this device.
|
* @param allowedActivities The set of activities explicitly allowed to stream on this device.
|
||||||
* Used only if the {@code activityPolicy} is
|
* Used only if the {@code activityPolicy} is
|
||||||
* {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_BLOCKED}.
|
* {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_BLOCKED}.
|
||||||
@@ -115,6 +123,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
|||||||
*/
|
*/
|
||||||
public GenericWindowPolicyController(int windowFlags, int systemWindowFlags,
|
public GenericWindowPolicyController(int windowFlags, int systemWindowFlags,
|
||||||
@NonNull ArraySet<UserHandle> allowedUsers,
|
@NonNull ArraySet<UserHandle> allowedUsers,
|
||||||
|
@NonNull Set<ComponentName> allowedCrossTaskNavigations,
|
||||||
|
@NonNull Set<ComponentName> blockedCrossTaskNavigations,
|
||||||
@NonNull Set<ComponentName> allowedActivities,
|
@NonNull Set<ComponentName> allowedActivities,
|
||||||
@NonNull Set<ComponentName> blockedActivities,
|
@NonNull Set<ComponentName> blockedActivities,
|
||||||
@ActivityPolicy int defaultActivityPolicy,
|
@ActivityPolicy int defaultActivityPolicy,
|
||||||
@@ -122,6 +132,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
|||||||
@NonNull Consumer<ActivityInfo> activityBlockedCallback) {
|
@NonNull Consumer<ActivityInfo> activityBlockedCallback) {
|
||||||
super();
|
super();
|
||||||
mAllowedUsers = allowedUsers;
|
mAllowedUsers = allowedUsers;
|
||||||
|
mAllowedCrossTaskNavigations = new ArraySet<>(allowedCrossTaskNavigations);
|
||||||
|
mBlockedCrossTaskNavigations = new ArraySet<>(blockedCrossTaskNavigations);
|
||||||
mAllowedActivities = new ArraySet<>(allowedActivities);
|
mAllowedActivities = new ArraySet<>(allowedActivities);
|
||||||
mBlockedActivities = new ArraySet<>(blockedActivities);
|
mBlockedActivities = new ArraySet<>(blockedActivities);
|
||||||
mDefaultActivityPolicy = defaultActivityPolicy;
|
mDefaultActivityPolicy = defaultActivityPolicy;
|
||||||
@@ -153,6 +165,46 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canActivityBeLaunched(ActivityInfo activityInfo,
|
||||||
|
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
|
||||||
|
boolean isNewTask) {
|
||||||
|
if (!isWindowingModeSupported(windowingMode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ComponentName activityComponent = activityInfo.getComponentName();
|
||||||
|
if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) {
|
||||||
|
// The error dialog alerting users that streaming is blocked is always allowed.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canContainActivity(activityInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) {
|
||||||
|
mActivityBlockedCallback.accept(activityInfo);
|
||||||
|
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.accept(activityInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isNewTask && !mAllowedCrossTaskNavigations.isEmpty()
|
||||||
|
&& !mAllowedCrossTaskNavigations.contains(activityComponent)) {
|
||||||
|
Slog.d(TAG, "Virtual device not allowing cross task navigation of "
|
||||||
|
+ activityComponent);
|
||||||
|
mActivityBlockedCallback.accept(activityInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
|
public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
|
||||||
int systemWindowFlags) {
|
int systemWindowFlags) {
|
||||||
|
|||||||
@@ -528,6 +528,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
|||||||
new GenericWindowPolicyController(FLAG_SECURE,
|
new GenericWindowPolicyController(FLAG_SECURE,
|
||||||
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
|
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
|
||||||
getAllowedUserHandles(),
|
getAllowedUserHandles(),
|
||||||
|
mParams.getAllowedCrossTaskNavigations(),
|
||||||
|
mParams.getBlockedCrossTaskNavigations(),
|
||||||
mParams.getAllowedActivities(),
|
mParams.getAllowedActivities(),
|
||||||
mParams.getBlockedActivities(),
|
mParams.getBlockedActivities(),
|
||||||
mParams.getDefaultActivityPolicy(),
|
mParams.getDefaultActivityPolicy(),
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ import com.android.server.wm.LaunchParamsController.LaunchParams;
|
|||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2036,12 +2035,13 @@ class ActivityStarter {
|
|||||||
final DisplayContent displayContent = mRootWindowContainer.getDisplayContentOrCreate(
|
final DisplayContent displayContent = mRootWindowContainer.getDisplayContentOrCreate(
|
||||||
mPreferredTaskDisplayArea.getDisplayId());
|
mPreferredTaskDisplayArea.getDisplayId());
|
||||||
if (displayContent != null && displayContent.mDwpcHelper.hasController()) {
|
if (displayContent != null && displayContent.mDwpcHelper.hasController()) {
|
||||||
final ArrayList<ActivityInfo> activities = new ArrayList<>();
|
|
||||||
activities.add(r.info);
|
|
||||||
final int targetWindowingMode = (targetTask != null)
|
final int targetWindowingMode = (targetTask != null)
|
||||||
? targetTask.getWindowingMode() : displayContent.getWindowingMode();
|
? targetTask.getWindowingMode() : displayContent.getWindowingMode();
|
||||||
|
final int launchingFromDisplayId =
|
||||||
|
mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY;
|
||||||
if (!displayContent.mDwpcHelper
|
if (!displayContent.mDwpcHelper
|
||||||
.canContainActivities(activities, targetWindowingMode)) {
|
.canActivityBeLaunched(r.info, targetWindowingMode, launchingFromDisplayId,
|
||||||
|
newTask)) {
|
||||||
Slog.w(TAG, "Abort to launch " + r.info.getComponentName()
|
Slog.w(TAG, "Abort to launch " + r.info.getComponentName()
|
||||||
+ " on display area " + mPreferredTaskDisplayArea);
|
+ " on display area " + mPreferredTaskDisplayArea);
|
||||||
return START_ABORTED;
|
return START_ABORTED;
|
||||||
|
|||||||
@@ -74,6 +74,19 @@ class DisplayWindowPolicyControllerHelper {
|
|||||||
return mDisplayWindowPolicyController.canContainActivities(activities, windowingMode);
|
return mDisplayWindowPolicyController.canContainActivities(activities, windowingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DisplayWindowPolicyController#canActivityBeLaunched(ActivityInfo, int, int, boolean)
|
||||||
|
*/
|
||||||
|
public boolean canActivityBeLaunched(ActivityInfo activityInfo,
|
||||||
|
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
|
||||||
|
boolean isNewTask) {
|
||||||
|
if (mDisplayWindowPolicyController == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, windowingMode,
|
||||||
|
launchingFromDisplayId, isNewTask);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int)
|
* @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ public class VirtualAudioControllerTest {
|
|||||||
FLAG_SECURE,
|
FLAG_SECURE,
|
||||||
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
|
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
|
||||||
/* allowedUsers= */ new ArraySet<>(),
|
/* allowedUsers= */ new ArraySet<>(),
|
||||||
|
/* allowedCrossTaskNavigations= */ new ArraySet<>(),
|
||||||
|
/* blockedCrossTaskNavigations= */ new ArraySet<>(),
|
||||||
/* allowedActivities= */ new ArraySet<>(),
|
/* allowedActivities= */ new ArraySet<>(),
|
||||||
/* blockedActivities= */ new ArraySet<>(),
|
/* blockedActivities= */ new ArraySet<>(),
|
||||||
VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED,
|
VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED,
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCanContainActivities() {
|
public void testCanActivityBeLaunched() {
|
||||||
ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm,
|
ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm,
|
||||||
mSupervisor, mock(ActivityStartInterceptor.class));
|
mSupervisor, mock(ActivityStartInterceptor.class));
|
||||||
final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build();
|
final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build();
|
||||||
@@ -203,6 +203,13 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
|
|||||||
int mTopActivityUid = UserHandle.USER_NULL;
|
int mTopActivityUid = UserHandle.USER_NULL;
|
||||||
ArraySet<Integer> mRunningUids = new ArraySet<>();
|
ArraySet<Integer> mRunningUids = new ArraySet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canActivityBeLaunched(@NonNull ActivityInfo activity,
|
||||||
|
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
|
||||||
|
boolean isNewTask) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
|
public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
|
||||||
@WindowConfiguration.WindowingMode int windowingMode) {
|
@WindowConfiguration.WindowingMode int windowingMode) {
|
||||||
|
|||||||
Reference in New Issue
Block a user