Loading core/java/android/companion/virtual/VirtualDeviceParams.java +102 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; Loading Loading @@ -65,18 +67,26 @@ public final class VirtualDeviceParams implements Parcelable { private final int mLockState; private final ArraySet<UserHandle> mUsersWithMatchingAccounts; @Nullable private final ArraySet<ComponentName> mAllowedActivities; @Nullable private final ArraySet<ComponentName> mBlockedActivities; private VirtualDeviceParams( @LockState int lockState, @NonNull Set<UserHandle> usersWithMatchingAccounts) { @NonNull Set<UserHandle> usersWithMatchingAccounts, @Nullable Set<ComponentName> allowedActivities, @Nullable Set<ComponentName> blockedActivities) { mLockState = lockState; mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts); mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities); mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities); } @SuppressWarnings("unchecked") private VirtualDeviceParams(Parcel parcel) { mLockState = parcel.readInt(); mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null); mAllowedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null); mBlockedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null); } /** Loading @@ -98,6 +108,33 @@ public final class VirtualDeviceParams implements Parcelable { return Collections.unmodifiableSet(mUsersWithMatchingAccounts); } /** * Returns the set of activities allowed to be streamed, or {@code null} if this is not set. * * @see Builder#setAllowedActivities(Set) */ @Nullable public Set<ComponentName> getAllowedActivities() { if (mAllowedActivities == null) { return null; } return Collections.unmodifiableSet(mAllowedActivities); } /** * Returns the set of activities that are blocked from streaming, or {@code null} if this is not * set. * * @see Builder#setBlockedActivities(Set) */ @Nullable public Set<ComponentName> getBlockedActivities() { if (mBlockedActivities == null) { return null; } return Collections.unmodifiableSet(mBlockedActivities); } @Override public int describeContents() { return 0; Loading @@ -107,6 +144,8 @@ public final class VirtualDeviceParams implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mLockState); dest.writeArraySet(mUsersWithMatchingAccounts); dest.writeArraySet(mAllowedActivities); dest.writeArraySet(mBlockedActivities); } @Override Loading @@ -118,8 +157,10 @@ public final class VirtualDeviceParams implements Parcelable { return false; } VirtualDeviceParams that = (VirtualDeviceParams) o; return mLockState == that.mLockState && mUsersWithMatchingAccounts.equals( that.mUsersWithMatchingAccounts); return mLockState == that.mLockState && mUsersWithMatchingAccounts.equals(that.mUsersWithMatchingAccounts) && Objects.equals(mAllowedActivities, that.mAllowedActivities) && Objects.equals(mBlockedActivities, that.mBlockedActivities); } @Override Loading @@ -132,6 +173,8 @@ public final class VirtualDeviceParams implements Parcelable { return "VirtualDeviceParams(" + " mLockState=" + mLockState + " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts + " mAllowedActivities=" + mAllowedActivities + " mBlockedActivities=" + mBlockedActivities + ")"; } Loading @@ -153,6 +196,8 @@ public final class VirtualDeviceParams implements Parcelable { private @LockState int mLockState = LOCK_STATE_ALWAYS_LOCKED; private Set<UserHandle> mUsersWithMatchingAccounts; @Nullable private Set<ComponentName> mBlockedActivities; @Nullable private Set<ComponentName> mAllowedActivities; /** * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY} Loading @@ -175,6 +220,7 @@ public final class VirtualDeviceParams implements Parcelable { * * @param usersWithMatchingAccounts A set of user handles with matching managed * accounts on the remote device this is streaming to. * * @see android.app.admin.DevicePolicyManager#NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY */ public Builder setUsersWithMatchingAccounts( Loading @@ -183,6 +229,52 @@ public final class VirtualDeviceParams implements Parcelable { return this; } /** * Sets the activities allowed to be launched in the virtual device. If * {@code allowedActivities} is non-null, all activities other than the ones in the set will * be blocked from launching. * * <p>{@code allowedActivities} and the set in {@link #setBlockedActivities(Set)} cannot * both be non-null at the same time. * * @throws IllegalArgumentException if {@link #setBlockedActivities(Set)} has been set to a * non-null value. * * @param allowedActivities A set of activity {@link ComponentName} allowed to be launched * in the virtual device. */ public Builder setAllowedActivities(@Nullable Set<ComponentName> allowedActivities) { if (mBlockedActivities != null && allowedActivities != null) { throw new IllegalArgumentException( "Allowed activities and Blocked activities cannot both be set."); } mAllowedActivities = allowedActivities; return this; } /** * Sets the activities blocked from launching in the virtual device. If the {@code * blockedActivities} is non-null, activities in the set are blocked from launching in the * virtual device. * * {@code blockedActivities} and the set in {@link #setAllowedActivities(Set)} cannot both * be non-null at the same time. * * @throws IllegalArgumentException if {@link #setAllowedActivities(Set)} has been set to a * non-null value. * * @param blockedActivities A set of {@link ComponentName} to be blocked launching from * virtual device. */ public Builder setBlockedActivities(@Nullable Set<ComponentName> blockedActivities) { if (mAllowedActivities != null && blockedActivities != null) { throw new IllegalArgumentException( "Allowed activities and Blocked activities cannot both be set."); } mBlockedActivities = blockedActivities; return this; } /** * Builds the {@link VirtualDeviceParams} instance. */ Loading @@ -191,7 +283,13 @@ public final class VirtualDeviceParams implements Parcelable { if (mUsersWithMatchingAccounts == null) { mUsersWithMatchingAccounts = Collections.emptySet(); } return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts); if (mAllowedActivities != null && mBlockedActivities != null) { // Should never reach here because the setters block this as well. throw new IllegalStateException( "Allowed activities and Blocked activities cannot both be set."); } return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts, mAllowedActivities, mBlockedActivities); } } } services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +27 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; Loading @@ -33,6 +34,7 @@ import android.util.Slog; import android.window.DisplayWindowPolicyController; import java.util.List; import java.util.Set; /** Loading @@ -49,13 +51,23 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @ChangeId @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE = 201712607L; @NonNull private final ArraySet<UserHandle> mAllowedUsers; @NonNull private final ArraySet<UserHandle> mAllowedUsers; @Nullable private final ArraySet<ComponentName> mAllowedActivities; @Nullable private final ArraySet<ComponentName> mBlockedActivities; @NonNull final ArraySet<Integer> mRunningUids = new ArraySet<>(); @NonNull final ArraySet<Integer> mRunningUids = new ArraySet<>(); GenericWindowPolicyController(int windowFlags, int systemWindowFlags, @NonNull ArraySet<UserHandle> allowedUsers) { @NonNull ArraySet<UserHandle> allowedUsers, @Nullable Set<ComponentName> allowedActivities, @Nullable Set<ComponentName> blockedActivities) { mAllowedUsers = allowedUsers; mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities); mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities); setInterestedWindowFlags(windowFlags, systemWindowFlags); } Loading Loading @@ -108,6 +120,18 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser); return false; } if (mBlockedActivities != null && mBlockedActivities.contains(activityInfo.getComponentName())) { Slog.d(TAG, "Virtual device blocking launch of " + activityInfo.getComponentName()); return false; } if (mAllowedActivities != null && !mAllowedActivities.contains(activityInfo.getComponentName())) { Slog.d(TAG, activityInfo.getComponentName() + " 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. Loading services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +4 −1 Original line number Diff line number Diff line Loading @@ -328,6 +328,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { fout.println(" VirtualDevice: "); fout.println(" mAssociationId: " + mAssociationInfo.getId()); fout.println(" mParams: " + mParams); fout.println(" mVirtualDisplayIds: "); synchronized (mVirtualDeviceLock) { for (int id : mVirtualDisplayIds) { Loading @@ -345,7 +346,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mVirtualDisplayIds.add(displayId); final GenericWindowPolicyController dwpc = new GenericWindowPolicyController(FLAG_SECURE, SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, getAllowedUserHandles()); SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, getAllowedUserHandles(), mParams.getAllowedActivities(), mParams.getBlockedActivities()); mWindowPolicyControllers.put(displayId, dwpc); return dwpc; } Loading Loading
core/java/android/companion/virtual/VirtualDeviceParams.java +102 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.content.ComponentName; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; Loading Loading @@ -65,18 +67,26 @@ public final class VirtualDeviceParams implements Parcelable { private final int mLockState; private final ArraySet<UserHandle> mUsersWithMatchingAccounts; @Nullable private final ArraySet<ComponentName> mAllowedActivities; @Nullable private final ArraySet<ComponentName> mBlockedActivities; private VirtualDeviceParams( @LockState int lockState, @NonNull Set<UserHandle> usersWithMatchingAccounts) { @NonNull Set<UserHandle> usersWithMatchingAccounts, @Nullable Set<ComponentName> allowedActivities, @Nullable Set<ComponentName> blockedActivities) { mLockState = lockState; mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts); mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities); mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities); } @SuppressWarnings("unchecked") private VirtualDeviceParams(Parcel parcel) { mLockState = parcel.readInt(); mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null); mAllowedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null); mBlockedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null); } /** Loading @@ -98,6 +108,33 @@ public final class VirtualDeviceParams implements Parcelable { return Collections.unmodifiableSet(mUsersWithMatchingAccounts); } /** * Returns the set of activities allowed to be streamed, or {@code null} if this is not set. * * @see Builder#setAllowedActivities(Set) */ @Nullable public Set<ComponentName> getAllowedActivities() { if (mAllowedActivities == null) { return null; } return Collections.unmodifiableSet(mAllowedActivities); } /** * Returns the set of activities that are blocked from streaming, or {@code null} if this is not * set. * * @see Builder#setBlockedActivities(Set) */ @Nullable public Set<ComponentName> getBlockedActivities() { if (mBlockedActivities == null) { return null; } return Collections.unmodifiableSet(mBlockedActivities); } @Override public int describeContents() { return 0; Loading @@ -107,6 +144,8 @@ public final class VirtualDeviceParams implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mLockState); dest.writeArraySet(mUsersWithMatchingAccounts); dest.writeArraySet(mAllowedActivities); dest.writeArraySet(mBlockedActivities); } @Override Loading @@ -118,8 +157,10 @@ public final class VirtualDeviceParams implements Parcelable { return false; } VirtualDeviceParams that = (VirtualDeviceParams) o; return mLockState == that.mLockState && mUsersWithMatchingAccounts.equals( that.mUsersWithMatchingAccounts); return mLockState == that.mLockState && mUsersWithMatchingAccounts.equals(that.mUsersWithMatchingAccounts) && Objects.equals(mAllowedActivities, that.mAllowedActivities) && Objects.equals(mBlockedActivities, that.mBlockedActivities); } @Override Loading @@ -132,6 +173,8 @@ public final class VirtualDeviceParams implements Parcelable { return "VirtualDeviceParams(" + " mLockState=" + mLockState + " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts + " mAllowedActivities=" + mAllowedActivities + " mBlockedActivities=" + mBlockedActivities + ")"; } Loading @@ -153,6 +196,8 @@ public final class VirtualDeviceParams implements Parcelable { private @LockState int mLockState = LOCK_STATE_ALWAYS_LOCKED; private Set<UserHandle> mUsersWithMatchingAccounts; @Nullable private Set<ComponentName> mBlockedActivities; @Nullable private Set<ComponentName> mAllowedActivities; /** * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY} Loading @@ -175,6 +220,7 @@ public final class VirtualDeviceParams implements Parcelable { * * @param usersWithMatchingAccounts A set of user handles with matching managed * accounts on the remote device this is streaming to. * * @see android.app.admin.DevicePolicyManager#NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY */ public Builder setUsersWithMatchingAccounts( Loading @@ -183,6 +229,52 @@ public final class VirtualDeviceParams implements Parcelable { return this; } /** * Sets the activities allowed to be launched in the virtual device. If * {@code allowedActivities} is non-null, all activities other than the ones in the set will * be blocked from launching. * * <p>{@code allowedActivities} and the set in {@link #setBlockedActivities(Set)} cannot * both be non-null at the same time. * * @throws IllegalArgumentException if {@link #setBlockedActivities(Set)} has been set to a * non-null value. * * @param allowedActivities A set of activity {@link ComponentName} allowed to be launched * in the virtual device. */ public Builder setAllowedActivities(@Nullable Set<ComponentName> allowedActivities) { if (mBlockedActivities != null && allowedActivities != null) { throw new IllegalArgumentException( "Allowed activities and Blocked activities cannot both be set."); } mAllowedActivities = allowedActivities; return this; } /** * Sets the activities blocked from launching in the virtual device. If the {@code * blockedActivities} is non-null, activities in the set are blocked from launching in the * virtual device. * * {@code blockedActivities} and the set in {@link #setAllowedActivities(Set)} cannot both * be non-null at the same time. * * @throws IllegalArgumentException if {@link #setAllowedActivities(Set)} has been set to a * non-null value. * * @param blockedActivities A set of {@link ComponentName} to be blocked launching from * virtual device. */ public Builder setBlockedActivities(@Nullable Set<ComponentName> blockedActivities) { if (mAllowedActivities != null && blockedActivities != null) { throw new IllegalArgumentException( "Allowed activities and Blocked activities cannot both be set."); } mBlockedActivities = blockedActivities; return this; } /** * Builds the {@link VirtualDeviceParams} instance. */ Loading @@ -191,7 +283,13 @@ public final class VirtualDeviceParams implements Parcelable { if (mUsersWithMatchingAccounts == null) { mUsersWithMatchingAccounts = Collections.emptySet(); } return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts); if (mAllowedActivities != null && mBlockedActivities != null) { // Should never reach here because the setters block this as well. throw new IllegalStateException( "Allowed activities and Blocked activities cannot both be set."); } return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts, mAllowedActivities, mBlockedActivities); } } }
services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +27 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; Loading @@ -33,6 +34,7 @@ import android.util.Slog; import android.window.DisplayWindowPolicyController; import java.util.List; import java.util.Set; /** Loading @@ -49,13 +51,23 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @ChangeId @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE = 201712607L; @NonNull private final ArraySet<UserHandle> mAllowedUsers; @NonNull private final ArraySet<UserHandle> mAllowedUsers; @Nullable private final ArraySet<ComponentName> mAllowedActivities; @Nullable private final ArraySet<ComponentName> mBlockedActivities; @NonNull final ArraySet<Integer> mRunningUids = new ArraySet<>(); @NonNull final ArraySet<Integer> mRunningUids = new ArraySet<>(); GenericWindowPolicyController(int windowFlags, int systemWindowFlags, @NonNull ArraySet<UserHandle> allowedUsers) { @NonNull ArraySet<UserHandle> allowedUsers, @Nullable Set<ComponentName> allowedActivities, @Nullable Set<ComponentName> blockedActivities) { mAllowedUsers = allowedUsers; mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities); mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities); setInterestedWindowFlags(windowFlags, systemWindowFlags); } Loading Loading @@ -108,6 +120,18 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser); return false; } if (mBlockedActivities != null && mBlockedActivities.contains(activityInfo.getComponentName())) { Slog.d(TAG, "Virtual device blocking launch of " + activityInfo.getComponentName()); return false; } if (mAllowedActivities != null && !mAllowedActivities.contains(activityInfo.getComponentName())) { Slog.d(TAG, activityInfo.getComponentName() + " 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. Loading
services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +4 −1 Original line number Diff line number Diff line Loading @@ -328,6 +328,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { fout.println(" VirtualDevice: "); fout.println(" mAssociationId: " + mAssociationInfo.getId()); fout.println(" mParams: " + mParams); fout.println(" mVirtualDisplayIds: "); synchronized (mVirtualDeviceLock) { for (int id : mVirtualDisplayIds) { Loading @@ -345,7 +346,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mVirtualDisplayIds.add(displayId); final GenericWindowPolicyController dwpc = new GenericWindowPolicyController(FLAG_SECURE, SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, getAllowedUserHandles()); SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, getAllowedUserHandles(), mParams.getAllowedActivities(), mParams.getBlockedActivities()); mWindowPolicyControllers.put(displayId, dwpc); return dwpc; } Loading