Merge "FocusRequester: refactor handleFocusLoss"
diff --git a/services/core/java/com/android/server/audio/FocusRequester.java b/services/core/java/com/android/server/audio/FocusRequester.java
index db55138..65472c9 100644
--- a/services/core/java/com/android/server/audio/FocusRequester.java
+++ b/services/core/java/com/android/server/audio/FocusRequester.java
@@ -364,28 +364,8 @@
// 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 @@
}
}
+ /**
+ * 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"); }
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 5c93071..c845981 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -105,12 +105,13 @@
//=================================================================
// 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 @@
}
}
- /** @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) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 3a25d98..f8ba55b 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -425,7 +425,8 @@
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 @@
}
@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);
diff --git a/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java b/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java
index 3c834da..89e7b782 100644
--- a/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java
+++ b/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java
@@ -16,6 +16,8 @@
package com.android.server.audio;
+import android.annotation.NonNull;
+
public interface PlayerFocusEnforcer {
/**
@@ -25,11 +27,24 @@
* @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();
}
\ No newline at end of file