Audio focus: fix focus loss notification for older SDKs
The feature of ducking enforced by the framework is gated by the SDK version of the focus owner. The check was performed by asking the SDK target level of the players to duck. But if there were no players in the STARTED state at the time, the check didn't report that the ducking shouldn't be performed by the framework, and thus the focus loss wasn't reported to the application. The fix consists in moving the SDK check at the focus owner level, so the check can happen regardless of whether there are active players or not. Add more informative logs where piids are logged (uid+pid). In the FocusRequester class, initialize mFocusLossWasNotified to true for the focus gain path, and don't set it to false after gaining focus, it is properly updated instead in the focus loss code path. Test: launch Audible, play then pause, play a notification, verify in the logs Audible is notified of the focus loss Bug: 37987086 Change-Id: I7c44d824b2563e71cf288ae1f256d001662a6a59
This commit is contained in:
@@ -99,6 +99,7 @@ public class FocusRequester {
|
||||
mFocusGainRequest = focusRequest;
|
||||
mGrantFlags = grantFlags;
|
||||
mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
|
||||
mFocusLossWasNotified = true;
|
||||
mFocusController = ctlr;
|
||||
mSdkTarget = sdk;
|
||||
}
|
||||
@@ -111,6 +112,7 @@ public class FocusRequester {
|
||||
mCallingUid = afi.getClientUid();
|
||||
mFocusGainRequest = afi.getGainRequest();
|
||||
mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
|
||||
mFocusLossWasNotified = true;
|
||||
mGrantFlags = afi.getFlags();
|
||||
mSdkTarget = afi.getSdkTarget();
|
||||
|
||||
@@ -324,7 +326,6 @@ public class FocusRequester {
|
||||
}
|
||||
}
|
||||
mFocusController.unduckPlayers(this);
|
||||
mFocusLossWasNotified = false;
|
||||
} catch (android.os.RemoteException e) {
|
||||
Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
|
||||
}
|
||||
@@ -378,6 +379,12 @@ public class FocusRequester {
|
||||
// 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 (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(fr, this);
|
||||
}
|
||||
|
||||
@@ -286,23 +286,20 @@ public final class PlaybackActivityMonitor
|
||||
&& loser.hasSameUid(apc.getClientUid())
|
||||
&& apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED)
|
||||
{
|
||||
if (MediaFocusControl.ENFORCE_DUCKING
|
||||
&& MediaFocusControl.ENFORCE_DUCKING_FOR_NEW
|
||||
&& loser.getSdkTarget() <= MediaFocusControl.DUCKING_IN_APP_SDK_LEVEL) {
|
||||
// legacy behavior, apps used to be notified when they should be ducking
|
||||
if (DEBUG) {Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
|
||||
+ ": old SDK"); }
|
||||
return false;
|
||||
} else if (apc.getAudioAttributes().getContentType() ==
|
||||
if (apc.getAudioAttributes().getContentType() ==
|
||||
AudioAttributes.CONTENT_TYPE_SPEECH) {
|
||||
// the player is speaking, ducking will make the speech unintelligible
|
||||
// so let the app handle it instead
|
||||
if (DEBUG) { Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
|
||||
+ ": SPEECH"); }
|
||||
Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
|
||||
+ " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
|
||||
+ " - SPEECH");
|
||||
return false;
|
||||
} else if (apc.getPlayerType()
|
||||
== AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
|
||||
// TODO support ducking of SoundPool players
|
||||
Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
|
||||
+ " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
|
||||
+ " - SoundPool");
|
||||
return false;
|
||||
}
|
||||
apcsToDuck.add(apc);
|
||||
@@ -351,7 +348,7 @@ public final class PlaybackActivityMonitor
|
||||
}
|
||||
if (mute) {
|
||||
try {
|
||||
Log.v(TAG, "call: muting player" + piid);
|
||||
Log.v(TAG, "call: muting player" + piid + " uid:" + apc.getClientUid());
|
||||
apc.getPlayerProxy().setVolume(0.0f);
|
||||
mMutedPlayers.add(new Integer(piid));
|
||||
} catch (Exception e) {
|
||||
@@ -375,10 +372,11 @@ public final class PlaybackActivityMonitor
|
||||
final AudioPlaybackConfiguration apc = mPlayers.get(piid);
|
||||
if (apc != null) {
|
||||
try {
|
||||
Log.v(TAG, "call: unmuting player" + piid);
|
||||
Log.v(TAG, "call: unmuting player" + piid + " uid:" + apc.getClientUid());
|
||||
apc.getPlayerProxy().setVolume(1.0f);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "call: error unmuting player " + piid, e);
|
||||
Log.e(TAG, "call: error unmuting player " + piid + " uid:"
|
||||
+ apc.getClientUid(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,13 +557,13 @@ public final class PlaybackActivityMonitor
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Log.v(TAG, "ducking player " + apc.getPlayerInterfaceId());
|
||||
Log.v(TAG, "ducking player " + apc.getPlayerInterfaceId() + " uid:" + mUid);
|
||||
apc.getPlayerProxy().applyVolumeShaper(
|
||||
DUCK_VSHAPE,
|
||||
PLAY_CREATE_IF_NEEDED);
|
||||
mDuckedPlayers.add(piid);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error ducking player " + piid, e);
|
||||
Log.e(TAG, "Error ducking player " + piid + " uid:" + mUid, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,12 +572,12 @@ public final class PlaybackActivityMonitor
|
||||
final AudioPlaybackConfiguration apc = players.get(piid);
|
||||
if (apc != null) {
|
||||
try {
|
||||
Log.v(TAG, "unducking player " + piid);
|
||||
Log.v(TAG, "unducking player " + piid + " uid:" + mUid);
|
||||
apc.getPlayerProxy().applyVolumeShaper(
|
||||
DUCK_ID,
|
||||
VolumeShaper.Operation.REVERSE);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error unducking player " + piid, e);
|
||||
Log.e(TAG, "Error unducking player " + piid + " uid:" + mUid, e);
|
||||
}
|
||||
} else {
|
||||
// this piid was in the list of ducked players, but wasn't found
|
||||
|
||||
Reference in New Issue
Block a user