diff options
| author | 2023-11-25 20:53:07 -0800 | |
|---|---|---|
| committer | 2023-12-18 15:44:11 -0800 | |
| commit | 3aab254691b4cb301be52799d003bec53bc8357f (patch) | |
| tree | a7f789d4aeae2a09af32b8bddc7d64900f01c3da | |
| parent | 428a66a74d6197d17c6406b612a40461f4e9b807 (diff) | |
Add API to set fade manager configuration
Fade manager configuration allows clients to set
custom fade out and in volume shaper configurations
for usages and audio attributes
Add api to allow clients set and update the fade
manager configuration with AudioPolicy.
Bug: 186905459
Bug: 304835727
API-Coverage-Bug: 308666800
Test: atest -c FadeManagerConfigurationUnitTest
Change-Id: Id1e2177bc4db9ec6bf499be539f26771f699dd7f
8 files changed, 312 insertions, 28 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 9a65388c2741..a1f9ebab09f2 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6673,6 +6673,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(); @@ -6891,15 +6954,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>); diff --git a/media/java/android/media/FadeManagerConfiguration.java b/media/java/android/media/FadeManagerConfiguration.java index 03b63dbd4649..40b0e3e03ef6 100644 --- a/media/java/android/media/FadeManagerConfiguration.java +++ b/media/java/android/media/FadeManagerConfiguration.java @@ -22,6 +22,7 @@ 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. diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index a52f0b08330d..1e25615674c0 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -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; @@ -754,4 +755,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(); } diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index e16849811b9d..b85decc74ff8 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -16,6 +16,8 @@ package android.media.audiopolicy; +import static android.media.audiopolicy.Flags.FLAG_ENABLE_FADE_MANAGER_CONFIGURATION; + import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; @@ -34,6 +36,7 @@ import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; +import android.media.FadeManagerConfiguration; import android.media.IAudioService; import android.media.MediaRecorder; import android.media.projection.MediaProjection; @@ -49,6 +52,7 @@ import android.util.Pair; import android.util.Slog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -612,6 +616,110 @@ public class AudioPolicy { return mRegistrationId; } + /** + * Sets a custom {@link FadeManagerConfiguration} to handle fade cycle of players during + * {@link android.media.AudioManager#AUDIOFOCUS_LOSS} + * + * @param fmcForFocusLoss custom {@link FadeManagerConfiguration} + * @return {@link AudioManager#SUCCESS} if the update was successful, + * {@link AudioManager#ERROR} otherwise + * @throws IllegalStateException if the audio policy is not registered + * @hide + */ + @FlaggedApi(FLAG_ENABLE_FADE_MANAGER_CONFIGURATION) + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + @SystemApi + public int setFadeManagerConfigurationForFocusLoss( + @NonNull FadeManagerConfiguration fmcForFocusLoss) { + Objects.requireNonNull(fmcForFocusLoss, + "FadeManagerConfiguration for focus loss cannot be null"); + + IAudioService service = getService(); + synchronized (mLock) { + Preconditions.checkState(isAudioPolicyRegisteredLocked(), + "Cannot set FadeManagerConfiguration with unregistered AudioPolicy"); + + try { + return service.setFadeManagerConfigurationForFocusLoss(fmcForFocusLoss); + } catch (RemoteException e) { + Log.e(TAG, "Received remote exception for setFadeManagerConfigurationForFocusLoss:", + e); + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Clear the current {@link FadeManagerConfiguration} set to handle fade cycles of players + * during {@link android.media.AudioManager#AUDIOFOCUS_LOSS} + * + * <p>In the absence of custom {@link FadeManagerConfiguration}, the default configurations will + * be used to handle fade cycles during audio focus loss. + * + * @return {@link AudioManager#SUCCESS} if the update was successful, + * {@link AudioManager#ERROR} otherwise + * @throws IllegalStateException if the audio policy is not registered + * @see #setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration) + * @hide + */ + @FlaggedApi(FLAG_ENABLE_FADE_MANAGER_CONFIGURATION) + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + @SystemApi + public int clearFadeManagerConfigurationForFocusLoss() { + IAudioService service = getService(); + synchronized (mLock) { + Preconditions.checkState(isAudioPolicyRegisteredLocked(), + "Cannot clear FadeManagerConfiguration from unregistered AudioPolicy"); + + try { + return service.clearFadeManagerConfigurationForFocusLoss(); + } catch (RemoteException e) { + Log.e(TAG, "Received remote exception for " + + "clearFadeManagerConfigurationForFocusLoss:", e); + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Get the current fade manager configuration used for fade operations during + * {@link android.media.AudioManager#AUDIOFOCUS_LOSS} + * + * <p>If no custom {@link FadeManagerConfiguration} is set, the default configuration currently + * active will be returned. + * + * @return the active {@link FadeManagerConfiguration} used during audio focus loss + * @throws IllegalStateException if the audio policy is not registered + * @see #setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration) + * @see #clearFadeManagerConfigurationForFocusLoss() + * @hide + */ + @FlaggedApi(FLAG_ENABLE_FADE_MANAGER_CONFIGURATION) + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + @SystemApi + @NonNull + public FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss() { + IAudioService service = getService(); + synchronized (mLock) { + Preconditions.checkState(isAudioPolicyRegisteredLocked(), + "Cannot get FadeManagerConfiguration from unregistered AudioPolicy"); + + try { + return service.getFadeManagerConfigurationForFocusLoss(); + } catch (RemoteException e) { + Log.e(TAG, "Received remote exception for getFadeManagerConfigurationForFocusLoss:", + e); + throw e.rethrowFromSystemServer(); + + } + } + } + + @GuardedBy("mLock") + private boolean isAudioPolicyRegisteredLocked() { + return mStatus == POLICY_STATUS_REGISTERED; + } + private boolean policyReadyToUse() { synchronized (mLock) { if (mStatus != POLICY_STATUS_REGISTERED) { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 44cb1367928d..a03d55543aba 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -33,6 +33,7 @@ import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; import static android.media.AudioManager.RINGER_MODE_VIBRATE; import static android.media.AudioManager.STREAM_SYSTEM; +import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; @@ -116,6 +117,7 @@ import android.media.AudioRoutesInfo; import android.media.AudioSystem; import android.media.AudioTrack; import android.media.BluetoothProfileConnectionInfo; +import android.media.FadeManagerConfiguration; import android.media.IAudioDeviceVolumeDispatcher; import android.media.IAudioFocusDispatcher; import android.media.IAudioModeDispatcher; @@ -4513,6 +4515,8 @@ public class AudioService extends IAudioService.Stub + bluetoothMacAddressAnonymization()); pw.println("\tcom.android.media.audio.Flags.disablePrescaleAbsoluteVolume:" + disablePrescaleAbsoluteVolume()); + pw.println("\tandroid.media.audiopolicy.enableFadeManagerConfiguration:" + + enableFadeManagerConfiguration()); } private void dumpAudioMode(PrintWriter pw) { @@ -12614,6 +12618,47 @@ public class AudioService extends IAudioService.Stub } /** + * see {@link AudioPolicy#setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration)} + */ + @android.annotation.EnforcePermission( + android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + public int setFadeManagerConfigurationForFocusLoss( + @NonNull FadeManagerConfiguration fmcForFocusLoss) { + super.setFadeManagerConfigurationForFocusLoss_enforcePermission(); + ensureFadeManagerConfigIsEnabled(); + Objects.requireNonNull(fmcForFocusLoss, + "Fade manager config for focus loss cannot be null"); + validateFadeManagerConfiguration(fmcForFocusLoss); + + return mPlaybackMonitor.setFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS, + fmcForFocusLoss); + } + + /** + * see {@link AudioPolicy#clearFadeManagerConfigurationForFocusLoss()} + */ + @android.annotation.EnforcePermission( + android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + public int clearFadeManagerConfigurationForFocusLoss() { + super.clearFadeManagerConfigurationForFocusLoss_enforcePermission(); + ensureFadeManagerConfigIsEnabled(); + + return mPlaybackMonitor.clearFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS); + } + + /** + * see {@link AudioPolicy#getFadeManagerConfigurationForFocusLoss()} + */ + @android.annotation.EnforcePermission( + android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) + public FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss() { + super.getFadeManagerConfigurationForFocusLoss_enforcePermission(); + ensureFadeManagerConfigIsEnabled(); + + return mPlaybackMonitor.getFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS); + } + + /** * @see AudioManager#getHalVersion */ public @Nullable AudioHalVersionInfo getHalVersion() { @@ -12814,6 +12859,19 @@ public class AudioService extends IAudioService.Stub } } + private void ensureFadeManagerConfigIsEnabled() { + Preconditions.checkState(enableFadeManagerConfiguration(), + "Fade manager configuration not supported"); + } + + private void validateFadeManagerConfiguration(FadeManagerConfiguration fmc) { + // validate permission of audio attributes + List<AudioAttributes> attrs = fmc.getAudioAttributesWithVolumeShaperConfigs(); + for (int index = 0; index < attrs.size(); index++) { + validateAudioAttributesUsage(attrs.get(index)); + } + } + //====================== // Audio policy callbacks from AudioSystem for dynamic policies //====================== @@ -13114,6 +13172,7 @@ public class AudioService extends IAudioService.Stub + "could not link to " + projection + " binder death", e); } } + int status = connectMixes(); if (status != AudioSystem.SUCCESS) { release(); diff --git a/services/core/java/com/android/server/audio/FadeConfigurations.java b/services/core/java/com/android/server/audio/FadeConfigurations.java index 3dc723045fa8..aaa377a8b793 100644 --- a/services/core/java/com/android/server/audio/FadeConfigurations.java +++ b/services/core/java/com/android/server/audio/FadeConfigurations.java @@ -21,6 +21,7 @@ import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; import android.annotation.NonNull; import android.annotation.Nullable; import android.media.AudioAttributes; +import android.media.AudioManager; import android.media.AudioPlaybackConfiguration; import android.media.FadeManagerConfiguration; import android.media.VolumeShaper; @@ -90,13 +91,14 @@ public final class FadeConfigurations { * Sets the custom fade manager configuration * * @param fadeManagerConfig custom fade manager configuration - * @return {@code true} if setting custom fade manager configuration succeeds or {@code false} - * otherwise (example - when fade manager configuration is disabled) + * @return {@link AudioManager#SUCCESS} if setting custom fade manager configuration succeeds + * or {@link AudioManager#ERROR} otherwise (example - when fade manager configuration + * feature is disabled) */ - public boolean setFadeManagerConfiguration( + public int setFadeManagerConfiguration( @NonNull FadeManagerConfiguration fadeManagerConfig) { if (!enableFadeManagerConfiguration()) { - return false; + return AudioManager.ERROR; } synchronized (mLock) { @@ -104,25 +106,44 @@ public final class FadeConfigurations { "Fade manager configuration cannot be null"); mActiveFadeManagerConfig = getActiveFadeMgrConfigLocked(); } - return true; + return AudioManager.SUCCESS; } /** * Clears the fade manager configuration that was previously set with * {@link #setFadeManagerConfiguration(FadeManagerConfiguration)} * - * @return {@code true} if previously set fade manager configuration is cleared or {@code false} - * otherwise (say, when fade manager configuration is disabled) + * @return {@link AudioManager#SUCCESS} if previously set fade manager configuration is cleared + * or {@link AudioManager#ERROR} otherwise (example, when fade manager configuration feature + * is disabled) */ - public boolean clearFadeManagerConfiguration() { + public int clearFadeManagerConfiguration() { if (!enableFadeManagerConfiguration()) { - return false; + return AudioManager.ERROR; } + synchronized (mLock) { mUpdatedFadeManagerConfig = null; mActiveFadeManagerConfig = getActiveFadeMgrConfigLocked(); } - return true; + return AudioManager.SUCCESS; + } + + /** + * Returns the active fade manager configuration + * + * @return {@code null} if feature is disabled, or the custom fade manager configuration if set, + * or default fade manager configuration if not set. + */ + @Nullable + public FadeManagerConfiguration getFadeManagerConfiguration() { + if (!enableFadeManagerConfiguration()) { + return null; + } + + synchronized (mLock) { + return mActiveFadeManagerConfig; + } } /** diff --git a/services/core/java/com/android/server/audio/FadeOutManager.java b/services/core/java/com/android/server/audio/FadeOutManager.java index a0f9eda8e2b4..413d1f9a943e 100644 --- a/services/core/java/com/android/server/audio/FadeOutManager.java +++ b/services/core/java/com/android/server/audio/FadeOutManager.java @@ -58,13 +58,10 @@ public final class FadeOutManager { * Sets the custom fade manager configuration to be used for player fade out and in * * @param fadeManagerConfig custom fade manager configuration - * @return {@code true} if setting fade manager config succeeded, {@code false} otherwise + * @return {@link AudioManager#SUCCESS} if setting fade manager config succeeded, + * {@link AudioManager#ERROR} otherwise */ - boolean setFadeManagerConfiguration(FadeManagerConfiguration fadeManagerConfig) { - if (!enableFadeManagerConfiguration()) { - return false; - } - + int setFadeManagerConfiguration(FadeManagerConfiguration fadeManagerConfig) { // locked to ensure the fade configs are not updated while faded app state is being updated synchronized (mLock) { return mFadeConfigurations.setFadeManagerConfiguration(fadeManagerConfig); @@ -75,19 +72,25 @@ public final class FadeOutManager { * Clears the fade manager configuration that was previously set with * {@link #setFadeManagerConfiguration(FadeManagerConfiguration)} * - * @return {@code true} if clearing fade manager config succeeded, {@code false} otherwise + * @return {@link AudioManager#SUCCESS} if clearing fade manager config succeeded, + * {@link AudioManager#ERROR} otherwise */ - boolean clearFadeManagerConfiguration() { - if (!enableFadeManagerConfiguration()) { - return false; - } - + int clearFadeManagerConfiguration() { // locked to ensure the fade configs are not updated while faded app state is being updated synchronized (mLock) { return mFadeConfigurations.clearFadeManagerConfiguration(); } } + /** + * Returns the active fade manager configuration + * + * @return the {@link FadeManagerConfiguration} + */ + FadeManagerConfiguration getFadeManagerConfiguration() { + return mFadeConfigurations.getFadeManagerConfiguration(); + } + // TODO explore whether a shorter fade out would be a better UX instead of not fading out at all // (legacy behavior) /** diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 1358a9b5d9a5..60b5a54d8d1e 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -38,6 +38,7 @@ import android.media.AudioPlaybackConfiguration; import android.media.AudioPlaybackConfiguration.FormatInfo; import android.media.AudioPlaybackConfiguration.PlayerMuteEvent; import android.media.AudioSystem; +import android.media.FadeManagerConfiguration; import android.media.IPlaybackConfigDispatcher; import android.media.PlayerBase; import android.media.VolumeShaper; @@ -1008,6 +1009,18 @@ public final class PlaybackActivityMonitor } } + int setFadeManagerConfiguration(int focusType, FadeManagerConfiguration fadeMgrConfig) { + return mFadeOutManager.setFadeManagerConfiguration(fadeMgrConfig); + } + + int clearFadeManagerConfiguration(int focusType) { + return mFadeOutManager.clearFadeManagerConfiguration(); + } + + FadeManagerConfiguration getFadeManagerConfiguration(int focusType) { + return mFadeOutManager.getFadeManagerConfiguration(); + } + /** * Inner class to track clients that want to be notified of playback updates */ |