Merge "Utilities for managing event listeners from AudioService 2/2"
This commit is contained in:
committed by
Android (Google) Code Review
commit
fe952b8df6
@@ -2995,19 +2995,17 @@ public class AudioManager {
|
||||
void onModeChanged(@AudioMode int mode);
|
||||
}
|
||||
|
||||
private final Object mModeListenerLock = new Object();
|
||||
/**
|
||||
* List of listeners for audio mode and their associated Executor.
|
||||
* List is lazy-initialized on first registration
|
||||
* manages the OnModeChangedListener listeners and the ModeDispatcherStub
|
||||
*/
|
||||
@GuardedBy("mModeListenerLock")
|
||||
private @Nullable ArrayList<ListenerInfo<OnModeChangedListener>> mModeListeners;
|
||||
private final CallbackUtil.LazyListenerManager<OnModeChangedListener> mModeChangedListenerMgr =
|
||||
new CallbackUtil.LazyListenerManager();
|
||||
|
||||
@GuardedBy("mModeListenerLock")
|
||||
private ModeDispatcherStub mModeDispatcherStub;
|
||||
|
||||
private final class ModeDispatcherStub extends IAudioModeDispatcher.Stub {
|
||||
final class ModeDispatcherStub extends IAudioModeDispatcher.Stub
|
||||
implements CallbackUtil.DispatcherStub {
|
||||
|
||||
@Override
|
||||
public void register(boolean register) {
|
||||
try {
|
||||
if (register) {
|
||||
@@ -3021,10 +3019,8 @@ public class AudioManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
public void dispatchAudioModeChanged(int mode) {
|
||||
CallbackUtil.callListeners(mModeListeners, mModeListenerLock,
|
||||
(listener) -> listener.onModeChanged(mode));
|
||||
mModeChangedListenerMgr.callListeners((listener) -> listener.onModeChanged(mode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3037,15 +3033,8 @@ public class AudioManager {
|
||||
public void addOnModeChangedListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull OnModeChangedListener listener) {
|
||||
synchronized (mModeListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnModeChangedListener>>, ModeDispatcherStub> res =
|
||||
CallbackUtil.addListener("addOnModeChangedListener",
|
||||
executor, listener, mModeListeners, mModeDispatcherStub,
|
||||
() -> new ModeDispatcherStub(),
|
||||
stub -> stub.register(true));
|
||||
mModeListeners = res.first;
|
||||
mModeDispatcherStub = res.second;
|
||||
}
|
||||
mModeChangedListenerMgr.addListener(executor, listener, "addOnModeChangedListener",
|
||||
() -> new ModeDispatcherStub());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3054,14 +3043,7 @@ public class AudioManager {
|
||||
* @param listener
|
||||
*/
|
||||
public void removeOnModeChangedListener(@NonNull OnModeChangedListener listener) {
|
||||
synchronized (mModeListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnModeChangedListener>>, ModeDispatcherStub> res =
|
||||
CallbackUtil.removeListener("removeOnModeChangedListener",
|
||||
listener, mModeListeners, mModeDispatcherStub,
|
||||
stub -> stub.register(false));
|
||||
mModeListeners = res.first;
|
||||
mModeDispatcherStub = res.second;
|
||||
}
|
||||
mModeChangedListenerMgr.removeListener(listener, "removeOnModeChangedListener");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7717,6 +7699,12 @@ public class AudioManager {
|
||||
void onCommunicationDeviceChanged(@Nullable AudioDeviceInfo device);
|
||||
}
|
||||
|
||||
/**
|
||||
* manages the OnCommunicationDeviceChangedListener listeners and the
|
||||
* CommunicationDeviceDispatcherStub
|
||||
*/
|
||||
private final CallbackUtil.LazyListenerManager<OnCommunicationDeviceChangedListener>
|
||||
mCommDeviceChangedListenerMgr = new CallbackUtil.LazyListenerManager();
|
||||
/**
|
||||
* Adds a listener for being notified of changes to the communication audio device.
|
||||
* See {@link #setCommunicationDevice(AudioDeviceInfo)}.
|
||||
@@ -7726,16 +7714,9 @@ public class AudioManager {
|
||||
public void addOnCommunicationDeviceChangedListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull OnCommunicationDeviceChangedListener listener) {
|
||||
synchronized (mCommDevListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnCommunicationDeviceChangedListener>>,
|
||||
CommunicationDeviceDispatcherStub> res =
|
||||
CallbackUtil.addListener("addOnCommunicationDeviceChangedListener",
|
||||
executor, listener, mCommDevListeners, mCommDevDispatcherStub,
|
||||
() -> new CommunicationDeviceDispatcherStub(),
|
||||
stub -> stub.register(true));
|
||||
mCommDevListeners = res.first;
|
||||
mCommDevDispatcherStub = res.second;
|
||||
}
|
||||
mCommDeviceChangedListenerMgr.addListener(
|
||||
executor, listener, "addOnCommunicationDeviceChangedListener",
|
||||
() -> new CommunicationDeviceDispatcherStub());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7745,32 +7726,14 @@ public class AudioManager {
|
||||
*/
|
||||
public void removeOnCommunicationDeviceChangedListener(
|
||||
@NonNull OnCommunicationDeviceChangedListener listener) {
|
||||
synchronized (mCommDevListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnCommunicationDeviceChangedListener>>,
|
||||
CommunicationDeviceDispatcherStub> res =
|
||||
CallbackUtil.removeListener("removeOnCommunicationDeviceChangedListener",
|
||||
listener, mCommDevListeners, mCommDevDispatcherStub,
|
||||
stub -> stub.register(false));
|
||||
mCommDevListeners = res.first;
|
||||
mCommDevDispatcherStub = res.second;
|
||||
}
|
||||
mCommDeviceChangedListenerMgr.removeListener(listener,
|
||||
"removeOnCommunicationDeviceChangedListener");
|
||||
}
|
||||
|
||||
private final Object mCommDevListenerLock = new Object();
|
||||
/**
|
||||
* List of listeners for preferred device for strategy and their associated Executor.
|
||||
* List is lazy-initialized on first registration
|
||||
*/
|
||||
@GuardedBy("mCommDevListenerLock")
|
||||
private @Nullable
|
||||
ArrayList<ListenerInfo<OnCommunicationDeviceChangedListener>> mCommDevListeners;
|
||||
|
||||
@GuardedBy("mCommDevListenerLock")
|
||||
private CommunicationDeviceDispatcherStub mCommDevDispatcherStub;
|
||||
|
||||
private final class CommunicationDeviceDispatcherStub
|
||||
extends ICommunicationDeviceDispatcher.Stub {
|
||||
extends ICommunicationDeviceDispatcher.Stub implements CallbackUtil.DispatcherStub {
|
||||
|
||||
@Override
|
||||
public void register(boolean register) {
|
||||
try {
|
||||
if (register) {
|
||||
@@ -7784,10 +7747,9 @@ public class AudioManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
public void dispatchCommunicationDeviceChanged(int portId) {
|
||||
AudioDeviceInfo device = getDeviceForPortId(portId, GET_DEVICES_OUTPUTS);
|
||||
CallbackUtil.callListeners(mCommDevListeners, mCommDevListenerLock,
|
||||
mCommDeviceChangedListenerMgr.callListeners(
|
||||
(listener) -> listener.onCommunicationDeviceChanged(device));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,14 @@ package android.media;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.media.permission.ClearCallingIdentityContext;
|
||||
import android.media.permission.SafeCloseable;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -221,4 +224,87 @@ import java.util.concurrent.Executor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface to be implemented by stub implementation for the events received from a server
|
||||
* to the class managing the listener API.
|
||||
* For an example see {@link AudioManager#ModeDispatcherStub} which registers with AudioService.
|
||||
*/
|
||||
interface DispatcherStub {
|
||||
/**
|
||||
* Register/unregister the stub as a listener of the events to be forwarded to the listeners
|
||||
* managed by LazyListenerManager.
|
||||
* @param register true for registering, false to unregister
|
||||
*/
|
||||
void register(boolean register);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to manage a list of listeners and their callback, and the associated stub which
|
||||
* receives the events to be forwarded to the listeners.
|
||||
* The list of listeners and the stub and its registration are lazily initialized and registered
|
||||
* @param <T> the listener class
|
||||
*/
|
||||
static class LazyListenerManager<T> {
|
||||
private final Object mListenerLock = new Object();
|
||||
|
||||
@GuardedBy("mListenerLock")
|
||||
private @Nullable ArrayList<ListenerInfo<T>> mListeners;
|
||||
|
||||
@GuardedBy("mListenerLock")
|
||||
private @Nullable DispatcherStub mDispatcherStub;
|
||||
|
||||
LazyListenerManager() {
|
||||
// nothing to initialize as instances of dispatcher and list of listeners
|
||||
// are lazily initialized
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new listener / executor pair for the configured listener
|
||||
* @param executor Executor for the callback
|
||||
* @param listener the listener to register
|
||||
* @param methodName the name of the method calling this utility method for easier to read
|
||||
* exception messages
|
||||
* @param newStub how to build a new instance of the stub receiving the events when the
|
||||
* number of listeners goes from 0 to 1, not called until then.
|
||||
*/
|
||||
void addListener(@NonNull Executor executor, @NonNull T listener, String methodName,
|
||||
@NonNull java.util.function.Supplier<DispatcherStub> newStub) {
|
||||
synchronized (mListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<T>>, DispatcherStub> res =
|
||||
CallbackUtil.addListener(methodName,
|
||||
executor, listener, mListeners, mDispatcherStub,
|
||||
newStub,
|
||||
stub -> stub.register(true));
|
||||
mListeners = res.first;
|
||||
mDispatcherStub = res.second;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a previously registered listener
|
||||
* @param listener the listener to unregister
|
||||
* @param methodName the name of the method calling this utility method for easier to read
|
||||
* exception messages
|
||||
*/
|
||||
void removeListener(@NonNull T listener, String methodName) {
|
||||
synchronized (mListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<T>>, DispatcherStub> res =
|
||||
CallbackUtil.removeListener(methodName,
|
||||
listener, mListeners, mDispatcherStub,
|
||||
stub -> stub.register(false));
|
||||
mListeners = res.first;
|
||||
mDispatcherStub = res.second;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the registered listeners with the given callback method
|
||||
* @param callback the listener method to invoke
|
||||
*/
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
void callListeners(CallbackMethod<T> callback) {
|
||||
CallbackUtil.callListeners(mListeners, mListenerLock, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.media.permission.ClearCallingIdentityContext;
|
||||
import android.media.permission.SafeCloseable;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
@@ -376,16 +375,8 @@ public class Spatializer {
|
||||
public void addOnSpatializerStateChangedListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull OnSpatializerStateChangedListener listener) {
|
||||
synchronized (mStateListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnSpatializerStateChangedListener>>,
|
||||
SpatializerInfoDispatcherStub> res =
|
||||
CallbackUtil.addListener("addOnSpatializerStateChangedListener",
|
||||
executor, listener, mStateListeners, mInfoDispatcherStub,
|
||||
() -> new SpatializerInfoDispatcherStub(),
|
||||
stub -> stub.register(true));
|
||||
mStateListeners = res.first;
|
||||
mInfoDispatcherStub = res.second;
|
||||
}
|
||||
mStateListenerMgr.addListener(executor, listener, "addOnSpatializerStateChangedListener",
|
||||
() -> new SpatializerInfoDispatcherStub());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,15 +387,7 @@ public class Spatializer {
|
||||
*/
|
||||
public void removeOnSpatializerStateChangedListener(
|
||||
@NonNull OnSpatializerStateChangedListener listener) {
|
||||
synchronized (mStateListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnSpatializerStateChangedListener>>,
|
||||
SpatializerInfoDispatcherStub> res =
|
||||
CallbackUtil.removeListener("removeOnSpatializerStateChangedListener",
|
||||
listener, mStateListeners, mInfoDispatcherStub,
|
||||
stub -> stub.register(false));
|
||||
mStateListeners = res.first;
|
||||
mInfoDispatcherStub = res.second;
|
||||
}
|
||||
mStateListenerMgr.removeListener(listener, "removeOnSpatializerStateChangedListener");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -459,18 +442,16 @@ public class Spatializer {
|
||||
}
|
||||
}
|
||||
|
||||
private final Object mStateListenerLock = new Object();
|
||||
/**
|
||||
* List of listeners for state listener and their associated Executor.
|
||||
* List is lazy-initialized on first registration
|
||||
* manages the OnSpatializerStateChangedListener listeners and the
|
||||
* SpatializerInfoDispatcherStub
|
||||
*/
|
||||
@GuardedBy("mStateListenerLock")
|
||||
private @Nullable ArrayList<ListenerInfo<OnSpatializerStateChangedListener>> mStateListeners;
|
||||
private final CallbackUtil.LazyListenerManager<OnSpatializerStateChangedListener>
|
||||
mStateListenerMgr = new CallbackUtil.LazyListenerManager();
|
||||
|
||||
@GuardedBy("mStateListenerLock")
|
||||
private @Nullable SpatializerInfoDispatcherStub mInfoDispatcherStub;
|
||||
|
||||
private final class SpatializerInfoDispatcherStub extends ISpatializerCallback.Stub {
|
||||
private final class SpatializerInfoDispatcherStub extends ISpatializerCallback.Stub
|
||||
implements CallbackUtil.DispatcherStub {
|
||||
@Override
|
||||
public void register(boolean register) {
|
||||
try {
|
||||
if (register) {
|
||||
@@ -486,7 +467,7 @@ public class Spatializer {
|
||||
@Override
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
public void dispatchSpatializerEnabledChanged(boolean enabled) {
|
||||
CallbackUtil.callListeners(mStateListeners, mStateListenerLock,
|
||||
mStateListenerMgr.callListeners(
|
||||
(listener) -> listener.onSpatializerEnabledChanged(
|
||||
Spatializer.this, enabled));
|
||||
}
|
||||
@@ -494,7 +475,7 @@ public class Spatializer {
|
||||
@Override
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
public void dispatchSpatializerAvailableChanged(boolean available) {
|
||||
CallbackUtil.callListeners(mStateListeners, mStateListenerLock,
|
||||
mStateListenerMgr.callListeners(
|
||||
(listener) -> listener.onSpatializerAvailableChanged(
|
||||
Spatializer.this, available));
|
||||
}
|
||||
@@ -612,16 +593,9 @@ public class Spatializer {
|
||||
public void addOnHeadTrackingModeChangedListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull OnHeadTrackingModeChangedListener listener) {
|
||||
synchronized (mHeadTrackingListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnHeadTrackingModeChangedListener>>,
|
||||
SpatializerHeadTrackingDispatcherStub> res = CallbackUtil.addListener(
|
||||
"addOnHeadTrackingModeChangedListener", executor, listener,
|
||||
mHeadTrackingListeners, mHeadTrackingDispatcherStub,
|
||||
() -> new SpatializerHeadTrackingDispatcherStub(),
|
||||
stub -> stub.register(true));
|
||||
mHeadTrackingListeners = res.first;
|
||||
mHeadTrackingDispatcherStub = res.second;
|
||||
}
|
||||
mHeadTrackingListenerMgr.addListener(executor, listener,
|
||||
"addOnHeadTrackingModeChangedListener",
|
||||
() -> new SpatializerHeadTrackingDispatcherStub());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -634,15 +608,8 @@ public class Spatializer {
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
|
||||
public void removeOnHeadTrackingModeChangedListener(
|
||||
@NonNull OnHeadTrackingModeChangedListener listener) {
|
||||
synchronized (mHeadTrackingListenerLock) {
|
||||
final Pair<ArrayList<ListenerInfo<OnHeadTrackingModeChangedListener>>,
|
||||
SpatializerHeadTrackingDispatcherStub> res = CallbackUtil.removeListener(
|
||||
"removeOnHeadTrackingModeChangedListener", listener,
|
||||
mHeadTrackingListeners, mHeadTrackingDispatcherStub,
|
||||
stub -> stub.register(false));
|
||||
mHeadTrackingListeners = res.first;
|
||||
mHeadTrackingDispatcherStub = res.second;
|
||||
}
|
||||
mHeadTrackingListenerMgr.removeListener(listener,
|
||||
"removeOnHeadTrackingModeChangedListener");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -828,20 +795,17 @@ public class Spatializer {
|
||||
//-----------------------------------------------------------------------------
|
||||
// head tracking callback management and stub
|
||||
|
||||
private final Object mHeadTrackingListenerLock = new Object();
|
||||
/**
|
||||
* List of listeners for head tracking mode listener and their associated Executor.
|
||||
* List is lazy-initialized on first registration
|
||||
* manages the OnHeadTrackingModeChangedListener listeners and the
|
||||
* SpatializerHeadTrackingDispatcherStub
|
||||
*/
|
||||
@GuardedBy("mHeadTrackingListenerLock")
|
||||
private @Nullable ArrayList<ListenerInfo<OnHeadTrackingModeChangedListener>>
|
||||
mHeadTrackingListeners;
|
||||
|
||||
@GuardedBy("mHeadTrackingListenerLock")
|
||||
private @Nullable SpatializerHeadTrackingDispatcherStub mHeadTrackingDispatcherStub;
|
||||
private final CallbackUtil.LazyListenerManager<OnHeadTrackingModeChangedListener>
|
||||
mHeadTrackingListenerMgr = new CallbackUtil.LazyListenerManager();
|
||||
|
||||
private final class SpatializerHeadTrackingDispatcherStub
|
||||
extends ISpatializerHeadTrackingModeCallback.Stub {
|
||||
extends ISpatializerHeadTrackingModeCallback.Stub
|
||||
implements CallbackUtil.DispatcherStub {
|
||||
@Override
|
||||
public void register(boolean register) {
|
||||
try {
|
||||
if (register) {
|
||||
@@ -857,14 +821,14 @@ public class Spatializer {
|
||||
@Override
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
public void dispatchSpatializerActualHeadTrackingModeChanged(int mode) {
|
||||
CallbackUtil.callListeners(mHeadTrackingListeners, mHeadTrackingListenerLock,
|
||||
mHeadTrackingListenerMgr.callListeners(
|
||||
(listener) -> listener.onHeadTrackingModeChanged(Spatializer.this, mode));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("GuardedBy") // lock applied inside callListeners method
|
||||
public void dispatchSpatializerDesiredHeadTrackingModeChanged(int mode) {
|
||||
CallbackUtil.callListeners(mHeadTrackingListeners, mHeadTrackingListenerLock,
|
||||
mHeadTrackingListenerMgr.callListeners(
|
||||
(listener) -> listener.onDesiredHeadTrackingModeChanged(
|
||||
Spatializer.this, mode));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user