Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4c299fa authored by Iris Yang's avatar Iris Yang
Browse files

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

Add an API in DWPC to monitor the Pip is allowed in the streamed display
by policy controller. If not allowed, pop up a warning toast for user.

Bug: 229837382
Test: manually, atest WmTests:ActivityRecordTests
Change-Id: Id1f39e8b54cd9c388c49b3886b9e798144ba5bf1
parent 29a55b03
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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() + "}");
+2 −0
Original line number Diff line number Diff line
@@ -6345,6 +6345,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>
+1 −0
Original line number Diff line number Diff line
@@ -4857,6 +4857,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"/>
+23 −0
Original line number Diff line number Diff line
@@ -84,6 +84,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}.
@@ -111,6 +120,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());
    private final ArraySet<RunningAppsChangedListener> mRunningAppsChangedListener =
            new ArraySet<>();
@@ -152,6 +162,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) {
@@ -166,6 +177,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
        setInterestedWindowFlags(windowFlags, systemWindowFlags);
        mActivityListener = activityListener;
        mDeviceProfile = deviceProfile;
        mPipBlockedCallback = pipBlockedCallback;
        mSecureWindowCallback = secureWindowCallback;
    }

@@ -306,6 +318,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.
+6 −0
Original line number Diff line number Diff line
@@ -579,6 +579,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
                            mParams.getBlockedActivities(),
                            mParams.getDefaultActivityPolicy(),
                            createListenerAdapter(),
                            this::onEnteringPipBlocked,
                            this::onActivityBlocked,
                            this::onSecureWindowShown,
                            mAssociationInfo.getDeviceProfile());
@@ -734,6 +735,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);
    }
Loading