diff options
4 files changed, 48 insertions, 8 deletions
diff --git a/core/tests/companiontests/src/android/companion/SystemDataTransportTest.java b/core/tests/companiontests/src/android/companion/SystemDataTransportTest.java index 73d7fe952af3..544ca56eb728 100644 --- a/core/tests/companiontests/src/android/companion/SystemDataTransportTest.java +++ b/core/tests/companiontests/src/android/companion/SystemDataTransportTest.java @@ -220,6 +220,36 @@ public class SystemDataTransportTest extends InstrumentationTestCase { assertEquals(0, out.toByteArray().length); } + public void testDisassociationCleanup() throws InterruptedException { + // Create a new association + final int associationId = createAssociation(); + + // Subscribe to transport updates for new association + final CountDownLatch attached = new CountDownLatch(1); + final CountDownLatch detached = new CountDownLatch(1); + mCdm.addOnTransportsChangedListener(Runnable::run, associations -> { + if (associations.stream() + .anyMatch(association -> associationId == association.getId())) { + attached.countDown(); + } else if (attached.getCount() == 0) { + detached.countDown(); + } + }); + + final ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + mCdm.attachSystemDataTransport(associationId, in, out); + + // Assert that the transport is attached + assertTrue(attached.await(1, TimeUnit.SECONDS)); + + // When CDM disassociates, any transport attached to that associated device should detach + mCdm.disassociate(associationId); + + // Assert that the transport is detached + assertTrue(detached.await(1, TimeUnit.SECONDS)); + } + public static byte[] concat(byte[]... blobs) { int length = 0; for (byte[] blob : blobs) { @@ -250,12 +280,14 @@ public class SystemDataTransportTest extends InstrumentationTestCase { } private int createAssociation() { + List<AssociationInfo> before = mCdm.getMyAssociations(); getInstrumentation().getUiAutomation().executeShellCommand("cmd companiondevice associate " + mContext.getUserId() + " " + mContext.getPackageName() + " AA:BB:CC:DD:EE:FF"); List<AssociationInfo> infos; for (int i = 0; i < 100; i++) { infos = mCdm.getMyAssociations(); - if (!infos.isEmpty()) { + if (infos.size() != before.size()) { + infos.removeAll(before); return infos.get(0).getId(); } else { SystemClock.sleep(100); diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index e4a1048e9faa..3846e981cbab 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -244,13 +244,14 @@ public class CompanionDeviceManagerService extends SystemService { context, mAssociationStore, mObservableUuidStore, mDevicePresenceMonitor, mPowerManagerInternal); + mTransportManager = new CompanionTransportManager(context, mAssociationStore); + mAssociationRevokeProcessor = new AssociationRevokeProcessor(this, mAssociationStore, mPackageManagerInternal, mDevicePresenceMonitor, mCompanionAppController, - mSystemDataTransferRequestStore); + mSystemDataTransferRequestStore, mTransportManager); loadAssociationsFromDisk(); - mTransportManager = new CompanionTransportManager(context, mAssociationStore); mSystemDataTransferProcessor = new SystemDataTransferProcessor(this, mPackageManagerInternal, mAssociationStore, mSystemDataTransferRequestStore, mTransportManager); diff --git a/services/companion/java/com/android/server/companion/association/AssociationRevokeProcessor.java b/services/companion/java/com/android/server/companion/association/AssociationRevokeProcessor.java index 490be0da593b..d1efbbcd3411 100644 --- a/services/companion/java/com/android/server/companion/association/AssociationRevokeProcessor.java +++ b/services/companion/java/com/android/server/companion/association/AssociationRevokeProcessor.java @@ -42,6 +42,7 @@ import com.android.server.companion.CompanionApplicationController; import com.android.server.companion.CompanionDeviceManagerService; import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import com.android.server.companion.presence.CompanionDevicePresenceMonitor; +import com.android.server.companion.transport.CompanionTransportManager; import java.util.HashMap; import java.util.Map; @@ -62,6 +63,7 @@ public class AssociationRevokeProcessor { private final @NonNull CompanionDevicePresenceMonitor mDevicePresenceMonitor; private final @NonNull SystemDataTransferRequestStore mSystemDataTransferRequestStore; private final @NonNull CompanionApplicationController mCompanionAppController; + private final @NonNull CompanionTransportManager mTransportManager; private final OnPackageVisibilityChangeListener mOnPackageVisibilityChangeListener; private final ActivityManager mActivityManager; @@ -97,7 +99,8 @@ public class AssociationRevokeProcessor { @NonNull PackageManagerInternal packageManager, @NonNull CompanionDevicePresenceMonitor devicePresenceMonitor, @NonNull CompanionApplicationController applicationController, - @NonNull SystemDataTransferRequestStore systemDataTransferRequestStore) { + @NonNull SystemDataTransferRequestStore systemDataTransferRequestStore, + @NonNull CompanionTransportManager companionTransportManager) { mService = service; mContext = service.getContext(); mActivityManager = mContext.getSystemService(ActivityManager.class); @@ -108,6 +111,7 @@ public class AssociationRevokeProcessor { mDevicePresenceMonitor = devicePresenceMonitor; mCompanionAppController = applicationController; mSystemDataTransferRequestStore = systemDataTransferRequestStore; + mTransportManager = companionTransportManager; } /** @@ -120,6 +124,9 @@ public class AssociationRevokeProcessor { final String packageName = association.getPackageName(); final String deviceProfile = association.getDeviceProfile(); + // Detach transport if exists + mTransportManager.detachSystemDataTransport(packageName, userId, associationId); + if (!maybeRemoveRoleHolderForAssociation(association)) { // Need to remove the app from list of the role holders, but will have to do it later // (the app is in foreground at the moment). diff --git a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java index 6dd14ac91a34..793fb7ff74b1 100644 --- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java +++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java @@ -153,12 +153,12 @@ public class CompanionTransportManager { public void detachSystemDataTransport(String packageName, int userId, int associationId) { synchronized (mTransports) { - final Transport transport = mTransports.get(associationId); - if (transport != null) { - mTransports.delete(associationId); - transport.stop(); + final Transport transport = mTransports.removeReturnOld(associationId); + if (transport == null) { + return; } + transport.stop(); notifyOnTransportsChanged(); } } |