Merge "Close VirtualDevice when CDM association is removed" into udc-dev

This commit is contained in:
TreeHugger Robot
2023-04-05 07:29:29 +00:00
committed by Android (Google) Code Review
2 changed files with 67 additions and 1 deletions

View File

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

View File

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