Loading services/core/java/com/android/server/media/AudioManagerRouteController.java +52 −4 Original line number Diff line number Diff line Loading @@ -117,6 +117,35 @@ import java.util.concurrent.CopyOnWriteArrayList; @NonNull private MediaRoute2Info mSelectedRoute; // A singleton AudioManagerRouteController. private static AudioManagerRouteController mInstance; // A flag indicating if the start function has been called. private boolean mStarted = false; // Get the singleton AudioManagerRouteController. Create a new one if it's not available yet. public static AudioManagerRouteController getInstance( @NonNull Context context, @NonNull AudioManager audioManager, @NonNull Looper looper, @NonNull AudioProductStrategy strategyForMedia, @NonNull BluetoothAdapter btAdapter) { if (!com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController()) { return new AudioManagerRouteController( context, audioManager, looper, strategyForMedia, btAdapter); } synchronized (AudioManagerRouteController.class) { if (mInstance == null) { mInstance = new AudioManagerRouteController( context, audioManager, looper, strategyForMedia, btAdapter); } return mInstance; } } // TODO: b/305199571 - Support nullable btAdapter and strategyForMedia which, when null, means // no support for transferring to inactive bluetooth routes and transferring to any routes // respectively. Loading @@ -130,13 +159,11 @@ import java.util.concurrent.CopyOnWriteArrayList; @NonNull AudioManager audioManager, @NonNull Looper looper, @NonNull AudioProductStrategy strategyForMedia, @NonNull BluetoothAdapter btAdapter, @NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) { @NonNull BluetoothAdapter btAdapter) { mContext = Objects.requireNonNull(context); mAudioManager = Objects.requireNonNull(audioManager); mHandler = new Handler(Objects.requireNonNull(looper)); mStrategyForMedia = Objects.requireNonNull(strategyForMedia); mOnDeviceRouteChangedListeners.add(Objects.requireNonNull(onDeviceRouteChangedListener)); mBuiltInSpeakerSuitabilityStatus = DeviceRouteController.getBuiltInSpeakerSuitabilityStatus(mContext); Loading @@ -154,6 +181,11 @@ import java.util.concurrent.CopyOnWriteArrayList; mOnDeviceRouteChangedListeners.add(onDeviceRouteChangedListener); } public void unregisterRouteChangeListener( @NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) { mOnDeviceRouteChangedListeners.remove(onDeviceRouteChangedListener); } @RequiresPermission( anyOf = { Manifest.permission.MODIFY_AUDIO_ROUTING, Loading @@ -161,7 +193,18 @@ import java.util.concurrent.CopyOnWriteArrayList; }) @Override public void start(UserHandle mUser) { mBluetoothRouteController.start(mUser); // When AudioManagerRouteController is singleton, only need to call this function once. if (com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController()) { if (mStarted) { return; } mStarted = true; } mBluetoothRouteController.start( com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController() ? UserHandle.SYSTEM : mUser); mAudioManager.registerAudioDeviceCallback(mAudioDeviceCallback, mHandler); mAudioManager.addOnDevicesForAttributesChangedListener( AudioRoutingUtils.ATTRIBUTES_MEDIA, Loading @@ -176,6 +219,11 @@ import java.util.concurrent.CopyOnWriteArrayList; }) @Override public void stop() { // Singleton AudioManagerRouteController doesn't need to call stop function. if (com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController()) { return; } mAudioManager.removeOnDevicesForAttributesChangedListener( mOnDevicesForAttributesChangedListener); mAudioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback); Loading services/core/java/com/android/server/media/DeviceRouteController.java +5 −7 Original line number Diff line number Diff line Loading @@ -65,13 +65,11 @@ import java.util.List; if (strategyForMedia != null && btAdapter != null && Flags.enableAudioPoliciesDeviceAndBluetoothController()) { return new AudioManagerRouteController( context, audioManager, looper, strategyForMedia, btAdapter, onDeviceRouteChangedListener); AudioManagerRouteController controller = AudioManagerRouteController.getInstance( context, audioManager, looper, strategyForMedia, btAdapter); controller.registerRouteChangeListener(onDeviceRouteChangedListener); return controller; } else { IAudioService audioService = IAudioService.Stub.asInterface( Loading services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -139,8 +139,8 @@ public class AudioManagerRouteControllerTest { mMockAudioManager, Looper.getMainLooper(), mMediaAudioProductStrategy, btAdapter, mOnDeviceRouteChangedListener); btAdapter); mControllerUnderTest.registerRouteChangeListener(mOnDeviceRouteChangedListener); mControllerUnderTest.start(UserHandle.CURRENT_OR_SELF); ArgumentCaptor<AudioDeviceCallback> deviceCallbackCaptor = Loading Loading
services/core/java/com/android/server/media/AudioManagerRouteController.java +52 −4 Original line number Diff line number Diff line Loading @@ -117,6 +117,35 @@ import java.util.concurrent.CopyOnWriteArrayList; @NonNull private MediaRoute2Info mSelectedRoute; // A singleton AudioManagerRouteController. private static AudioManagerRouteController mInstance; // A flag indicating if the start function has been called. private boolean mStarted = false; // Get the singleton AudioManagerRouteController. Create a new one if it's not available yet. public static AudioManagerRouteController getInstance( @NonNull Context context, @NonNull AudioManager audioManager, @NonNull Looper looper, @NonNull AudioProductStrategy strategyForMedia, @NonNull BluetoothAdapter btAdapter) { if (!com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController()) { return new AudioManagerRouteController( context, audioManager, looper, strategyForMedia, btAdapter); } synchronized (AudioManagerRouteController.class) { if (mInstance == null) { mInstance = new AudioManagerRouteController( context, audioManager, looper, strategyForMedia, btAdapter); } return mInstance; } } // TODO: b/305199571 - Support nullable btAdapter and strategyForMedia which, when null, means // no support for transferring to inactive bluetooth routes and transferring to any routes // respectively. Loading @@ -130,13 +159,11 @@ import java.util.concurrent.CopyOnWriteArrayList; @NonNull AudioManager audioManager, @NonNull Looper looper, @NonNull AudioProductStrategy strategyForMedia, @NonNull BluetoothAdapter btAdapter, @NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) { @NonNull BluetoothAdapter btAdapter) { mContext = Objects.requireNonNull(context); mAudioManager = Objects.requireNonNull(audioManager); mHandler = new Handler(Objects.requireNonNull(looper)); mStrategyForMedia = Objects.requireNonNull(strategyForMedia); mOnDeviceRouteChangedListeners.add(Objects.requireNonNull(onDeviceRouteChangedListener)); mBuiltInSpeakerSuitabilityStatus = DeviceRouteController.getBuiltInSpeakerSuitabilityStatus(mContext); Loading @@ -154,6 +181,11 @@ import java.util.concurrent.CopyOnWriteArrayList; mOnDeviceRouteChangedListeners.add(onDeviceRouteChangedListener); } public void unregisterRouteChangeListener( @NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) { mOnDeviceRouteChangedListeners.remove(onDeviceRouteChangedListener); } @RequiresPermission( anyOf = { Manifest.permission.MODIFY_AUDIO_ROUTING, Loading @@ -161,7 +193,18 @@ import java.util.concurrent.CopyOnWriteArrayList; }) @Override public void start(UserHandle mUser) { mBluetoothRouteController.start(mUser); // When AudioManagerRouteController is singleton, only need to call this function once. if (com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController()) { if (mStarted) { return; } mStarted = true; } mBluetoothRouteController.start( com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController() ? UserHandle.SYSTEM : mUser); mAudioManager.registerAudioDeviceCallback(mAudioDeviceCallback, mHandler); mAudioManager.addOnDevicesForAttributesChangedListener( AudioRoutingUtils.ATTRIBUTES_MEDIA, Loading @@ -176,6 +219,11 @@ import java.util.concurrent.CopyOnWriteArrayList; }) @Override public void stop() { // Singleton AudioManagerRouteController doesn't need to call stop function. if (com.android.media.flags.Flags.enableUseOfSingletonAudioManagerRouteController()) { return; } mAudioManager.removeOnDevicesForAttributesChangedListener( mOnDevicesForAttributesChangedListener); mAudioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback); Loading
services/core/java/com/android/server/media/DeviceRouteController.java +5 −7 Original line number Diff line number Diff line Loading @@ -65,13 +65,11 @@ import java.util.List; if (strategyForMedia != null && btAdapter != null && Flags.enableAudioPoliciesDeviceAndBluetoothController()) { return new AudioManagerRouteController( context, audioManager, looper, strategyForMedia, btAdapter, onDeviceRouteChangedListener); AudioManagerRouteController controller = AudioManagerRouteController.getInstance( context, audioManager, looper, strategyForMedia, btAdapter); controller.registerRouteChangeListener(onDeviceRouteChangedListener); return controller; } else { IAudioService audioService = IAudioService.Stub.asInterface( Loading
services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -139,8 +139,8 @@ public class AudioManagerRouteControllerTest { mMockAudioManager, Looper.getMainLooper(), mMediaAudioProductStrategy, btAdapter, mOnDeviceRouteChangedListener); btAdapter); mControllerUnderTest.registerRouteChangeListener(mOnDeviceRouteChangedListener); mControllerUnderTest.start(UserHandle.CURRENT_OR_SELF); ArgumentCaptor<AudioDeviceCallback> deviceCallbackCaptor = Loading