Loading services/core/java/com/android/server/media/BluetoothRouteController.java 0 → 100644 +176 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothManager; import android.content.Context; import android.media.MediaRoute2Info; import android.os.UserHandle; import java.util.Collections; import java.util.List; import java.util.Objects; /** * Provides control over bluetooth routes. */ /* package */ interface BluetoothRouteController { /** * Returns a new instance of {@link LegacyBluetoothRouteController}. * * <p>It may return {@link NoOpBluetoothRouteController} if Bluetooth is not supported on this * hardware platform. */ @NonNull static BluetoothRouteController createInstance(@NonNull Context context, @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) { Objects.requireNonNull(context); Objects.requireNonNull(listener); BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter btAdapter = bluetoothManager.getAdapter(); if (btAdapter == null) { return new NoOpBluetoothRouteController(); } return new LegacyBluetoothRouteController(context, btAdapter, listener); } /** * Makes the controller to listen to events from Bluetooth stack. * * @param userHandle is needed to subscribe for broadcasts on user's behalf. */ void start(@NonNull UserHandle userHandle); /** * Stops the controller from listening to any Bluetooth events. */ void stop(); /** * Transfers Bluetooth output to the given route. * * <p>If the route is {@code null} then active route will be deactivated. * * @param routeId to switch to or {@code null} to unset the active device. */ void transferTo(@Nullable String routeId); /** * Returns currently selected Bluetooth route. * * @return the selected route or {@code null} if there are no active routes. */ @Nullable MediaRoute2Info getSelectedRoute(); /** * Returns transferable routes. * * <p>A route is considered to be transferable if the bluetooth device is connected but not * considered as selected. * * @return list of transferable routes or an empty list. */ @NonNull List<MediaRoute2Info> getTransferableRoutes(); /** * Provides all connected Bluetooth routes. * * @return list of Bluetooth routes or an empty list. */ @NonNull List<MediaRoute2Info> getAllBluetoothRoutes(); /** * Updates the volume for all Bluetooth devices for the given profile. * * @param devices specifies the profile, may be, {@link android.bluetooth.BluetoothA2dp}, {@link * android.bluetooth.BluetoothLeAudio}, or {@link android.bluetooth.BluetoothHearingAid} * @param volume the specific volume value for the given devices or 0 if unknown. * @return {@code true} if updated successfully and {@code false} otherwise. */ boolean updateVolumeForDevices(int devices, int volume); /** * Interface for receiving events about Bluetooth routes changes. */ interface BluetoothRoutesUpdatedListener { /** * Called when Bluetooth routes have changed. * * @param routes updated Bluetooth routes list. */ void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes); } /** * No-op implementation of {@link BluetoothRouteController}. * * <p>Useful if the device does not support Bluetooth. */ class NoOpBluetoothRouteController implements BluetoothRouteController { @Override public void start(UserHandle userHandle) { // no op } @Override public void stop() { // no op } @Override public void transferTo(String routeId) { // no op } @Override public MediaRoute2Info getSelectedRoute() { // no op return null; } @Override public List<MediaRoute2Info> getTransferableRoutes() { // no op return Collections.emptyList(); } @Override public List<MediaRoute2Info> getAllBluetoothRoutes() { // no op return Collections.emptyList(); } @Override public boolean updateVolumeForDevices(int devices, int volume) { // no op return false; } } } services/core/java/com/android/server/media/BluetoothRouteProvider.java→services/core/java/com/android/server/media/LegacyBluetoothRouteController.java +18 −36 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -50,10 +49,9 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; class BluetoothRouteProvider { class LegacyBluetoothRouteController implements BluetoothRouteController { private static final String TAG = "BTRouteProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); Loading @@ -69,7 +67,7 @@ class BluetoothRouteProvider { private final Context mContext; private final BluetoothAdapter mBluetoothAdapter; private final BluetoothRoutesUpdatedListener mListener; private final BluetoothRouteController.BluetoothRoutesUpdatedListener mListener; private final AudioManager mAudioManager; private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener(); Loading @@ -82,27 +80,8 @@ class BluetoothRouteProvider { private BluetoothHearingAid mHearingAidProfile; private BluetoothLeAudio mLeAudioProfile; /** * Create an instance of {@link BluetoothRouteProvider}. * It may return {@code null} if Bluetooth is not supported on this hardware platform. */ @Nullable static BluetoothRouteProvider createInstance(@NonNull Context context, @NonNull BluetoothRoutesUpdatedListener listener) { Objects.requireNonNull(context); Objects.requireNonNull(listener); BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter btAdapter = bluetoothManager.getAdapter(); if (btAdapter == null) { return null; } return new BluetoothRouteProvider(context, btAdapter, listener); } private BluetoothRouteProvider(Context context, BluetoothAdapter btAdapter, BluetoothRoutesUpdatedListener listener) { LegacyBluetoothRouteController(Context context, BluetoothAdapter btAdapter, BluetoothRouteController.BluetoothRoutesUpdatedListener listener) { mContext = context; mBluetoothAdapter = btAdapter; mListener = listener; Loading @@ -119,7 +98,8 @@ class BluetoothRouteProvider { * * @param user {@code UserHandle} as which receiver is registered */ void start(UserHandle user) { @Override public void start(UserHandle user) { mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP); mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID); mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.LE_AUDIO); Loading @@ -146,7 +126,8 @@ class BluetoothRouteProvider { deviceStateChangedIntentFilter, null, null); } void stop() { @Override public void stop() { mContext.unregisterReceiver(mAdapterStateChangedReceiver); mContext.unregisterReceiver(mDeviceStateChangedReceiver); } Loading @@ -158,7 +139,8 @@ class BluetoothRouteProvider { * @param routeId the id of the Bluetooth device. {@code null} denotes to clear the use of * BT routes. */ void transferTo(@Nullable String routeId) { @Override public void transferTo(@Nullable String routeId) { if (routeId == null) { clearActiveDevices(); return; Loading Loading @@ -213,14 +195,16 @@ class BluetoothRouteProvider { } @Nullable MediaRoute2Info getSelectedRoute() { @Override public MediaRoute2Info getSelectedRoute() { // For now, active routes can be multiple only when a pair of hearing aid devices is active. // Let the first active device represent them. return (mActiveRoutes.isEmpty() ? null : mActiveRoutes.get(0).mRoute); } @NonNull List<MediaRoute2Info> getTransferableRoutes() { @Override public List<MediaRoute2Info> getTransferableRoutes() { List<MediaRoute2Info> routes = getAllBluetoothRoutes(); for (BluetoothRouteInfo btRoute : mActiveRoutes) { routes.remove(btRoute.mRoute); Loading @@ -229,7 +213,8 @@ class BluetoothRouteProvider { } @NonNull List<MediaRoute2Info> getAllBluetoothRoutes() { @Override public List<MediaRoute2Info> getAllBluetoothRoutes() { List<MediaRoute2Info> routes = new ArrayList<>(); List<String> routeIds = new ArrayList<>(); Loading @@ -255,7 +240,8 @@ class BluetoothRouteProvider { * * @return true if devices can be handled by the provider. */ boolean updateVolumeForDevices(int devices, int volume) { @Override public boolean updateVolumeForDevices(int devices, int volume) { int routeType; if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) { routeType = MediaRoute2Info.TYPE_HEARING_AID; Loading Loading @@ -415,10 +401,6 @@ class BluetoothRouteProvider { } } interface BluetoothRoutesUpdatedListener { void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes); } private static class BluetoothRouteInfo { private BluetoothDevice mBtDevice; private MediaRoute2Info mRoute; Loading services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +35 −47 Original line number Diff line number Diff line Loading @@ -76,7 +76,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private final Handler mHandler; private final Context mContext; private final UserHandle mUser; private final BluetoothRouteProvider mBtRouteProvider; private final BluetoothRouteController mBtRouteProvider; private String mSelectedRouteId; // For apps without MODIFYING_AUDIO_ROUTING permission. Loading Loading @@ -108,7 +108,6 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SystemMediaRoute2Provider(Context context, UserHandle user) { super(COMPONENT_NAME); mIsSystemRouteProvider = true; mContext = context; mUser = user; Loading @@ -117,20 +116,23 @@ 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) { } updateDeviceRoute(newAudioRoutes); // .getInstance returns null if there is no bt adapter available mBtRouteProvider = BluetoothRouteProvider.createInstance(context, (routes) -> { mBtRouteProvider = BluetoothRouteController.createInstance(context, (routes) -> { publishProviderState(); if (updateSessionInfosIfNeeded()) { notifySessionInfoUpdated(); } }); AudioRoutesInfo newAudioRoutes = null; try { newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver); } catch (RemoteException e) { } // The methods below should be called after all fields are initialized, as they // access the fields inside. updateDeviceRoute(newAudioRoutes); updateSessionInfosIfNeeded(); } Loading @@ -140,24 +142,20 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { mContext.registerReceiverAsUser(mAudioReceiver, mUser, intentFilter, null, null); if (mBtRouteProvider != null) { mHandler.post(() -> { mBtRouteProvider.start(mUser); notifyProviderState(); }); } updateVolume(); } public void stop() { mContext.unregisterReceiver(mAudioReceiver); if (mBtRouteProvider != null) { mHandler.post(() -> { mBtRouteProvider.stop(); notifyProviderState(); }); } } @Override public void setCallback(Callback callback) { Loading Loading @@ -218,14 +216,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { // The currently selected route is the default route. return; } if (mBtRouteProvider != null) { if (TextUtils.equals(routeId, mDeviceRoute.getId())) { mBtRouteProvider.transferTo(null); } else { mBtRouteProvider.transferTo(routeId); } } } @Override public void setRouteVolume(long requestId, String routeId, int volume) { Loading Loading @@ -261,11 +257,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder( SYSTEM_SESSION_ID, packageName).setSystemSession(true); builder.addSelectedRoute(mDeviceRoute.getId()); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) { builder.addTransferableRoute(route.getId()); } } return builder.setProviderId(mUniqueId).build(); } } Loading Loading @@ -311,11 +305,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private void updateProviderState() { MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); builder.addRoute(mDeviceRoute); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) { builder.addRoute(route); } } MediaRoute2ProviderInfo providerInfo = builder.build(); setProviderState(providerInfo); if (DEBUG) { Loading @@ -336,13 +328,11 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .setSystemSession(true); MediaRoute2Info selectedRoute = mDeviceRoute; if (mBtRouteProvider != null) { MediaRoute2Info selectedBtRoute = mBtRouteProvider.getSelectedRoute(); if (selectedBtRoute != null) { selectedRoute = selectedBtRoute; builder.addTransferableRoute(mDeviceRoute.getId()); } } mSelectedRouteId = selectedRoute.getId(); mDefaultRoute = new MediaRoute2Info.Builder(DEFAULT_ROUTE_ID, selectedRoute) .setSystemRoute(true) Loading @@ -350,11 +340,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .build(); builder.addSelectedRoute(mSelectedRouteId); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { builder.addTransferableRoute(route.getId()); } } RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build(); Loading Loading @@ -432,7 +420,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .build(); } if (mBtRouteProvider != null && mBtRouteProvider.updateVolumeForDevices(devices, volume)) { if (mBtRouteProvider.updateVolumeForDevices(devices, volume)) { return; } if (mDeviceVolume != volume) { Loading Loading
services/core/java/com/android/server/media/BluetoothRouteController.java 0 → 100644 +176 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothManager; import android.content.Context; import android.media.MediaRoute2Info; import android.os.UserHandle; import java.util.Collections; import java.util.List; import java.util.Objects; /** * Provides control over bluetooth routes. */ /* package */ interface BluetoothRouteController { /** * Returns a new instance of {@link LegacyBluetoothRouteController}. * * <p>It may return {@link NoOpBluetoothRouteController} if Bluetooth is not supported on this * hardware platform. */ @NonNull static BluetoothRouteController createInstance(@NonNull Context context, @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) { Objects.requireNonNull(context); Objects.requireNonNull(listener); BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter btAdapter = bluetoothManager.getAdapter(); if (btAdapter == null) { return new NoOpBluetoothRouteController(); } return new LegacyBluetoothRouteController(context, btAdapter, listener); } /** * Makes the controller to listen to events from Bluetooth stack. * * @param userHandle is needed to subscribe for broadcasts on user's behalf. */ void start(@NonNull UserHandle userHandle); /** * Stops the controller from listening to any Bluetooth events. */ void stop(); /** * Transfers Bluetooth output to the given route. * * <p>If the route is {@code null} then active route will be deactivated. * * @param routeId to switch to or {@code null} to unset the active device. */ void transferTo(@Nullable String routeId); /** * Returns currently selected Bluetooth route. * * @return the selected route or {@code null} if there are no active routes. */ @Nullable MediaRoute2Info getSelectedRoute(); /** * Returns transferable routes. * * <p>A route is considered to be transferable if the bluetooth device is connected but not * considered as selected. * * @return list of transferable routes or an empty list. */ @NonNull List<MediaRoute2Info> getTransferableRoutes(); /** * Provides all connected Bluetooth routes. * * @return list of Bluetooth routes or an empty list. */ @NonNull List<MediaRoute2Info> getAllBluetoothRoutes(); /** * Updates the volume for all Bluetooth devices for the given profile. * * @param devices specifies the profile, may be, {@link android.bluetooth.BluetoothA2dp}, {@link * android.bluetooth.BluetoothLeAudio}, or {@link android.bluetooth.BluetoothHearingAid} * @param volume the specific volume value for the given devices or 0 if unknown. * @return {@code true} if updated successfully and {@code false} otherwise. */ boolean updateVolumeForDevices(int devices, int volume); /** * Interface for receiving events about Bluetooth routes changes. */ interface BluetoothRoutesUpdatedListener { /** * Called when Bluetooth routes have changed. * * @param routes updated Bluetooth routes list. */ void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes); } /** * No-op implementation of {@link BluetoothRouteController}. * * <p>Useful if the device does not support Bluetooth. */ class NoOpBluetoothRouteController implements BluetoothRouteController { @Override public void start(UserHandle userHandle) { // no op } @Override public void stop() { // no op } @Override public void transferTo(String routeId) { // no op } @Override public MediaRoute2Info getSelectedRoute() { // no op return null; } @Override public List<MediaRoute2Info> getTransferableRoutes() { // no op return Collections.emptyList(); } @Override public List<MediaRoute2Info> getAllBluetoothRoutes() { // no op return Collections.emptyList(); } @Override public boolean updateVolumeForDevices(int devices, int volume) { // no op return false; } } }
services/core/java/com/android/server/media/BluetoothRouteProvider.java→services/core/java/com/android/server/media/LegacyBluetoothRouteController.java +18 −36 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -50,10 +49,9 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; class BluetoothRouteProvider { class LegacyBluetoothRouteController implements BluetoothRouteController { private static final String TAG = "BTRouteProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); Loading @@ -69,7 +67,7 @@ class BluetoothRouteProvider { private final Context mContext; private final BluetoothAdapter mBluetoothAdapter; private final BluetoothRoutesUpdatedListener mListener; private final BluetoothRouteController.BluetoothRoutesUpdatedListener mListener; private final AudioManager mAudioManager; private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener(); Loading @@ -82,27 +80,8 @@ class BluetoothRouteProvider { private BluetoothHearingAid mHearingAidProfile; private BluetoothLeAudio mLeAudioProfile; /** * Create an instance of {@link BluetoothRouteProvider}. * It may return {@code null} if Bluetooth is not supported on this hardware platform. */ @Nullable static BluetoothRouteProvider createInstance(@NonNull Context context, @NonNull BluetoothRoutesUpdatedListener listener) { Objects.requireNonNull(context); Objects.requireNonNull(listener); BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter btAdapter = bluetoothManager.getAdapter(); if (btAdapter == null) { return null; } return new BluetoothRouteProvider(context, btAdapter, listener); } private BluetoothRouteProvider(Context context, BluetoothAdapter btAdapter, BluetoothRoutesUpdatedListener listener) { LegacyBluetoothRouteController(Context context, BluetoothAdapter btAdapter, BluetoothRouteController.BluetoothRoutesUpdatedListener listener) { mContext = context; mBluetoothAdapter = btAdapter; mListener = listener; Loading @@ -119,7 +98,8 @@ class BluetoothRouteProvider { * * @param user {@code UserHandle} as which receiver is registered */ void start(UserHandle user) { @Override public void start(UserHandle user) { mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP); mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID); mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.LE_AUDIO); Loading @@ -146,7 +126,8 @@ class BluetoothRouteProvider { deviceStateChangedIntentFilter, null, null); } void stop() { @Override public void stop() { mContext.unregisterReceiver(mAdapterStateChangedReceiver); mContext.unregisterReceiver(mDeviceStateChangedReceiver); } Loading @@ -158,7 +139,8 @@ class BluetoothRouteProvider { * @param routeId the id of the Bluetooth device. {@code null} denotes to clear the use of * BT routes. */ void transferTo(@Nullable String routeId) { @Override public void transferTo(@Nullable String routeId) { if (routeId == null) { clearActiveDevices(); return; Loading Loading @@ -213,14 +195,16 @@ class BluetoothRouteProvider { } @Nullable MediaRoute2Info getSelectedRoute() { @Override public MediaRoute2Info getSelectedRoute() { // For now, active routes can be multiple only when a pair of hearing aid devices is active. // Let the first active device represent them. return (mActiveRoutes.isEmpty() ? null : mActiveRoutes.get(0).mRoute); } @NonNull List<MediaRoute2Info> getTransferableRoutes() { @Override public List<MediaRoute2Info> getTransferableRoutes() { List<MediaRoute2Info> routes = getAllBluetoothRoutes(); for (BluetoothRouteInfo btRoute : mActiveRoutes) { routes.remove(btRoute.mRoute); Loading @@ -229,7 +213,8 @@ class BluetoothRouteProvider { } @NonNull List<MediaRoute2Info> getAllBluetoothRoutes() { @Override public List<MediaRoute2Info> getAllBluetoothRoutes() { List<MediaRoute2Info> routes = new ArrayList<>(); List<String> routeIds = new ArrayList<>(); Loading @@ -255,7 +240,8 @@ class BluetoothRouteProvider { * * @return true if devices can be handled by the provider. */ boolean updateVolumeForDevices(int devices, int volume) { @Override public boolean updateVolumeForDevices(int devices, int volume) { int routeType; if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) { routeType = MediaRoute2Info.TYPE_HEARING_AID; Loading Loading @@ -415,10 +401,6 @@ class BluetoothRouteProvider { } } interface BluetoothRoutesUpdatedListener { void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes); } private static class BluetoothRouteInfo { private BluetoothDevice mBtDevice; private MediaRoute2Info mRoute; Loading
services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +35 −47 Original line number Diff line number Diff line Loading @@ -76,7 +76,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private final Handler mHandler; private final Context mContext; private final UserHandle mUser; private final BluetoothRouteProvider mBtRouteProvider; private final BluetoothRouteController mBtRouteProvider; private String mSelectedRouteId; // For apps without MODIFYING_AUDIO_ROUTING permission. Loading Loading @@ -108,7 +108,6 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SystemMediaRoute2Provider(Context context, UserHandle user) { super(COMPONENT_NAME); mIsSystemRouteProvider = true; mContext = context; mUser = user; Loading @@ -117,20 +116,23 @@ 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) { } updateDeviceRoute(newAudioRoutes); // .getInstance returns null if there is no bt adapter available mBtRouteProvider = BluetoothRouteProvider.createInstance(context, (routes) -> { mBtRouteProvider = BluetoothRouteController.createInstance(context, (routes) -> { publishProviderState(); if (updateSessionInfosIfNeeded()) { notifySessionInfoUpdated(); } }); AudioRoutesInfo newAudioRoutes = null; try { newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver); } catch (RemoteException e) { } // The methods below should be called after all fields are initialized, as they // access the fields inside. updateDeviceRoute(newAudioRoutes); updateSessionInfosIfNeeded(); } Loading @@ -140,24 +142,20 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { mContext.registerReceiverAsUser(mAudioReceiver, mUser, intentFilter, null, null); if (mBtRouteProvider != null) { mHandler.post(() -> { mBtRouteProvider.start(mUser); notifyProviderState(); }); } updateVolume(); } public void stop() { mContext.unregisterReceiver(mAudioReceiver); if (mBtRouteProvider != null) { mHandler.post(() -> { mBtRouteProvider.stop(); notifyProviderState(); }); } } @Override public void setCallback(Callback callback) { Loading Loading @@ -218,14 +216,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { // The currently selected route is the default route. return; } if (mBtRouteProvider != null) { if (TextUtils.equals(routeId, mDeviceRoute.getId())) { mBtRouteProvider.transferTo(null); } else { mBtRouteProvider.transferTo(routeId); } } } @Override public void setRouteVolume(long requestId, String routeId, int volume) { Loading Loading @@ -261,11 +257,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder( SYSTEM_SESSION_ID, packageName).setSystemSession(true); builder.addSelectedRoute(mDeviceRoute.getId()); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) { builder.addTransferableRoute(route.getId()); } } return builder.setProviderId(mUniqueId).build(); } } Loading Loading @@ -311,11 +305,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private void updateProviderState() { MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); builder.addRoute(mDeviceRoute); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) { builder.addRoute(route); } } MediaRoute2ProviderInfo providerInfo = builder.build(); setProviderState(providerInfo); if (DEBUG) { Loading @@ -336,13 +328,11 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .setSystemSession(true); MediaRoute2Info selectedRoute = mDeviceRoute; if (mBtRouteProvider != null) { MediaRoute2Info selectedBtRoute = mBtRouteProvider.getSelectedRoute(); if (selectedBtRoute != null) { selectedRoute = selectedBtRoute; builder.addTransferableRoute(mDeviceRoute.getId()); } } mSelectedRouteId = selectedRoute.getId(); mDefaultRoute = new MediaRoute2Info.Builder(DEFAULT_ROUTE_ID, selectedRoute) .setSystemRoute(true) Loading @@ -350,11 +340,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .build(); builder.addSelectedRoute(mSelectedRouteId); if (mBtRouteProvider != null) { for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { builder.addTransferableRoute(route.getId()); } } RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build(); Loading Loading @@ -432,7 +420,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .build(); } if (mBtRouteProvider != null && mBtRouteProvider.updateVolumeForDevices(devices, volume)) { if (mBtRouteProvider.updateVolumeForDevices(devices, volume)) { return; } if (mDeviceVolume != volume) { Loading