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

Commit cd5f79d2 authored by Raj Goparaju's avatar Raj Goparaju Committed by Android (Google) Code Review
Browse files

Merge changes from topic "feature_audioCrossover" into main

* changes:
  Support dispatch audio focus with fade manager config
  Add API to set fade manager configuration
  Adapt fade manager configurations
  Remove fade manager aconfig from media solutions repo
parents 68fb1e93 0428580b
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -430,10 +430,7 @@ java_aconfig_library {
aconfig_declarations {
    name: "com.android.media.flags.bettertogether-aconfig",
    package: "com.android.media.flags",
    srcs: [
        "media/java/android/media/flags/media_better_together.aconfig",
        "media/java/android/media/flags/fade_manager_configuration.aconfig",
    ],
    srcs: ["media/java/android/media/flags/media_better_together.aconfig"],
}

java_aconfig_library {
+67 −0
Original line number Diff line number Diff line
@@ -6472,6 +6472,7 @@ package android.media {
    method public void clearAudioServerStateCallback();
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
    method @FlaggedApi("android.media.audiopolicy.enable_fade_manager_configuration") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public int dispatchAudioFocusChangeWithFade(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy, @NonNull java.util.List<android.media.AudioFocusInfo>, @Nullable android.media.FadeManagerConfiguration);
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getActiveAssistantServicesUids();
    method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getAssistantServicesUids();
@@ -6671,6 +6672,69 @@ package android.media {
    field public static final int CONTENT_ID_NONE = 0; // 0x0
  }
  @FlaggedApi("android.media.audiopolicy.enable_fade_manager_configuration") public final class FadeManagerConfiguration implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public java.util.List<android.media.AudioAttributes> getAudioAttributesWithVolumeShaperConfigs();
    method public long getFadeInDelayForOffenders();
    method public long getFadeInDurationForAudioAttributes(@NonNull android.media.AudioAttributes);
    method public long getFadeInDurationForUsage(int);
    method @Nullable public android.media.VolumeShaper.Configuration getFadeInVolumeShaperConfigForAudioAttributes(@NonNull android.media.AudioAttributes);
    method @Nullable public android.media.VolumeShaper.Configuration getFadeInVolumeShaperConfigForUsage(int);
    method public long getFadeOutDurationForAudioAttributes(@NonNull android.media.AudioAttributes);
    method public long getFadeOutDurationForUsage(int);
    method @Nullable public android.media.VolumeShaper.Configuration getFadeOutVolumeShaperConfigForAudioAttributes(@NonNull android.media.AudioAttributes);
    method @Nullable public android.media.VolumeShaper.Configuration getFadeOutVolumeShaperConfigForUsage(int);
    method public int getFadeState();
    method @NonNull public java.util.List<java.lang.Integer> getFadeableUsages();
    method @NonNull public java.util.List<android.media.AudioAttributes> getUnfadeableAudioAttributes();
    method @NonNull public java.util.List<java.lang.Integer> getUnfadeableContentTypes();
    method @NonNull public java.util.List<java.lang.Integer> getUnfadeablePlayerTypes();
    method @NonNull public java.util.List<java.lang.Integer> getUnfadeableUids();
    method public boolean isAudioAttributesUnfadeable(@NonNull android.media.AudioAttributes);
    method public boolean isContentTypeUnfadeable(int);
    method public boolean isFadeEnabled();
    method public boolean isPlayerTypeUnfadeable(int);
    method public boolean isUidUnfadeable(int);
    method public boolean isUsageFadeable(int);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.FadeManagerConfiguration> CREATOR;
    field public static final long DURATION_NOT_SET = 0L; // 0x0L
    field public static final int FADE_STATE_DISABLED = 0; // 0x0
    field public static final int FADE_STATE_ENABLED_AUTO = 2; // 0x2
    field public static final int FADE_STATE_ENABLED_DEFAULT = 1; // 0x1
    field public static final String TAG = "FadeManagerConfiguration";
    field public static final int VOLUME_SHAPER_SYSTEM_FADE_ID = 2; // 0x2
  }
  public static final class FadeManagerConfiguration.Builder {
    ctor public FadeManagerConfiguration.Builder();
    ctor public FadeManagerConfiguration.Builder(long, long);
    ctor public FadeManagerConfiguration.Builder(@NonNull android.media.FadeManagerConfiguration);
    method @NonNull public android.media.FadeManagerConfiguration.Builder addFadeableUsage(int);
    method @NonNull public android.media.FadeManagerConfiguration.Builder addUnfadeableAudioAttributes(@NonNull android.media.AudioAttributes);
    method @NonNull public android.media.FadeManagerConfiguration.Builder addUnfadeableContentType(int);
    method @NonNull public android.media.FadeManagerConfiguration.Builder addUnfadeableUid(int);
    method @NonNull public android.media.FadeManagerConfiguration build();
    method @NonNull public android.media.FadeManagerConfiguration.Builder clearFadeableUsage(int);
    method @NonNull public android.media.FadeManagerConfiguration.Builder clearUnfadeableAudioAttributes(@NonNull android.media.AudioAttributes);
    method @NonNull public android.media.FadeManagerConfiguration.Builder clearUnfadeableContentType(int);
    method @NonNull public android.media.FadeManagerConfiguration.Builder clearUnfadeableUid(int);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeInDelayForOffenders(long);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeInDurationForAudioAttributes(@NonNull android.media.AudioAttributes, long);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeInDurationForUsage(int, long);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeInVolumeShaperConfigForAudioAttributes(@NonNull android.media.AudioAttributes, @Nullable android.media.VolumeShaper.Configuration);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeInVolumeShaperConfigForUsage(int, @Nullable android.media.VolumeShaper.Configuration);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeOutDurationForAudioAttributes(@NonNull android.media.AudioAttributes, long);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeOutDurationForUsage(int, long);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeOutVolumeShaperConfigForAudioAttributes(@NonNull android.media.AudioAttributes, @Nullable android.media.VolumeShaper.Configuration);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeOutVolumeShaperConfigForUsage(int, @Nullable android.media.VolumeShaper.Configuration);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeState(int);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setFadeableUsages(@NonNull java.util.List<java.lang.Integer>);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setUnfadeableAudioAttributes(@NonNull java.util.List<android.media.AudioAttributes>);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setUnfadeableContentTypes(@NonNull java.util.List<java.lang.Integer>);
    method @NonNull public android.media.FadeManagerConfiguration.Builder setUnfadeableUids(@NonNull java.util.List<java.lang.Integer>);
  }
  public class HwAudioSource {
    method public boolean isPlaying();
    method public void start();
@@ -6889,15 +6953,18 @@ package android.media.audiopolicy {
  public class AudioPolicy {
    method public int attachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
    method @FlaggedApi("android.media.audiopolicy.enable_fade_manager_configuration") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public int clearFadeManagerConfigurationForFocusLoss();
    method public android.media.AudioRecord createAudioRecordSink(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
    method public android.media.AudioTrack createAudioTrackSource(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
    method public int detachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
    method @FlaggedApi("android.media.audiopolicy.enable_fade_manager_configuration") @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public android.media.FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss();
    method public int getFocusDuckingBehavior();
    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioFocusInfo> getFocusStack();
    method public int getStatus();
    method public boolean removeUidDeviceAffinity(int);
    method public boolean removeUserIdDeviceAffinity(int);
    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean sendFocusLoss(@NonNull android.media.AudioFocusInfo) throws java.lang.IllegalStateException;
    method @FlaggedApi("android.media.audiopolicy.enable_fade_manager_configuration") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public int setFadeManagerConfigurationForFocusLoss(@NonNull android.media.FadeManagerConfiguration);
    method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
    method public void setRegistration(String);
    method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>);
+66 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.content.Context.DEVICE_ID_DEFAULT;
import static android.media.audio.Flags.autoPublicVolumeApiHardening;
import static android.media.audio.Flags.automaticBtDeviceType;
import static android.media.audio.Flags.FLAG_FOCUS_FREEZE_TEST_API;
import static android.media.audiopolicy.Flags.FLAG_ENABLE_FADE_MANAGER_CONFIGURATION;

import android.Manifest;
import android.annotation.CallbackExecutor;
@@ -5119,6 +5120,71 @@ public class AudioManager {
        }
    }

    /**
     * Notifies an application with a focus listener of gain or loss of audio focus
     *
     * <p>This is similar to {@link #dispatchAudioFocusChange(AudioFocusInfo, int, AudioPolicy)} but
     * with additional functionality  of fade. The players of the application with  audio focus
     * change, provided they meet the active {@link FadeManagerConfiguration} requirements, are
     * faded before dispatching the callback to the application. For example, players of the
     * application losing audio focus will be faded out, whereas players of the application gaining
     * audio focus will be faded in, if needed.
     *
     * <p>The applicability of fade is decided against the supplied active {@link AudioFocusInfo}.
     * This list cannot be {@code null}. The list can be empty if no other active
     * {@link AudioFocusInfo} available at the time of the dispatch.
     *
     * <p>The {@link FadeManagerConfiguration} supplied here is prioritized over existing fade
     * configurations. If none supplied, either the {@link FadeManagerConfiguration} set through
     * {@link AudioPolicy} or the default will be used to determine the fade properties.
     *
     * <p>This method can only be used by owners of an {@link AudioPolicy} configured with
     * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to true.
     *
     * @param afi the recipient of the focus change, that has previously requested audio focus, and
     *     that was received by the {@code AudioPolicy} through
     *     {@link AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(AudioFocusInfo, int)}
     * @param focusChange one of focus gain types ({@link #AUDIOFOCUS_GAIN},
     *     {@link #AUDIOFOCUS_GAIN_TRANSIENT}, {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} or
     *     {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE})
     *     or one of the focus loss types ({@link AudioManager#AUDIOFOCUS_LOSS},
     *     {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT},
     *     or {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}).
     *     <br>For the focus gain, the change type should be the same as the app requested
     * @param ap a valid registered {@link AudioPolicy} configured as a focus policy.
     * @param otherActiveAfis active {@link AudioFocusInfo} that are granted audio focus at the time
     *     of dispatch
     * @param transientFadeMgrConfig {@link FadeManagerConfiguration} that will be used for fading
     *     players resulting from this dispatch. This is a transient configuration that is only
     *     valid for this focus change and shall be discarded after processing this request.
     * @return {@link #AUDIOFOCUS_REQUEST_FAILED} if the focus client didn't have a listener or if
     *     there was an error sending the request, or {@link #AUDIOFOCUS_REQUEST_GRANTED} if the
     *     dispatch was successfully sent, or {@link #AUDIOFOCUS_REQUEST_DELAYED} if
     *     the request was successful but the dispatch of focus change was delayed due to a fade
     *     operation.
     * @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} or list of
     *     other active {@link AudioFocusInfo} are {@code null}.
     * @hide
     */
    @FlaggedApi(FLAG_ENABLE_FADE_MANAGER_CONFIGURATION)
    @SystemApi
    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
    public int dispatchAudioFocusChangeWithFade(@NonNull AudioFocusInfo afi, int focusChange,
            @NonNull AudioPolicy ap, @NonNull List<AudioFocusInfo> otherActiveAfis,
            @Nullable FadeManagerConfiguration transientFadeMgrConfig) {
        Objects.requireNonNull(afi, "AudioFocusInfo cannot be null");
        Objects.requireNonNull(ap, "AudioPolicy cannot be null");
        Objects.requireNonNull(otherActiveAfis, "Other active AudioFocusInfo list cannot be null");

        IAudioService service = getService();
        try {
            return service.dispatchFocusChangeWithFade(afi, focusChange, ap.cb(), otherActiveAfis,
                    transientFadeMgrConfig);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     * Used internally by telephony package to abandon audio focus, typically after a call or
+8 −7
Original line number Diff line number Diff line
@@ -16,12 +16,13 @@

package android.media;

import static com.android.media.flags.Flags.FLAG_ENABLE_FADE_MANAGER_CONFIGURATION;
import static android.media.audiopolicy.Flags.FLAG_ENABLE_FADE_MANAGER_CONFIGURATION;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -93,11 +94,9 @@ import java.util.Objects;
 *      Helps with recreating a new instance from another to simply change/add on top of the
 *      existing ones</li>
 * </ul>
 * TODO(b/304835727): Convert into system API so that it can be set through AudioPolicy
 *
 * @hide
 */

@SystemApi
@FlaggedApi(FLAG_ENABLE_FADE_MANAGER_CONFIGURATION)
public final class FadeManagerConfiguration implements Parcelable {

@@ -523,6 +522,7 @@ public final class FadeManagerConfiguration implements Parcelable {
     *
     * @param fadeState one of the fade state in {@link FadeStateEnum}
     * @return human-readable string
     * @hide
     */
    @NonNull
    public static String fadeStateToString(@FadeStateEnum int fadeState) {
@@ -712,7 +712,8 @@ public final class FadeManagerConfiguration implements Parcelable {
     *
     * <p><b>Notes:</b>
     * <ul>
     *     <li>When fade state is set to enabled, the builder expects at least one valid usage to be
     *     <li>When fade state is set to {@link #FADE_STATE_ENABLED_DEFAULT} or
     *     {@link #FADE_STATE_ENABLED_AUTO}, the builder expects at least one valid usage to be
     *     set/added. Failure to do so will result in an exception during {@link #build()}</li>
     *     <li>Every usage added to the fadeable list should have corresponding volume shaper
     *     configs defined. This can be achieved by setting either the duration or volume shaper
@@ -720,8 +721,8 @@ public final class FadeManagerConfiguration implements Parcelable {
     *     {@link #setFadeOutVolumeShaperConfigForUsage(int, VolumeShaper.Configuration)}</li>
     *     <li> It is recommended to set volume shaper configurations individually for fade out and
     *     fade in</li>
     *     <li>For any incomplete volume shaper configs a volume shaper configuration will be
     *     created using either the default fade durations or the ones provided as part of the
     *     <li>For any incomplete volume shaper configurations, a volume shaper configuration will
     *     be created using either the default fade durations or the ones provided as part of the
     *     {@link #Builder(long, long)}</li>
     *     <li>Additional volume shaper configs can also configured for a given usage
     *     with additional attributes like content-type in order to achieve finer fade controls.
+21 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.media.AudioPlaybackConfiguration;
import android.media.AudioRecordingConfiguration;
import android.media.AudioRoutesInfo;
import android.media.BluetoothProfileConnectionInfo;
import android.media.FadeManagerConfiguration;
import android.media.IAudioDeviceVolumeDispatcher;
import android.media.IAudioFocusDispatcher;
import android.media.IAudioModeDispatcher;
@@ -398,6 +399,14 @@ interface IAudioService {
    int dispatchFocusChange(in AudioFocusInfo afi, in int focusChange,
            in IAudioPolicyCallback pcb);

    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)")
    int dispatchFocusChangeWithFade(in AudioFocusInfo afi,
            in int focusChange,
            in IAudioPolicyCallback pcb,
            in List<AudioFocusInfo> otherActiveAfis,
            in FadeManagerConfiguration transientFadeMgrConfig);

    oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);

    @EnforcePermission("BLUETOOTH_STACK")
@@ -754,4 +763,16 @@ interface IAudioService {
    oneway void removeLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo);

    PersistableBundle getLoudnessParams(int piid, in LoudnessCodecInfo codecInfo);

    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)")
    int setFadeManagerConfigurationForFocusLoss(in FadeManagerConfiguration fmcForFocusLoss);

    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)")
    int clearFadeManagerConfigurationForFocusLoss();

    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)")
    FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss();
}
Loading