summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/DisplayWindowPolicyController.java10
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java23
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java5
10 files changed, 62 insertions, 4 deletions
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java
index a5aefd5157ce..f55932eb05fd 100644
--- a/core/java/android/window/DisplayWindowPolicyController.java
+++ b/core/java/android/window/DisplayWindowPolicyController.java
@@ -16,6 +16,8 @@
package android.window;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
import android.annotation.NonNull;
import android.app.WindowConfiguration;
import android.content.ComponentName;
@@ -142,6 +144,14 @@ public abstract class DisplayWindowPolicyController {
*/
public void onRunningAppsChanged(ArraySet<Integer> runningUids) {}
+ /**
+ * This is called when an Activity is entering PIP.
+ * Returns {@code true} if the Activity is allowed to enter PIP.
+ */
+ public boolean isEnteringPipAllowed(int uid) {
+ return isWindowingModeSupported(WINDOWING_MODE_PINNED);
+ }
+
/** Dump debug data */
public void dump(String prefix, final PrintWriter pw) {
pw.println(prefix + "DisplayWindowPolicyController{" + super.toString() + "}");
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 48484c7d41f9..216975d2d2e6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6331,6 +6331,8 @@ ul.</string>
<string name="vdm_camera_access_denied" product="tablet">Can’t access the tablet’s camera from your <xliff:g id="device" example="Chromebook">%1$s</xliff:g></string>
<!-- Error message indicating the user cannot access secure content when running on a virtual device. [CHAR LIMIT=NONE] -->
<string name="vdm_secure_window">This can’t be accessed while streaming. Try on your phone instead.</string>
+ <!-- Error message indicating the user cannot view picture-in-picture when running on a virtual device. [CHAR LIMIT=NONE] -->
+ <string name="vdm_pip_blocked">Can’t view picture-in-picture while streaming</string>
<!-- Title for preference of the system default locale. [CHAR LIMIT=50]-->
<string name="system_locale_title">System default</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 375a2c01762c..5eb62919214c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4861,6 +4861,7 @@
<!-- For VirtualDeviceManager -->
<java-symbol type="string" name="vdm_camera_access_denied" />
<java-symbol type="string" name="vdm_secure_window" />
+ <java-symbol type="string" name="vdm_pip_blocked" />
<java-symbol type="color" name="camera_privacy_light_day"/>
<java-symbol type="color" name="camera_privacy_light_night"/>
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index 000bafe1d650..ce7854d7368a 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -86,6 +86,15 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
}
/**
+ * For communicating when activities are blocked from entering PIP on the display by this
+ * policy controller.
+ */
+ public interface PipBlockedCallback {
+ /** Called when an activity is blocked from entering PIP. */
+ void onEnteringPipBlocked(int uid);
+ }
+
+ /**
* If required, allow the secure activity to display on remote device since
* {@link android.os.Build.VERSION_CODES#TIRAMISU}.
*/
@@ -112,6 +121,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@GuardedBy("mGenericWindowPolicyControllerLock")
final ArraySet<Integer> mRunningUids = new ArraySet<>();
@Nullable private final ActivityListener mActivityListener;
+ @Nullable private final PipBlockedCallback mPipBlockedCallback;
private final Handler mHandler = new Handler(Looper.getMainLooper());
@NonNull
@GuardedBy("mGenericWindowPolicyControllerLock")
@@ -155,6 +165,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@NonNull Set<ComponentName> blockedActivities,
@ActivityPolicy int defaultActivityPolicy,
@NonNull ActivityListener activityListener,
+ @NonNull PipBlockedCallback pipBlockedCallback,
@NonNull ActivityBlockedCallback activityBlockedCallback,
@NonNull SecureWindowCallback secureWindowCallback,
@AssociationRequest.DeviceProfile String deviceProfile) {
@@ -169,6 +180,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
setInterestedWindowFlags(windowFlags, systemWindowFlags);
mActivityListener = activityListener;
mDeviceProfile = deviceProfile;
+ mPipBlockedCallback = pipBlockedCallback;
mSecureWindowCallback = secureWindowCallback;
}
@@ -317,6 +329,17 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
}
}
+ @Override
+ public boolean isEnteringPipAllowed(int uid) {
+ if (super.isEnteringPipAllowed(uid)) {
+ return true;
+ }
+ mHandler.post(() -> {
+ mPipBlockedCallback.onEnteringPipBlocked(uid);
+ });
+ return false;
+ }
+
/**
* Returns true if an app with the given UID has an activity running on the virtual display for
* this controller.
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 5ebbf07526f1..be2107529f8b 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -624,6 +624,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
mParams.getBlockedActivities(),
mParams.getDefaultActivityPolicy(),
createListenerAdapter(),
+ this::onEnteringPipBlocked,
this::onActivityBlocked,
this::onSecureWindowShown,
mAssociationInfo.getDeviceProfile());
@@ -779,6 +780,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
return mVirtualDisplayIds.contains(displayId);
}
+ void onEnteringPipBlocked(int uid) {
+ showToastWhereUidIsRunning(uid, com.android.internal.R.string.vdm_pip_blocked,
+ Toast.LENGTH_LONG, mContext.getMainLooper());
+ }
+
interface OnDeviceCloseListener {
void onClose(int associationId);
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e5401f509394..eba337594f26 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3131,8 +3131,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
// Check to see if PiP is supported for the display this container is on.
- if (mDisplayContent != null && !mDisplayContent.mDwpcHelper.isWindowingModeSupported(
- WINDOWING_MODE_PINNED)) {
+ if (mDisplayContent != null && !mDisplayContent.mDwpcHelper.isEnteringPipAllowed(
+ getUid())) {
Slog.w(TAG, "Display " + mDisplayContent.getDisplayId()
+ " doesn't support enter picture-in-picture mode. caller = " + caller);
return false;
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 5d4904264056..6f821b55e54a 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -162,6 +162,17 @@ class DisplayWindowPolicyControllerHelper {
return mDisplayWindowPolicyController.canShowTasksInRecents();
}
+ /**
+ * @see DisplayWindowPolicyController#isEnteringPipAllowed(int)
+ */
+ public final boolean isEnteringPipAllowed(int uid) {
+ if (mDisplayWindowPolicyController == null) {
+ return true;
+ }
+ return mDisplayWindowPolicyController.isEnteringPipAllowed(uid);
+ }
+
+
void dump(String prefix, PrintWriter pw) {
if (mDisplayWindowPolicyController != null) {
pw.println();
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index 4c939f077940..0262f564911b 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -82,6 +82,7 @@ public class VirtualAudioControllerTest {
/* blockedActivities= */ new ArraySet<>(),
VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED,
/* activityListener= */ null,
+ /* pipBlockedCallback= */ null,
/* activityBlockedCallback= */ null,
/* secureWindowCallback= */ null,
/* deviceProfile= */ DEVICE_PROFILE_APP_STREAMING);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 3a8e1ccce122..bd8da4e713b7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2284,8 +2284,7 @@ public class ActivityRecordTests extends WindowTestsBase {
doReturn(false).when(mAtm).shouldDisableNonVrUiLocked();
spyOn(mDisplayContent.mDwpcHelper);
- doReturn(false).when(mDisplayContent.mDwpcHelper).isWindowingModeSupported(
- WINDOWING_MODE_PINNED);
+ doReturn(false).when(mDisplayContent.mDwpcHelper).isEnteringPipAllowed(anyInt());
assertFalse(activity.checkEnterPictureInPictureState("TEST", false /* beforeStopping */));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index 21197baaf8cc..db1d15a4584a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -246,5 +246,10 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
public boolean canShowTasksInRecents() {
return true;
}
+
+ @Override
+ public boolean isEnteringPipAllowed(int uid) {
+ return true;
+ }
}
}