Merge "Prevent deadlocks during VirtualDisplay creation" into tm-dev am: fc6eb70e0e
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18246032 Change-Id: Ieafea2c80f875c16215ed05f77c22ec7445fe8af Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -19,6 +19,8 @@ package android.companion.virtual;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.companion.virtual.IVirtualDeviceActivityListener;
|
||||
import android.companion.virtual.VirtualDeviceParams;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
|
||||
/**
|
||||
* Interface for communication between VirtualDeviceManager and VirtualDeviceManagerService.
|
||||
@@ -42,4 +44,16 @@ interface IVirtualDeviceManager {
|
||||
IVirtualDevice createVirtualDevice(
|
||||
in IBinder token, String packageName, int associationId,
|
||||
in VirtualDeviceParams params, in IVirtualDeviceActivityListener activityListener);
|
||||
|
||||
/**
|
||||
* Creates a virtual display owned by a particular virtual device.
|
||||
*
|
||||
* @param virtualDisplayConfig The configuration used in creating the display
|
||||
* @param callback A callback that receives display lifecycle events
|
||||
* @param virtualDevice The device that will own this display
|
||||
* @param packageName The package name of the calling app
|
||||
*/
|
||||
int createVirtualDisplay(in VirtualDisplayConfig virtualDisplayConfig,
|
||||
in IVirtualDisplayCallback callback, in IVirtualDevice virtualDevice,
|
||||
String packageName);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManager.VirtualDisplayFlag;
|
||||
import android.hardware.display.DisplayManagerGlobal;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.hardware.input.VirtualKeyboard;
|
||||
@@ -65,7 +67,7 @@ import java.util.function.IntConsumer;
|
||||
public final class VirtualDeviceManager {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String LOG_TAG = "VirtualDeviceManager";
|
||||
private static final String TAG = "VirtualDeviceManager";
|
||||
|
||||
private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS =
|
||||
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
|
||||
@@ -150,6 +152,7 @@ public final class VirtualDeviceManager {
|
||||
public static class VirtualDevice implements AutoCloseable {
|
||||
|
||||
private final Context mContext;
|
||||
private final IVirtualDeviceManager mService;
|
||||
private final IVirtualDevice mVirtualDevice;
|
||||
private final ArrayMap<ActivityListener, ActivityListenerDelegate> mActivityListeners =
|
||||
new ArrayMap<>();
|
||||
@@ -189,6 +192,7 @@ public final class VirtualDeviceManager {
|
||||
Context context,
|
||||
int associationId,
|
||||
VirtualDeviceParams params) throws RemoteException {
|
||||
mService = service;
|
||||
mContext = context.getApplicationContext();
|
||||
mVirtualDevice = service.createVirtualDevice(
|
||||
new Binder(),
|
||||
@@ -274,18 +278,23 @@ public final class VirtualDeviceManager {
|
||||
// TODO(b/205343547): Handle display groups properly instead of creating a new display
|
||||
// group for every new virtual display created using this API.
|
||||
// belongs to the same display group.
|
||||
DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
|
||||
// DisplayManager will call into VirtualDeviceManagerInternal to register the
|
||||
// created displays.
|
||||
return displayManager.createVirtualDisplay(
|
||||
mVirtualDevice,
|
||||
new VirtualDisplayConfig.Builder(
|
||||
getVirtualDisplayName(), width, height, densityDpi)
|
||||
.setSurface(surface)
|
||||
.setFlags(getVirtualDisplayFlags(flags))
|
||||
.build(),
|
||||
callback,
|
||||
executor);
|
||||
VirtualDisplayConfig config = new VirtualDisplayConfig.Builder(
|
||||
getVirtualDisplayName(), width, height, densityDpi)
|
||||
.setSurface(surface)
|
||||
.setFlags(getVirtualDisplayFlags(flags))
|
||||
.build();
|
||||
IVirtualDisplayCallback callbackWrapper =
|
||||
new DisplayManagerGlobal.VirtualDisplayCallback(callback, executor);
|
||||
final int displayId;
|
||||
try {
|
||||
displayId = mService.createVirtualDisplay(config, callbackWrapper, mVirtualDevice,
|
||||
mContext.getPackageName());
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
|
||||
return displayManager.createVirtualDisplayWrapper(config, mContext, callbackWrapper,
|
||||
displayId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,6 @@ import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.KeyguardManager;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -971,17 +970,8 @@ public final class DisplayManager {
|
||||
executor = new HandlerExecutor(
|
||||
Handler.createAsync(handler != null ? handler.getLooper() : Looper.myLooper()));
|
||||
}
|
||||
return mGlobal.createVirtualDisplay(mContext, projection, null /* virtualDevice */,
|
||||
virtualDisplayConfig, callback, executor, windowContext);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public VirtualDisplay createVirtualDisplay(@Nullable IVirtualDevice virtualDevice,
|
||||
@NonNull VirtualDisplayConfig virtualDisplayConfig,
|
||||
@Nullable VirtualDisplay.Callback callback,
|
||||
@Nullable Executor executor) {
|
||||
return mGlobal.createVirtualDisplay(mContext, null /* projection */, virtualDevice,
|
||||
virtualDisplayConfig, callback, executor, null);
|
||||
return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
|
||||
executor, windowContext);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.PropertyInvalidatedCache;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
@@ -586,18 +585,28 @@ public final class DisplayManagerGlobal {
|
||||
}
|
||||
|
||||
public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
|
||||
IVirtualDevice virtualDevice, @NonNull VirtualDisplayConfig virtualDisplayConfig,
|
||||
VirtualDisplay.Callback callback, @Nullable Executor executor,
|
||||
@Nullable Context windowContext) {
|
||||
@NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback,
|
||||
@Nullable Executor executor, @Nullable Context windowContext) {
|
||||
VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, executor);
|
||||
IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
|
||||
int displayId;
|
||||
try {
|
||||
displayId = mDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper,
|
||||
projectionToken, virtualDevice, context.getPackageName());
|
||||
projectionToken, context.getPackageName());
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
return createVirtualDisplayWrapper(virtualDisplayConfig, windowContext, callbackWrapper,
|
||||
displayId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a VirtualDisplay wrapper object for a newly created virtual display ; to be called
|
||||
* once the display has been created in system_server.
|
||||
*/
|
||||
@Nullable
|
||||
public VirtualDisplay createVirtualDisplayWrapper(VirtualDisplayConfig virtualDisplayConfig,
|
||||
Context windowContext, IVirtualDisplayCallback callbackWrapper, int displayId) {
|
||||
if (displayId < 0) {
|
||||
Log.e(TAG, "Could not create virtual display: " + virtualDisplayConfig.getName());
|
||||
return null;
|
||||
@@ -1050,7 +1059,10 @@ public final class DisplayManagerGlobal {
|
||||
}
|
||||
}
|
||||
|
||||
private final static class VirtualDisplayCallback extends IVirtualDisplayCallback.Stub {
|
||||
/**
|
||||
* Assists in dispatching VirtualDisplay lifecycle event callbacks on a given Executor.
|
||||
*/
|
||||
public static final class VirtualDisplayCallback extends IVirtualDisplayCallback.Stub {
|
||||
@Nullable private final VirtualDisplay.Callback mCallback;
|
||||
@Nullable private final Executor mExecutor;
|
||||
|
||||
@@ -1062,7 +1074,7 @@ public final class DisplayManagerGlobal {
|
||||
* @param executor The executor to call the {@code callback} on. Must not be {@code null} if
|
||||
* the callback is not {@code null}.
|
||||
*/
|
||||
VirtualDisplayCallback(VirtualDisplay.Callback callback, Executor executor) {
|
||||
public VirtualDisplayCallback(VirtualDisplay.Callback callback, Executor executor) {
|
||||
mCallback = callback;
|
||||
mExecutor = mCallback != null ? Objects.requireNonNull(executor) : null;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.hardware.display;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.graphics.Point;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Handler;
|
||||
@@ -59,6 +60,14 @@ public abstract class DisplayManagerInternal {
|
||||
public abstract void initPowerManagement(DisplayPowerCallbacks callbacks,
|
||||
Handler handler, SensorManager sensorManager);
|
||||
|
||||
/**
|
||||
* Called by the VirtualDeviceManagerService to create a VirtualDisplay owned by a
|
||||
* VirtualDevice.
|
||||
*/
|
||||
public abstract int createVirtualDisplay(VirtualDisplayConfig config,
|
||||
IVirtualDisplayCallback callback, IVirtualDevice virtualDevice,
|
||||
DisplayWindowPolicyController dwpc, String packageName);
|
||||
|
||||
/**
|
||||
* Called by the power manager to request a new power state.
|
||||
* <p>
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package android.hardware.display;
|
||||
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.graphics.Point;
|
||||
import android.hardware.display.BrightnessConfiguration;
|
||||
@@ -88,10 +87,10 @@ interface IDisplayManager {
|
||||
void requestColorMode(int displayId, int colorMode);
|
||||
|
||||
// Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
|
||||
// MediaProjection token or VirtualDevice for certain combinations of flags.
|
||||
// MediaProjection token for certain combinations of flags.
|
||||
int createVirtualDisplay(in VirtualDisplayConfig virtualDisplayConfig,
|
||||
in IVirtualDisplayCallback callback, in IMediaProjection projectionToken,
|
||||
in IVirtualDevice virtualDevice, String packageName);
|
||||
String packageName);
|
||||
|
||||
// No permissions required, but must be same Uid as the creator.
|
||||
void resizeVirtualDisplay(in IVirtualDisplayCallback token,
|
||||
|
||||
@@ -48,7 +48,6 @@ import com.android.internal.app.BlockedAppStreamingActivity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
/**
|
||||
@@ -66,6 +65,14 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
void onRunningAppsChanged(ArraySet<Integer> runningUids);
|
||||
}
|
||||
|
||||
/**
|
||||
* For communicating when activities are blocked from running on the display by this policy
|
||||
* controller.
|
||||
*/
|
||||
public interface ActivityBlockedCallback {
|
||||
/** Called when an activity is blocked.*/
|
||||
void onActivityBlocked(int displayId, ActivityInfo activityInfo);
|
||||
}
|
||||
private static final ComponentName BLOCKED_APP_STREAMING_COMPONENT =
|
||||
new ComponentName("android", BlockedAppStreamingActivity.class.getName());
|
||||
|
||||
@@ -89,7 +96,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
private final Object mGenericWindowPolicyControllerLock = new Object();
|
||||
@ActivityPolicy
|
||||
private final int mDefaultActivityPolicy;
|
||||
private final Consumer<ActivityInfo> mActivityBlockedCallback;
|
||||
private final ActivityBlockedCallback mActivityBlockedCallback;
|
||||
private int mDisplayId = Display.INVALID_DISPLAY;
|
||||
|
||||
@NonNull
|
||||
@GuardedBy("mGenericWindowPolicyControllerLock")
|
||||
@@ -98,6 +106,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private final ArraySet<RunningAppsChangedListener> mRunningAppsChangedListener =
|
||||
new ArraySet<>();
|
||||
@Nullable
|
||||
private final @AssociationRequest.DeviceProfile String mDeviceProfile;
|
||||
|
||||
/**
|
||||
@@ -119,8 +128,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
* {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_ALLOWED}
|
||||
* @param defaultActivityPolicy Whether activities are default allowed to be displayed or
|
||||
* blocked.
|
||||
* @param activityListener Activity listener to listen for activity changes. The display ID
|
||||
* is not populated in this callback and is always {@link Display#INVALID_DISPLAY}.
|
||||
* @param activityListener Activity listener to listen for activity changes.
|
||||
* @param activityBlockedCallback Callback that is called when an activity is blocked from
|
||||
* launching.
|
||||
* @param deviceProfile The {@link AssociationRequest.DeviceProfile} of this virtual device.
|
||||
@@ -133,7 +141,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
@NonNull Set<ComponentName> blockedActivities,
|
||||
@ActivityPolicy int defaultActivityPolicy,
|
||||
@NonNull ActivityListener activityListener,
|
||||
@NonNull Consumer<ActivityInfo> activityBlockedCallback,
|
||||
@NonNull ActivityBlockedCallback activityBlockedCallback,
|
||||
@AssociationRequest.DeviceProfile String deviceProfile) {
|
||||
super();
|
||||
mAllowedUsers = allowedUsers;
|
||||
@@ -148,6 +156,13 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
mDeviceProfile = deviceProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expected to be called once this object is associated with a newly created display.
|
||||
*/
|
||||
public void setDisplayId(int displayId) {
|
||||
mDisplayId = displayId;
|
||||
}
|
||||
|
||||
/** Register a listener for running applications changes. */
|
||||
public void registerRunningAppsChangedListener(@NonNull RunningAppsChangedListener listener) {
|
||||
mRunningAppsChangedListener.add(listener);
|
||||
@@ -169,7 +184,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
for (int i = 0; i < activityCount; i++) {
|
||||
final ActivityInfo aInfo = activities.get(i);
|
||||
if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) {
|
||||
mActivityBlockedCallback.accept(aInfo);
|
||||
mActivityBlockedCallback.onActivityBlocked(mDisplayId, aInfo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +206,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
}
|
||||
|
||||
if (!canContainActivity(activityInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) {
|
||||
mActivityBlockedCallback.accept(activityInfo);
|
||||
mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -201,14 +216,14 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
if (isNewTask && !mBlockedCrossTaskNavigations.isEmpty()
|
||||
&& mBlockedCrossTaskNavigations.contains(activityComponent)) {
|
||||
Slog.d(TAG, "Virtual device blocking cross task navigation of " + activityComponent);
|
||||
mActivityBlockedCallback.accept(activityInfo);
|
||||
mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
|
||||
return false;
|
||||
}
|
||||
if (isNewTask && !mAllowedCrossTaskNavigations.isEmpty()
|
||||
&& !mAllowedCrossTaskNavigations.contains(activityComponent)) {
|
||||
Slog.d(TAG, "Virtual device not allowing cross task navigation of "
|
||||
+ activityComponent);
|
||||
mActivityBlockedCallback.accept(activityInfo);
|
||||
mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -220,7 +235,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
|
||||
int systemWindowFlags) {
|
||||
if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) {
|
||||
mActivityBlockedCallback.accept(activityInfo);
|
||||
mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -234,7 +249,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
if (mActivityListener != null && topActivity != null) {
|
||||
// Post callback on the main thread so it doesn't block activity launching
|
||||
mHandler.post(() ->
|
||||
mActivityListener.onTopActivityChanged(Display.INVALID_DISPLAY, topActivity));
|
||||
mActivityListener.onTopActivityChanged(mDisplayId, topActivity));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +260,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
mRunningUids.addAll(runningUids);
|
||||
if (mActivityListener != null && mRunningUids.isEmpty()) {
|
||||
// Post callback on the main thread so it doesn't block activity launching
|
||||
mHandler.post(() -> mActivityListener.onDisplayEmpty(Display.INVALID_DISPLAY));
|
||||
mHandler.post(() -> mActivityListener.onDisplayEmpty(mDisplayId));
|
||||
}
|
||||
}
|
||||
mHandler.post(() -> {
|
||||
@@ -257,7 +272,10 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
|
||||
|
||||
@Override
|
||||
public boolean canShowTasksInRecents() {
|
||||
// TODO(b/234075973) : Remove this once proper API is ready.
|
||||
if (mDeviceProfile == null) {
|
||||
return true;
|
||||
}
|
||||
// TODO(b/234075973) : Remove this once proper API is ready.
|
||||
switch (mDeviceProfile) {
|
||||
case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION:
|
||||
return false;
|
||||
|
||||
@@ -64,7 +64,6 @@ import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
import android.window.DisplayWindowPolicyController;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -110,11 +109,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
@GuardedBy("mVirtualDeviceLock")
|
||||
private boolean mDefaultShowPointerIcon = true;
|
||||
|
||||
private ActivityListener createListenerAdapter(int displayId) {
|
||||
private ActivityListener createListenerAdapter() {
|
||||
return new ActivityListener() {
|
||||
|
||||
@Override
|
||||
public void onTopActivityChanged(int unusedDisplayId, ComponentName topActivity) {
|
||||
public void onTopActivityChanged(int displayId, ComponentName topActivity) {
|
||||
try {
|
||||
mActivityListener.onTopActivityChanged(displayId, topActivity);
|
||||
} catch (RemoteException e) {
|
||||
@@ -123,7 +122,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayEmpty(int unusedDisplayId) {
|
||||
public void onDisplayEmpty(int displayId) {
|
||||
try {
|
||||
mActivityListener.onDisplayEmpty(displayId);
|
||||
} catch (RemoteException e) {
|
||||
@@ -529,24 +528,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
mInputController.dump(fout);
|
||||
}
|
||||
|
||||
DisplayWindowPolicyController onVirtualDisplayCreatedLocked(int displayId) {
|
||||
GenericWindowPolicyController createWindowPolicyController() {
|
||||
synchronized (mVirtualDeviceLock) {
|
||||
if (mVirtualDisplayIds.contains(displayId)) {
|
||||
throw new IllegalStateException(
|
||||
"Virtual device already have a virtual display with ID " + displayId);
|
||||
}
|
||||
mVirtualDisplayIds.add(displayId);
|
||||
mInputController.setShowPointerIcon(mDefaultShowPointerIcon, displayId);
|
||||
mInputController.setPointerAcceleration(1f, displayId);
|
||||
mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false,
|
||||
displayId);
|
||||
mInputController.setLocalIme(displayId);
|
||||
|
||||
// Since we're being called in the middle of the display being created, we post a
|
||||
// task to grab the wakelock instead of doing it synchronously here, to avoid
|
||||
// reentrancy problems.
|
||||
mContext.getMainThreadHandler().post(() -> addWakeLockForDisplay(displayId));
|
||||
|
||||
final GenericWindowPolicyController gwpc =
|
||||
new GenericWindowPolicyController(FLAG_SECURE,
|
||||
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
|
||||
@@ -556,19 +539,36 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
mParams.getAllowedActivities(),
|
||||
mParams.getBlockedActivities(),
|
||||
mParams.getDefaultActivityPolicy(),
|
||||
createListenerAdapter(displayId),
|
||||
activityInfo -> onActivityBlocked(displayId, activityInfo),
|
||||
createListenerAdapter(),
|
||||
this::onActivityBlocked,
|
||||
mAssociationInfo.getDeviceProfile());
|
||||
gwpc.registerRunningAppsChangedListener(/* listener= */ this);
|
||||
mWindowPolicyControllers.put(displayId, gwpc);
|
||||
return gwpc;
|
||||
}
|
||||
}
|
||||
|
||||
void addWakeLockForDisplay(int displayId) {
|
||||
void onVirtualDisplayCreatedLocked(GenericWindowPolicyController gwpc, int displayId) {
|
||||
synchronized (mVirtualDeviceLock) {
|
||||
if (!mVirtualDisplayIds.contains(displayId)
|
||||
|| mPerDisplayWakelocks.containsKey(displayId)) {
|
||||
if (displayId == Display.INVALID_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
if (mVirtualDisplayIds.contains(displayId)) {
|
||||
throw new IllegalStateException(
|
||||
"Virtual device already has a virtual display with ID " + displayId);
|
||||
}
|
||||
mVirtualDisplayIds.add(displayId);
|
||||
|
||||
gwpc.setDisplayId(displayId);
|
||||
mWindowPolicyControllers.put(displayId, gwpc);
|
||||
|
||||
mInputController.setShowPointerIcon(mDefaultShowPointerIcon, displayId);
|
||||
mInputController.setPointerAcceleration(1f, displayId);
|
||||
mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false,
|
||||
displayId);
|
||||
mInputController.setLocalIme(displayId);
|
||||
|
||||
|
||||
if (mPerDisplayWakelocks.containsKey(displayId)) {
|
||||
Slog.e(TAG, "Not creating wakelock for displayId " + displayId);
|
||||
return;
|
||||
}
|
||||
@@ -576,8 +576,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
|
||||
PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
|
||||
TAG + ":" + displayId, displayId);
|
||||
wakeLock.acquire();
|
||||
mPerDisplayWakelocks.put(displayId, wakeLock);
|
||||
wakeLock.acquire();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ import android.companion.virtual.IVirtualDeviceManager;
|
||||
import android.companion.virtual.VirtualDeviceManager;
|
||||
import android.companion.virtual.VirtualDeviceParams;
|
||||
import android.content.Context;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.display.IVirtualDisplayCallback;
|
||||
import android.hardware.display.VirtualDisplayConfig;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
@@ -41,9 +45,9 @@ import android.util.ExceptionUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.widget.Toast;
|
||||
import android.window.DisplayWindowPolicyController;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.companion.virtual.VirtualDeviceImpl.PendingTrampoline;
|
||||
@@ -203,6 +207,7 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
class VirtualDeviceManagerImpl extends IVirtualDeviceManager.Stub implements
|
||||
VirtualDeviceImpl.PendingTrampolineCallback {
|
||||
|
||||
@@ -265,6 +270,50 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
|
||||
IVirtualDisplayCallback callback, IVirtualDevice virtualDevice, String packageName)
|
||||
throws RemoteException {
|
||||
final int callingUid = getCallingUid();
|
||||
if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
|
||||
throw new SecurityException(
|
||||
"Package name " + packageName + " does not belong to calling uid "
|
||||
+ callingUid);
|
||||
}
|
||||
VirtualDeviceImpl virtualDeviceImpl;
|
||||
synchronized (mVirtualDeviceManagerLock) {
|
||||
virtualDeviceImpl = mVirtualDevices.get(virtualDevice.getAssociationId());
|
||||
if (virtualDeviceImpl == null) {
|
||||
throw new SecurityException("Invalid VirtualDevice");
|
||||
}
|
||||
}
|
||||
if (virtualDeviceImpl.getOwnerUid() != callingUid) {
|
||||
throw new SecurityException(
|
||||
"uid " + callingUid
|
||||
+ " is not the owner of the supplied VirtualDevice");
|
||||
}
|
||||
GenericWindowPolicyController gwpc;
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
gwpc = virtualDeviceImpl.createWindowPolicyController();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
|
||||
DisplayManagerInternal displayManager = getLocalService(
|
||||
DisplayManagerInternal.class);
|
||||
int displayId = displayManager.createVirtualDisplay(virtualDisplayConfig, callback,
|
||||
virtualDevice, gwpc, packageName);
|
||||
|
||||
final long tokenTwo = Binder.clearCallingIdentity();
|
||||
try {
|
||||
virtualDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, displayId);
|
||||
return displayId;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(tokenTwo);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private AssociationInfo getAssociationInfo(String packageName, int associationId) {
|
||||
final int callingUserId = getCallingUserHandle().getIdentifier();
|
||||
@@ -336,14 +385,6 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayWindowPolicyController onVirtualDisplayCreated(IVirtualDevice virtualDevice,
|
||||
int displayId) {
|
||||
synchronized (mVirtualDeviceManagerLock) {
|
||||
return ((VirtualDeviceImpl) virtualDevice).onVirtualDisplayCreatedLocked(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVirtualDisplayRemoved(IVirtualDevice virtualDevice, int displayId) {
|
||||
synchronized (mVirtualDeviceManagerLock) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.server.companion.virtual;
|
||||
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.window.DisplayWindowPolicyController;
|
||||
|
||||
/**
|
||||
* Virtual device manager local service interface.
|
||||
@@ -30,17 +29,6 @@ public abstract class VirtualDeviceManagerInternal {
|
||||
*/
|
||||
public abstract boolean isValidVirtualDevice(IVirtualDevice virtualDevice);
|
||||
|
||||
/**
|
||||
* Notify a virtual display is created.
|
||||
*
|
||||
* @param virtualDevice The virtual device where the virtual display located.
|
||||
* @param displayId The display id of the created virtual display.
|
||||
*
|
||||
* @return The {@link DisplayWindowPolicyController} of the virtual device.
|
||||
*/
|
||||
public abstract DisplayWindowPolicyController onVirtualDisplayCreated(
|
||||
IVirtualDevice virtualDevice, int displayId);
|
||||
|
||||
/**
|
||||
* Notify a virtual display is removed.
|
||||
*
|
||||
|
||||
@@ -1231,7 +1231,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
|
||||
private int createVirtualDisplayInternal(VirtualDisplayConfig virtualDisplayConfig,
|
||||
IVirtualDisplayCallback callback, IMediaProjection projection,
|
||||
IVirtualDevice virtualDevice, String packageName) {
|
||||
IVirtualDevice virtualDevice, DisplayWindowPolicyController dwpc, String packageName) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
if (!validatePackageName(callingUid, packageName)) {
|
||||
throw new SecurityException("packageName must match the calling uid");
|
||||
@@ -1351,8 +1351,13 @@ public final class DisplayManagerService extends SystemService {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mSyncRoot) {
|
||||
return createVirtualDisplayLocked(callback, projection, virtualDevice, callingUid,
|
||||
final int displayId = createVirtualDisplayLocked(callback, projection, callingUid,
|
||||
packageName, surface, flags, virtualDisplayConfig);
|
||||
if (displayId != Display.INVALID_DISPLAY && virtualDevice != null && dwpc != null) {
|
||||
mDisplayWindowPolicyControllers.put(displayId,
|
||||
Pair.create(virtualDevice, dwpc));
|
||||
}
|
||||
return displayId;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
@@ -1360,8 +1365,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private int createVirtualDisplayLocked(IVirtualDisplayCallback callback,
|
||||
IMediaProjection projection, IVirtualDevice virtualDevice,
|
||||
int callingUid, String packageName, Surface surface,
|
||||
IMediaProjection projection, int callingUid, String packageName, Surface surface,
|
||||
int flags, VirtualDisplayConfig virtualDisplayConfig) {
|
||||
if (mVirtualDisplayAdapter == null) {
|
||||
Slog.w(TAG, "Rejecting request to create private virtual display "
|
||||
@@ -1389,16 +1393,7 @@ public final class DisplayManagerService extends SystemService {
|
||||
|
||||
final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
|
||||
if (display != null) {
|
||||
final int displayId = display.getDisplayIdLocked();
|
||||
if (virtualDevice != null) {
|
||||
final VirtualDeviceManagerInternal vdm =
|
||||
getLocalService(VirtualDeviceManagerInternal.class);
|
||||
final DisplayWindowPolicyController controller =
|
||||
vdm.onVirtualDisplayCreated(virtualDevice, displayId);
|
||||
mDisplayWindowPolicyControllers.put(displayId,
|
||||
Pair.create(virtualDevice, controller));
|
||||
}
|
||||
return displayId;
|
||||
return display.getDisplayIdLocked();
|
||||
}
|
||||
|
||||
// Something weird happened and the logical display was not created.
|
||||
@@ -3066,9 +3061,9 @@ public final class DisplayManagerService extends SystemService {
|
||||
@Override // Binder call
|
||||
public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
|
||||
IVirtualDisplayCallback callback, IMediaProjection projection,
|
||||
IVirtualDevice virtualDeviceToken, String packageName) {
|
||||
String packageName) {
|
||||
return createVirtualDisplayInternal(virtualDisplayConfig, callback, projection,
|
||||
virtualDeviceToken, packageName);
|
||||
null, null, packageName);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
@@ -3534,7 +3529,8 @@ public final class DisplayManagerService extends SystemService {
|
||||
return !Float.isNaN(refreshRate) && (refreshRate > 0.0f);
|
||||
}
|
||||
|
||||
private final class LocalService extends DisplayManagerInternal {
|
||||
@VisibleForTesting
|
||||
final class LocalService extends DisplayManagerInternal {
|
||||
|
||||
@Override
|
||||
public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
|
||||
@@ -3549,6 +3545,14 @@ public final class DisplayManagerService extends SystemService {
|
||||
mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int createVirtualDisplay(VirtualDisplayConfig config,
|
||||
IVirtualDisplayCallback callback, IVirtualDevice virtualDevice,
|
||||
DisplayWindowPolicyController dwpc, String packageName) {
|
||||
return createVirtualDisplayInternal(config, callback, null, virtualDevice, dwpc,
|
||||
packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestPowerState(int groupId, DisplayPowerRequest request,
|
||||
boolean waitForNegativeProximity) {
|
||||
|
||||
@@ -228,36 +228,36 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void onVirtualDisplayRemovedLocked_doesNotThrowException() {
|
||||
final int displayId = 2;
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
// This call should not throw any exceptions.
|
||||
mDeviceImpl.onVirtualDisplayRemovedLocked(displayId);
|
||||
mDeviceImpl.onVirtualDisplayRemovedLocked(DISPLAY_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onVirtualDisplayCreatedLocked_wakeLockIsAcquired() throws RemoteException {
|
||||
final int displayId = 2;
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
|
||||
verify(mIPowerManagerMock, never()).acquireWakeLock(any(Binder.class), anyInt(),
|
||||
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
|
||||
nullable(String.class), anyInt(), eq(null));
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(any(Binder.class), anyInt(),
|
||||
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
|
||||
nullable(String.class), eq(displayId), eq(null));
|
||||
nullable(String.class), eq(DISPLAY_ID), eq(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onVirtualDisplayCreatedLocked_duplicateCalls_onlyOneWakeLockIsAcquired()
|
||||
throws RemoteException {
|
||||
final int displayId = 2;
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.createWindowPolicyController();
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> mDeviceImpl.onVirtualDisplayCreatedLocked(displayId));
|
||||
() -> mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID));
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(any(Binder.class), anyInt(),
|
||||
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
|
||||
nullable(String.class), eq(displayId), eq(null));
|
||||
nullable(String.class), eq(DISPLAY_ID), eq(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -269,30 +269,30 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void onVirtualDisplayRemovedLocked_wakeLockIsReleased() throws RemoteException {
|
||||
final int displayId = 2;
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
ArgumentCaptor<IBinder> wakeLockCaptor = ArgumentCaptor.forClass(IBinder.class);
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(wakeLockCaptor.capture(),
|
||||
anyInt(),
|
||||
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
|
||||
nullable(String.class), eq(displayId), eq(null));
|
||||
nullable(String.class), eq(DISPLAY_ID), eq(null));
|
||||
|
||||
IBinder wakeLock = wakeLockCaptor.getValue();
|
||||
mDeviceImpl.onVirtualDisplayRemovedLocked(displayId);
|
||||
mDeviceImpl.onVirtualDisplayRemovedLocked(DISPLAY_ID);
|
||||
verify(mIPowerManagerMock, Mockito.times(1)).releaseWakeLock(eq(wakeLock), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addVirtualDisplay_displayNotReleased_wakeLockIsReleased() throws RemoteException {
|
||||
final int displayId = 2;
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
ArgumentCaptor<IBinder> wakeLockCaptor = ArgumentCaptor.forClass(IBinder.class);
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(wakeLockCaptor.capture(),
|
||||
anyInt(),
|
||||
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
|
||||
nullable(String.class), eq(displayId), eq(null));
|
||||
nullable(String.class), eq(DISPLAY_ID), eq(null));
|
||||
IBinder wakeLock = wakeLockCaptor.getValue();
|
||||
|
||||
// Close the VirtualDevice without first notifying it of the VirtualDisplay removal.
|
||||
@@ -416,7 +416,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void onAudioSessionStarting_hasVirtualAudioController() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
|
||||
mDeviceImpl.onAudioSessionStarting(DISPLAY_ID, mRoutingCallback, mConfigChangedCallback);
|
||||
|
||||
@@ -425,7 +426,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void onAudioSessionEnded_noVirtualAudioController() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
mDeviceImpl.onAudioSessionStarting(DISPLAY_ID, mRoutingCallback, mConfigChangedCallback);
|
||||
|
||||
mDeviceImpl.onAudioSessionEnded();
|
||||
@@ -435,7 +437,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void close_cleanVirtualAudioController() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
mDeviceImpl.onAudioSessionStarting(DISPLAY_ID, mRoutingCallback, mConfigChangedCallback);
|
||||
|
||||
mDeviceImpl.close();
|
||||
@@ -659,7 +662,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void openNonBlockedAppOnVirtualDisplay_doesNotStartBlockedAlertActivity() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
|
||||
DISPLAY_ID);
|
||||
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
|
||||
@@ -677,7 +681,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void openPermissionControllerOnVirtualDisplay_startBlockedAlertActivity() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
|
||||
DISPLAY_ID);
|
||||
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
|
||||
@@ -695,7 +700,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void openSettingsOnVirtualDisplay_startBlockedAlertActivity() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
|
||||
DISPLAY_ID);
|
||||
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
|
||||
@@ -713,7 +719,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void openVendingOnVirtualDisplay_startBlockedAlertActivity() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
|
||||
DISPLAY_ID);
|
||||
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
|
||||
@@ -731,7 +738,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void openGoogleDialerOnVirtualDisplay_startBlockedAlertActivity() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
|
||||
DISPLAY_ID);
|
||||
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
|
||||
@@ -749,7 +757,8 @@ public class VirtualDeviceManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void openGoogleMapsOnVirtualDisplay_startBlockedAlertActivity() {
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
|
||||
mDeviceImpl.onVirtualDisplayCreatedLocked(
|
||||
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
|
||||
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
|
||||
DISPLAY_ID);
|
||||
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.hardware.display.BrightnessConfiguration;
|
||||
import android.hardware.display.Curve;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManagerGlobal;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.display.DisplayViewport;
|
||||
import android.hardware.display.DisplayedContentSample;
|
||||
import android.hardware.display.DisplayedContentSamplingAttributes;
|
||||
@@ -63,6 +64,7 @@ import android.view.DisplayEventReceiver;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.DisplayWindowPolicyController;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@@ -220,7 +222,7 @@ public class DisplayManagerServiceTest {
|
||||
builder.setUniqueId(uniqueId);
|
||||
builder.setFlags(flags);
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
null /* projection */, PACKAGE_NAME);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
@@ -346,7 +348,7 @@ public class DisplayManagerServiceTest {
|
||||
builder.setFlags(flags);
|
||||
builder.setUniqueId(uniqueId);
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
null /* projection */, PACKAGE_NAME);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
@@ -586,8 +588,7 @@ public class DisplayManagerServiceTest {
|
||||
VIRTUAL_DISPLAY_NAME, width, height, dpi);
|
||||
builder.setUniqueId(uniqueId);
|
||||
final int firstDisplayId = binderService.createVirtualDisplay(builder.build(),
|
||||
mMockAppToken /* callback */, null /* projection */, null /* virtualDeviceToken */,
|
||||
PACKAGE_NAME);
|
||||
mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
|
||||
|
||||
// The second virtual display requests to mirror the first virtual display.
|
||||
final String uniqueId2 = "uniqueId --- displayIdToMirrorTest #2";
|
||||
@@ -598,7 +599,7 @@ public class DisplayManagerServiceTest {
|
||||
builder2.setDisplayIdToMirror(firstDisplayId);
|
||||
final int secondDisplayId = binderService.createVirtualDisplay(builder2.build(),
|
||||
mMockAppToken2 /* callback */, null /* projection */,
|
||||
null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
PACKAGE_NAME);
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
// flush the handler
|
||||
@@ -636,8 +637,7 @@ public class DisplayManagerServiceTest {
|
||||
builder.setSurface(surface);
|
||||
builder.setUniqueId(uniqueId);
|
||||
final int displayId = binderService.createVirtualDisplay(builder.build(),
|
||||
mMockAppToken /* callback */, null /* projection */, null /* virtualDeviceToken */,
|
||||
PACKAGE_NAME);
|
||||
mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
|
||||
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
|
||||
@@ -669,7 +669,7 @@ public class DisplayManagerServiceTest {
|
||||
builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
|
||||
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
null /* projection */, PACKAGE_NAME);
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
|
||||
DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
|
||||
@@ -700,7 +700,7 @@ public class DisplayManagerServiceTest {
|
||||
|
||||
try {
|
||||
bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
null /* projection */, PACKAGE_NAME);
|
||||
fail("Creating virtual display with VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP without "
|
||||
+ "ADD_TRUSTED_DISPLAY permission should throw SecurityException.");
|
||||
} catch (SecurityException e) {
|
||||
@@ -716,6 +716,8 @@ public class DisplayManagerServiceTest {
|
||||
public void testOwnDisplayGroup_allowCreationWithVirtualDevice() {
|
||||
DisplayManagerService displayManager =
|
||||
new DisplayManagerService(mContext, mBasicInjector);
|
||||
DisplayManagerInternal localService = displayManager.new LocalService();
|
||||
|
||||
registerDefaultDisplays(displayManager);
|
||||
|
||||
DisplayManagerService.BinderService bs = displayManager.new BinderService();
|
||||
@@ -733,8 +735,9 @@ public class DisplayManagerServiceTest {
|
||||
when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
|
||||
.thenReturn(true);
|
||||
|
||||
int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
|
||||
null /* projection */, virtualDevice /* virtualDeviceToken */, PACKAGE_NAME);
|
||||
int displayId = localService.createVirtualDisplay(builder.build(),
|
||||
mMockAppToken /* callback */, virtualDevice /* virtualDeviceToken */,
|
||||
mock(DisplayWindowPolicyController.class), PACKAGE_NAME);
|
||||
displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
|
||||
displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
|
||||
DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
|
||||
|
||||
Reference in New Issue
Block a user