Loading core/api/system-current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -6607,6 +6607,7 @@ package android.media { public class AudioManager { method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addAssistantServicesUids(@NonNull int[]); method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public void addOnDevicesForAttributesChangedListener(@NonNull android.media.AudioAttributes, @NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnDevicesForAttributesChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnNonDefaultDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnNonDefaultDevicesForStrategyChangedListener) throws java.lang.SecurityException; method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException; Loading Loading @@ -6647,6 +6648,7 @@ package android.media { method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeAssistantServicesUids(@NonNull int[]); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removeDeviceAsNonDefaultForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public void removeOnDevicesForAttributesChangedListener(@NonNull android.media.AudioManager.OnDevicesForAttributesChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnNonDefaultDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnNonDefaultDevicesForStrategyChangedListener); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener); Loading Loading @@ -6704,6 +6706,10 @@ package android.media { field public static final int EVENT_TIMEOUT = 2; // 0x2 } public static interface AudioManager.OnDevicesForAttributesChangedListener { method public void onDevicesForAttributesChanged(@NonNull android.media.AudioAttributes, @NonNull java.util.List<android.media.AudioDeviceAttributes>); } public static interface AudioManager.OnNonDefaultDevicesForStrategyChangedListener { method public void onNonDefaultDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>); } media/java/android/media/AudioManager.java +111 −0 Original line number Diff line number Diff line Loading @@ -5855,6 +5855,117 @@ public class AudioManager { } } // Each listener corresponds to a unique callback stub because each listener can subscribe to // different AudioAttributes. private final ConcurrentHashMap<OnDevicesForAttributesChangedListener, IDevicesForAttributesCallbackStub> mDevicesForAttributesListenerToStub = new ConcurrentHashMap<>(); private static final class IDevicesForAttributesCallbackStub extends IDevicesForAttributesCallback.Stub { ListenerInfo<OnDevicesForAttributesChangedListener> mInfo; IDevicesForAttributesCallbackStub(@NonNull OnDevicesForAttributesChangedListener listener, @NonNull Executor executor) { mInfo = new ListenerInfo<>(listener, executor); } public void register(boolean register, AudioAttributes attributes) { try { if (register) { getService().addOnDevicesForAttributesChangedListener(attributes, this); } else { getService().removeOnDevicesForAttributesChangedListener(this); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public void onDevicesForAttributesChanged(AudioAttributes attributes, boolean forVolume, List<AudioDeviceAttributes> devices) { // forVolume is ignored. The case where it is `true` is not handled. mInfo.mExecutor.execute(() -> mInfo.mListener.onDevicesForAttributesChanged( attributes, devices)); } } /** * @hide * Interface to be notified of when routing changes for the registered audio attributes. */ @SystemApi public interface OnDevicesForAttributesChangedListener { /** * Called on the listener to indicate that the audio devices for the given audio * attributes have changed. * @param attributes the {@link AudioAttributes} whose routing changed * @param devices a list of newly routed audio devices */ void onDevicesForAttributesChanged(@NonNull AudioAttributes attributes, @NonNull List<AudioDeviceAttributes> devices); } /** * @hide * Adds a listener for being notified of routing changes for the given {@link AudioAttributes}. * @param attributes the {@link AudioAttributes} to listen for routing changes * @param executor * @param listener */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void addOnDevicesForAttributesChangedListener(@NonNull AudioAttributes attributes, @NonNull @CallbackExecutor Executor executor, @NonNull OnDevicesForAttributesChangedListener listener) { Objects.requireNonNull(attributes); Objects.requireNonNull(executor); Objects.requireNonNull(listener); synchronized (mDevicesForAttributesListenerToStub) { IDevicesForAttributesCallbackStub callbackStub = mDevicesForAttributesListenerToStub.get(listener); if (callbackStub == null) { callbackStub = new IDevicesForAttributesCallbackStub(listener, executor); mDevicesForAttributesListenerToStub.put(listener, callbackStub); } callbackStub.register(true, attributes); } } /** * @hide * Removes a previously registered listener for being notified of routing changes for the given * {@link AudioAttributes}. * @param listener */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void removeOnDevicesForAttributesChangedListener( @NonNull OnDevicesForAttributesChangedListener listener) { Objects.requireNonNull(listener); synchronized (mDevicesForAttributesListenerToStub) { IDevicesForAttributesCallbackStub callbackStub = mDevicesForAttributesListenerToStub.get(listener); if (callbackStub != null) { callbackStub.register(false, null /* attributes */); } mDevicesForAttributesListenerToStub.remove(listener); } } /** * Get the audio devices that would be used for the routing of the given audio attributes. * These are the devices anticipated to play sound from an {@link AudioTrack} created with Loading media/java/android/media/IAudioService.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.media.IAudioServerStateDispatcher; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IDevicesForAttributesCallback; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IPreferredMixerAttributesDispatcher; Loading Loading @@ -356,6 +357,12 @@ interface IAudioService { List<AudioDeviceAttributes> getDevicesForAttributesUnprotected(in AudioAttributes attributes); void addOnDevicesForAttributesChangedListener(in AudioAttributes attributes, in IDevicesForAttributesCallback callback); oneway void removeOnDevicesForAttributesChangedListener( in IDevicesForAttributesCallback callback); int setAllowedCapturePolicy(in int capturePolicy); int getAllowedCapturePolicy(); Loading media/java/android/media/IDevicesForAttributesCallback.aidl 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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 android.media; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; /** * AIDL for AudioService to signal updates of audio devices routing for attributes. * * {@hide} */ oneway interface IDevicesForAttributesCallback { void onDevicesForAttributesChanged(in AudioAttributes attributes, boolean forVolume, in List<AudioDeviceAttributes> devices); } services/core/java/com/android/server/audio/AudioService.java +20 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ import android.media.IAudioService; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IDevicesForAttributesCallback; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IPreferredMixerAttributesDispatcher; Loading Loading @@ -3124,6 +3125,25 @@ public class AudioService extends IAudioService.Stub return mAudioSystem.getDevicesForAttributes(attributes, forVolume); } /** * @see AudioManager#addOnDevicesForAttributesChangedListener( * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) */ public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback) { mAudioSystem.addOnDevicesForAttributesChangedListener( attributes, false /* forVolume */, callback); } /** * @see AudioManager#removeOnDevicesForAttributesChangedListener( * OnDevicesForAttributesChangedListener) */ public void removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback) { mAudioSystem.removeOnDevicesForAttributesChangedListener(callback); } // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, Loading Loading
core/api/system-current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -6607,6 +6607,7 @@ package android.media { public class AudioManager { method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addAssistantServicesUids(@NonNull int[]); method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public void addOnDevicesForAttributesChangedListener(@NonNull android.media.AudioAttributes, @NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnDevicesForAttributesChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnNonDefaultDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnNonDefaultDevicesForStrategyChangedListener) throws java.lang.SecurityException; method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException; Loading Loading @@ -6647,6 +6648,7 @@ package android.media { method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeAssistantServicesUids(@NonNull int[]); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removeDeviceAsNonDefaultForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public void removeOnDevicesForAttributesChangedListener(@NonNull android.media.AudioManager.OnDevicesForAttributesChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnNonDefaultDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnNonDefaultDevicesForStrategyChangedListener); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener); Loading Loading @@ -6704,6 +6706,10 @@ package android.media { field public static final int EVENT_TIMEOUT = 2; // 0x2 } public static interface AudioManager.OnDevicesForAttributesChangedListener { method public void onDevicesForAttributesChanged(@NonNull android.media.AudioAttributes, @NonNull java.util.List<android.media.AudioDeviceAttributes>); } public static interface AudioManager.OnNonDefaultDevicesForStrategyChangedListener { method public void onNonDefaultDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>); }
media/java/android/media/AudioManager.java +111 −0 Original line number Diff line number Diff line Loading @@ -5855,6 +5855,117 @@ public class AudioManager { } } // Each listener corresponds to a unique callback stub because each listener can subscribe to // different AudioAttributes. private final ConcurrentHashMap<OnDevicesForAttributesChangedListener, IDevicesForAttributesCallbackStub> mDevicesForAttributesListenerToStub = new ConcurrentHashMap<>(); private static final class IDevicesForAttributesCallbackStub extends IDevicesForAttributesCallback.Stub { ListenerInfo<OnDevicesForAttributesChangedListener> mInfo; IDevicesForAttributesCallbackStub(@NonNull OnDevicesForAttributesChangedListener listener, @NonNull Executor executor) { mInfo = new ListenerInfo<>(listener, executor); } public void register(boolean register, AudioAttributes attributes) { try { if (register) { getService().addOnDevicesForAttributesChangedListener(attributes, this); } else { getService().removeOnDevicesForAttributesChangedListener(this); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public void onDevicesForAttributesChanged(AudioAttributes attributes, boolean forVolume, List<AudioDeviceAttributes> devices) { // forVolume is ignored. The case where it is `true` is not handled. mInfo.mExecutor.execute(() -> mInfo.mListener.onDevicesForAttributesChanged( attributes, devices)); } } /** * @hide * Interface to be notified of when routing changes for the registered audio attributes. */ @SystemApi public interface OnDevicesForAttributesChangedListener { /** * Called on the listener to indicate that the audio devices for the given audio * attributes have changed. * @param attributes the {@link AudioAttributes} whose routing changed * @param devices a list of newly routed audio devices */ void onDevicesForAttributesChanged(@NonNull AudioAttributes attributes, @NonNull List<AudioDeviceAttributes> devices); } /** * @hide * Adds a listener for being notified of routing changes for the given {@link AudioAttributes}. * @param attributes the {@link AudioAttributes} to listen for routing changes * @param executor * @param listener */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void addOnDevicesForAttributesChangedListener(@NonNull AudioAttributes attributes, @NonNull @CallbackExecutor Executor executor, @NonNull OnDevicesForAttributesChangedListener listener) { Objects.requireNonNull(attributes); Objects.requireNonNull(executor); Objects.requireNonNull(listener); synchronized (mDevicesForAttributesListenerToStub) { IDevicesForAttributesCallbackStub callbackStub = mDevicesForAttributesListenerToStub.get(listener); if (callbackStub == null) { callbackStub = new IDevicesForAttributesCallbackStub(listener, executor); mDevicesForAttributesListenerToStub.put(listener, callbackStub); } callbackStub.register(true, attributes); } } /** * @hide * Removes a previously registered listener for being notified of routing changes for the given * {@link AudioAttributes}. * @param listener */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void removeOnDevicesForAttributesChangedListener( @NonNull OnDevicesForAttributesChangedListener listener) { Objects.requireNonNull(listener); synchronized (mDevicesForAttributesListenerToStub) { IDevicesForAttributesCallbackStub callbackStub = mDevicesForAttributesListenerToStub.get(listener); if (callbackStub != null) { callbackStub.register(false, null /* attributes */); } mDevicesForAttributesListenerToStub.remove(listener); } } /** * Get the audio devices that would be used for the routing of the given audio attributes. * These are the devices anticipated to play sound from an {@link AudioTrack} created with Loading
media/java/android/media/IAudioService.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.media.IAudioServerStateDispatcher; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IDevicesForAttributesCallback; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IPreferredMixerAttributesDispatcher; Loading Loading @@ -356,6 +357,12 @@ interface IAudioService { List<AudioDeviceAttributes> getDevicesForAttributesUnprotected(in AudioAttributes attributes); void addOnDevicesForAttributesChangedListener(in AudioAttributes attributes, in IDevicesForAttributesCallback callback); oneway void removeOnDevicesForAttributesChangedListener( in IDevicesForAttributesCallback callback); int setAllowedCapturePolicy(in int capturePolicy); int getAllowedCapturePolicy(); Loading
media/java/android/media/IDevicesForAttributesCallback.aidl 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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 android.media; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; /** * AIDL for AudioService to signal updates of audio devices routing for attributes. * * {@hide} */ oneway interface IDevicesForAttributesCallback { void onDevicesForAttributesChanged(in AudioAttributes attributes, boolean forVolume, in List<AudioDeviceAttributes> devices); }
services/core/java/com/android/server/audio/AudioService.java +20 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ import android.media.IAudioService; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IDevicesForAttributesCallback; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IPreferredMixerAttributesDispatcher; Loading Loading @@ -3124,6 +3125,25 @@ public class AudioService extends IAudioService.Stub return mAudioSystem.getDevicesForAttributes(attributes, forVolume); } /** * @see AudioManager#addOnDevicesForAttributesChangedListener( * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) */ public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback) { mAudioSystem.addOnDevicesForAttributesChangedListener( attributes, false /* forVolume */, callback); } /** * @see AudioManager#removeOnDevicesForAttributesChangedListener( * OnDevicesForAttributesChangedListener) */ public void removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback) { mAudioSystem.removeOnDevicesForAttributesChangedListener(callback); } // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, Loading