From ea1eaf74f3a0450d7d56947ea27f0cb1d2b46855 Mon Sep 17 00:00:00 2001 From: Sungsoo Lim Date: Wed, 12 Feb 2020 11:00:06 +0900 Subject: [PATCH] Remove code duplications Also prevent callback be called before SysMRP created Test: pass MediaRouter cts Change-Id: I0cde791fc73a33de5d42dcb6e550016644301ffd --- .../server/media/BluetoothRouteProvider.java | 23 ++- .../media/SystemMediaRoute2Provider.java | 163 +++++++----------- 2 files changed, 81 insertions(+), 105 deletions(-) diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index 8379614cf423a..33e01bd211055 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -166,6 +166,20 @@ class BluetoothRouteProvider { } } + @Nullable + MediaRoute2Info getSelectedRoute() { + return (mSelectedRoute == null) ? null : mSelectedRoute.route; + } + + @NonNull + List getTransferableRoutes() { + List routes = getAllBluetoothRoutes(); + if (mSelectedRoute != null) { + routes.remove(mSelectedRoute.route); + } + return routes; + } + @NonNull List getAllBluetoothRoutes() { ArrayList routes = new ArrayList<>(); @@ -175,9 +189,12 @@ class BluetoothRouteProvider { return routes; } - @Nullable - String getSelectedRouteId() { - return mSelectedRoute == null ? null : mSelectedRoute.route.getId(); + boolean setSelectedRouteVolume(int volume) { + if (mSelectedRoute == null) return false; + mSelectedRoute.route = new MediaRoute2Info.Builder(mSelectedRoute.route) + .setVolume(volume) + .build(); + return true; } private void notifyBluetoothRoutesUpdated() { diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 777a8fec34643..8e3811452cc18 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -19,7 +19,6 @@ package com.android.server.media; import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO; import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO; -import android.annotation.NonNull; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -42,15 +41,13 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.R; -import com.android.internal.annotations.GuardedBy; -import java.util.Collections; -import java.util.List; import java.util.Objects; /** * Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers. */ +// TODO: check thread safety. We may need to use lock to protect variables. class SystemMediaRoute2Provider extends MediaRoute2Provider { private static final String TAG = "MR2SystemProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -68,19 +65,16 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SystemMediaRoute2Provider.class.getPackageName$(), SystemMediaRoute2Provider.class.getName()); - @GuardedBy("mLock") private String mSelectedRouteId; MediaRoute2Info mDefaultRoute; - @NonNull List mBluetoothRoutes = Collections.EMPTY_LIST; final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo(); final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() { @Override public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) { - mHandler.post(new Runnable() { - @Override public void run() { - updateAudioRoutes(newRoutes); - } + mHandler.post(() -> { + updateDefaultRoute(newRoutes); + notifyProviderState(); }); } }; @@ -97,11 +91,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mAudioService = IAudioService.Stub.asInterface( ServiceManager.getService(Context.AUDIO_SERVICE)); + AudioRoutesInfo newAudioRoutes = null; + try { + newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver); + } catch (RemoteException e) { + } + updateDefaultRoute(newAudioRoutes); - initializeDefaultRoute(); mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> { - mBluetoothRoutes = routes; - publishRoutes(); + publishProviderState(); boolean sessionInfoChanged; synchronized (mLock) { @@ -111,7 +109,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { notifySessionInfoUpdated(); } }); - initializeSessionInfo(); + + mHandler.post(() -> notifyProviderState()); + + //TODO: clean up this + // This is required because it is not instantiated in the main thread and + // BluetoothRoutesUpdatedListener can be called before here + synchronized (mLock) { + updateSessionInfosIfNeededLocked(); + } mContext.registerReceiver(new VolumeChangeReceiver(), new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION)); @@ -164,65 +170,21 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { // Do nothing since we don't support grouping volume yet. } - private void initializeDefaultRoute() { - mDefaultRoute = new MediaRoute2Info.Builder( - DEFAULT_ROUTE_ID, - mContext.getResources().getText(R.string.default_audio_route_name).toString()) - .setVolumeHandling(mAudioManager.isVolumeFixed() - ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED - : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE) - .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)) - .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)) - .addFeature(FEATURE_LIVE_AUDIO) - .addFeature(FEATURE_LIVE_VIDEO) - .build(); - - AudioRoutesInfo newAudioRoutes = null; - try { - newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver); - } catch (RemoteException e) { - } - if (newAudioRoutes != null) { - // This will select the active BT route if there is one and the current - // selected route is the default system route, or if there is no selected - // route yet. - updateAudioRoutes(newAudioRoutes); - } - } - - private void initializeSessionInfo() { - mBluetoothRoutes = mBtRouteProvider.getAllBluetoothRoutes(); - - MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); - builder.addRoute(mDefaultRoute); - for (MediaRoute2Info route : mBluetoothRoutes) { - builder.addRoute(route); - } - setProviderState(builder.build()); - mHandler.post(() -> notifyProviderState()); - - //TODO: clean up this - // This is required because it is not instantiated in the main thread and - // BluetoothRoutesUpdatedListener can be called before this function - synchronized (mLock) { - updateSessionInfosIfNeededLocked(); - } - } - - private void updateAudioRoutes(AudioRoutesInfo newRoutes) { + private void updateDefaultRoute(AudioRoutesInfo newRoutes) { int name = R.string.default_audio_route_name; - mCurAudioRoutesInfo.mainType = newRoutes.mainType; - if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0 - || (newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) { - name = com.android.internal.R.string.default_audio_route_name_headphones; - } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) { - name = com.android.internal.R.string.default_audio_route_name_dock_speakers; - } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) { - name = com.android.internal.R.string.default_audio_route_name_hdmi; - } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) { - name = com.android.internal.R.string.default_audio_route_name_usb; + if (newRoutes != null) { + mCurAudioRoutesInfo.mainType = newRoutes.mainType; + if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0 + || (newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) { + name = com.android.internal.R.string.default_audio_route_name_headphones; + } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) { + name = com.android.internal.R.string.default_audio_route_name_dock_speakers; + } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) { + name = com.android.internal.R.string.default_audio_route_name_hdmi; + } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) { + name = com.android.internal.R.string.default_audio_route_name_usb; + } } - mDefaultRoute = new MediaRoute2Info.Builder( DEFAULT_ROUTE_ID, mContext.getResources().getText(name).toString()) .setVolumeHandling(mAudioManager.isVolumeFixed() @@ -232,9 +194,20 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)) .addFeature(FEATURE_LIVE_AUDIO) .addFeature(FEATURE_LIVE_VIDEO) + .setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED) .build(); + updateProviderState(); + } - publishRoutes(); + private void updateProviderState() { + MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); + builder.addRoute(mDefaultRoute); + if (mBtRouteProvider != null) { + for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) { + builder.addRoute(route); + } + } + setProviderState(builder.build()); } /** @@ -246,21 +219,21 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder( SYSTEM_SESSION_ID, "" /* clientPackageName */) .setSystemSession(true); - String activeBtDeviceAddress = mBtRouteProvider.getSelectedRouteId(); - mSelectedRouteId = TextUtils.isEmpty(activeBtDeviceAddress) ? mDefaultRoute.getId() - : activeBtDeviceAddress; - builder.addSelectedRoute(mSelectedRouteId); - if (!TextUtils.isEmpty(activeBtDeviceAddress)) { + MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute(); + if (selectedRoute == null) { + selectedRoute = mDefaultRoute; + } else { builder.addTransferableRoute(mDefaultRoute.getId()); } + mSelectedRouteId = selectedRoute.getId(); + builder.addSelectedRoute(mSelectedRouteId); - for (MediaRoute2Info route : mBluetoothRoutes) { - if (!TextUtils.equals(mSelectedRouteId, route.getId())) { - builder.addTransferableRoute(route.getId()); - } + for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { + builder.addTransferableRoute(route.getId()); } + RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build(); if (Objects.equals(oldSessionInfo, newSessionInfo)) { return false; @@ -271,13 +244,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } } - void publishRoutes() { - MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); - builder.addRoute(mDefaultRoute); - for (MediaRoute2Info route : mBluetoothRoutes) { - builder.addRoute(route); - } - setAndNotifyProviderState(builder.build()); + void publishProviderState() { + updateProviderState(); + notifyProviderState(); } void notifySessionInfoUpdated() { @@ -306,24 +275,14 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0); if (newVolume != oldVolume) { - String activeBtDeviceAddress = mBtRouteProvider.getSelectedRouteId(); - if (!TextUtils.isEmpty(activeBtDeviceAddress)) { - for (int i = mBluetoothRoutes.size() - 1; i >= 0; i--) { - MediaRoute2Info route = mBluetoothRoutes.get(i); - if (TextUtils.equals(activeBtDeviceAddress, route.getId())) { - mBluetoothRoutes.set(i, - new MediaRoute2Info.Builder(route) - .setVolume(newVolume) - .build()); - break; - } - } - } else { + if (TextUtils.equals(mDefaultRoute.getId(), mSelectedRouteId)) { mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute) .setVolume(newVolume) .build(); + } else { + mBtRouteProvider.setSelectedRouteVolume(newVolume); } - publishRoutes(); + publishProviderState(); } } }