summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/java/android/media/IMediaRouter2.aidl2
-rw-r--r--media/java/android/media/MediaRouter2.java127
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java23
3 files changed, 124 insertions, 28 deletions
diff --git a/media/java/android/media/IMediaRouter2.aidl b/media/java/android/media/IMediaRouter2.aidl
index a8b82ba401eb..ca14052c964f 100644
--- a/media/java/android/media/IMediaRouter2.aidl
+++ b/media/java/android/media/IMediaRouter2.aidl
@@ -24,6 +24,8 @@ import android.os.Bundle;
* @hide
*/
oneway interface IMediaRouter2 {
+ void notifyRouterRegistered(in List<MediaRoute2Info> currentRoutes,
+ in RoutingSessionInfo currentSystemSessionInfo);
void notifyRoutesAdded(in List<MediaRoute2Info> routes);
void notifyRoutesRemoved(in List<MediaRoute2Info> routes);
void notifyRoutesChanged(in List<MediaRoute2Info> routes);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 6634d4b4190e..20e26cd66e34 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -92,7 +92,7 @@ public final class MediaRouter2 {
MediaRouter2Stub mStub;
@GuardedBy("sRouterLock")
- private final Map<String, RoutingController> mRoutingControllers = new ArrayMap<>();
+ private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
private final AtomicInteger mControllerCreationRequestCnt = new AtomicInteger(1);
@@ -230,7 +230,7 @@ public final class MediaRouter2 {
Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.");
}
}
- if (mRouteCallbackRecords.size() == 0) {
+ if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()) {
try {
mMediaRouterService.unregisterRouter2(mStub);
} catch (RemoteException ex) {
@@ -470,7 +470,7 @@ public final class MediaRouter2 {
List<RoutingController> result = new ArrayList<>();
result.add(0, mSystemController);
synchronized (sRouterLock) {
- result.addAll(mRoutingControllers.values());
+ result.addAll(mNonSystemRoutingControllers.values());
}
return result;
}
@@ -500,6 +500,77 @@ public final class MediaRouter2 {
}
}
+ void syncRoutesOnHandler(List<MediaRoute2Info> currentRoutes,
+ RoutingSessionInfo currentSystemSessionInfo) {
+ if (currentRoutes == null || currentRoutes.isEmpty() || currentSystemSessionInfo == null) {
+ Log.e(TAG, "syncRoutesOnHandler: Received wrong data. currentRoutes=" + currentRoutes
+ + ", currentSystemSessionInfo=" + currentSystemSessionInfo);
+ return;
+ }
+
+ List<MediaRoute2Info> addedRoutes = new ArrayList<>();
+ List<MediaRoute2Info> removedRoutes = new ArrayList<>();
+ List<MediaRoute2Info> changedRoutes = new ArrayList<>();
+
+ synchronized (sRouterLock) {
+ List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
+ .collect(Collectors.toList());
+
+ for (String routeId : mRoutes.keySet()) {
+ if (!currentRoutesIds.contains(routeId)) {
+ // This route is removed while the callback is unregistered.
+ MediaRoute2Info route = mRoutes.get(routeId);
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ removedRoutes.add(mRoutes.get(routeId));
+ }
+ }
+ }
+
+ for (MediaRoute2Info route : currentRoutes) {
+ if (mRoutes.containsKey(route.getId())) {
+ if (!route.equals(mRoutes.get(route.getId()))) {
+ // This route is changed while the callback is unregistered.
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(
+ mDiscoveryPreference.getPreferredFeatures())) {
+ changedRoutes.add(route);
+ }
+ }
+ } else {
+ // This route is added while the callback is unregistered.
+ if (route.isSystemRoute()
+ || route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+ addedRoutes.add(route);
+ }
+ }
+ }
+
+ mRoutes.clear();
+ for (MediaRoute2Info route : currentRoutes) {
+ mRoutes.put(route.getId(), route);
+ }
+
+ mShouldUpdateRoutes = true;
+ }
+
+ if (addedRoutes.size() > 0) {
+ notifyRoutesAdded(addedRoutes);
+ }
+ if (removedRoutes.size() > 0) {
+ notifyRoutesRemoved(removedRoutes);
+ }
+ if (changedRoutes.size() > 0) {
+ notifyRoutesChanged(changedRoutes);
+ }
+
+ RoutingSessionInfo oldInfo = mSystemController.getRoutingSessionInfo();
+ mSystemController.setRoutingSessionInfo(currentSystemSessionInfo);
+ if (!oldInfo.equals(currentSystemSessionInfo)) {
+ notifyControllerUpdated(mSystemController);
+ }
+ }
+
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
// TODO(b/157874065): When onRoutesAdded is first called,
// 1) clear mRoutes before adding the routes
@@ -617,7 +688,7 @@ public final class MediaRouter2 {
} else {
newController = new RoutingController(sessionInfo);
synchronized (sRouterLock) {
- mRoutingControllers.put(newController.getId(), newController);
+ mNonSystemRoutingControllers.put(newController.getId(), newController);
}
}
@@ -645,7 +716,7 @@ public final class MediaRouter2 {
RoutingController matchingController;
synchronized (sRouterLock) {
- matchingController = mRoutingControllers.get(sessionInfo.getId());
+ matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
if (matchingController == null) {
@@ -674,7 +745,7 @@ public final class MediaRouter2 {
final String uniqueSessionId = sessionInfo.getId();
RoutingController matchingController;
synchronized (sRouterLock) {
- matchingController = mRoutingControllers.get(uniqueSessionId);
+ matchingController = mNonSystemRoutingControllers.get(uniqueSessionId);
}
if (matchingController == null) {
@@ -1232,23 +1303,34 @@ public final class MediaRouter2 {
mIsReleased = true;
}
- MediaRouter2Stub stub;
synchronized (sRouterLock) {
- mRoutingControllers.remove(getId(), this);
- stub = mStub;
- }
+ if (!mNonSystemRoutingControllers.remove(getId(), this)) {
+ Log.w(TAG, "releaseInternal: Ignoring unknown controller.");
+ return false;
+ }
- if (shouldReleaseSession && stub != null) {
- try {
- mMediaRouterService.releaseSessionWithRouter2(stub, getId());
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to release session", ex);
+ if (shouldReleaseSession && mStub != null) {
+ try {
+ mMediaRouterService.releaseSessionWithRouter2(mStub, getId());
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Unable to release session", ex);
+ }
}
- }
- if (shouldNotifyStop) {
- mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
- RoutingController.this));
+ if (shouldNotifyStop) {
+ mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
+ RoutingController.this));
+ }
+
+ if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()
+ && mStub != null) {
+ try {
+ mMediaRouterService.unregisterRouter2(mStub);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "releaseInternal: Unable to unregister media router.", ex);
+ }
+ mStub = null;
+ }
}
return true;
}
@@ -1415,6 +1497,13 @@ public final class MediaRouter2 {
class MediaRouter2Stub extends IMediaRouter2.Stub {
@Override
+ public void notifyRouterRegistered(List<MediaRoute2Info> currentRoutes,
+ RoutingSessionInfo currentSystemSessionInfo) {
+ mHandler.sendMessage(obtainMessage(MediaRouter2::syncRoutesOnHandler,
+ MediaRouter2.this, currentRoutes, currentSystemSessionInfo));
+ }
+
+ @Override
public void notifyRoutesAdded(List<MediaRoute2Info> routes) {
mHandler.sendMessage(obtainMessage(MediaRouter2::addRoutesOnHandler,
MediaRouter2.this, routes));
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 75a89a213052..0e997155e7af 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -584,7 +584,7 @@ class MediaRouter2ServiceImpl {
mAllRouterRecords.put(binder, routerRecord);
userRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyRoutesToRouter,
+ obtainMessage(UserHandler::notifyRouterRegistered,
userRecord.mHandler, routerRecord));
}
@@ -1769,8 +1769,8 @@ class MediaRouter2ServiceImpl {
}
}
- private void notifyRoutesToRouter(@NonNull RouterRecord routerRecord) {
- List<MediaRoute2Info> routes = new ArrayList<>();
+ private void notifyRouterRegistered(@NonNull RouterRecord routerRecord) {
+ List<MediaRoute2Info> currentRoutes = new ArrayList<>();
MediaRoute2ProviderInfo systemProviderInfo = null;
for (MediaRoute2ProviderInfo providerInfo : mLastProviderInfos) {
@@ -1780,27 +1780,32 @@ class MediaRouter2ServiceImpl {
systemProviderInfo = providerInfo;
continue;
}
- routes.addAll(providerInfo.getRoutes());
+ currentRoutes.addAll(providerInfo.getRoutes());
}
+ RoutingSessionInfo currentSystemSessionInfo;
if (routerRecord.mHasModifyAudioRoutingPermission) {
if (systemProviderInfo != null) {
- routes.addAll(systemProviderInfo.getRoutes());
+ currentRoutes.addAll(systemProviderInfo.getRoutes());
} else {
// This shouldn't happen.
Slog.w(TAG, "notifyRoutesToRouter: System route provider not found.");
}
+ currentSystemSessionInfo = mSystemProvider.getSessionInfos().get(0);
} else {
- routes.add(mSystemProvider.getDefaultRoute());
+ currentRoutes.add(mSystemProvider.getDefaultRoute());
+ currentSystemSessionInfo = mSystemProvider.getDefaultSessionInfo();
}
- if (routes.size() == 0) {
+ if (currentRoutes.size() == 0) {
return;
}
+
try {
- routerRecord.mRouter.notifyRoutesAdded(routes);
+ routerRecord.mRouter.notifyRouterRegistered(
+ currentRoutes, currentSystemSessionInfo);
} catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify all routes. Router probably died.", ex);
+ Slog.w(TAG, "Failed to notify router registered. Router probably died.", ex);
}
}