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

Commit 8d22ffaf authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "New APIs for immersive audio" into sc-v2-dev am: 2590c69b am: 36e20b28

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

Change-Id: I81e2a7a2f450c634986588a3d0af1875912da0fe
parents d59b61cf 36e20b28
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -20219,8 +20219,10 @@ package android.media {
    method public int getAllowedCapturePolicy();
    method public int getContentType();
    method public int getFlags();
    method public int getSpatializationBehavior();
    method public int getUsage();
    method public int getVolumeControlStream();
    method public boolean isContentSpatialized();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final int ALLOW_CAPTURE_BY_ALL = 1; // 0x1
    field public static final int ALLOW_CAPTURE_BY_NONE = 3; // 0x3
@@ -20234,6 +20236,8 @@ package android.media {
    field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1
    field public static final int FLAG_HW_AV_SYNC = 16; // 0x10
    field @Deprecated public static final int FLAG_LOW_LATENCY = 256; // 0x100
    field public static final int SPATIALIZATION_BEHAVIOR_AUTO = 0; // 0x0
    field public static final int SPATIALIZATION_BEHAVIOR_NEVER = 1; // 0x1
    field public static final int USAGE_ALARM = 4; // 0x4
    field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb
    field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc
@@ -20260,7 +20264,9 @@ package android.media {
    method public android.media.AudioAttributes.Builder setContentType(int);
    method public android.media.AudioAttributes.Builder setFlags(int);
    method @NonNull public android.media.AudioAttributes.Builder setHapticChannelsMuted(boolean);
    method @NonNull public android.media.AudioAttributes.Builder setIsContentSpatialized(boolean);
    method public android.media.AudioAttributes.Builder setLegacyStreamType(int);
    method @NonNull public android.media.AudioAttributes.Builder setSpatializationBehavior(int);
    method public android.media.AudioAttributes.Builder setUsage(int);
  }
@@ -20485,6 +20491,7 @@ package android.media {
    method public String getProperty(String);
    method public int getRingerMode();
    method @Deprecated public int getRouting(int);
    method @Nullable public android.media.Spatializer getSpatializer();
    method public int getStreamMaxVolume(int);
    method public int getStreamMinVolume(int);
    method public int getStreamVolume(int);
@@ -23897,6 +23904,19 @@ package android.media {
    method public void onLoadComplete(android.media.SoundPool, int, int);
  }
  public class Spatializer {
    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 boolean isAvailable();
    method public boolean isEnabled();
    method public void removeOnSpatializerStateChangedListener(@NonNull android.media.Spatializer.OnSpatializerStateChangedListener);
  }
  public static interface Spatializer.OnSpatializerStateChangedListener {
    method public void onSpatializerAvailableChanged(@NonNull android.media.Spatializer, boolean);
    method public void onSpatializerEnabledChanged(@NonNull android.media.Spatializer, boolean);
  }
  public final class SubtitleData {
    ctor public SubtitleData(int, long, long, @NonNull byte[]);
    method @NonNull public byte[] getData();
+7 −0
Original line number Diff line number Diff line
@@ -5411,6 +5411,13 @@ package android.media {
    field public static final android.media.RouteDiscoveryPreference EMPTY;
  }
  public class Spatializer {
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void addCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes);
    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 void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setEnabled(boolean);
  }
}
package android.media.audiofx {
+98 −1
Original line number Diff line number Diff line
@@ -459,13 +459,26 @@ public final class AudioAttributes implements Parcelable {
     */
    public static final int FLAG_CAPTURE_PRIVATE = 0x1 << 13;

    /**
     * @hide
     * Flag indicating the audio content has been processed to provide a virtual multichannel
     * audio experience
     */
    public static final int FLAG_CONTENT_SPATIALIZED = 0x1 << 14;

    /**
     * @hide
     * Flag indicating the audio content is to never be spatialized
     */
    public static final int FLAG_NEVER_SPATIALIZE = 0x1 << 15;

    // Note that even though FLAG_MUTE_HAPTIC is stored as a flag bit, it is not here since
    // it is known as a boolean value outside of AudioAttributes.
    private static final int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO
            | FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY
            | FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_NO_MEDIA_PROJECTION
            | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE;
            | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE | FLAG_CONTENT_SPATIALIZED
            | FLAG_NEVER_SPATIALIZE;
    private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
            FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
    /* mask of flags that can be set by SDK and System APIs through the Builder */
@@ -626,6 +639,49 @@ public final class AudioAttributes implements Parcelable {
        return (mFlags & FLAG_MUTE_HAPTIC) != 0;
    }

    /**
     * Return true if the audio content associated with these attributes has already been
     * spatialized, that is it has already been processed to offer a binaural or transaural
     * immersive audio experience.
     * @return {@code true} if the content has been processed
     */
    public boolean isContentSpatialized() {
        return (mFlags & FLAG_CONTENT_SPATIALIZED) != 0;
    }

    /** @hide */
    @IntDef(flag = false, value = {
            SPATIALIZATION_BEHAVIOR_AUTO,
            SPATIALIZATION_BEHAVIOR_NEVER,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SpatializationBehavior {};

    /**
     * Constant indicating the audio content associated with these attributes will follow the
     * default platform behavior with regards to which content will be spatialized or not.
     * @see #getSpatializationBehavior()
     * @see Spatializer
     */
    public static final int SPATIALIZATION_BEHAVIOR_AUTO = 0;

    /**
     * Constant indicating the audio content associated with these attributes should never
     * be virtualized.
     * @see #getSpatializationBehavior()
     * @see Spatializer
     */
    public static final int SPATIALIZATION_BEHAVIOR_NEVER = 1;

    /**
     * Return the behavior affecting whether spatialization will be used.
     * @return the spatialization behavior
     */
    public @SpatializationBehavior int getSpatializationBehavior() {
        return ((mFlags & FLAG_NEVER_SPATIALIZE) != 0)
                ? SPATIALIZATION_BEHAVIOR_NEVER : SPATIALIZATION_BEHAVIOR_AUTO;
    }

    /**
     * Return the capture policy.
     * @return the capture policy set by {@link Builder#setAllowedCapturePolicy(int)} or
@@ -669,6 +725,8 @@ public final class AudioAttributes implements Parcelable {
        private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
        private int mFlags = 0x0;
        private boolean mMuteHapticChannels = true;
        private boolean mIsContentSpatialized = false;
        private int mSpatializationBehavior = SPATIALIZATION_BEHAVIOR_AUTO;
        private HashSet<String> mTags = new HashSet<String>();
        private Bundle mBundle;
        private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
@@ -699,6 +757,8 @@ public final class AudioAttributes implements Parcelable {
            mFlags = aa.getAllFlags();
            mTags = (HashSet<String>) aa.mTags.clone();
            mMuteHapticChannels = aa.areHapticChannelsMuted();
            mIsContentSpatialized = aa.isContentSpatialized();
            mSpatializationBehavior = aa.getSpatializationBehavior();
        }

        /**
@@ -731,6 +791,12 @@ public final class AudioAttributes implements Parcelable {
            if (mMuteHapticChannels) {
                aa.mFlags |= FLAG_MUTE_HAPTIC;
            }
            if (mIsContentSpatialized) {
                aa.mFlags |= FLAG_CONTENT_SPATIALIZED;
            }
            if (mSpatializationBehavior == SPATIALIZATION_BEHAVIOR_NEVER) {
                aa.mFlags |= FLAG_NEVER_SPATIALIZE;
            }

            if (mPrivacySensitive == PRIVACY_SENSITIVE_DEFAULT) {
                // capturing for camcorder or communication is private by default to
@@ -917,6 +983,35 @@ public final class AudioAttributes implements Parcelable {
            return this;
        }

        /**
         * Specifies whether the content has already been processed for spatialization.
         * If it has, setting this to true will prevent issues such as double-processing.
         * @param isSpatialized
         * @return the same Builder instance
         */
        public @NonNull Builder setIsContentSpatialized(boolean isSpatialized) {
            mIsContentSpatialized = isSpatialized;
            return this;
        }

        /**
         * Sets the behavior affecting whether spatialization will be used.
         * @param sb the spatialization behavior
         * @return the same Builder instance
         *
         */
        public @NonNull Builder setSpatializationBehavior(@SpatializationBehavior int sb) {
            switch (sb) {
                case SPATIALIZATION_BEHAVIOR_NEVER:
                case SPATIALIZATION_BEHAVIOR_AUTO:
                    break;
                default:
                    throw new IllegalArgumentException("Invalid spatialization behavior " + sb);
            }
            mSpatializationBehavior = sb;
            return this;
        }

        /**
         * @hide
         * Replaces flags.
@@ -1002,6 +1097,8 @@ public final class AudioAttributes implements Parcelable {
                    mContentType = attributes.mContentType;
                    mFlags = attributes.getAllFlags();
                    mMuteHapticChannels = attributes.areHapticChannelsMuted();
                    mIsContentSpatialized = attributes.isContentSpatialized();
                    mSpatializationBehavior = attributes.getSpatializationBehavior();
                    mTags = attributes.mTags;
                    mBundle = attributes.mBundle;
                    mSource = attributes.mSource;
+20 −1
Original line number Diff line number Diff line
@@ -817,7 +817,7 @@ public class AudioManager {
    }

    @UnsupportedAppUsage
    private static IAudioService getService()
    static IAudioService getService()
    {
        if (sService != null) {
            return sService;
@@ -2452,6 +2452,25 @@ public class AudioManager {
        return AudioSystem.getOffloadSupport(format, attributes);
    }

    //====================================================================
    // Immersive audio

    /**
     * Return a handle to the optional platform's {@link Spatializer}
     * @return {@code null} if spatialization is not supported, the {@code Spatializer} instance
     *         otherwise.
     */
    public @Nullable Spatializer getSpatializer() {
        int level = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
        try {
            level = getService().getSpatializerImmersiveAudioLevel();
        } catch (Exception e) { /* using NONE */ }
        if (level == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
            return null;
        }
        return new Spatializer(this);
    }

    //====================================================================
    // Bluetooth SCO control
    /**
+22 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioFormat;
import android.media.AudioFocusInfo;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioRecordingConfiguration;
@@ -34,6 +35,7 @@ import android.media.IPlaybackConfigDispatcher;
import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.ISpatializerCallback;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.PlayerBase;
@@ -396,4 +398,24 @@ interface IAudioService {
    void registerModeDispatcher(IAudioModeDispatcher dispatcher);

    oneway void unregisterModeDispatcher(IAudioModeDispatcher dispatcher);

    int getSpatializerImmersiveAudioLevel();

    boolean isSpatializerEnabled();

    boolean isSpatializerAvailable();

    void setSpatializerEnabled(boolean enabled);

    boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);

    void registerSpatializerCallback(in ISpatializerCallback callback);

    void unregisterSpatializerCallback(in ISpatializerCallback callback);

    List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices();

    void addSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada);

    void removeSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada);
}
Loading