diff options
| author | 2019-11-19 07:16:23 +0000 | |
|---|---|---|
| committer | 2019-11-19 07:16:23 +0000 | |
| commit | bff5f30f0431ebb2040cf4fa2871f2a82540319e (patch) | |
| tree | 54f55c0dcd9d753616ffab19d7149c7cb57f710b | |
| parent | db32920931b5bc903282efbc62cc75f1f890452c (diff) | |
| parent | cfa8f9ab6181d4c9c32da4d1ea769f1be6655072 (diff) | |
Merge "MediaRouter: Add SystemMediaRoute2Provider to publish default route"
5 files changed, 335 insertions, 66 deletions
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java index 240e7d1b6357..d0f7c780ceb2 100644 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java @@ -82,6 +82,11 @@ public class MediaRouterManagerTest { public static final String CATEGORY_SPECIAL = "com.android.mediarouteprovider.CATEGORY_SPECIAL"; + // system routes + private static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE"; + private static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO"; + private static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO"; + private static final int TIMEOUT_MS = 5000; private Context mContext; @@ -90,13 +95,17 @@ public class MediaRouterManagerTest { private Executor mExecutor; private String mPackageName; - private static final List<String> CONTROL_CATEGORIES_ALL = new ArrayList(); - private static final List<String> CONTROL_CATEGORIES_SPECIAL = new ArrayList(); + private static final List<String> CATEGORIES_ALL = new ArrayList(); + private static final List<String> CATEGORIES_SPECIAL = new ArrayList(); + private static final List<String> CATEGORIES_LIVE_AUDIO = new ArrayList<>(); static { - CONTROL_CATEGORIES_ALL.add(CATEGORY_SAMPLE); - CONTROL_CATEGORIES_ALL.add(CATEGORY_SPECIAL); + CATEGORIES_ALL.add(CATEGORY_SAMPLE); + CATEGORIES_ALL.add(CATEGORY_SPECIAL); + CATEGORIES_ALL.add(CATEGORY_LIVE_AUDIO); + + CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL); - CONTROL_CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL); + CATEGORIES_LIVE_AUDIO.add(CATEGORY_LIVE_AUDIO); } @Before @@ -153,7 +162,7 @@ public class MediaRouterManagerTest { mRouter2.registerCallback(mExecutor, routerCallback); Map<String, MediaRoute2Info> routes = - waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL); + waitAndGetRoutesWithManager(CATEGORIES_ALL); CountDownLatch latch = new CountDownLatch(1); MediaRouter2Manager.Callback callback = new MediaRouter2Manager.Callback() { @@ -187,7 +196,7 @@ public class MediaRouterManagerTest { mManager.registerCallback(mExecutor, mockCallback); Map<String, MediaRoute2Info> routes = - waitAndGetRoutesWithManager(CONTROL_CATEGORIES_SPECIAL); + waitAndGetRoutesWithManager(CATEGORIES_SPECIAL); Assert.assertEquals(1, routes.size()); Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY)); @@ -203,7 +212,7 @@ public class MediaRouterManagerTest { MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class); mRouter2.registerCallback(mExecutor, mockCallback); - Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CONTROL_CATEGORIES_SPECIAL); + Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_SPECIAL); Assert.assertEquals(1, routes.size()); Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY)); @@ -219,7 +228,7 @@ public class MediaRouterManagerTest { mManager.registerCallback(mExecutor, managerCallback); mRouter2.registerCallback(mExecutor, routerCallback); - Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL); + Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL); MediaRoute2Info routeToSelect = routes.get(ROUTE_ID1); assertNotNull(routeToSelect); @@ -242,7 +251,7 @@ public class MediaRouterManagerTest { mRouter2.registerCallback(mExecutor, routerCallback); - Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL); + Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL); awaitOnRouteChangedManager( () -> mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1)), @@ -264,7 +273,7 @@ public class MediaRouterManagerTest { @Test public void testControlVolumeWithRouter() throws Exception { - Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CONTROL_CATEGORIES_ALL); + Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_ALL); MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME); int originalVolume = volRoute.getVolume(); @@ -286,7 +295,7 @@ public class MediaRouterManagerTest { MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class); mRouter2.registerCallback(mExecutor, mockCallback); - Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CONTROL_CATEGORIES_ALL); + Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL); MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME); int originalVolume = volRoute.getVolume(); @@ -309,7 +318,7 @@ public class MediaRouterManagerTest { public void testVolumeHandling() throws Exception { MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class); mRouter2.registerCallback(mExecutor, mockCallback); - Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CONTROL_CATEGORIES_ALL); + Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_ALL); MediaRoute2Info fixedVolumeRoute = routes.get(ROUTE_ID_FIXED_VOLUME); MediaRoute2Info variableVolumeRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME); @@ -321,6 +330,13 @@ public class MediaRouterManagerTest { mRouter2.unregisterCallback(mockCallback); } + @Test + public void testDefaultRoute() throws Exception { + Map<String, MediaRoute2Info> routes = waitAndGetRoutes(CATEGORIES_LIVE_AUDIO); + + assertNotNull(routes.get(DEFAULT_ROUTE_ID)); + } + Map<String, MediaRoute2Info> waitAndGetRoutes(List<String> controlCategories) throws Exception { CountDownLatch latch = new CountDownLatch(1); MediaRouter2.Callback callback = new MediaRouter2.Callback() { @@ -417,6 +433,7 @@ public class MediaRouterManagerTest { static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) { Map<String, MediaRoute2Info> routeMap = new HashMap<>(); for (MediaRoute2Info route : routes) { + // intentionally not route.getUniqueId() for convenience. routeMap.put(route.getId(), route); } return routeMap; diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java new file mode 100644 index 000000000000..91c9253269a3 --- /dev/null +++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java @@ -0,0 +1,82 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.media; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.Intent; +import android.media.MediaRoute2Info; +import android.media.MediaRoute2ProviderInfo; + +import java.util.Objects; + +abstract class MediaRoute2Provider { + final ComponentName mComponentName; + final String mUniqueId; + + private Callback mCallback; + private MediaRoute2ProviderInfo mProviderInfo; + + MediaRoute2Provider(@NonNull ComponentName componentName) { + mComponentName = Objects.requireNonNull(componentName, "Component name must not be null."); + mUniqueId = componentName.flattenToShortString(); + } + + public void setCallback(MediaRoute2ProviderProxy.Callback callback) { + mCallback = callback; + } + + public abstract void requestSelectRoute(String packageName, String routeId, int seq); + public abstract void unselectRoute(String packageName, String routeId); + public abstract void sendControlRequest(MediaRoute2Info route, Intent request); + public abstract void requestSetVolume(MediaRoute2Info route, int volume); + public abstract void requestUpdateVolume(MediaRoute2Info route, int delta); + + @NonNull + public String getUniqueId() { + return mUniqueId; + } + + @Nullable + public MediaRoute2ProviderInfo getProviderInfo() { + return mProviderInfo; + } + + void setAndNotifyProviderInfo(MediaRoute2ProviderInfo info) { + //TODO: check if info is not updated + if (info == null) { + mProviderInfo = null; + } else { + mProviderInfo = new MediaRoute2ProviderInfo.Builder(info) + .setUniqueId(mUniqueId) + .build(); + } + if (mCallback != null) { + mCallback.onProviderStateChanged(this); + } + } + + public boolean hasComponentName(String packageName, String className) { + return mComponentName.getPackageName().equals(packageName) + && mComponentName.getClassName().equals(className); + } + + public interface Callback { + void onProviderStateChanged(MediaRoute2Provider provider); + } +} diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java index 51a0df33bc65..3b6580ad7357 100644 --- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java +++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java @@ -17,7 +17,6 @@ package com.android.server.media; import android.annotation.NonNull; -import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -42,20 +41,14 @@ import java.util.Objects; /** * Maintains a connection to a particular media route provider service. */ -final class MediaRoute2ProviderProxy implements ServiceConnection { +final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements ServiceConnection { private static final String TAG = "MR2ProviderProxy"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final Context mContext; - private final ComponentName mComponentName; - private final String mUniqueId; private final int mUserId; private final Handler mHandler; - private Callback mCallback; - - private MediaRoute2ProviderInfo mProviderInfo; - // Connection state private boolean mRunning; private boolean mBound; @@ -64,9 +57,8 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { MediaRoute2ProviderProxy(@NonNull Context context, @NonNull ComponentName componentName, int userId) { + super(componentName); mContext = Objects.requireNonNull(context, "Context must not be null."); - mComponentName = Objects.requireNonNull(componentName, "Component name must not be null."); - mUniqueId = componentName.flattenToShortString(); mUserId = userId; mHandler = new Handler(); } @@ -80,10 +72,7 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { pw.println(prefix + " mConnectionReady=" + mConnectionReady); } - public void setCallback(Callback callback) { - mCallback = callback; - } - + @Override public void requestSelectRoute(String packageName, String routeId, int seq) { if (mConnectionReady) { mActiveConnection.requestSelectRoute(packageName, routeId, seq); @@ -91,6 +80,7 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { } } + @Override public void unselectRoute(String packageName, String routeId) { if (mConnectionReady) { mActiveConnection.unselectRoute(packageName, routeId); @@ -98,6 +88,7 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { } } + @Override public void sendControlRequest(MediaRoute2Info route, Intent request) { if (mConnectionReady) { mActiveConnection.sendControlRequest(route.getId(), request); @@ -105,6 +96,7 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { } } + @Override public void requestSetVolume(MediaRoute2Info route, int volume) { if (mConnectionReady) { mActiveConnection.requestSetVolume(route.getId(), volume); @@ -112,6 +104,7 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { } } + @Override public void requestUpdateVolume(MediaRoute2Info route, int delta) { if (mConnectionReady) { mActiveConnection.requestUpdateVolume(route.getId(), delta); @@ -119,16 +112,6 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { } } - @NonNull - public String getUniqueId() { - return mUniqueId; - } - - @Nullable - public MediaRoute2ProviderInfo getProviderInfo() { - return mProviderInfo; - } - public boolean hasComponentName(String packageName, String className) { return mComponentName.getPackageName().equals(packageName) && mComponentName.getClassName().equals(className); @@ -270,20 +253,6 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { setAndNotifyProviderInfo(info); } - private void setAndNotifyProviderInfo(MediaRoute2ProviderInfo info) { - //TODO: check if info is not updated - if (info == null) { - mProviderInfo = null; - } else { - mProviderInfo = new MediaRoute2ProviderInfo.Builder(info) - .setUniqueId(mUniqueId) - .build(); - } - if (mCallback != null) { - mCallback.onProviderStateChanged(MediaRoute2ProviderProxy.this); - } - } - private void disconnect() { if (mActiveConnection != null) { mConnectionReady = false; @@ -298,10 +267,6 @@ final class MediaRoute2ProviderProxy implements ServiceConnection { return "Service connection " + mComponentName.flattenToShortString(); } - public interface Callback { - void onProviderStateChanged(@NonNull MediaRoute2ProviderProxy provider); - } - private final class Connection implements DeathRecipient { private final IMediaRoute2Provider mProvider; private final ProviderClient mClient; diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index adfb9cb0964e..7820cd705193 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -728,14 +728,15 @@ class MediaRouter2ServiceImpl { static final class UserHandler extends Handler implements MediaRoute2ProviderWatcher.Callback, - MediaRoute2ProviderProxy.Callback { + MediaRoute2Provider.Callback { private final WeakReference<MediaRouter2ServiceImpl> mServiceRef; private final UserRecord mUserRecord; private final MediaRoute2ProviderWatcher mWatcher; //TODO: Make this thread-safe. - private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders = + private final SystemMediaRoute2Provider mSystemProvider; + private final ArrayList<MediaRoute2Provider> mMediaProviders = new ArrayList<>(); private final List<MediaRoute2ProviderInfo> mProviderInfos = new ArrayList<>(); @@ -746,6 +747,8 @@ class MediaRouter2ServiceImpl { super(Looper.getMainLooper(), null, true); mServiceRef = new WeakReference<>(service); mUserRecord = userRecord; + mSystemProvider = new SystemMediaRoute2Provider(service.mContext, this); + mMediaProviders.add(mSystemProvider); mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this, this, mUserRecord.mUserId); } @@ -777,7 +780,7 @@ class MediaRouter2ServiceImpl { } @Override - public void onProviderStateChanged(@NonNull MediaRoute2ProviderProxy provider) { + public void onProviderStateChanged(@NonNull MediaRoute2Provider provider) { sendMessage(PooledLambda.obtainMessage(UserHandler::updateProvider, this, provider)); } @@ -790,7 +793,7 @@ class MediaRouter2ServiceImpl { controlHints, seq)); } - private void updateProvider(MediaRoute2ProviderProxy provider) { + private void updateProvider(MediaRoute2Provider provider) { int providerIndex = getProviderInfoIndex(provider.getUniqueId()); MediaRoute2ProviderInfo providerInfo = provider.getProviderInfo(); MediaRoute2ProviderInfo prevInfo = @@ -954,7 +957,7 @@ class MediaRouter2ServiceImpl { private void requestSelectRoute(String clientPackageName, MediaRoute2Info route, int seq) { if (route != null) { - MediaRoute2ProviderProxy provider = findProvider(route.getProviderId()); + MediaRoute2Provider provider = findProvider(route.getProviderId()); if (provider == null) { Slog.w(TAG, "Ignoring to select route of unknown provider " + route); } else { @@ -965,7 +968,7 @@ class MediaRouter2ServiceImpl { private void unselectRoute(String clientPackageName, MediaRoute2Info route) { if (route != null) { - MediaRoute2ProviderProxy provider = findProvider(route.getProviderId()); + MediaRoute2Provider provider = findProvider(route.getProviderId()); if (provider == null) { Slog.w(TAG, "Ignoring to unselect route of unknown provider " + route); } else { @@ -975,21 +978,21 @@ class MediaRouter2ServiceImpl { } private void sendControlRequest(MediaRoute2Info route, Intent request) { - final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId()); + final MediaRoute2Provider provider = findProvider(route.getProviderId()); if (provider != null) { provider.sendControlRequest(route, request); } } private void requestSetVolume(MediaRoute2Info route, int volume) { - final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId()); + final MediaRoute2Provider provider = findProvider(route.getProviderId()); if (provider != null) { provider.requestSetVolume(route, volume); } } private void requestUpdateVolume(MediaRoute2Info route, int delta) { - final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId()); + final MediaRoute2Provider provider = findProvider(route.getProviderId()); if (provider != null) { provider.requestUpdateVolume(route, delta); } @@ -1153,8 +1156,8 @@ class MediaRouter2ServiceImpl { } } - private MediaRoute2ProviderProxy findProvider(String providerId) { - for (MediaRoute2ProviderProxy provider : mMediaProviders) { + private MediaRoute2Provider findProvider(String providerId) { + for (MediaRoute2Provider provider : mMediaProviders) { 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 new file mode 100644 index 000000000000..13ded61f6fd7 --- /dev/null +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -0,0 +1,202 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.media; + +import android.annotation.NonNull; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.media.AudioRoutesInfo; +import android.media.IAudioRoutesObserver; +import android.media.IAudioService; +import android.media.MediaRoute2Info; +import android.media.MediaRoute2ProviderInfo; +import android.os.Handler; +import android.os.Looper; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.text.TextUtils; +import android.util.Log; + +import com.android.internal.R; + +/** + * Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers. + */ +class SystemMediaRoute2Provider extends MediaRoute2Provider { + private static final String TAG = "MR2SystemProvider"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + private static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE"; + private static final String BLUETOOTH_ROUTE_ID = "BLUETOOTH_ROUTE"; + + // TODO: Move these to a proper place + public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO"; + public static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO"; + + private final AudioManager mAudioManager; + private final IAudioService mAudioService; + private final Handler mHandler; + private final Context mContext; + + private static ComponentName sComponentName = new ComponentName( + SystemMediaRoute2Provider.class.getPackageName$(), + SystemMediaRoute2Provider.class.getName()); + + //TODO: Clean up these when audio manager support multiple bt devices + MediaRoute2Info mDefaultRoute; + MediaRoute2Info mBluetoothA2dpRoute; + 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); + } + }); + } + }; + + SystemMediaRoute2Provider(Context context, Callback callback) { + super(sComponentName); + setCallback(callback); + + mContext = context; + mHandler = new Handler(Looper.getMainLooper()); + + mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + mAudioService = IAudioService.Stub.asInterface( + ServiceManager.getService(Context.AUDIO_SERVICE)); + + initializeRoutes(); + } + + //TODO: implement method + @Override + public void requestSelectRoute(@NonNull String packageName, @NonNull String routeId, int seq) { + try { + mAudioService.setBluetoothA2dpOn( + !TextUtils.equals(routeId, mDefaultRoute.getId())); + } catch (RemoteException ex) { + Log.e(TAG, "Error changing Bluetooth A2DP route"); + } + } + + //TODO: implement method + @Override + public void unselectRoute(@NonNull String packageName, @NonNull String routeId) { + // does nothing..? + } + + //TODO: implement method + @Override + public void sendControlRequest(@NonNull MediaRoute2Info route, @NonNull Intent request) { + } + + //TODO: implement method + @Override + public void requestSetVolume(MediaRoute2Info route, int volume) { + } + + //TODO: implement method + @Override + public void requestUpdateVolume(MediaRoute2Info route, int delta) { + } + + void initializeRoutes() { + //TODO: adds necessary info + 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)) + .addSupportedCategory(CATEGORY_LIVE_AUDIO) + .addSupportedCategory(CATEGORY_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); + } + + publishRoutes(); + } + + void updateAudioRoutes(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; + } + + mDefaultRoute = new MediaRoute2Info.Builder( + DEFAULT_ROUTE_ID, mContext.getResources().getText(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)) + .addSupportedCategory(CATEGORY_LIVE_AUDIO) + .addSupportedCategory(CATEGORY_LIVE_VIDEO) + .build(); + + if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) { + mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName; + if (mCurAudioRoutesInfo.bluetoothName != null) { + //TODO: mark as bluetooth once MediaRoute2Info has device type + mBluetoothA2dpRoute = new MediaRoute2Info.Builder(BLUETOOTH_ROUTE_ID, + mCurAudioRoutesInfo.bluetoothName.toString()) + .setDescription(mContext.getResources().getText( + R.string.bluetooth_a2dp_audio_route_name).toString()) + .addSupportedCategory(CATEGORY_LIVE_AUDIO) + .build(); + } else if (mBluetoothA2dpRoute != null) { + mBluetoothA2dpRoute = null; + } + } + + publishRoutes(); + } + void publishRoutes() { + MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder() + .addRoute(mDefaultRoute); + if (mBluetoothA2dpRoute != null) { + builder.addRoute(mBluetoothA2dpRoute); + } + setAndNotifyProviderInfo(builder.build()); + } +} |