Loading services/core/java/com/android/server/media/AudioManagerRouteController.java +11 −5 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.server.media.BluetoothRouteController.NoOpBluetoothRouteController; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -121,8 +122,7 @@ import java.util.concurrent.CopyOnWriteArrayList; new HashMap<>(); @GuardedBy("this") @NonNull private MediaRoute2Info mSelectedRoute; private List<MediaRoute2Info> mSelectedRoutes = Collections.emptyList(); // A singleton AudioManagerRouteController. private static AudioManagerRouteController mInstance; Loading Loading @@ -255,8 +255,12 @@ import java.util.concurrent.CopyOnWriteArrayList; @Override @NonNull public synchronized MediaRoute2Info getSelectedRoute() { return mSelectedRoute; public synchronized List<MediaRoute2Info> getSelectedRoutes() { if (mSelectedRoutes.isEmpty()) { // mSelectedRoutes should non-empty from initialization. throw new IllegalStateException("Selected routes should not be empty"); } return mSelectedRoutes; } @Override Loading Loading @@ -499,7 +503,9 @@ import java.util.concurrent.CopyOnWriteArrayList; mRouteIdToAvailableDeviceRoutes.put( newSelectedRouteHolder.mMediaRoute2Info.getId(), selectedRouteHolderWithUpdatedVolumeInfo); mSelectedRoute = selectedRouteHolderWithUpdatedVolumeInfo.mMediaRoute2Info; mSelectedRoutes = Collections.singletonList( selectedRouteHolderWithUpdatedVolumeInfo.mMediaRoute2Info); // We only add those BT routes that we have not already obtained from audio manager (which // are active). Loading services/core/java/com/android/server/media/DeviceRouteController.java +4 −4 Original line number Diff line number Diff line Loading @@ -104,17 +104,17 @@ import java.util.List; } } /** Returns the currently selected device (built-in or wired) route. */ /** Returns a list of currently selected devices (built-in, wired or bt) route. */ @NonNull MediaRoute2Info getSelectedRoute(); List<MediaRoute2Info> getSelectedRoutes(); /** * Returns all available routes. * * <p>Note that this method returns available routes including the selected route because (a) * this interface doesn't guarantee that the internal state of the controller won't change * between calls to {@link #getSelectedRoute()} and this method and (b) {@link * #getSelectedRoute()} may be treated as a transferable route (not a selected route) if the * between calls to {@link #getSelectedRoutes()} and this method and (b) {@link * #getSelectedRoutes()} may be treated as a transferable route (not a selected route) if the * selected route is from {@link BluetoothRouteController}. */ List<MediaRoute2Info> getAvailableRoutes(); Loading services/core/java/com/android/server/media/LegacyDeviceRouteController.java +2 −2 Original line number Diff line number Diff line Loading @@ -127,8 +127,8 @@ import java.util.Objects; @Override @NonNull public synchronized MediaRoute2Info getSelectedRoute() { return mDeviceRoute; public synchronized List<MediaRoute2Info> getSelectedRoutes() { return List.of(mDeviceRoute); } @Override Loading services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +49 −29 Original line number Diff line number Diff line Loading @@ -42,9 +42,11 @@ import com.android.internal.annotations.GuardedBy; import com.android.media.flags.Flags; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers. Loading @@ -69,7 +71,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private final DeviceRouteController mDeviceRouteController; private final BluetoothRouteController mBluetoothRouteController; private String mSelectedRouteId; @GuardedBy("mLock") private List<String> mSelectedRouteIds = Collections.emptyList(); /** * Placeholder {@link MediaRoute2Info} representation of the currently selected route for apps Loading Loading @@ -185,19 +188,18 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return; } if (!Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { if (TextUtils.equals(routeOriginalId, mSelectedRouteId)) { RoutingSessionInfo currentSessionInfo; synchronized (mLock) { currentSessionInfo = if (!Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { if (mSelectedRouteIds.size() == 1 && mSelectedRouteIds.contains(routeOriginalId)) { RoutingSessionInfo currentSessionInfo = Flags.enableMirroringInMediaRouter2() ? mSystemSessionInfo : mSessionInfos.get(0); } mCallback.onSessionCreated(this, requestId, currentSessionInfo); return; } } } synchronized (mRequestLock) { // Handle the previous request as a failure if exists. Loading Loading @@ -257,7 +259,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { String sessionOriginalId, String routeOriginalId, @RoutingSessionInfo.TransferReason int transferReason) { String selectedDeviceRouteId = mDeviceRouteController.getSelectedRoute().getId(); String selectedDeviceRouteId = mDeviceRouteController.getSelectedRoutes().getFirst().getId(); if (TextUtils.equals(routeOriginalId, MediaRoute2Info.ROUTE_ID_DEFAULT)) { if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { // Transfer to the default route (which is the selected route). We replace the id to Loading Loading @@ -309,9 +312,11 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override public void setRouteVolume(long requestId, String routeOriginalId, int volume) { if (!TextUtils.equals(routeOriginalId, mSelectedRouteId)) { synchronized (mLock) { if (!mSelectedRouteIds.contains(routeOriginalId)) { return; } } mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); } Loading Loading @@ -383,19 +388,27 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return null; } MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute(); List<MediaRoute2Info> selectedDeviceRoutes = mDeviceRouteController.getSelectedRoutes(); RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(SYSTEM_SESSION_ID, packageName) .setSystemSession(true); builder.addSelectedRoute(selectedDeviceRoute.getId()); for (MediaRoute2Info route : selectedDeviceRoutes) { builder.addSelectedRoute(route.getId()); } for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) { builder.addTransferableRoute(route.getId()); } if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) { // Cache to list to avoid redundant list conversions Set<String> selectedRouteIds = selectedDeviceRoutes.stream() .map(MediaRoute2Info::getId) .collect(Collectors.toUnmodifiableSet()); for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) { if (!TextUtils.equals(selectedDeviceRoute.getId(), route.getId())) { if (!selectedRouteIds.contains(route.getId())) { builder.addTransferableRoute(route.getId()); } } Loading Loading @@ -461,7 +474,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { setProviderState(builder.build()); } } else { builder.addRoute(mDeviceRouteController.getSelectedRoute()); builder.addRoute(mDeviceRouteController.getSelectedRoutes().getFirst()); } for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) { Loading Loading @@ -490,19 +503,23 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SYSTEM_SESSION_ID, "" /* clientPackageName */) .setSystemSession(true); MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute(); MediaRoute2Info selectedRoute = selectedDeviceRoute; List<MediaRoute2Info> selectedDeviceRoutes = mDeviceRouteController.getSelectedRoutes(); List<MediaRoute2Info> selectedRoutes = selectedDeviceRoutes; MediaRoute2Info selectedBtRoute = mBluetoothRouteController.getSelectedRoute(); List<String> transferableRoutes = new ArrayList<>(); if (selectedBtRoute != null) { selectedRoute = selectedBtRoute; selectedRoutes = List.of(selectedBtRoute); for (MediaRoute2Info selectedDeviceRoute : selectedDeviceRoutes) { transferableRoutes.add(selectedDeviceRoute.getId()); } mSelectedRouteId = selectedRoute.getId(); } mSelectedRouteIds = selectedRoutes.stream().map(MediaRoute2Info::getId).toList(); var defaultRouteBuilder = new MediaRoute2Info.Builder(MediaRoute2Info.ROUTE_ID_DEFAULT, selectedRoute) new MediaRoute2Info.Builder( MediaRoute2Info.ROUTE_ID_DEFAULT, selectedRoutes.getFirst()) .setSystemRoute(true) .setProviderId(mUniqueId); if (Flags.hideBtAddressFromAppsWithoutBtPermission()) { Loading @@ -510,11 +527,13 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } mDefaultRoute = defaultRouteBuilder.build(); builder.addSelectedRoute(mSelectedRouteId); for (String selectedRouteId : mSelectedRouteIds) { builder.addSelectedRoute(selectedRouteId); } if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) { for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) { String routeId = route.getId(); if (!mSelectedRouteId.equals(routeId)) { if (!mSelectedRouteIds.contains(routeId)) { transferableRoutes.add(routeId); } } Loading @@ -533,7 +552,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { String transferInitiatorPackageName = null; if (oldSessionInfo != null && containsSelectedRouteWithId(oldSessionInfo, selectedRoute.getId())) { && containsSelectedRouteWithId( oldSessionInfo, mSelectedRouteIds.getFirst())) { transferReason = oldSessionInfo.getTransferReason(); transferInitiatorUserHandle = oldSessionInfo.getTransferInitiatorUserHandle(); transferInitiatorPackageName = oldSessionInfo.getTransferInitiatorPackageName(); Loading @@ -542,7 +562,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { synchronized (mTransferLock) { if (mPendingTransferRequest != null) { boolean isTransferringToTheSelectedRoute = mPendingTransferRequest.isTargetRoute(selectedRoute); mPendingTransferRequest.isTargetRoute(selectedRoutes.getFirst()); boolean canBePotentiallyTransferred = mPendingTransferRequest.isTargetRouteIdInRouteOriginalIdList( transferableRoutes); Loading Loading @@ -616,8 +636,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } long pendingRequestId = mPendingSessionCreationOrTransferRequest.mRequestId; if (mPendingSessionCreationOrTransferRequest.mTargetOriginalRouteId.equals( mSelectedRouteId)) { if (mSelectedRouteIds.contains( mPendingSessionCreationOrTransferRequest.mTargetOriginalRouteId)) { if (DEBUG) { Slog.w( TAG, Loading Loading @@ -705,10 +725,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override protected String getDebugString() { return TextUtils.formatSimple( "%s - package: %s, selected route id: %s, bluetooth impl: %s", "%s - package: %s, selected route ids: %s, bluetooth impl: %s", getClass().getSimpleName(), mComponentName.getPackageName(), mSelectedRouteId, mSelectedRouteIds, mBluetoothRouteController.getClass().getSimpleName()); } Loading services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java +11 −11 Original line number Diff line number Diff line Loading @@ -162,20 +162,20 @@ public class AudioManagerRouteControllerTest { @Test public void getSelectedRoute_afterDevicesConnect_returnsRightSelectedRoute() { assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); addAvailableAudioDeviceInfo( /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP); verify(mOnDeviceRouteChangedListener).onDeviceRouteChanged(); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); addAvailableAudioDeviceInfo( /* newSelectedDevice= */ null, // Selected device doesn't change. /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); } Loading @@ -191,19 +191,19 @@ public class AudioManagerRouteControllerTest { /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP); verify(mOnDeviceRouteChangedListener, times(2)).onDeviceRouteChanged(); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); removeAvailableAudioDeviceInfos( /* newSelectedDevice= */ null, /* devicesToRemove...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); removeAvailableAudioDeviceInfos( /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_BUILTIN_SPEAKER, /* devicesToRemove...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); } Loading Loading @@ -232,7 +232,7 @@ public class AudioManagerRouteControllerTest { .map(MediaRoute2Info::getType) .toList()) .containsExactly(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); } Loading Loading @@ -271,7 +271,7 @@ public class AudioManagerRouteControllerTest { /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoute(); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoutes().getFirst(); assertThat(selectedRoute.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADSET); assertThat(selectedRoute.getVolume()).isEqualTo(2); assertThat(selectedRoute.getVolumeMax()).isEqualTo(3); Loading @@ -294,7 +294,7 @@ public class AudioManagerRouteControllerTest { when(mMockAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)).thenReturn(0); when(mMockAudioManager.isVolumeFixed()).thenReturn(true); mControllerUnderTest.updateVolume(0); MediaRoute2Info newSelectedRoute = mControllerUnderTest.getSelectedRoute(); MediaRoute2Info newSelectedRoute = mControllerUnderTest.getSelectedRoutes().getFirst(); assertThat(newSelectedRoute.getVolume()).isEqualTo(0); assertThat(newSelectedRoute.getVolumeHandling()) .isEqualTo(MediaRoute2Info.PLAYBACK_VOLUME_FIXED); Loading @@ -302,14 +302,14 @@ public class AudioManagerRouteControllerTest { @Test public void getAvailableRoutes_whenNoProductNameIsProvided_usesTypeToPopulateName() { assertThat(mControllerUnderTest.getSelectedRoute().getName().toString()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getName().toString()) .isEqualTo(FAKE_AUDIO_DEVICE_INFO_BUILTIN_SPEAKER.getProductName().toString()); addAvailableAudioDeviceInfo( /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_NO_NAME, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_NO_NAME); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoute(); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoutes().getFirst(); assertThat(selectedRoute.getName().toString()).isEqualTo(FAKE_ROUTE_NAME); } Loading Loading
services/core/java/com/android/server/media/AudioManagerRouteController.java +11 −5 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.server.media.BluetoothRouteController.NoOpBluetoothRouteController; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -121,8 +122,7 @@ import java.util.concurrent.CopyOnWriteArrayList; new HashMap<>(); @GuardedBy("this") @NonNull private MediaRoute2Info mSelectedRoute; private List<MediaRoute2Info> mSelectedRoutes = Collections.emptyList(); // A singleton AudioManagerRouteController. private static AudioManagerRouteController mInstance; Loading Loading @@ -255,8 +255,12 @@ import java.util.concurrent.CopyOnWriteArrayList; @Override @NonNull public synchronized MediaRoute2Info getSelectedRoute() { return mSelectedRoute; public synchronized List<MediaRoute2Info> getSelectedRoutes() { if (mSelectedRoutes.isEmpty()) { // mSelectedRoutes should non-empty from initialization. throw new IllegalStateException("Selected routes should not be empty"); } return mSelectedRoutes; } @Override Loading Loading @@ -499,7 +503,9 @@ import java.util.concurrent.CopyOnWriteArrayList; mRouteIdToAvailableDeviceRoutes.put( newSelectedRouteHolder.mMediaRoute2Info.getId(), selectedRouteHolderWithUpdatedVolumeInfo); mSelectedRoute = selectedRouteHolderWithUpdatedVolumeInfo.mMediaRoute2Info; mSelectedRoutes = Collections.singletonList( selectedRouteHolderWithUpdatedVolumeInfo.mMediaRoute2Info); // We only add those BT routes that we have not already obtained from audio manager (which // are active). Loading
services/core/java/com/android/server/media/DeviceRouteController.java +4 −4 Original line number Diff line number Diff line Loading @@ -104,17 +104,17 @@ import java.util.List; } } /** Returns the currently selected device (built-in or wired) route. */ /** Returns a list of currently selected devices (built-in, wired or bt) route. */ @NonNull MediaRoute2Info getSelectedRoute(); List<MediaRoute2Info> getSelectedRoutes(); /** * Returns all available routes. * * <p>Note that this method returns available routes including the selected route because (a) * this interface doesn't guarantee that the internal state of the controller won't change * between calls to {@link #getSelectedRoute()} and this method and (b) {@link * #getSelectedRoute()} may be treated as a transferable route (not a selected route) if the * between calls to {@link #getSelectedRoutes()} and this method and (b) {@link * #getSelectedRoutes()} may be treated as a transferable route (not a selected route) if the * selected route is from {@link BluetoothRouteController}. */ List<MediaRoute2Info> getAvailableRoutes(); Loading
services/core/java/com/android/server/media/LegacyDeviceRouteController.java +2 −2 Original line number Diff line number Diff line Loading @@ -127,8 +127,8 @@ import java.util.Objects; @Override @NonNull public synchronized MediaRoute2Info getSelectedRoute() { return mDeviceRoute; public synchronized List<MediaRoute2Info> getSelectedRoutes() { return List.of(mDeviceRoute); } @Override Loading
services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +49 −29 Original line number Diff line number Diff line Loading @@ -42,9 +42,11 @@ import com.android.internal.annotations.GuardedBy; import com.android.media.flags.Flags; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers. Loading @@ -69,7 +71,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private final DeviceRouteController mDeviceRouteController; private final BluetoothRouteController mBluetoothRouteController; private String mSelectedRouteId; @GuardedBy("mLock") private List<String> mSelectedRouteIds = Collections.emptyList(); /** * Placeholder {@link MediaRoute2Info} representation of the currently selected route for apps Loading Loading @@ -185,19 +188,18 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return; } if (!Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { if (TextUtils.equals(routeOriginalId, mSelectedRouteId)) { RoutingSessionInfo currentSessionInfo; synchronized (mLock) { currentSessionInfo = if (!Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { if (mSelectedRouteIds.size() == 1 && mSelectedRouteIds.contains(routeOriginalId)) { RoutingSessionInfo currentSessionInfo = Flags.enableMirroringInMediaRouter2() ? mSystemSessionInfo : mSessionInfos.get(0); } mCallback.onSessionCreated(this, requestId, currentSessionInfo); return; } } } synchronized (mRequestLock) { // Handle the previous request as a failure if exists. Loading Loading @@ -257,7 +259,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { String sessionOriginalId, String routeOriginalId, @RoutingSessionInfo.TransferReason int transferReason) { String selectedDeviceRouteId = mDeviceRouteController.getSelectedRoute().getId(); String selectedDeviceRouteId = mDeviceRouteController.getSelectedRoutes().getFirst().getId(); if (TextUtils.equals(routeOriginalId, MediaRoute2Info.ROUTE_ID_DEFAULT)) { if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { // Transfer to the default route (which is the selected route). We replace the id to Loading Loading @@ -309,9 +312,11 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override public void setRouteVolume(long requestId, String routeOriginalId, int volume) { if (!TextUtils.equals(routeOriginalId, mSelectedRouteId)) { synchronized (mLock) { if (!mSelectedRouteIds.contains(routeOriginalId)) { return; } } mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); } Loading Loading @@ -383,19 +388,27 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return null; } MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute(); List<MediaRoute2Info> selectedDeviceRoutes = mDeviceRouteController.getSelectedRoutes(); RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(SYSTEM_SESSION_ID, packageName) .setSystemSession(true); builder.addSelectedRoute(selectedDeviceRoute.getId()); for (MediaRoute2Info route : selectedDeviceRoutes) { builder.addSelectedRoute(route.getId()); } for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) { builder.addTransferableRoute(route.getId()); } if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) { // Cache to list to avoid redundant list conversions Set<String> selectedRouteIds = selectedDeviceRoutes.stream() .map(MediaRoute2Info::getId) .collect(Collectors.toUnmodifiableSet()); for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) { if (!TextUtils.equals(selectedDeviceRoute.getId(), route.getId())) { if (!selectedRouteIds.contains(route.getId())) { builder.addTransferableRoute(route.getId()); } } Loading Loading @@ -461,7 +474,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { setProviderState(builder.build()); } } else { builder.addRoute(mDeviceRouteController.getSelectedRoute()); builder.addRoute(mDeviceRouteController.getSelectedRoutes().getFirst()); } for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) { Loading Loading @@ -490,19 +503,23 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SYSTEM_SESSION_ID, "" /* clientPackageName */) .setSystemSession(true); MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute(); MediaRoute2Info selectedRoute = selectedDeviceRoute; List<MediaRoute2Info> selectedDeviceRoutes = mDeviceRouteController.getSelectedRoutes(); List<MediaRoute2Info> selectedRoutes = selectedDeviceRoutes; MediaRoute2Info selectedBtRoute = mBluetoothRouteController.getSelectedRoute(); List<String> transferableRoutes = new ArrayList<>(); if (selectedBtRoute != null) { selectedRoute = selectedBtRoute; selectedRoutes = List.of(selectedBtRoute); for (MediaRoute2Info selectedDeviceRoute : selectedDeviceRoutes) { transferableRoutes.add(selectedDeviceRoute.getId()); } mSelectedRouteId = selectedRoute.getId(); } mSelectedRouteIds = selectedRoutes.stream().map(MediaRoute2Info::getId).toList(); var defaultRouteBuilder = new MediaRoute2Info.Builder(MediaRoute2Info.ROUTE_ID_DEFAULT, selectedRoute) new MediaRoute2Info.Builder( MediaRoute2Info.ROUTE_ID_DEFAULT, selectedRoutes.getFirst()) .setSystemRoute(true) .setProviderId(mUniqueId); if (Flags.hideBtAddressFromAppsWithoutBtPermission()) { Loading @@ -510,11 +527,13 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } mDefaultRoute = defaultRouteBuilder.build(); builder.addSelectedRoute(mSelectedRouteId); for (String selectedRouteId : mSelectedRouteIds) { builder.addSelectedRoute(selectedRouteId); } if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) { for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) { String routeId = route.getId(); if (!mSelectedRouteId.equals(routeId)) { if (!mSelectedRouteIds.contains(routeId)) { transferableRoutes.add(routeId); } } Loading @@ -533,7 +552,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { String transferInitiatorPackageName = null; if (oldSessionInfo != null && containsSelectedRouteWithId(oldSessionInfo, selectedRoute.getId())) { && containsSelectedRouteWithId( oldSessionInfo, mSelectedRouteIds.getFirst())) { transferReason = oldSessionInfo.getTransferReason(); transferInitiatorUserHandle = oldSessionInfo.getTransferInitiatorUserHandle(); transferInitiatorPackageName = oldSessionInfo.getTransferInitiatorPackageName(); Loading @@ -542,7 +562,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { synchronized (mTransferLock) { if (mPendingTransferRequest != null) { boolean isTransferringToTheSelectedRoute = mPendingTransferRequest.isTargetRoute(selectedRoute); mPendingTransferRequest.isTargetRoute(selectedRoutes.getFirst()); boolean canBePotentiallyTransferred = mPendingTransferRequest.isTargetRouteIdInRouteOriginalIdList( transferableRoutes); Loading Loading @@ -616,8 +636,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } long pendingRequestId = mPendingSessionCreationOrTransferRequest.mRequestId; if (mPendingSessionCreationOrTransferRequest.mTargetOriginalRouteId.equals( mSelectedRouteId)) { if (mSelectedRouteIds.contains( mPendingSessionCreationOrTransferRequest.mTargetOriginalRouteId)) { if (DEBUG) { Slog.w( TAG, Loading Loading @@ -705,10 +725,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override protected String getDebugString() { return TextUtils.formatSimple( "%s - package: %s, selected route id: %s, bluetooth impl: %s", "%s - package: %s, selected route ids: %s, bluetooth impl: %s", getClass().getSimpleName(), mComponentName.getPackageName(), mSelectedRouteId, mSelectedRouteIds, mBluetoothRouteController.getClass().getSimpleName()); } Loading
services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java +11 −11 Original line number Diff line number Diff line Loading @@ -162,20 +162,20 @@ public class AudioManagerRouteControllerTest { @Test public void getSelectedRoute_afterDevicesConnect_returnsRightSelectedRoute() { assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); addAvailableAudioDeviceInfo( /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP); verify(mOnDeviceRouteChangedListener).onDeviceRouteChanged(); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); addAvailableAudioDeviceInfo( /* newSelectedDevice= */ null, // Selected device doesn't change. /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); } Loading @@ -191,19 +191,19 @@ public class AudioManagerRouteControllerTest { /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_BLUETOOTH_A2DP); verify(mOnDeviceRouteChangedListener, times(2)).onDeviceRouteChanged(); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); removeAvailableAudioDeviceInfos( /* newSelectedDevice= */ null, /* devicesToRemove...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BLUETOOTH_A2DP); removeAvailableAudioDeviceInfos( /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_BUILTIN_SPEAKER, /* devicesToRemove...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); } Loading Loading @@ -232,7 +232,7 @@ public class AudioManagerRouteControllerTest { .map(MediaRoute2Info::getType) .toList()) .containsExactly(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); assertThat(mControllerUnderTest.getSelectedRoute().getType()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getType()) .isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER); } Loading Loading @@ -271,7 +271,7 @@ public class AudioManagerRouteControllerTest { /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_INFO_WIRED_HEADSET); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoute(); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoutes().getFirst(); assertThat(selectedRoute.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADSET); assertThat(selectedRoute.getVolume()).isEqualTo(2); assertThat(selectedRoute.getVolumeMax()).isEqualTo(3); Loading @@ -294,7 +294,7 @@ public class AudioManagerRouteControllerTest { when(mMockAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)).thenReturn(0); when(mMockAudioManager.isVolumeFixed()).thenReturn(true); mControllerUnderTest.updateVolume(0); MediaRoute2Info newSelectedRoute = mControllerUnderTest.getSelectedRoute(); MediaRoute2Info newSelectedRoute = mControllerUnderTest.getSelectedRoutes().getFirst(); assertThat(newSelectedRoute.getVolume()).isEqualTo(0); assertThat(newSelectedRoute.getVolumeHandling()) .isEqualTo(MediaRoute2Info.PLAYBACK_VOLUME_FIXED); Loading @@ -302,14 +302,14 @@ public class AudioManagerRouteControllerTest { @Test public void getAvailableRoutes_whenNoProductNameIsProvided_usesTypeToPopulateName() { assertThat(mControllerUnderTest.getSelectedRoute().getName().toString()) assertThat(mControllerUnderTest.getSelectedRoutes().getFirst().getName().toString()) .isEqualTo(FAKE_AUDIO_DEVICE_INFO_BUILTIN_SPEAKER.getProductName().toString()); addAvailableAudioDeviceInfo( /* newSelectedDevice= */ FAKE_AUDIO_DEVICE_NO_NAME, /* newAvailableDevices...= */ FAKE_AUDIO_DEVICE_NO_NAME); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoute(); MediaRoute2Info selectedRoute = mControllerUnderTest.getSelectedRoutes().getFirst(); assertThat(selectedRoute.getName().toString()).isEqualTo(FAKE_ROUTE_NAME); } Loading