Merge "Manage scan requests in MediaRouter2Manager"

This commit is contained in:
TreeHugger Robot
2022-07-27 12:32:04 +00:00
committed by Android (Google) Code Review
4 changed files with 48 additions and 32 deletions

View File

@@ -48,6 +48,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@@ -124,6 +125,7 @@ public final class MediaRouter2 {
private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
private final AtomicBoolean mIsScanning = new AtomicBoolean(/* initialValue= */ false);
final Handler mHandler;
@@ -255,7 +257,9 @@ public final class MediaRouter2 {
@RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
public void startScan() {
if (isSystemRouter()) {
sManager.startScan();
if (!mIsScanning.getAndSet(true)) {
sManager.registerScanRequest();
}
}
}
@@ -281,7 +285,9 @@ public final class MediaRouter2 {
@RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
public void stopScan() {
if (isSystemRouter()) {
sManager.stopScan();
if (mIsScanning.getAndSet(false)) {
sManager.unregisterScanRequest();
}
}
}

View File

@@ -82,6 +82,7 @@ public final class MediaRouter2Manager {
@GuardedBy("sLock")
private Client mClient;
private final IMediaRouterService mMediaRouterService;
private final AtomicInteger mScanRequestCount = new AtomicInteger(/* initialValue= */ 0);
final Handler mHandler;
final CopyOnWriteArrayList<CallbackRecord> mCallbackRecords = new CopyOnWriteArrayList<>();
@@ -155,20 +156,17 @@ public final class MediaRouter2Manager {
}
/**
* Starts scanning remote routes.
* <p>
* Route discovery can happen even when the {@link #startScan()} is not called.
* This is because the scanning could be started before by other apps.
* Therefore, calling this method after calling {@link #stopScan()} does not necessarily mean
* that the routes found before are removed and added again.
* <p>
* Use {@link Callback} to get the route related events.
* <p>
* @see #stopScan()
* Registers a request to scan for remote routes.
*
* <p>Increases the count of active scanning requests. When the count transitions from zero to
* one, sends a request to the system server to start scanning.
*
* <p>Clients must {@link #unregisterScanRequest() unregister their scan requests} when scanning
* is no longer needed, to avoid unnecessary resource usage.
*/
public void startScan() {
Client client = getOrCreateClient();
if (client != null) {
public void registerScanRequest() {
if (mScanRequestCount.getAndIncrement() == 0) {
Client client = getOrCreateClient();
try {
mMediaRouterService.startScan(client);
} catch (RemoteException ex) {
@@ -178,21 +176,25 @@ public final class MediaRouter2Manager {
}
/**
* Stops scanning remote routes to reduce resource consumption.
* <p>
* Route discovery can be continued even after this method is called.
* This is because the scanning is only turned off when all the apps stop scanning.
* Therefore, calling this method does not necessarily mean the routes are removed.
* Also, for the same reason it does not mean that {@link Callback#onRoutesAdded(List)}
* is not called afterwards.
* <p>
* Use {@link Callback} to get the route related events.
* Unregisters a scan request made by {@link #registerScanRequest()}.
*
* @see #startScan()
* <p>Decreases the count of active scanning requests. When the count transitions from one to
* zero, sends a request to the system server to stop scanning.
*
* @throws IllegalStateException If called while there are no active scan requests.
*/
public void stopScan() {
Client client = getOrCreateClient();
if (client != null) {
public void unregisterScanRequest() {
if (mScanRequestCount.updateAndGet(
count -> {
if (count == 0) {
throw new IllegalStateException(
"No active scan requests to unregister.");
} else {
return --count;
}
})
== 0) {
Client client = getOrCreateClient();
try {
mMediaRouterService.stopScan(client);
} catch (RemoteException ex) {

View File

@@ -39,6 +39,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import android.Manifest;
@@ -121,7 +122,7 @@ public class MediaRouter2ManagerTest {
MediaRouter2ManagerTestActivity.startActivity(mContext);
mManager = MediaRouter2Manager.getInstance(mContext);
mManager.startScan();
mManager.registerScanRequest();
mRouter2 = MediaRouter2.getInstance(mContext);
// If we need to support thread pool executors, change this to thread pool executor.
@@ -152,7 +153,7 @@ public class MediaRouter2ManagerTest {
@After
public void tearDown() {
mManager.stopScan();
mManager.unregisterScanRequest();
// order matters (callbacks should be cleared at the last)
releaseAllSessions();
@@ -818,6 +819,13 @@ public class MediaRouter2ManagerTest {
assertFalse(failureLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
@Test
public void unregisterScanRequest_enforcesANonNegativeCount() {
mManager.unregisterScanRequest(); // One request was made in the test setup.
assertThrows(IllegalStateException.class, () -> mManager.unregisterScanRequest());
mManager.registerScanRequest(); // So that the cleanup doesn't fail.
}
/**
* Tests if getSelectableRoutes and getDeselectableRoutes filter routes based on
* selected routes

View File

@@ -92,14 +92,14 @@ public class InfoMediaManager extends MediaManager {
public void startScan() {
mMediaDevices.clear();
mRouterManager.registerCallback(mExecutor, mMediaRouterCallback);
mRouterManager.startScan();
mRouterManager.registerScanRequest();
refreshDevices();
}
@Override
public void stopScan() {
mRouterManager.unregisterCallback(mMediaRouterCallback);
mRouterManager.stopScan();
mRouterManager.unregisterScanRequest();
}
/**