Loading api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3487,6 +3487,7 @@ package android.media { method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy); method public void unregisterVolumeGroupCallback(@NonNull android.media.AudioManager.VolumeGroupCallback); field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1 Loading media/java/android/media/AudioManager.java +22 −0 Original line number Diff line number Diff line Loading @@ -3308,6 +3308,7 @@ public class AudioManager { /** * @hide * Unregisters an {@link AudioPolicy} asynchronously. * @param policy the non-null {@link AudioPolicy} to unregister. */ @SystemApi Loading @@ -3329,6 +3330,27 @@ public class AudioManager { } } /** * @hide * Unregisters an {@link AudioPolicy} synchronously. * This method also invalidates all {@link AudioRecord} and {@link AudioTrack} objects * associated with mixes of this policy. * @param policy the non-null {@link AudioPolicy} to unregister. */ @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull AudioPolicy policy) { Preconditions.checkNotNull(policy, "Illegal null AudioPolicy argument"); final IAudioService service = getService(); try { policy.invalidateCaptorsAndInjectors(); service.unregisterAudioPolicy(policy.cb()); policy.setRegistration(null); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } //==================================================================== // Notification of playback activity & playback configuration /** Loading media/java/android/media/IAudioService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ interface IAudioService { oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb); void unregisterAudioPolicy(in IAudioPolicyCallback pcb); int addMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb); int removeMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb); Loading media/java/android/media/audiopolicy/AudioPolicy.java +60 −0 Original line number Diff line number Diff line Loading @@ -43,8 +43,11 @@ import android.os.ServiceManager; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; Loading Loading @@ -73,6 +76,19 @@ public class AudioPolicy { private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy; /** * The list of AudioTrack instances created to inject audio into the associated mixes * Lazy initialization in {@link #createAudioTrackSource(AudioMix)} */ @GuardedBy("mLock") @Nullable private ArrayList<WeakReference<AudioTrack>> mInjectors; /** * The list AudioRecord instances created to capture audio from the associated mixes * Lazy initialization in {@link #createAudioRecordSink(AudioMix)} */ @GuardedBy("mLock") @Nullable private ArrayList<WeakReference<AudioRecord>> mCaptors; /** * The behavior of a policy with regards to audio focus where it relies on the application * to do the ducking, the is the legacy and default behavior. Loading Loading @@ -606,6 +622,12 @@ public class AudioPolicy { AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()), AudioManager.AUDIO_SESSION_ID_GENERATE ); synchronized (mLock) { if (mCaptors == null) { mCaptors = new ArrayList<>(1); } mCaptors.add(new WeakReference<AudioRecord>(ar)); } return ar; } Loading Loading @@ -638,9 +660,47 @@ public class AudioPolicy { AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE ); synchronized (mLock) { if (mInjectors == null) { mInjectors = new ArrayList<>(1); } mInjectors.add(new WeakReference<AudioTrack>(at)); } return at; } /** * @hide */ public void invalidateCaptorsAndInjectors() { if (!policyReadyToUse()) { return; } synchronized (mLock) { if (mInjectors != null) { for (final WeakReference<AudioTrack> weakTrack : mInjectors) { final AudioTrack track = weakTrack.get(); if (track == null) { break; } // TODO: add synchronous versions track.stop(); track.flush(); } } if (mCaptors != null) { for (final WeakReference<AudioRecord> weakRecord : mCaptors) { final AudioRecord record = weakRecord.get(); if (record == null) { break; } // TODO: if needed: implement an invalidate method record.stop(); } } } } public int getStatus() { return mStatus; } Loading services/core/java/com/android/server/audio/AudioService.java +22 −1 Original line number Diff line number Diff line Loading @@ -6387,7 +6387,28 @@ public class AudioService extends IAudioService.Stub return mProjectionService; } public void unregisterAudioPolicyAsync(IAudioPolicyCallback pcb) { /** * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} * Declared oneway * @param pcb nullable because on service interface */ public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { unregisterAudioPolicy(pcb); } /** * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} * @param pcb nullable because on service interface */ public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { if (pcb == null) { return; } unregisterAudioPolicyInt(pcb); } private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb) { mDynPolicyLogger.log((new AudioEventLogger.StringEvent("unregisterAudioPolicyAsync for " + pcb.asBinder()).printLog(TAG))); synchronized (mAudioPolicies) { Loading Loading
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3487,6 +3487,7 @@ package android.media { method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy); method public void unregisterVolumeGroupCallback(@NonNull android.media.AudioManager.VolumeGroupCallback); field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1 Loading
media/java/android/media/AudioManager.java +22 −0 Original line number Diff line number Diff line Loading @@ -3308,6 +3308,7 @@ public class AudioManager { /** * @hide * Unregisters an {@link AudioPolicy} asynchronously. * @param policy the non-null {@link AudioPolicy} to unregister. */ @SystemApi Loading @@ -3329,6 +3330,27 @@ public class AudioManager { } } /** * @hide * Unregisters an {@link AudioPolicy} synchronously. * This method also invalidates all {@link AudioRecord} and {@link AudioTrack} objects * associated with mixes of this policy. * @param policy the non-null {@link AudioPolicy} to unregister. */ @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull AudioPolicy policy) { Preconditions.checkNotNull(policy, "Illegal null AudioPolicy argument"); final IAudioService service = getService(); try { policy.invalidateCaptorsAndInjectors(); service.unregisterAudioPolicy(policy.cb()); policy.setRegistration(null); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } //==================================================================== // Notification of playback activity & playback configuration /** Loading
media/java/android/media/IAudioService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ interface IAudioService { oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb); void unregisterAudioPolicy(in IAudioPolicyCallback pcb); int addMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb); int removeMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb); Loading
media/java/android/media/audiopolicy/AudioPolicy.java +60 −0 Original line number Diff line number Diff line Loading @@ -43,8 +43,11 @@ import android.os.ServiceManager; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; Loading Loading @@ -73,6 +76,19 @@ public class AudioPolicy { private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy; /** * The list of AudioTrack instances created to inject audio into the associated mixes * Lazy initialization in {@link #createAudioTrackSource(AudioMix)} */ @GuardedBy("mLock") @Nullable private ArrayList<WeakReference<AudioTrack>> mInjectors; /** * The list AudioRecord instances created to capture audio from the associated mixes * Lazy initialization in {@link #createAudioRecordSink(AudioMix)} */ @GuardedBy("mLock") @Nullable private ArrayList<WeakReference<AudioRecord>> mCaptors; /** * The behavior of a policy with regards to audio focus where it relies on the application * to do the ducking, the is the legacy and default behavior. Loading Loading @@ -606,6 +622,12 @@ public class AudioPolicy { AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()), AudioManager.AUDIO_SESSION_ID_GENERATE ); synchronized (mLock) { if (mCaptors == null) { mCaptors = new ArrayList<>(1); } mCaptors.add(new WeakReference<AudioRecord>(ar)); } return ar; } Loading Loading @@ -638,9 +660,47 @@ public class AudioPolicy { AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE ); synchronized (mLock) { if (mInjectors == null) { mInjectors = new ArrayList<>(1); } mInjectors.add(new WeakReference<AudioTrack>(at)); } return at; } /** * @hide */ public void invalidateCaptorsAndInjectors() { if (!policyReadyToUse()) { return; } synchronized (mLock) { if (mInjectors != null) { for (final WeakReference<AudioTrack> weakTrack : mInjectors) { final AudioTrack track = weakTrack.get(); if (track == null) { break; } // TODO: add synchronous versions track.stop(); track.flush(); } } if (mCaptors != null) { for (final WeakReference<AudioRecord> weakRecord : mCaptors) { final AudioRecord record = weakRecord.get(); if (record == null) { break; } // TODO: if needed: implement an invalidate method record.stop(); } } } } public int getStatus() { return mStatus; } Loading
services/core/java/com/android/server/audio/AudioService.java +22 −1 Original line number Diff line number Diff line Loading @@ -6387,7 +6387,28 @@ public class AudioService extends IAudioService.Stub return mProjectionService; } public void unregisterAudioPolicyAsync(IAudioPolicyCallback pcb) { /** * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} * Declared oneway * @param pcb nullable because on service interface */ public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { unregisterAudioPolicy(pcb); } /** * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} * @param pcb nullable because on service interface */ public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { if (pcb == null) { return; } unregisterAudioPolicyInt(pcb); } private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb) { mDynPolicyLogger.log((new AudioEventLogger.StringEvent("unregisterAudioPolicyAsync for " + pcb.asBinder()).printLog(TAG))); synchronized (mAudioPolicies) { Loading