Merge "FocusRequester: refactor handleFocusLoss"

This commit is contained in:
Treehugger Robot
2019-09-10 20:49:49 +00:00
committed by Gerrit Code Review
4 changed files with 82 additions and 31 deletions

View File

@@ -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"); }

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();
}