Merge "AudioPolicy: add synchronous unregister method"
This commit is contained in:
committed by
Android (Google) Code Review
commit
b64c10bc06
@@ -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
|
||||
|
||||
@@ -3308,6 +3308,7 @@ public class AudioManager {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Unregisters an {@link AudioPolicy} asynchronously.
|
||||
* @param policy the non-null {@link AudioPolicy} to unregister.
|
||||
*/
|
||||
@SystemApi
|
||||
@@ -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
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user