Loading core/api/system-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -5377,10 +5377,12 @@ package android.media { method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void addCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void addOnHeadTrackingModeChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadTrackingModeChangedListener); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void clearOnHeadToSoundstagePoseUpdatedListener(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void clearOnSpatializerOutputChangedListener(); method @NonNull @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public java.util.List<android.media.AudioDeviceAttributes> getCompatibleAudioDevices(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getDesiredHeadTrackingMode(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void getEffectParameter(int, @NonNull byte[]); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getHeadTrackingMode(); method @IntRange(from=0) @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getOutput(); method @NonNull @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public java.util.List<java.lang.Integer> getSupportedHeadTrackingModes(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void recenterHeadTracker(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); Loading @@ -5390,6 +5392,7 @@ package android.media { method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setEnabled(boolean); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setGlobalTransform(@NonNull float[]); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setOnHeadToSoundstagePoseUpdatedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadToSoundstagePoseUpdatedListener); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setOnSpatializerOutputChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerOutputChangedListener); field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_DISABLED = -1; // 0xffffffff field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_OTHER = 0; // 0x0 field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_RELATIVE_DEVICE = 2; // 0x2 Loading @@ -5406,6 +5409,10 @@ package android.media { method public void onHeadTrackingModeChanged(@NonNull android.media.Spatializer, int); } public static interface Spatializer.OnSpatializerOutputChangedListener { method public void onSpatializerOutputChanged(@NonNull android.media.Spatializer, @IntRange(from=0) int); } } package android.media.audiofx { media/java/android/media/IAudioService.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.media.IStrategyPreferredDevicesDispatcher; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerOutputCallback; import android.media.IVolumeController; import android.media.IVolumeController; import android.media.PlayerBase; Loading Loading @@ -440,4 +441,10 @@ interface IAudioService { void setSpatializerParameter(int key, in byte[] value); void getSpatializerParameter(int key, inout byte[] value); int getSpatializerOutput(); void registerSpatializerOutputCallback(in ISpatializerOutputCallback cb); void unregisterSpatializerOutputCallback(in ISpatializerOutputCallback cb); } media/java/android/media/ISpatializerOutputCallback.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 Spatializer output changes. * * {@hide} */ oneway interface ISpatializerOutputCallback { void dispatchSpatializerOutputChanged(int output); } media/java/android/media/Spatializer.java +117 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.media; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; Loading Loading @@ -298,6 +299,24 @@ public class Spatializer { @HeadTrackingModeSet int mode); } /** * @hide * An interface to be notified of changes to the output stream used by the spatializer * effect. * @see #getOutput() */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) public interface OnSpatializerOutputChangedListener { /** * Called when the id of the output stream of the spatializer effect changed. * @param spatializer the {@code Spatializer} instance whose output is updated * @param output the id of the output stream, or 0 when there is no spatializer output */ void onSpatializerOutputChanged(@NonNull Spatializer spatializer, @IntRange(from = 0) int output); } /** * @hide * An interface to be notified of updates to the head to soundstage pose, as represented by the Loading Loading @@ -844,6 +863,73 @@ public class Spatializer { } } /** * @hide * Returns the id of the output stream used for the spatializer effect playback * @return id of the output stream, or 0 if no spatializer playback is active */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) public @IntRange(from = 0) int getOutput() { try { return mAm.getService().getSpatializerOutput(); } catch (RemoteException e) { Log.e(TAG, "Error calling getSpatializerOutput", e); return 0; } } /** * @hide * Sets the listener to receive spatializer effect output updates * @param executor the {@code Executor} handling the callbacks * @param listener the listener to register * @see #clearOnSpatializerOutputChangedListener() * @see #getOutput() */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) public void setOnSpatializerOutputChangedListener( @NonNull @CallbackExecutor Executor executor, @NonNull OnSpatializerOutputChangedListener listener) { Objects.requireNonNull(executor); Objects.requireNonNull(listener); synchronized (mOutputListenerLock) { if (mOutputListener != null) { throw new IllegalStateException("Trying to overwrite existing listener"); } mOutputListener = new ListenerInfo<OnSpatializerOutputChangedListener>(listener, executor); mOutputDispatcher = new SpatializerOutputDispatcherStub(); try { mAm.getService().registerSpatializerOutputCallback(mOutputDispatcher); } catch (RemoteException e) { mOutputListener = null; mOutputDispatcher = null; } } } /** * @hide * Clears the listener for spatializer effect output updates * @see #setOnSpatializerOutputChangedListener(Executor, OnSpatializerOutputChangedListener) */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) public void clearOnSpatializerOutputChangedListener() { synchronized (mOutputListenerLock) { if (mOutputDispatcher == null) { throw (new IllegalStateException("No listener to clear")); } try { mAm.getService().unregisterSpatializerOutputCallback(mOutputDispatcher); } catch (RemoteException e) { } mOutputListener = null; mOutputDispatcher = null; } } //----------------------------------------------------------------------------- // callback helper definitions Loading Loading @@ -969,4 +1055,35 @@ public class Spatializer { } } } //----------------------------------------------------------------------------- // output callback management and stub private final Object mOutputListenerLock = new Object(); /** * Listener for output updates */ @GuardedBy("mOutputListenerLock") private @Nullable ListenerInfo<OnSpatializerOutputChangedListener> mOutputListener; @GuardedBy("mOutputListenerLock") private @Nullable SpatializerOutputDispatcherStub mOutputDispatcher; private final class SpatializerOutputDispatcherStub extends ISpatializerOutputCallback.Stub { @Override public void dispatchSpatializerOutputChanged(int output) { // make a copy of ref to listener so callback is not executed under lock final ListenerInfo<OnSpatializerOutputChangedListener> listener; synchronized (mOutputListenerLock) { listener = mOutputListener; } if (listener == null) { return; } try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { listener.mExecutor.execute(() -> listener.mListener .onSpatializerOutputChanged(Spatializer.this, output)); } } } } services/core/java/com/android/server/audio/AudioService.java +21 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.media.IRingtonePlayer; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerOutputCallback; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.IVolumeController; import android.media.MediaMetrics; Loading Loading @@ -8498,6 +8499,26 @@ public class AudioService extends IAudioService.Stub mSpatializerHelper.getEffectParameter(key, value); } /** @see Spatializer#getOutput */ public int getSpatializerOutput() { enforceModifyDefaultAudioEffectsPermission(); return mSpatializerHelper.getOutput(); } /** @see Spatializer#setOnSpatializerOutputChangedListener */ public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { enforceModifyDefaultAudioEffectsPermission(); Objects.requireNonNull(cb); mSpatializerHelper.registerSpatializerOutputCallback(cb); } /** @see Spatializer#clearOnSpatializerOutputChangedListener */ public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { enforceModifyDefaultAudioEffectsPermission(); Objects.requireNonNull(cb); mSpatializerHelper.unregisterSpatializerOutputCallback(cb); } /** * post a message to schedule init/release of head tracking sensors * @param init initialization if true, release if false Loading Loading
core/api/system-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -5377,10 +5377,12 @@ package android.media { method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void addCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void addOnHeadTrackingModeChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadTrackingModeChangedListener); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void clearOnHeadToSoundstagePoseUpdatedListener(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void clearOnSpatializerOutputChangedListener(); method @NonNull @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public java.util.List<android.media.AudioDeviceAttributes> getCompatibleAudioDevices(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getDesiredHeadTrackingMode(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void getEffectParameter(int, @NonNull byte[]); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getHeadTrackingMode(); method @IntRange(from=0) @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getOutput(); method @NonNull @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public java.util.List<java.lang.Integer> getSupportedHeadTrackingModes(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void recenterHeadTracker(); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); Loading @@ -5390,6 +5392,7 @@ package android.media { method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setEnabled(boolean); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setGlobalTransform(@NonNull float[]); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setOnHeadToSoundstagePoseUpdatedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadToSoundstagePoseUpdatedListener); method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setOnSpatializerOutputChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerOutputChangedListener); field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_DISABLED = -1; // 0xffffffff field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_OTHER = 0; // 0x0 field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_RELATIVE_DEVICE = 2; // 0x2 Loading @@ -5406,6 +5409,10 @@ package android.media { method public void onHeadTrackingModeChanged(@NonNull android.media.Spatializer, int); } public static interface Spatializer.OnSpatializerOutputChangedListener { method public void onSpatializerOutputChanged(@NonNull android.media.Spatializer, @IntRange(from=0) int); } } package android.media.audiofx {
media/java/android/media/IAudioService.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.media.IStrategyPreferredDevicesDispatcher; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerOutputCallback; import android.media.IVolumeController; import android.media.IVolumeController; import android.media.PlayerBase; Loading Loading @@ -440,4 +441,10 @@ interface IAudioService { void setSpatializerParameter(int key, in byte[] value); void getSpatializerParameter(int key, inout byte[] value); int getSpatializerOutput(); void registerSpatializerOutputCallback(in ISpatializerOutputCallback cb); void unregisterSpatializerOutputCallback(in ISpatializerOutputCallback cb); }
media/java/android/media/ISpatializerOutputCallback.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 Spatializer output changes. * * {@hide} */ oneway interface ISpatializerOutputCallback { void dispatchSpatializerOutputChanged(int output); }
media/java/android/media/Spatializer.java +117 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.media; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; Loading Loading @@ -298,6 +299,24 @@ public class Spatializer { @HeadTrackingModeSet int mode); } /** * @hide * An interface to be notified of changes to the output stream used by the spatializer * effect. * @see #getOutput() */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) public interface OnSpatializerOutputChangedListener { /** * Called when the id of the output stream of the spatializer effect changed. * @param spatializer the {@code Spatializer} instance whose output is updated * @param output the id of the output stream, or 0 when there is no spatializer output */ void onSpatializerOutputChanged(@NonNull Spatializer spatializer, @IntRange(from = 0) int output); } /** * @hide * An interface to be notified of updates to the head to soundstage pose, as represented by the Loading Loading @@ -844,6 +863,73 @@ public class Spatializer { } } /** * @hide * Returns the id of the output stream used for the spatializer effect playback * @return id of the output stream, or 0 if no spatializer playback is active */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) public @IntRange(from = 0) int getOutput() { try { return mAm.getService().getSpatializerOutput(); } catch (RemoteException e) { Log.e(TAG, "Error calling getSpatializerOutput", e); return 0; } } /** * @hide * Sets the listener to receive spatializer effect output updates * @param executor the {@code Executor} handling the callbacks * @param listener the listener to register * @see #clearOnSpatializerOutputChangedListener() * @see #getOutput() */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) public void setOnSpatializerOutputChangedListener( @NonNull @CallbackExecutor Executor executor, @NonNull OnSpatializerOutputChangedListener listener) { Objects.requireNonNull(executor); Objects.requireNonNull(listener); synchronized (mOutputListenerLock) { if (mOutputListener != null) { throw new IllegalStateException("Trying to overwrite existing listener"); } mOutputListener = new ListenerInfo<OnSpatializerOutputChangedListener>(listener, executor); mOutputDispatcher = new SpatializerOutputDispatcherStub(); try { mAm.getService().registerSpatializerOutputCallback(mOutputDispatcher); } catch (RemoteException e) { mOutputListener = null; mOutputDispatcher = null; } } } /** * @hide * Clears the listener for spatializer effect output updates * @see #setOnSpatializerOutputChangedListener(Executor, OnSpatializerOutputChangedListener) */ @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) public void clearOnSpatializerOutputChangedListener() { synchronized (mOutputListenerLock) { if (mOutputDispatcher == null) { throw (new IllegalStateException("No listener to clear")); } try { mAm.getService().unregisterSpatializerOutputCallback(mOutputDispatcher); } catch (RemoteException e) { } mOutputListener = null; mOutputDispatcher = null; } } //----------------------------------------------------------------------------- // callback helper definitions Loading Loading @@ -969,4 +1055,35 @@ public class Spatializer { } } } //----------------------------------------------------------------------------- // output callback management and stub private final Object mOutputListenerLock = new Object(); /** * Listener for output updates */ @GuardedBy("mOutputListenerLock") private @Nullable ListenerInfo<OnSpatializerOutputChangedListener> mOutputListener; @GuardedBy("mOutputListenerLock") private @Nullable SpatializerOutputDispatcherStub mOutputDispatcher; private final class SpatializerOutputDispatcherStub extends ISpatializerOutputCallback.Stub { @Override public void dispatchSpatializerOutputChanged(int output) { // make a copy of ref to listener so callback is not executed under lock final ListenerInfo<OnSpatializerOutputChangedListener> listener; synchronized (mOutputListenerLock) { listener = mOutputListener; } if (listener == null) { return; } try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { listener.mExecutor.execute(() -> listener.mListener .onSpatializerOutputChanged(Spatializer.this, output)); } } } }
services/core/java/com/android/server/audio/AudioService.java +21 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.media.IRingtonePlayer; import android.media.ISpatializerCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerOutputCallback; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.IVolumeController; import android.media.MediaMetrics; Loading Loading @@ -8498,6 +8499,26 @@ public class AudioService extends IAudioService.Stub mSpatializerHelper.getEffectParameter(key, value); } /** @see Spatializer#getOutput */ public int getSpatializerOutput() { enforceModifyDefaultAudioEffectsPermission(); return mSpatializerHelper.getOutput(); } /** @see Spatializer#setOnSpatializerOutputChangedListener */ public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { enforceModifyDefaultAudioEffectsPermission(); Objects.requireNonNull(cb); mSpatializerHelper.registerSpatializerOutputCallback(cb); } /** @see Spatializer#clearOnSpatializerOutputChangedListener */ public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { enforceModifyDefaultAudioEffectsPermission(); Objects.requireNonNull(cb); mSpatializerHelper.unregisterSpatializerOutputCallback(cb); } /** * post a message to schedule init/release of head tracking sensors * @param init initialization if true, release if false Loading