Merge "Audio focus: tweaks for less intrusive fade outs" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a7dc8bef03
@@ -18,6 +18,7 @@ package com.android.server.audio;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.media.AudioAttributes;
|
import android.media.AudioAttributes;
|
||||||
|
import android.media.AudioManager;
|
||||||
import android.media.AudioPlaybackConfiguration;
|
import android.media.AudioPlaybackConfiguration;
|
||||||
import android.media.VolumeShaper;
|
import android.media.VolumeShaper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -35,15 +36,15 @@ public final class FadeOutManager {
|
|||||||
|
|
||||||
public static final String TAG = "AudioService.FadeOutManager";
|
public static final String TAG = "AudioService.FadeOutManager";
|
||||||
|
|
||||||
/*package*/ static final long FADE_OUT_DURATION_MS = 2500;
|
/*package*/ static final long FADE_OUT_DURATION_MS = 2000;
|
||||||
|
|
||||||
private static final boolean DEBUG = PlaybackActivityMonitor.DEBUG;
|
private static final boolean DEBUG = PlaybackActivityMonitor.DEBUG;
|
||||||
|
|
||||||
private static final VolumeShaper.Configuration FADEOUT_VSHAPE =
|
private static final VolumeShaper.Configuration FADEOUT_VSHAPE =
|
||||||
new VolumeShaper.Configuration.Builder()
|
new VolumeShaper.Configuration.Builder()
|
||||||
.setId(PlaybackActivityMonitor.VOLUME_SHAPER_SYSTEM_FADEOUT_ID)
|
.setId(PlaybackActivityMonitor.VOLUME_SHAPER_SYSTEM_FADEOUT_ID)
|
||||||
.setCurve(new float[]{0.f, 1.0f} /* times */,
|
.setCurve(new float[]{0.f, 0.25f, 1.0f} /* times */,
|
||||||
new float[]{1.f, 0.0f} /* volumes */)
|
new float[]{1.f, 0.65f, 0.0f} /* volumes */)
|
||||||
.setOptionFlags(VolumeShaper.Configuration.OPTION_FLAG_CLOCK_TIME)
|
.setOptionFlags(VolumeShaper.Configuration.OPTION_FLAG_CLOCK_TIME)
|
||||||
.setDuration(FADE_OUT_DURATION_MS)
|
.setDuration(FADE_OUT_DURATION_MS)
|
||||||
.build();
|
.build();
|
||||||
@@ -70,6 +71,30 @@ public final class FadeOutManager {
|
|||||||
private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
|
private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
|
||||||
new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
|
new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
|
||||||
|
|
||||||
|
|
||||||
|
// TODO explore whether a shorter fade out would be a better UX instead of not fading out at all
|
||||||
|
// (legacy behavior)
|
||||||
|
/**
|
||||||
|
* Determine whether the focus request would trigger a fade out, given the parameters of the
|
||||||
|
* requester and those of the focus loser
|
||||||
|
* @param requester the parameters for the focus request
|
||||||
|
* @return true if there can be a fade out over the requester starting to play
|
||||||
|
*/
|
||||||
|
static boolean canCauseFadeOut(@NonNull FocusRequester requester,
|
||||||
|
@NonNull FocusRequester loser) {
|
||||||
|
if (requester.getAudioAttributes().getContentType() == AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||||
|
{
|
||||||
|
if (DEBUG) { Log.i(TAG, "not fading out: new focus is for speech"); }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((loser.getGrantFlags() & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0) {
|
||||||
|
if (DEBUG) { Log.i(TAG, "not fading out: loser has PAUSES_ON_DUCKABLE_LOSS"); }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates whether the player associated with this configuration can and should be faded out
|
* Evaluates whether the player associated with this configuration can and should be faded out
|
||||||
* @param apc the configuration of the player
|
* @param apc the configuration of the player
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ public class FocusRequester {
|
|||||||
return mGrantFlags;
|
return mGrantFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioAttributes getAudioAttributes() {
|
@NonNull AudioAttributes getAudioAttributes() {
|
||||||
return mAttributes;
|
return mAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -888,6 +888,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
|||||||
mEventLogger.log((new AudioEventLogger.StringEvent(
|
mEventLogger.log((new AudioEventLogger.StringEvent(
|
||||||
"requestAudioFocus() from uid/pid " + uid
|
"requestAudioFocus() from uid/pid " + uid
|
||||||
+ "/" + Binder.getCallingPid()
|
+ "/" + Binder.getCallingPid()
|
||||||
|
+ " AA=" + aa.usageToString() + "/" + aa.contentTypeToString()
|
||||||
+ " clientId=" + clientId + " callingPack=" + callingPackageName
|
+ " clientId=" + clientId + " callingPack=" + callingPackageName
|
||||||
+ " req=" + focusChangeHint
|
+ " req=" + focusChangeHint
|
||||||
+ " flags=0x" + Integer.toHexString(flags)
|
+ " flags=0x" + Integer.toHexString(flags)
|
||||||
|
|||||||
@@ -707,6 +707,9 @@ public final class PlaybackActivityMonitor
|
|||||||
if (DEBUG) { Log.v(TAG, "no players to fade out"); }
|
if (DEBUG) { Log.v(TAG, "no players to fade out"); }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!FadeOutManager.canCauseFadeOut(winner, loser)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// check if this UID needs to be faded out (return false if not), and gather list of
|
// check if this UID needs to be faded out (return false if not), and gather list of
|
||||||
// eligible players to fade out
|
// eligible players to fade out
|
||||||
final Iterator<AudioPlaybackConfiguration> apcIterator = mPlayers.values().iterator();
|
final Iterator<AudioPlaybackConfiguration> apcIterator = mPlayers.values().iterator();
|
||||||
|
|||||||
Reference in New Issue
Block a user