Loading media/java/android/media/AudioManager.java +24 −62 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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)); } } Loading @@ -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()); } /** Loading @@ -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"); } /** Loading Loading @@ -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)}. Loading @@ -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()); } /** Loading @@ -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) { Loading @@ -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)); } } Loading media/java/android/media/CallbackUtil.java +86 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } } media/java/android/media/Spatializer.java +26 −62 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()); } /** Loading @@ -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"); } /** Loading Loading @@ -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) { Loading @@ -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)); } Loading @@ -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)); } Loading Loading @@ -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()); } /** Loading @@ -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"); } /** Loading Loading @@ -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) { Loading @@ -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)); } Loading Loading
media/java/android/media/AudioManager.java +24 −62 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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)); } } Loading @@ -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()); } /** Loading @@ -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"); } /** Loading Loading @@ -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)}. Loading @@ -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()); } /** Loading @@ -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) { Loading @@ -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)); } } Loading
media/java/android/media/CallbackUtil.java +86 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } }
media/java/android/media/Spatializer.java +26 −62 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()); } /** Loading @@ -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"); } /** Loading Loading @@ -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) { Loading @@ -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)); } Loading @@ -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)); } Loading Loading @@ -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()); } /** Loading @@ -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"); } /** Loading Loading @@ -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) { Loading @@ -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)); } Loading