Merge "Audio focus: make media fade out temporary" into sc-qpr1-dev am: cee2cddebe
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15916332 Change-Id: I93d9a5a4414aaff389dcf6683071c3f84ec83061
This commit is contained in:
@@ -36,7 +36,16 @@ public final class FadeOutManager {
|
|||||||
|
|
||||||
public static final String TAG = "AudioService.FadeOutManager";
|
public static final String TAG = "AudioService.FadeOutManager";
|
||||||
|
|
||||||
|
/** duration of the fade out curve */
|
||||||
/*package*/ static final long FADE_OUT_DURATION_MS = 2000;
|
/*package*/ static final long FADE_OUT_DURATION_MS = 2000;
|
||||||
|
/**
|
||||||
|
* delay after which a faded out player will be faded back in. This will be heard by the user
|
||||||
|
* only in the case of unmuting players that didn't respect audio focus and didn't stop/pause
|
||||||
|
* when their app lost focus.
|
||||||
|
* This is the amount of time between the app being notified of
|
||||||
|
* the focus loss (when its muted by the fade out), and the time fade in (to unmute) starts
|
||||||
|
*/
|
||||||
|
/*package*/ static final long DELAY_FADE_IN_OFFENDERS_MS = 2000;
|
||||||
|
|
||||||
private static final boolean DEBUG = PlaybackActivityMonitor.DEBUG;
|
private static final boolean DEBUG = PlaybackActivityMonitor.DEBUG;
|
||||||
|
|
||||||
@@ -148,6 +157,11 @@ public final class FadeOutManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the app for the given UID from the list of faded out apps, unfade out its players
|
||||||
|
* @param uid the uid for the app to unfade out
|
||||||
|
* @param players map of current available players (so we can get an APC from piid)
|
||||||
|
*/
|
||||||
synchronized void unfadeOutUid(int uid, HashMap<Integer, AudioPlaybackConfiguration> players) {
|
synchronized void unfadeOutUid(int uid, HashMap<Integer, AudioPlaybackConfiguration> players) {
|
||||||
Log.i(TAG, "unfadeOutUid() uid:" + uid);
|
Log.i(TAG, "unfadeOutUid() uid:" + uid);
|
||||||
final FadedOutApp fa = mFadedApps.remove(uid);
|
final FadedOutApp fa = mFadedApps.remove(uid);
|
||||||
@@ -157,12 +171,6 @@ public final class FadeOutManager {
|
|||||||
fa.removeUnfadeAll(players);
|
fa.removeUnfadeAll(players);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void forgetUid(int uid) {
|
|
||||||
//Log.v(TAG, "forget() uid:" + uid);
|
|
||||||
//mFadedApps.remove(uid);
|
|
||||||
// TODO unfade all players later in case they are reused or the app continued to play
|
|
||||||
}
|
|
||||||
|
|
||||||
// pre-condition: apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
|
// pre-condition: apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
|
||||||
// see {@link PlaybackActivityMonitor#playerEvent}
|
// see {@link PlaybackActivityMonitor#playerEvent}
|
||||||
synchronized void checkFade(@NonNull AudioPlaybackConfiguration apc) {
|
synchronized void checkFade(@NonNull AudioPlaybackConfiguration apc) {
|
||||||
|
|||||||
@@ -131,6 +131,11 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
|||||||
@Override
|
@Override
|
||||||
public void restoreVShapedPlayers(@NonNull FocusRequester winner) {
|
public void restoreVShapedPlayers(@NonNull FocusRequester winner) {
|
||||||
mFocusEnforcer.restoreVShapedPlayers(winner);
|
mFocusEnforcer.restoreVShapedPlayers(winner);
|
||||||
|
// remove scheduled events to unfade out offending players (if any) corresponding to
|
||||||
|
// this uid, as we're removing any effects of muting/ducking/fade out now
|
||||||
|
mFocusHandler.removeEqualMessages(MSL_L_FORGET_UID,
|
||||||
|
new ForgetFadeUidInfo(winner.getClientUid()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1182,6 +1187,13 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
|||||||
mFocusHandler.obtainMessage(MSG_L_FOCUS_LOSS_AFTER_FADE, focusLoser),
|
mFocusHandler.obtainMessage(MSG_L_FOCUS_LOSS_AFTER_FADE, focusLoser),
|
||||||
FadeOutManager.FADE_OUT_DURATION_MS);
|
FadeOutManager.FADE_OUT_DURATION_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void postForgetUidLater(int uid) {
|
||||||
|
mFocusHandler.sendMessageDelayed(
|
||||||
|
mFocusHandler.obtainMessage(MSL_L_FORGET_UID, new ForgetFadeUidInfo(uid)),
|
||||||
|
FadeOutManager.DELAY_FADE_IN_OFFENDERS_MS);
|
||||||
|
}
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
// Message handling
|
// Message handling
|
||||||
private Handler mFocusHandler;
|
private Handler mFocusHandler;
|
||||||
@@ -1196,6 +1208,8 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
|||||||
*/
|
*/
|
||||||
private static final int MSG_L_FOCUS_LOSS_AFTER_FADE = 1;
|
private static final int MSG_L_FOCUS_LOSS_AFTER_FADE = 1;
|
||||||
|
|
||||||
|
private static final int MSL_L_FORGET_UID = 2;
|
||||||
|
|
||||||
private void initFocusThreading() {
|
private void initFocusThreading() {
|
||||||
mFocusThread = new HandlerThread(TAG);
|
mFocusThread = new HandlerThread(TAG);
|
||||||
mFocusThread.start();
|
mFocusThread.start();
|
||||||
@@ -1213,15 +1227,56 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
|||||||
if (loser.isInFocusLossLimbo()) {
|
if (loser.isInFocusLossLimbo()) {
|
||||||
loser.dispatchFocusChange(AudioManager.AUDIOFOCUS_LOSS);
|
loser.dispatchFocusChange(AudioManager.AUDIOFOCUS_LOSS);
|
||||||
loser.release();
|
loser.release();
|
||||||
mFocusEnforcer.forgetUid(loser.getClientUid());
|
postForgetUidLater(loser.getClientUid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSL_L_FORGET_UID:
|
||||||
|
final int uid = ((ForgetFadeUidInfo) msg.obj).mUid;
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "MSL_L_FORGET_UID uid=" + uid);
|
||||||
|
}
|
||||||
|
mFocusEnforcer.forgetUid(uid);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to associate a UID with a scheduled event to "forget" a UID for the fade out behavior.
|
||||||
|
* Having a class with an equals() override allows using Handler.removeEqualsMessage() to
|
||||||
|
* unschedule events when needed. Here we need to unschedule the "unfading out" == "forget uid"
|
||||||
|
* whenever a new, more recent, focus related event happens before this one is handled.
|
||||||
|
*/
|
||||||
|
private static final class ForgetFadeUidInfo {
|
||||||
|
private final int mUid;
|
||||||
|
|
||||||
|
ForgetFadeUidInfo(int uid) {
|
||||||
|
mUid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ForgetFadeUidInfo f = (ForgetFadeUidInfo) o;
|
||||||
|
if (f.mUid != mUid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return mUid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -747,7 +747,11 @@ public final class PlaybackActivityMonitor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forgetUid(int uid) {
|
public void forgetUid(int uid) {
|
||||||
mFadingManager.forgetUid(uid);
|
final HashMap<Integer, AudioPlaybackConfiguration> players;
|
||||||
|
synchronized (mPlayerLock) {
|
||||||
|
players = (HashMap<Integer, AudioPlaybackConfiguration>) mPlayers.clone();
|
||||||
|
}
|
||||||
|
mFadingManager.unfadeOutUid(uid, players);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user