FocusRequester: refactor handleFocusLoss
Break out the checks to see if a focus loss is handled by the framework in a separate method, and reorder the if statements for code clarity. Annotate PlayerFocusEnforcer methods for nullability, add javadoc Test: atest AudioFocusTest Change-Id: I9aaab804c78a2e2627ddbd7b9bd41fdec47d2b57 Merged-In: I9aaab804c78a2e2627ddbd7b9bd41fdec47d2b57
This commit is contained in:
@@ -364,28 +364,8 @@ public class FocusRequester {
|
||||
|
||||
// check enforcement by the framework
|
||||
boolean handled = false;
|
||||
if (focusLoss == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
|
||||
&& MediaFocusControl.ENFORCE_DUCKING
|
||||
&& frWinner != null) {
|
||||
// candidate for enforcement by the framework
|
||||
if (frWinner.mCallingUid != this.mCallingUid) {
|
||||
if (!forceDuck && ((mGrantFlags
|
||||
& AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0)) {
|
||||
// the focus loser declared it would pause instead of duck, let it
|
||||
// handle it (the framework doesn't pause for apps)
|
||||
handled = false;
|
||||
Log.v(TAG, "not ducking uid " + this.mCallingUid + " - flags");
|
||||
} else if (!forceDuck && (MediaFocusControl.ENFORCE_DUCKING_FOR_NEW &&
|
||||
this.getSdkTarget() <= MediaFocusControl.DUCKING_IN_APP_SDK_LEVEL))
|
||||
{
|
||||
// legacy behavior, apps used to be notified when they should be ducking
|
||||
handled = false;
|
||||
Log.v(TAG, "not ducking uid " + this.mCallingUid + " - old SDK");
|
||||
} else {
|
||||
handled = mFocusController.duckPlayers(frWinner, this, forceDuck);
|
||||
}
|
||||
} // else: the focus change is within the same app, so let the dispatching
|
||||
// happen as if the framework was not involved.
|
||||
if (frWinner != null) {
|
||||
handled = frameworkHandleFocusLoss(focusLoss, frWinner, forceDuck);
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
@@ -415,6 +395,47 @@ public class FocusRequester {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the framework handle the focus loss if possible
|
||||
* @param focusLoss
|
||||
* @param frWinner
|
||||
* @param forceDuck
|
||||
* @return true if the framework handled the focus loss
|
||||
*/
|
||||
@GuardedBy("MediaFocusControl.mAudioFocusLock")
|
||||
private boolean frameworkHandleFocusLoss(int focusLoss, @NonNull final FocusRequester frWinner,
|
||||
boolean forceDuck) {
|
||||
if (frWinner.mCallingUid == this.mCallingUid) {
|
||||
// the focus change is within the same app, so let the dispatching
|
||||
// happen as if the framework was not involved.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (focusLoss == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
|
||||
if (!MediaFocusControl.ENFORCE_DUCKING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// candidate for enforcement by the framework
|
||||
if (!forceDuck && ((mGrantFlags
|
||||
& AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) != 0)) {
|
||||
// the focus loser declared it would pause instead of duck, let it
|
||||
// handle it (the framework doesn't pause for apps)
|
||||
Log.v(TAG, "not ducking uid " + this.mCallingUid + " - flags");
|
||||
return false;
|
||||
}
|
||||
if (!forceDuck && (MediaFocusControl.ENFORCE_DUCKING_FOR_NEW
|
||||
&& this.getSdkTarget() <= MediaFocusControl.DUCKING_IN_APP_SDK_LEVEL)) {
|
||||
// legacy behavior, apps used to be notified when they should be ducking
|
||||
Log.v(TAG, "not ducking uid " + this.mCallingUid + " - old SDK");
|
||||
return false;
|
||||
}
|
||||
|
||||
return mFocusController.duckPlayers(frWinner, this, forceDuck);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int dispatchFocusChange(int focusChange) {
|
||||
if (mFocusDispatcher == null) {
|
||||
if (MediaFocusControl.DEBUG) { Log.e(TAG, "dispatchFocusChange: no focus dispatcher"); }
|
||||
|
||||
@@ -105,12 +105,13 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
||||
//=================================================================
|
||||
// PlayerFocusEnforcer implementation
|
||||
@Override
|
||||
public boolean duckPlayers(FocusRequester winner, FocusRequester loser, boolean forceDuck) {
|
||||
public boolean duckPlayers(@NonNull FocusRequester winner, @NonNull FocusRequester loser,
|
||||
boolean forceDuck) {
|
||||
return mFocusEnforcer.duckPlayers(winner, loser, forceDuck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unduckPlayers(FocusRequester winner) {
|
||||
public void unduckPlayers(@NonNull FocusRequester winner) {
|
||||
mFocusEnforcer.unduckPlayers(winner);
|
||||
}
|
||||
|
||||
@@ -742,7 +743,20 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
|
||||
}
|
||||
}
|
||||
|
||||
/** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int, int) */
|
||||
/** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int, int)
|
||||
* @param aa
|
||||
* @param focusChangeHint
|
||||
* @param cb
|
||||
* @param fd
|
||||
* @param clientId
|
||||
* @param callingPackageName
|
||||
* @param flags
|
||||
* @param sdk
|
||||
* @param forceDuck only true if
|
||||
* {@link android.media.AudioFocusRequest.Builder#setFocusGain(int)} was set to true for
|
||||
* accessibility.
|
||||
* @return
|
||||
*/
|
||||
protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb,
|
||||
IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName,
|
||||
int flags, int sdk, boolean forceDuck) {
|
||||
|
||||
@@ -425,7 +425,8 @@ public final class PlaybackActivityMonitor
|
||||
private final DuckingManager mDuckingManager = new DuckingManager();
|
||||
|
||||
@Override
|
||||
public boolean duckPlayers(FocusRequester winner, FocusRequester loser, boolean forceDuck) {
|
||||
public boolean duckPlayers(@NonNull FocusRequester winner, @NonNull FocusRequester loser,
|
||||
boolean forceDuck) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, String.format("duckPlayers: uids winner=%d loser=%d",
|
||||
winner.getClientUid(), loser.getClientUid()));
|
||||
@@ -473,7 +474,7 @@ public final class PlaybackActivityMonitor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unduckPlayers(FocusRequester winner) {
|
||||
public void unduckPlayers(@NonNull FocusRequester winner) {
|
||||
if (DEBUG) { Log.v(TAG, "unduckPlayers: uids winner=" + winner.getClientUid()); }
|
||||
synchronized (mPlayerLock) {
|
||||
mDuckingManager.unduckUid(winner.getClientUid(), mPlayers);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.audio;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
public interface PlayerFocusEnforcer {
|
||||
|
||||
/**
|
||||
@@ -25,11 +27,24 @@ public interface PlayerFocusEnforcer {
|
||||
* @param loser
|
||||
* @return
|
||||
*/
|
||||
public boolean duckPlayers(FocusRequester winner, FocusRequester loser, boolean forceDuck);
|
||||
boolean duckPlayers(@NonNull FocusRequester winner, @NonNull FocusRequester loser,
|
||||
boolean forceDuck);
|
||||
|
||||
public void unduckPlayers(FocusRequester winner);
|
||||
/**
|
||||
* Unduck the players that had been ducked with
|
||||
* {@link #duckPlayers(FocusRequester, FocusRequester, boolean)}
|
||||
* @param winner
|
||||
*/
|
||||
void unduckPlayers(@NonNull FocusRequester winner);
|
||||
|
||||
public void mutePlayersForCall(int[] usagesToMute);
|
||||
/**
|
||||
* Mute players at the beginning of a call
|
||||
* @param usagesToMute array of {@link android.media.AudioAttributes} usages to mute
|
||||
*/
|
||||
void mutePlayersForCall(int[] usagesToMute);
|
||||
|
||||
public void unmutePlayersForCall();
|
||||
/**
|
||||
* Unmute players at the end of a call
|
||||
*/
|
||||
void unmutePlayersForCall();
|
||||
}
|
||||
Reference in New Issue
Block a user