Merge "Close VirtualDevice when CDM association is removed" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
362ca09afc
@@ -126,7 +126,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
private final VirtualDeviceManagerService mService;
|
||||
private final PendingTrampolineCallback mPendingTrampolineCallback;
|
||||
private final int mOwnerUid;
|
||||
private final int mDeviceId;
|
||||
private int mDeviceId;
|
||||
// Thou shall not hold the mVirtualDeviceLock over the mInputController calls.
|
||||
// Holding the lock can lead to lock inversion with GlobalWindowManagerLock.
|
||||
// 1. After display is created the window manager calls into VDM during construction
|
||||
@@ -404,6 +404,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
super.close_enforcePermission();
|
||||
// Remove about-to-be-closed virtual device from the service before butchering it.
|
||||
mService.removeVirtualDevice(mDeviceId);
|
||||
mDeviceId = Context.DEVICE_ID_INVALID;
|
||||
|
||||
VirtualDisplayWrapper[] virtualDisplaysToBeReleased;
|
||||
synchronized (mVirtualDeviceLock) {
|
||||
|
||||
@@ -66,7 +66,9 @@ import com.android.server.wm.ActivityTaskManagerInternal;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
@@ -86,6 +88,14 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
private static AtomicInteger sNextUniqueIndex = new AtomicInteger(
|
||||
Context.DEVICE_ID_DEFAULT + 1);
|
||||
|
||||
private final CompanionDeviceManager.OnAssociationsChangedListener mCdmAssociationListener =
|
||||
new CompanionDeviceManager.OnAssociationsChangedListener() {
|
||||
@Override
|
||||
public void onAssociationsChanged(@NonNull List<AssociationInfo> associations) {
|
||||
syncVirtualDevicesToCdmAssociations(associations);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mapping from device IDs to virtual devices.
|
||||
*/
|
||||
@@ -204,11 +214,56 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
getContext().sendBroadcastAsUser(i, UserHandle.ALL);
|
||||
|
||||
synchronized (mVirtualDeviceManagerLock) {
|
||||
if (mVirtualDevices.size() == 0) {
|
||||
unregisterCdmAssociationListener();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncVirtualDevicesToCdmAssociations(List<AssociationInfo> associations) {
|
||||
Set<VirtualDeviceImpl> virtualDevicesToRemove = new HashSet<>();
|
||||
synchronized (mVirtualDeviceManagerLock) {
|
||||
if (mVirtualDevices.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> activeAssociationIds = new HashSet<>(associations.size());
|
||||
for (AssociationInfo association : associations) {
|
||||
activeAssociationIds.add(association.getId());
|
||||
}
|
||||
|
||||
for (int i = 0; i < mVirtualDevices.size(); i++) {
|
||||
VirtualDeviceImpl virtualDevice = mVirtualDevices.valueAt(i);
|
||||
if (!activeAssociationIds.contains(virtualDevice.getAssociationId())) {
|
||||
virtualDevicesToRemove.add(virtualDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (VirtualDeviceImpl virtualDevice : virtualDevicesToRemove) {
|
||||
virtualDevice.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void registerCdmAssociationListener() {
|
||||
final CompanionDeviceManager cdm = getContext().getSystemService(
|
||||
CompanionDeviceManager.class);
|
||||
cdm.addOnAssociationsChangedListener(getContext().getMainExecutor(),
|
||||
mCdmAssociationListener);
|
||||
}
|
||||
|
||||
private void unregisterCdmAssociationListener() {
|
||||
final CompanionDeviceManager cdm = getContext().getSystemService(
|
||||
CompanionDeviceManager.class);
|
||||
cdm.removeOnAssociationsChangedListener(mCdmAssociationListener);
|
||||
}
|
||||
|
||||
class VirtualDeviceManagerImpl extends IVirtualDeviceManager.Stub {
|
||||
|
||||
private final VirtualDeviceImpl.PendingTrampolineCallback mPendingTrampolineCallback =
|
||||
@@ -254,7 +309,17 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
if (associationInfo == null) {
|
||||
throw new IllegalArgumentException("No association with ID " + associationId);
|
||||
}
|
||||
|
||||
synchronized (mVirtualDeviceManagerLock) {
|
||||
if (mVirtualDevices.size() == 0) {
|
||||
final long callindId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
registerCdmAssociationListener();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(callindId);
|
||||
}
|
||||
}
|
||||
|
||||
final UserHandle userHandle = getCallingUserHandle();
|
||||
final CameraAccessController cameraAccessController =
|
||||
getCameraAccessController(userHandle);
|
||||
|
||||
Reference in New Issue
Block a user