MediaRouter2: Sync routes when first RouteCallback is registered
Bug: 149526397
Test: Passed CTS and mediaroutertest
Also checked logs that DEFAULT_ROUTE is not added.
Change-Id: Icc0a5f2ea8f93fd7baba132a9bd4a1f9d798bba9
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 (shouldReleaseSession && stub != null) {
|
||||
try {
|
||||
mMediaRouterService.releaseSessionWithRouter2(stub, getId());
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Unable to release session", ex);
|
||||
if (!mNonSystemRoutingControllers.remove(getId(), this)) {
|
||||
Log.w(TAG, "releaseInternal: Ignoring unknown controller.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldNotifyStop) {
|
||||
mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
|
||||
RoutingController.this));
|
||||
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 (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;
|
||||
}
|
||||
@@ -1414,6 +1496,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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user