Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 350d7b42 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Clear routes when media router manager has no callback

This CL clears routes when the last callback of MediaRouter2Manager
is unregistered. By doing this, we can ensure
MediaRouter2Manager#getAvailableRoutes() returns correct routes
during at least a single callback is registered.

A test for the behavior is added as well.

This CL also fixed a bug that unregistering a callback from MediaRouter2
disconnects it when multiple callback is used.

Bug: 153515567
Test: atest mediaroutertest & cts test & manually
 using MediaRouter2Demo and Sample OutputSwitcher to see
 if forgotten BT device is correctly removed.
 (w/o this CL forgotten BT device remains)
Change-Id: I31a5001115f1f163c8971bbd906516551b860252
parent 9c5a02c2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -237,9 +237,9 @@ public final class MediaRouter2 {
                } catch (RemoteException ex) {
                    Log.e(TAG, "Unable to unregister media router.", ex);
                }
                mStub = null;
            }
            mShouldUpdateRoutes = true;
            mStub = null;
        }
    }

+9 −7
Original line number Diff line number Diff line
@@ -147,14 +147,16 @@ public final class MediaRouter2Manager {
        }

        synchronized (sLock) {
            if (mCallbackRecords.size() == 0 && mClient != null) {
            if (mCallbackRecords.size() == 0) {
                if (mClient != null) {
                    try {
                        mMediaRouterService.unregisterManager(mClient);
                    } catch (RemoteException ex) {
                        Log.e(TAG, "Unable to unregister media router manager", ex);
                    }
                //TODO: clear mRoutes?
                    mClient = null;
                }
                mRoutes.clear();
                mPreferredFeaturesMap.clear();
            }
        }
+50 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static com.android.mediaroutertest.StubMediaRoute2ProviderService.VOLUME_
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.assertTrue;

import android.content.Context;
@@ -160,6 +161,7 @@ public class MediaRouter2ManagerTest {
        });

        MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2);
        assertNotNull(routeToRemove);

        StubMediaRoute2ProviderService sInstance =
                StubMediaRoute2ProviderService.getInstance();
@@ -171,6 +173,52 @@ public class MediaRouter2ManagerTest {
        assertTrue(addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testGetRoutes_removedRoute_returnsCorrectRoutes() throws Exception {
        CountDownLatch addedLatch = new CountDownLatch(1);
        CountDownLatch removedLatch = new CountDownLatch(1);

        RouteCallback routeCallback = new RouteCallback() {
            // Used to ensure the removed route is added.
            @Override
            public void onRoutesAdded(List<MediaRoute2Info> routes) {
                if (removedLatch.getCount() > 0) {
                    return;
                }
                addedLatch.countDown();
            }

            @Override
            public void onRoutesRemoved(List<MediaRoute2Info> routes) {
                removedLatch.countDown();
            }
        };

        mRouter2.registerRouteCallback(mExecutor, routeCallback,
                new RouteDiscoveryPreference.Builder(FEATURES_ALL, true).build());
        mRouteCallbacks.add(routeCallback);

        Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
        MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2);
        assertNotNull(routeToRemove);

        StubMediaRoute2ProviderService sInstance =
                StubMediaRoute2ProviderService.getInstance();
        assertNotNull(sInstance);
        sInstance.removeRoute(ROUTE_ID2);

        // Wait until the route is removed.
        assertTrue(removedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));

        Map<String, MediaRoute2Info> newRoutes = waitAndGetRoutesWithManager(FEATURES_ALL);
        assertNull(newRoutes.get(ROUTE_ID2));

        // Revert the removal.
        sInstance.addRoute(routeToRemove);
        assertTrue(addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        mRouter2.unregisterRouteCallback(routeCallback);
    }

    /**
     * Tests if we get proper routes for application that has special route feature.
     */
@@ -475,8 +523,8 @@ public class MediaRouter2ManagerTest {
        MediaRouter2Manager.Callback managerCallback = new MediaRouter2Manager.Callback() {
            @Override
            public void onRoutesAdded(List<MediaRoute2Info> routes) {
                for (int i = 0; i < routes.size(); i++) {
                    if (!routes.get(i).isSystemRoute()) {
                for (MediaRoute2Info route : routes) {
                    if (!route.isSystemRoute()) {
                        addedLatch.countDown();
                        break;
                    }
+2 −2
Original line number Diff line number Diff line
@@ -65,9 +65,9 @@ public class StubMediaRoute2ProviderService extends MediaRoute2ProviderService {
    public static final String ROUTE_NAME_VARIABLE_VOLUME = "Variable Volume Route";

    public static final String FEATURE_SAMPLE =
            "com.android.mediarouteprovider.FEATURE_SAMPLE";
            "com.android.mediaroutertest.FEATURE_SAMPLE";
    public static final String FEATURE_SPECIAL =
            "com.android.mediarouteprovider.FEATURE_SPECIAL";
            "com.android.mediaroutertest..FEATURE_SPECIAL";

    Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
    Map<String, String> mRouteIdToSessionId = new HashMap<>();