Support library workaround: switch to bluetooth route if available (DO NOT MERGE)
Bug: 10003524
Change-Id: I55c2da39ac312265b3a8bcc118d54057d3808f13
(cherry picked from commit 014127a0e1841120ee0968831d40728a80f16b00)
(cherry picked from commit a0db5749e35878f8372929c942d905c464ec1d43)
(cherry picked from commit 35af7c925d660508fe0892f38eec99a3845630e4)
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index a7f550e..47d8c9f 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -1637,10 +1637,20 @@
route.updateDescriptor(null);
// 2. Remove the route from the list.
mRoutes.remove(route);
- provider.mRoutes.remove(i);
// 3. Unselect route if needed before notifying about removal.
unselectRouteIfNeeded(route);
- // 4. Notify clients about removal.
+ }
+
+ // Choose a new selected route if needed.
+ selectRouteIfNeeded();
+
+ // Now notify clients about routes that were removed.
+ // We do this after updating the selected route to ensure
+ // that the framework media router observes the new route
+ // selection before the removal since removing the currently
+ // selected route may have side-effects.
+ for (int i = provider.mRoutes.size() - 1; i >= targetIndex; i--) {
+ RouteInfo route = provider.mRoutes.remove(i);
if (DEBUG) {
Log.d(TAG, "Route removed: " + route);
}
@@ -1652,9 +1662,6 @@
Log.d(TAG, "Provider changed: " + provider);
}
mCallbackHandler.post(CallbackHandler.MSG_PROVIDER_CHANGED, provider);
-
- // Choose a new selected route if needed.
- selectRouteIfNeeded();
}
}
@@ -1686,15 +1693,19 @@
private void unselectRouteIfNeeded(RouteInfo route) {
if (mDefaultRoute == route && !isRouteSelectable(route)) {
- Log.i(TAG, "Choosing a new default route because the current one "
+ Log.i(TAG, "Clearing the default route because it "
+ "is no longer selectable: " + route);
mDefaultRoute = null;
}
if (mSelectedRoute == route && !isRouteSelectable(route)) {
- Log.i(TAG, "Choosing a new selected route because the current one "
+ Log.i(TAG, "Clearing the selected route because it "
+ "is no longer selectable: " + route);
setSelectedRouteInternal(null);
}
+ // When this function terminates, the default or selected route
+ // may be null. The caller is responsible for invoking
+ // selectRouteIfNeeded() to choose new routes after it has
+ // finished applying any other necessary changes.
}
private void selectRouteIfNeeded() {
@@ -1707,10 +1718,31 @@
}
}
if (mSelectedRoute == null) {
- setSelectedRouteInternal(mDefaultRoute);
+ setSelectedRouteInternal(chooseFallbackRoute());
}
}
+ private RouteInfo chooseFallbackRoute() {
+ // When the current route is removed or no longer selectable,
+ // we want to revert to a live audio route if there is
+ // one (usually Bluetooth A2DP). Failing that, use
+ // the default route.
+ for (RouteInfo route : mRoutes) {
+ if (route != mDefaultRoute
+ && isSystemLiveAudioOnlyRoute(route)
+ && isRouteSelectable(route)) {
+ return route;
+ }
+ }
+ return mDefaultRoute;
+ }
+
+ private boolean isSystemLiveAudioOnlyRoute(RouteInfo route) {
+ return route.getProviderInstance() == mSystemProvider
+ && route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
+ && !route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO);
+ }
+
private boolean isRouteSelectable(RouteInfo route) {
// This tests whether the route is still valid and enabled.
// The route descriptor field is set to null when the route is removed.