Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b24dfaec authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Automerger Merge Worker
Browse files

Merge "Spatializer: add API for monitoring output changes" into sc-v2-dev am: 31ecebec

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16036279

Change-Id: Ic9aaf7906a8f3cad566e389fa13b27f2f356611b
parents 4fd2aa3c 31ecebec
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -5416,10 +5416,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 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 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 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 @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 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 void getEffectParameter(int, @NonNull byte[]);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getHeadTrackingMode();
    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 @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 recenterHeadTracker();
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes);
@@ -5429,6 +5431,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 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 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 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_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_OTHER = 0; // 0x0
    field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_RELATIVE_DEVICE = 2; // 0x2
    field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_RELATIVE_DEVICE = 2; // 0x2
@@ -5445,6 +5448,10 @@ package android.media {
    method public void onHeadTrackingModeChanged(@NonNull android.media.Spatializer, int);
    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 {
package android.media.audiofx {
+7 −0
Original line number Original line Diff line number Diff line
@@ -38,6 +38,7 @@ import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.ISpatializerCallback;
import android.media.ISpatializerCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
import android.media.ISpatializerOutputCallback;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.PlayerBase;
import android.media.PlayerBase;
@@ -445,4 +446,10 @@ interface IAudioService {
    void setSpatializerParameter(int key, in byte[] value);
    void setSpatializerParameter(int key, in byte[] value);


    void getSpatializerParameter(int key, inout byte[] value);
    void getSpatializerParameter(int key, inout byte[] value);

    int getSpatializerOutput();

    void registerSpatializerOutputCallback(in ISpatializerOutputCallback cb);

    void unregisterSpatializerOutputCallback(in ISpatializerOutputCallback cb);
}
}
+27 −0
Original line number Original line 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);
}
+117 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package android.media;


import android.annotation.CallbackExecutor;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
@@ -298,6 +299,24 @@ public class Spatializer {
                @HeadTrackingModeSet int mode);
                @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
     * @hide
     * An interface to be notified of updates to the head to soundstage pose, as represented by the
     * An interface to be notified of updates to the head to soundstage pose, as represented by the
@@ -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
    // callback helper definitions


@@ -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));
            }
        }
    }
}
}
+21 −0
Original line number Original line Diff line number Diff line
@@ -96,6 +96,7 @@ import android.media.IRingtonePlayer;
import android.media.ISpatializerCallback;
import android.media.ISpatializerCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerOutputCallback;
import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.MediaMetrics;
import android.media.MediaMetrics;
@@ -8530,6 +8531,26 @@ public class AudioService extends IAudioService.Stub
        mSpatializerHelper.getEffectParameter(key, value);
        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
     * post a message to schedule init/release of head tracking sensors
     * @param init initialization if true, release if false
     * @param init initialization if true, release if false
Loading