Merge "Show a warning toast when PiP is blocked in the streamed display"
This commit is contained in:
@@ -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() + "}");
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */));
|
||||
}
|
||||
|
||||
@@ -246,5 +246,10 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
|
||||
public boolean canShowTasksInRecents() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnteringPipAllowed(int uid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user