Loading core/api/current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -23548,17 +23548,24 @@ package android.media { } public class Spatializer { method public void addOnHeadTrackerAvailableListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadTrackerAvailableListener); method public void addOnSpatializerStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerStateChangedListener); method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat); method public int getImmersiveAudioLevel(); method public boolean isAvailable(); method public boolean isEnabled(); method public boolean isHeadTrackerAvailable(); method public void removeOnHeadTrackerAvailableListener(@NonNull android.media.Spatializer.OnHeadTrackerAvailableListener); method public void removeOnSpatializerStateChangedListener(@NonNull android.media.Spatializer.OnSpatializerStateChangedListener); field public static final int SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL = 1; // 0x1 field public static final int SPATIALIZER_IMMERSIVE_LEVEL_NONE = 0; // 0x0 field public static final int SPATIALIZER_IMMERSIVE_LEVEL_OTHER = -1; // 0xffffffff } public static interface Spatializer.OnHeadTrackerAvailableListener { method public void onHeadTrackerAvailableChanged(@NonNull android.media.Spatializer, boolean); } public static interface Spatializer.OnSpatializerStateChangedListener { method public void onSpatializerAvailableChanged(@NonNull android.media.Spatializer, boolean); method public void onSpatializerEnabledChanged(@NonNull android.media.Spatializer, boolean); media/java/android/media/IAudioService.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadTrackerAvailableCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerOutputCallback; Loading Loading @@ -414,6 +415,11 @@ interface IAudioService { boolean isHeadTrackerEnabled(in AudioDeviceAttributes device); boolean isHeadTrackerAvailable(); void registerSpatializerHeadTrackerAvailableCallback( in ISpatializerHeadTrackerAvailableCallback cb, boolean register); void setSpatializerEnabled(boolean enabled); boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af); Loading media/java/android/media/ISpatializerHeadTrackerAvailableCallback.aidl 0 → 100644 +27 −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; /** * AIDL for the AudioService to signal whether audio device used by Spatializer has head tracker. * * {@hide} */ oneway interface ISpatializerHeadTrackerAvailableCallback { void dispatchSpatializerHeadTrackerAvailable(boolean available); } media/java/android/media/Spatializer.java +85 −0 Original line number Diff line number Diff line Loading @@ -185,6 +185,45 @@ public class Spatializer { return false; } /** * Returns whether a head tracker is currently available for the audio device used by the * spatializer effect. * @return true if a head tracker is available and the effect is enabled, false otherwise. * @see OnHeadTrackerAvailableListener * @see #addOnHeadTrackerAvailableListener(Executor, OnHeadTrackerAvailableListener) */ public boolean isHeadTrackerAvailable() { try { return mAm.getService().isHeadTrackerAvailable(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } return false; } /** * Adds a listener to be notified of changes to the availability of a head tracker. * @param executor the {@code Executor} handling the callback * @param listener the listener to receive availability updates * @see #removeOnHeadTrackerAvailableListener(OnHeadTrackerAvailableListener) */ public void addOnHeadTrackerAvailableListener(@NonNull @CallbackExecutor Executor executor, @NonNull OnHeadTrackerAvailableListener listener) { mHeadTrackerListenerMgr.addListener(executor, listener, "addOnHeadTrackerAvailableListener", () -> new SpatializerHeadTrackerAvailableDispatcherStub()); } /** * Removes a previously registered listener for the availability of a head tracker. * @param listener the listener previously registered with * {@link #addOnHeadTrackerAvailableListener(Executor, OnHeadTrackerAvailableListener)} */ public void removeOnHeadTrackerAvailableListener( @NonNull OnHeadTrackerAvailableListener listener) { mHeadTrackerListenerMgr.removeListener(listener, "removeOnHeadTrackerAvailableListener"); } /** @hide */ @IntDef(flag = false, value = { SPATIALIZER_IMMERSIVE_LEVEL_OTHER, Loading Loading @@ -401,6 +440,22 @@ public class Spatializer { @HeadTrackingModeSet int mode); } /** * Interface to be notified of changes to the availability of a head tracker on the audio * device to be used by the spatializer effect. */ public interface OnHeadTrackerAvailableListener { /** * Called when the availability of the head tracker changed. * @param spatializer the {@code Spatializer} instance for which the head tracker * availability was updated * @param available true if the audio device that would output audio processed by * the {@code Spatializer} has a head tracker associated with it, false * otherwise. */ void onHeadTrackerAvailableChanged(@NonNull Spatializer spatializer, boolean available); } /** * @hide Loading Loading @@ -934,6 +989,36 @@ public class Spatializer { } } //----------------------------------------------------------------------------- // head tracker availability callback management and stub /** * manages the OnHeadTrackerAvailableListener listeners and the * SpatializerHeadTrackerAvailableDispatcherStub */ private final CallbackUtil.LazyListenerManager<OnHeadTrackerAvailableListener> mHeadTrackerListenerMgr = new CallbackUtil.LazyListenerManager(); private final class SpatializerHeadTrackerAvailableDispatcherStub extends ISpatializerHeadTrackerAvailableCallback.Stub implements CallbackUtil.DispatcherStub { @Override public void register(boolean register) { try { mAm.getService().registerSpatializerHeadTrackerAvailableCallback(this, register); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } @Override @SuppressLint("GuardedBy") // lock applied inside callListeners method public void dispatchSpatializerHeadTrackerAvailable(boolean available) { mHeadTrackerListenerMgr.callListeners( (listener) -> listener.onHeadTrackerAvailableChanged( Spatializer.this, available)); } } //----------------------------------------------------------------------------- // head pose callback management and stub private final Object mPoseListenerLock = new Object(); Loading services/core/java/com/android/server/audio/AudioService.java +13 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerHeadTrackerAvailableCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerOutputCallback; import android.media.IStrategyPreferredDevicesDispatcher; Loading Loading @@ -8723,6 +8724,11 @@ public class AudioService extends IAudioService.Stub return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); } /** @see Spatializer#isHeadTrackerAvailable() */ public boolean isHeadTrackerAvailable() { return mSpatializerHelper.isHeadTrackerAvailable(); } /** @see Spatializer#setSpatializerEnabled(boolean) */ public void setSpatializerEnabled(boolean enabled) { enforceModifyDefaultAudioEffectsPermission(); Loading Loading @@ -8767,6 +8773,13 @@ public class AudioService extends IAudioService.Stub mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); } /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ public void registerSpatializerHeadTrackerAvailableCallback( @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { Objects.requireNonNull(cb); mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); } /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ public void registerHeadToSoundstagePoseCallback( @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { Loading Loading
core/api/current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -23548,17 +23548,24 @@ package android.media { } public class Spatializer { method public void addOnHeadTrackerAvailableListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadTrackerAvailableListener); method public void addOnSpatializerStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerStateChangedListener); method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat); method public int getImmersiveAudioLevel(); method public boolean isAvailable(); method public boolean isEnabled(); method public boolean isHeadTrackerAvailable(); method public void removeOnHeadTrackerAvailableListener(@NonNull android.media.Spatializer.OnHeadTrackerAvailableListener); method public void removeOnSpatializerStateChangedListener(@NonNull android.media.Spatializer.OnSpatializerStateChangedListener); field public static final int SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL = 1; // 0x1 field public static final int SPATIALIZER_IMMERSIVE_LEVEL_NONE = 0; // 0x0 field public static final int SPATIALIZER_IMMERSIVE_LEVEL_OTHER = -1; // 0xffffffff } public static interface Spatializer.OnHeadTrackerAvailableListener { method public void onHeadTrackerAvailableChanged(@NonNull android.media.Spatializer, boolean); } public static interface Spatializer.OnSpatializerStateChangedListener { method public void onSpatializerAvailableChanged(@NonNull android.media.Spatializer, boolean); method public void onSpatializerEnabledChanged(@NonNull android.media.Spatializer, boolean);
media/java/android/media/IAudioService.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadTrackerAvailableCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerOutputCallback; Loading Loading @@ -414,6 +415,11 @@ interface IAudioService { boolean isHeadTrackerEnabled(in AudioDeviceAttributes device); boolean isHeadTrackerAvailable(); void registerSpatializerHeadTrackerAvailableCallback( in ISpatializerHeadTrackerAvailableCallback cb, boolean register); void setSpatializerEnabled(boolean enabled); boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af); Loading
media/java/android/media/ISpatializerHeadTrackerAvailableCallback.aidl 0 → 100644 +27 −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; /** * AIDL for the AudioService to signal whether audio device used by Spatializer has head tracker. * * {@hide} */ oneway interface ISpatializerHeadTrackerAvailableCallback { void dispatchSpatializerHeadTrackerAvailable(boolean available); }
media/java/android/media/Spatializer.java +85 −0 Original line number Diff line number Diff line Loading @@ -185,6 +185,45 @@ public class Spatializer { return false; } /** * Returns whether a head tracker is currently available for the audio device used by the * spatializer effect. * @return true if a head tracker is available and the effect is enabled, false otherwise. * @see OnHeadTrackerAvailableListener * @see #addOnHeadTrackerAvailableListener(Executor, OnHeadTrackerAvailableListener) */ public boolean isHeadTrackerAvailable() { try { return mAm.getService().isHeadTrackerAvailable(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } return false; } /** * Adds a listener to be notified of changes to the availability of a head tracker. * @param executor the {@code Executor} handling the callback * @param listener the listener to receive availability updates * @see #removeOnHeadTrackerAvailableListener(OnHeadTrackerAvailableListener) */ public void addOnHeadTrackerAvailableListener(@NonNull @CallbackExecutor Executor executor, @NonNull OnHeadTrackerAvailableListener listener) { mHeadTrackerListenerMgr.addListener(executor, listener, "addOnHeadTrackerAvailableListener", () -> new SpatializerHeadTrackerAvailableDispatcherStub()); } /** * Removes a previously registered listener for the availability of a head tracker. * @param listener the listener previously registered with * {@link #addOnHeadTrackerAvailableListener(Executor, OnHeadTrackerAvailableListener)} */ public void removeOnHeadTrackerAvailableListener( @NonNull OnHeadTrackerAvailableListener listener) { mHeadTrackerListenerMgr.removeListener(listener, "removeOnHeadTrackerAvailableListener"); } /** @hide */ @IntDef(flag = false, value = { SPATIALIZER_IMMERSIVE_LEVEL_OTHER, Loading Loading @@ -401,6 +440,22 @@ public class Spatializer { @HeadTrackingModeSet int mode); } /** * Interface to be notified of changes to the availability of a head tracker on the audio * device to be used by the spatializer effect. */ public interface OnHeadTrackerAvailableListener { /** * Called when the availability of the head tracker changed. * @param spatializer the {@code Spatializer} instance for which the head tracker * availability was updated * @param available true if the audio device that would output audio processed by * the {@code Spatializer} has a head tracker associated with it, false * otherwise. */ void onHeadTrackerAvailableChanged(@NonNull Spatializer spatializer, boolean available); } /** * @hide Loading Loading @@ -934,6 +989,36 @@ public class Spatializer { } } //----------------------------------------------------------------------------- // head tracker availability callback management and stub /** * manages the OnHeadTrackerAvailableListener listeners and the * SpatializerHeadTrackerAvailableDispatcherStub */ private final CallbackUtil.LazyListenerManager<OnHeadTrackerAvailableListener> mHeadTrackerListenerMgr = new CallbackUtil.LazyListenerManager(); private final class SpatializerHeadTrackerAvailableDispatcherStub extends ISpatializerHeadTrackerAvailableCallback.Stub implements CallbackUtil.DispatcherStub { @Override public void register(boolean register) { try { mAm.getService().registerSpatializerHeadTrackerAvailableCallback(this, register); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } @Override @SuppressLint("GuardedBy") // lock applied inside callListeners method public void dispatchSpatializerHeadTrackerAvailable(boolean available) { mHeadTrackerListenerMgr.callListeners( (listener) -> listener.onHeadTrackerAvailableChanged( Spatializer.this, available)); } } //----------------------------------------------------------------------------- // head pose callback management and stub private final Object mPoseListenerLock = new Object(); Loading
services/core/java/com/android/server/audio/AudioService.java +13 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerHeadTrackerAvailableCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerOutputCallback; import android.media.IStrategyPreferredDevicesDispatcher; Loading Loading @@ -8723,6 +8724,11 @@ public class AudioService extends IAudioService.Stub return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); } /** @see Spatializer#isHeadTrackerAvailable() */ public boolean isHeadTrackerAvailable() { return mSpatializerHelper.isHeadTrackerAvailable(); } /** @see Spatializer#setSpatializerEnabled(boolean) */ public void setSpatializerEnabled(boolean enabled) { enforceModifyDefaultAudioEffectsPermission(); Loading Loading @@ -8767,6 +8773,13 @@ public class AudioService extends IAudioService.Stub mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); } /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ public void registerSpatializerHeadTrackerAvailableCallback( @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { Objects.requireNonNull(cb); mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); } /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ public void registerHeadToSoundstagePoseCallback( @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { Loading