From ddf140da1211e6a1ae568bb25fd9c5d6e108d1fc Mon Sep 17 00:00:00 2001 From: Sungsoo Lim Date: Wed, 25 Mar 2020 08:53:55 +0900 Subject: [PATCH] Differentiate the default route with the device route Default route denotes the route that will be selected by SystemMediaRoute2Provider by default. While the device route denotes the route that is currenctly active among the phone speaker and wired headsets. Also, some variables and methods are renamed for readability. Bug: 149796428 Test: pass MR2 tests Change-Id: I9133bb106ce6b509147e5f837cc30f229a762088 --- media/java/android/media/MediaRoute2Info.java | 36 +++++++++++++++++-- .../server/media/MediaRouter2ServiceImpl.java | 22 ++++++------ .../media/SystemMediaRoute2Provider.java | 32 ++++++++++------- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java index 998561316dd43..e5ad569bb24f4 100644 --- a/media/java/android/media/MediaRoute2Info.java +++ b/media/java/android/media/MediaRoute2Info.java @@ -663,8 +663,8 @@ public final class MediaRoute2Info implements Parcelable { } /** - * Constructor for builder to create {@link MediaRoute2Info} with - * existing {@link MediaRoute2Info} instance. + * Constructor for builder to create {@link MediaRoute2Info} with existing + * {@link MediaRoute2Info} instance. * * @param routeInfo the existing instance to copy data from. */ @@ -689,6 +689,38 @@ public final class MediaRoute2Info implements Parcelable { mProviderId = routeInfo.mProviderId; } + /** + * Constructor for builder to create {@link MediaRoute2Info} with existing + * {@link MediaRoute2Info} instance and replace ID with the given {@code id}. + * + * @param id The ID of the new route. Must not be empty. + * @param routeInfo the existing instance to copy data from. + * @hide + */ + public Builder(@NonNull String id, @NonNull MediaRoute2Info routeInfo) { + if (TextUtils.isEmpty(id)) { + throw new IllegalArgumentException("id must not be empty"); + } + Objects.requireNonNull(routeInfo, "routeInfo must not be null"); + + mId = id; + mName = routeInfo.mName; + mFeatures = new ArrayList<>(routeInfo.mFeatures); + mType = routeInfo.mType; + mIsSystem = routeInfo.mIsSystem; + mIconUri = routeInfo.mIconUri; + mDescription = routeInfo.mDescription; + mConnectionState = routeInfo.mConnectionState; + mClientPackageName = routeInfo.mClientPackageName; + mVolumeHandling = routeInfo.mVolumeHandling; + mVolumeMax = routeInfo.mVolumeMax; + mVolume = routeInfo.mVolume; + if (routeInfo.mExtras != null) { + mExtras = new Bundle(routeInfo.mExtras); + } + mProviderId = routeInfo.mProviderId; + } + /** * Adds a feature for the route. * @param feature a feature that the route has. May be one of predefined features diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 9bbbc3b93fd7b..6aae62ea3f18f 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -708,7 +708,7 @@ class MediaRouter2ServiceImpl { } List sessionInfos = new ArrayList<>(); - for (MediaRoute2Provider provider : managerRecord.mUserRecord.mHandler.mMediaProviders) { + for (MediaRoute2Provider provider : managerRecord.mUserRecord.mHandler.mRouteProviders) { sessionInfos.addAll(provider.getSessionInfos()); } return sessionInfos; @@ -1059,7 +1059,7 @@ class MediaRouter2ServiceImpl { //TODO: Make this thread-safe. private final SystemMediaRoute2Provider mSystemProvider; - private final ArrayList mMediaProviders = + private final ArrayList mRouteProviders = new ArrayList<>(); private final List mLastProviderInfos = new ArrayList<>(); @@ -1074,7 +1074,7 @@ class MediaRouter2ServiceImpl { mServiceRef = new WeakReference<>(service); mUserRecord = userRecord; mSystemProvider = new SystemMediaRoute2Provider(service.mContext, this); - mMediaProviders.add(mSystemProvider); + mRouteProviders.add(mSystemProvider); mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this, this, mUserRecord.mUserId); } @@ -1097,13 +1097,13 @@ class MediaRouter2ServiceImpl { @Override public void onAddProviderService(@NonNull MediaRoute2ProviderServiceProxy proxy) { proxy.setCallback(this); - mMediaProviders.add(proxy); + mRouteProviders.add(proxy); proxy.updateDiscoveryPreference(mUserRecord.mCompositeDiscoveryPreference); } @Override public void onRemoveProviderService(@NonNull MediaRoute2ProviderServiceProxy proxy) { - mMediaProviders.remove(proxy); + mRouteProviders.remove(proxy); } @Override @@ -1148,10 +1148,10 @@ class MediaRouter2ServiceImpl { //TODO: notify session info updates private void onProviderStateChangedOnHandler(@NonNull MediaRoute2Provider provider) { - int providerIndex = getProviderInfoIndex(provider.getUniqueId()); + int providerInfoIndex = getLastProviderInfoIndex(provider.getUniqueId()); MediaRoute2ProviderInfo providerInfo = provider.getProviderInfo(); MediaRoute2ProviderInfo prevInfo = - (providerIndex < 0) ? null : mLastProviderInfos.get(providerIndex); + (providerInfoIndex < 0) ? null : mLastProviderInfos.get(providerInfoIndex); if (Objects.equals(prevInfo, providerInfo)) return; @@ -1171,7 +1171,7 @@ class MediaRouter2ServiceImpl { this, getRouters(), new ArrayList<>(removedRoutes))); } } else { - mLastProviderInfos.set(providerIndex, providerInfo); + mLastProviderInfos.set(providerInfoIndex, providerInfo); List addedRoutes = new ArrayList<>(); List removedRoutes = new ArrayList<>(); List changedRoutes = new ArrayList<>(); @@ -1219,7 +1219,7 @@ class MediaRouter2ServiceImpl { } } - private int getProviderInfoIndex(@NonNull String providerId) { + private int getLastProviderInfoIndex(@NonNull String providerId) { for (int i = 0; i < mLastProviderInfos.size(); i++) { MediaRoute2ProviderInfo providerInfo = mLastProviderInfos.get(i); if (TextUtils.equals(providerInfo.getUniqueId(), providerId)) { @@ -1795,13 +1795,13 @@ class MediaRouter2ServiceImpl { new RouteDiscoveryPreference.Builder(discoveryPreferences) .build(); } - for (MediaRoute2Provider provider : mMediaProviders) { + for (MediaRoute2Provider provider : mRouteProviders) { provider.updateDiscoveryPreference(mUserRecord.mCompositeDiscoveryPreference); } } private MediaRoute2Provider findProvider(@Nullable String providerId) { - for (MediaRoute2Provider provider : mMediaProviders) { + for (MediaRoute2Provider provider : mRouteProviders) { if (TextUtils.equals(provider.getUniqueId(), providerId)) { return provider; } diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index c7d14e0afe7b0..c69787d602e28 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -54,6 +54,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE"; + static final String DEVICE_ROUTE_ID = "DEVICE_ROUTE"; static final String SYSTEM_SESSION_ID = "SYSTEM_SESSION"; private final AudioManager mAudioManager; @@ -67,14 +68,17 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SystemMediaRoute2Provider.class.getName()); private String mSelectedRouteId; + // For apps without MODIFYING_AUDIO_ROUTING permission. + // This should be the currently selected route. MediaRoute2Info mDefaultRoute; + MediaRoute2Info mDeviceRoute; final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo(); final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() { @Override public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) { mHandler.post(() -> { - updateDefaultRoute(newRoutes); + updateDeviceRoute(newRoutes); notifyProviderState(); }); } @@ -97,7 +101,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver); } catch (RemoteException e) { } - updateDefaultRoute(newAudioRoutes); + updateDeviceRoute(newAudioRoutes); mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> { publishProviderState(); @@ -109,7 +113,6 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } }); updateSessionInfosIfNeeded(); - mContext.registerReceiver(new VolumeChangeReceiver(), new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION)); @@ -150,7 +153,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override public void transferToRoute(long requestId, String sessionId, String routeId) { - if (TextUtils.equals(routeId, mDefaultRoute.getId())) { + if (TextUtils.equals(routeId, mDeviceRoute.getId())) { mBtRouteProvider.transferTo(null); } else { mBtRouteProvider.transferTo(routeId); @@ -170,7 +173,11 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { // Do nothing since we don't support grouping volume yet. } - private void updateDefaultRoute(AudioRoutesInfo newRoutes) { + public MediaRoute2Info getDefaultRoute() { + return mDefaultRoute; + } + + private void updateDeviceRoute(AudioRoutesInfo newRoutes) { int name = R.string.default_audio_route_name; if (newRoutes != null) { mCurAudioRoutesInfo.mainType = newRoutes.mainType; @@ -185,8 +192,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { name = com.android.internal.R.string.default_audio_route_name_usb; } } - mDefaultRoute = new MediaRoute2Info.Builder( - DEFAULT_ROUTE_ID, mContext.getResources().getText(name).toString()) + mDeviceRoute = new MediaRoute2Info.Builder( + DEVICE_ROUTE_ID, mContext.getResources().getText(name).toString()) .setVolumeHandling(mAudioManager.isVolumeFixed() ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE) @@ -203,7 +210,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private void updateProviderState() { MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); - builder.addRoute(mDefaultRoute); + builder.addRoute(mDeviceRoute); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) { builder.addRoute(route); @@ -228,11 +235,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute(); if (selectedRoute == null) { - selectedRoute = mDefaultRoute; + selectedRoute = mDeviceRoute; } else { - builder.addTransferableRoute(mDefaultRoute.getId()); + builder.addTransferableRoute(mDeviceRoute.getId()); } mSelectedRouteId = selectedRoute.getId(); + mDefaultRoute = new MediaRoute2Info.Builder(DEFAULT_ROUTE_ID, selectedRoute).build(); builder.addSelectedRoute(mSelectedRouteId); for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { @@ -282,8 +290,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0); if (newVolume != oldVolume) { - if (TextUtils.equals(mDefaultRoute.getId(), mSelectedRouteId)) { - mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute) + if (TextUtils.equals(mDeviceRoute.getId(), mSelectedRouteId)) { + mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute) .setVolume(newVolume) .build(); } else {