Merge "Show a warning toast when PiP is blocked in the streamed display"

This commit is contained in:
Iris Yang
2022-11-14 09:09:16 +00:00
committed by Android (Google) Code Review
10 changed files with 62 additions and 4 deletions

View File

@@ -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() + "}");

View File

@@ -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>

View File

@@ -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"/>

View File

@@ -85,6 +85,15 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
void onSecureWindowShown(int displayId, int uid);
}
/**
* 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.

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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 */));
}

View File

@@ -246,5 +246,10 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
public boolean canShowTasksInRecents() {
return true;
}
@Override
public boolean isEnteringPipAllowed(int uid) {
return true;
}
}
}