Loading core/java/android/companion/virtual/IVirtualDeviceManager.aidl +6 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.companion.virtual; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.VirtualDeviceParams; /** * Interface for communication between VirtualDeviceManager and VirtualDeviceManagerService. Loading @@ -33,6 +34,10 @@ interface IVirtualDeviceManager { * that this belongs to the calling UID. * @param associationId The association ID as returned by {@link AssociationInfo#getId()} from * CDM. Virtual devices must have a corresponding association with CDM in order to be created. * @param params The parameters for creating this virtual device. See {@link * VirtualDeviceManager.VirtualDeviceParams}. */ IVirtualDevice createVirtualDevice(in IBinder token, String packageName, int associationId); IVirtualDevice createVirtualDevice( in IBinder token, String packageName, int associationId, in VirtualDeviceParams params); } core/java/android/companion/virtual/VirtualDeviceManager.java +8 −2 Original line number Diff line number Diff line Loading @@ -100,11 +100,11 @@ public final class VirtualDeviceManager { */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @Nullable public VirtualDevice createVirtualDevice(int associationId) { public VirtualDevice createVirtualDevice(int associationId, VirtualDeviceParams params) { // TODO(b/194949534): Unhide this API try { IVirtualDevice virtualDevice = mService.createVirtualDevice( new Binder(), mContext.getPackageName(), associationId); new Binder(), mContext.getPackageName(), associationId, params); return new VirtualDevice(mContext, virtualDevice); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -273,6 +273,12 @@ public final class VirtualDeviceManager { } } /** * Returns the display flags that should be added to a particular virtual display. * Additional device-level flags from {@link * com.android.server.companion.virtual.VirtualDeviceImpl#getBaseVirtualDisplayFlags()} will * be added by DisplayManagerService. */ private int getVirtualDisplayFlags(@DisplayFlags int flags) { int virtualDisplayFlags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; if ((flags & DISPLAY_FLAG_TRUSTED) != 0) { Loading core/java/android/companion/virtual/VirtualDeviceParams.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.companion.virtual; parcelable VirtualDeviceParams; core/java/android/companion/virtual/VirtualDeviceParams.java 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.companion.virtual; import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; import android.util.ArraySet; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Collections; import java.util.Objects; import java.util.Set; /** * Params that can be configured when creating virtual devices. * * @hide */ // TODO(b/194949534): Unhide this API public final class VirtualDeviceParams implements Parcelable { /** @hide */ @IntDef(prefix = "LOCK_STATE_", value = {LOCK_STATE_ALWAYS_LOCKED, LOCK_STATE_ALWAYS_UNLOCKED}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface LockState {} /** * Indicates that the lock state of the virtual device should be always locked. * * @hide // TODO(b/194949534): Unhide this API */ public static final int LOCK_STATE_ALWAYS_LOCKED = 0; /** * Indicates that the lock state of the virtual device should be always unlocked. * * @hide // TODO(b/194949534): Unhide this API */ public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1; private final int mLockState; private final ArraySet<UserHandle> mUsersWithMatchingAccounts; private VirtualDeviceParams( @LockState int lockState, @NonNull Set<UserHandle> usersWithMatchingAccounts) { mLockState = lockState; mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts); } @SuppressWarnings("unchecked") private VirtualDeviceParams(Parcel parcel) { mLockState = parcel.readInt(); mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null); } /** * Returns the lock state of the virtual device. */ @LockState public int getLockState() { return mLockState; } /** * Returns the user handles with matching managed accounts on the remote device to which * this virtual device is streaming. * * @see android.app.admin.DevicePolicyManager#NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY */ @NonNull public Set<UserHandle> getUsersWithMatchingAccounts() { return Collections.unmodifiableSet(mUsersWithMatchingAccounts); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mLockState); dest.writeArraySet(mUsersWithMatchingAccounts); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof VirtualDeviceParams)) { return false; } VirtualDeviceParams that = (VirtualDeviceParams) o; return mLockState == that.mLockState && mUsersWithMatchingAccounts.equals( that.mUsersWithMatchingAccounts); } @Override public int hashCode() { return Objects.hash(mLockState, mUsersWithMatchingAccounts); } @Override public String toString() { return "VirtualDeviceParams(" + " mLockState=" + mLockState + " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts + ")"; } public static final Parcelable.Creator<VirtualDeviceParams> CREATOR = new Parcelable.Creator<VirtualDeviceParams>() { public VirtualDeviceParams createFromParcel(Parcel in) { return new VirtualDeviceParams(in); } public VirtualDeviceParams[] newArray(int size) { return new VirtualDeviceParams[size]; } }; /** * Builder for {@link VirtualDeviceParams}. */ public static final class Builder { private @LockState int mLockState = LOCK_STATE_ALWAYS_LOCKED; private Set<UserHandle> mUsersWithMatchingAccounts; /** * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY} * is required if this is set to {@link #LOCK_STATE_ALWAYS_UNLOCKED}. * The default is {@link #LOCK_STATE_ALWAYS_LOCKED}. * * @param lockState The lock state, either {@link #LOCK_STATE_ALWAYS_LOCKED} or * {@link #LOCK_STATE_ALWAYS_UNLOCKED}. */ @RequiresPermission(value = ADD_ALWAYS_UNLOCKED_DISPLAY, conditional = true) @NonNull public Builder setLockState(@LockState int lockState) { mLockState = lockState; return this; } /** * Sets the user handles with matching managed accounts on the remote device to which * this virtual device is streaming. * * @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( @NonNull Set<UserHandle> usersWithMatchingAccounts) { mUsersWithMatchingAccounts = usersWithMatchingAccounts; return this; } /** * Builds the {@link VirtualDeviceParams} instance. */ @NonNull public VirtualDeviceParams build() { if (mUsersWithMatchingAccounts == null) { mUsersWithMatchingAccounts = Collections.emptySet(); } return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts); } } } services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +36 −19 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.companion.virtual; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; Loading @@ -27,9 +28,10 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.os.Build; import android.os.UserHandle; import android.util.ArraySet; import android.util.Slog; import android.window.DisplayWindowPolicyController; import java.util.HashSet; import java.util.List; Loading @@ -38,6 +40,8 @@ import java.util.List; */ class GenericWindowPolicyController extends DisplayWindowPolicyController { private static final String TAG = "VirtualDeviceManager"; /** * If required, allow the secure activity to display on remote device since * {@link android.os.Build.VERSION_CODES#TIRAMISU}. Loading @@ -45,10 +49,13 @@ 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 final HashSet<Integer> mRunningUids = new HashSet<>(); @NonNull final ArraySet<Integer> mRunningUids = new ArraySet<>(); GenericWindowPolicyController(int windowFlags, int systemWindowFlags) { GenericWindowPolicyController(int windowFlags, int systemWindowFlags, @NonNull ArraySet<UserHandle> allowedUsers) { mAllowedUsers = allowedUsers; setInterestedWindowFlags(windowFlags, systemWindowFlags); } Loading @@ -58,7 +65,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if ((aInfo.flags & ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { return false; } } Loading @@ -68,21 +75,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @Override public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { return false; } 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) { return false; } if ((systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { return false; } } return true; return canContainActivity(activityInfo, windowFlags, systemWindowFlags); } @Override Loading @@ -105,4 +98,28 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { boolean containsUid(int uid) { return mRunningUids.contains(uid); } private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { 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 (!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; } } Loading
core/java/android/companion/virtual/IVirtualDeviceManager.aidl +6 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.companion.virtual; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.VirtualDeviceParams; /** * Interface for communication between VirtualDeviceManager and VirtualDeviceManagerService. Loading @@ -33,6 +34,10 @@ interface IVirtualDeviceManager { * that this belongs to the calling UID. * @param associationId The association ID as returned by {@link AssociationInfo#getId()} from * CDM. Virtual devices must have a corresponding association with CDM in order to be created. * @param params The parameters for creating this virtual device. See {@link * VirtualDeviceManager.VirtualDeviceParams}. */ IVirtualDevice createVirtualDevice(in IBinder token, String packageName, int associationId); IVirtualDevice createVirtualDevice( in IBinder token, String packageName, int associationId, in VirtualDeviceParams params); }
core/java/android/companion/virtual/VirtualDeviceManager.java +8 −2 Original line number Diff line number Diff line Loading @@ -100,11 +100,11 @@ public final class VirtualDeviceManager { */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @Nullable public VirtualDevice createVirtualDevice(int associationId) { public VirtualDevice createVirtualDevice(int associationId, VirtualDeviceParams params) { // TODO(b/194949534): Unhide this API try { IVirtualDevice virtualDevice = mService.createVirtualDevice( new Binder(), mContext.getPackageName(), associationId); new Binder(), mContext.getPackageName(), associationId, params); return new VirtualDevice(mContext, virtualDevice); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -273,6 +273,12 @@ public final class VirtualDeviceManager { } } /** * Returns the display flags that should be added to a particular virtual display. * Additional device-level flags from {@link * com.android.server.companion.virtual.VirtualDeviceImpl#getBaseVirtualDisplayFlags()} will * be added by DisplayManagerService. */ private int getVirtualDisplayFlags(@DisplayFlags int flags) { int virtualDisplayFlags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; if ((flags & DISPLAY_FLAG_TRUSTED) != 0) { Loading
core/java/android/companion/virtual/VirtualDeviceParams.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.companion.virtual; parcelable VirtualDeviceParams;
core/java/android/companion/virtual/VirtualDeviceParams.java 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.companion.virtual; import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; import android.util.ArraySet; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Collections; import java.util.Objects; import java.util.Set; /** * Params that can be configured when creating virtual devices. * * @hide */ // TODO(b/194949534): Unhide this API public final class VirtualDeviceParams implements Parcelable { /** @hide */ @IntDef(prefix = "LOCK_STATE_", value = {LOCK_STATE_ALWAYS_LOCKED, LOCK_STATE_ALWAYS_UNLOCKED}) @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface LockState {} /** * Indicates that the lock state of the virtual device should be always locked. * * @hide // TODO(b/194949534): Unhide this API */ public static final int LOCK_STATE_ALWAYS_LOCKED = 0; /** * Indicates that the lock state of the virtual device should be always unlocked. * * @hide // TODO(b/194949534): Unhide this API */ public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1; private final int mLockState; private final ArraySet<UserHandle> mUsersWithMatchingAccounts; private VirtualDeviceParams( @LockState int lockState, @NonNull Set<UserHandle> usersWithMatchingAccounts) { mLockState = lockState; mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts); } @SuppressWarnings("unchecked") private VirtualDeviceParams(Parcel parcel) { mLockState = parcel.readInt(); mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null); } /** * Returns the lock state of the virtual device. */ @LockState public int getLockState() { return mLockState; } /** * Returns the user handles with matching managed accounts on the remote device to which * this virtual device is streaming. * * @see android.app.admin.DevicePolicyManager#NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY */ @NonNull public Set<UserHandle> getUsersWithMatchingAccounts() { return Collections.unmodifiableSet(mUsersWithMatchingAccounts); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mLockState); dest.writeArraySet(mUsersWithMatchingAccounts); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof VirtualDeviceParams)) { return false; } VirtualDeviceParams that = (VirtualDeviceParams) o; return mLockState == that.mLockState && mUsersWithMatchingAccounts.equals( that.mUsersWithMatchingAccounts); } @Override public int hashCode() { return Objects.hash(mLockState, mUsersWithMatchingAccounts); } @Override public String toString() { return "VirtualDeviceParams(" + " mLockState=" + mLockState + " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts + ")"; } public static final Parcelable.Creator<VirtualDeviceParams> CREATOR = new Parcelable.Creator<VirtualDeviceParams>() { public VirtualDeviceParams createFromParcel(Parcel in) { return new VirtualDeviceParams(in); } public VirtualDeviceParams[] newArray(int size) { return new VirtualDeviceParams[size]; } }; /** * Builder for {@link VirtualDeviceParams}. */ public static final class Builder { private @LockState int mLockState = LOCK_STATE_ALWAYS_LOCKED; private Set<UserHandle> mUsersWithMatchingAccounts; /** * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY} * is required if this is set to {@link #LOCK_STATE_ALWAYS_UNLOCKED}. * The default is {@link #LOCK_STATE_ALWAYS_LOCKED}. * * @param lockState The lock state, either {@link #LOCK_STATE_ALWAYS_LOCKED} or * {@link #LOCK_STATE_ALWAYS_UNLOCKED}. */ @RequiresPermission(value = ADD_ALWAYS_UNLOCKED_DISPLAY, conditional = true) @NonNull public Builder setLockState(@LockState int lockState) { mLockState = lockState; return this; } /** * Sets the user handles with matching managed accounts on the remote device to which * this virtual device is streaming. * * @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( @NonNull Set<UserHandle> usersWithMatchingAccounts) { mUsersWithMatchingAccounts = usersWithMatchingAccounts; return this; } /** * Builds the {@link VirtualDeviceParams} instance. */ @NonNull public VirtualDeviceParams build() { if (mUsersWithMatchingAccounts == null) { mUsersWithMatchingAccounts = Collections.emptySet(); } return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts); } } }
services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +36 −19 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.companion.virtual; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; Loading @@ -27,9 +28,10 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.os.Build; import android.os.UserHandle; import android.util.ArraySet; import android.util.Slog; import android.window.DisplayWindowPolicyController; import java.util.HashSet; import java.util.List; Loading @@ -38,6 +40,8 @@ import java.util.List; */ class GenericWindowPolicyController extends DisplayWindowPolicyController { private static final String TAG = "VirtualDeviceManager"; /** * If required, allow the secure activity to display on remote device since * {@link android.os.Build.VERSION_CODES#TIRAMISU}. Loading @@ -45,10 +49,13 @@ 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 final HashSet<Integer> mRunningUids = new HashSet<>(); @NonNull final ArraySet<Integer> mRunningUids = new ArraySet<>(); GenericWindowPolicyController(int windowFlags, int systemWindowFlags) { GenericWindowPolicyController(int windowFlags, int systemWindowFlags, @NonNull ArraySet<UserHandle> allowedUsers) { mAllowedUsers = allowedUsers; setInterestedWindowFlags(windowFlags, systemWindowFlags); } Loading @@ -58,7 +65,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { final int activityCount = activities.size(); for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if ((aInfo.flags & ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { return false; } } Loading @@ -68,21 +75,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @Override public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { return false; } 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) { return false; } if ((systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { return false; } } return true; return canContainActivity(activityInfo, windowFlags, systemWindowFlags); } @Override Loading @@ -105,4 +98,28 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { boolean containsUid(int uid) { return mRunningUids.contains(uid); } private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { 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 (!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; } }