summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vlad Popa <pvlad@google.com> 2022-07-01 17:39:46 +0200
committer Vlad Popa <pvlad@google.com> 2022-07-29 11:37:19 +0200
commit15f85a8f5eca2d0114ac04fe20ee9d2ee66dcf80 (patch)
tree9278b82a8c906638af9957dc0d42002bf0732b86
parentead8130b1b4582c1e023e9d48e8e54a5aa92feb7 (diff)
Notify the client about the muted state
The logic enforces sending the started state only when the player is not muted. Muted events are anonymized for unprivileged clients. We still need to optimize the reporting to unprivileged clients since one can now receive updates for which nothing changed for their visibility level Test: dumpsys audio Bug: 235521198 Change-Id: I3698261ba9edf71b91950ef281086bb0a3af066d
-rw-r--r--media/java/android/media/AudioPlaybackConfiguration.java53
-rw-r--r--services/core/java/com/android/server/audio/PlaybackActivityMonitor.java14
2 files changed, 58 insertions, 9 deletions
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index f7a97e00fbff..c213fccb90d3 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -220,6 +220,11 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* @hide
+ * Mute state used for anonymization.
+ */
+ public static final int PLAYER_MUTE_INVALID = -1;
+ /**
+ * @hide
* Flag used when muted by master volume.
*/
public static final int PLAYER_MUTE_MASTER = (1 << 0);
@@ -265,6 +270,8 @@ public final class AudioPlaybackConfiguration implements Parcelable {
private int mSessionId;
+ @PlayerMuteEvent private int mMutedState;
+
/**
* Never use without initializing parameters afterwards
*/
@@ -285,6 +292,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
mPlayerType = pic.mPlayerType;
mClientUid = uid;
mClientPid = pid;
+ mMutedState = PLAYER_MUTE_INVALID;
mDeviceId = PLAYER_DEVICEID_INVALID;
mPlayerState = PLAYER_STATE_IDLE;
mPlayerAttr = pic.mAttributes;
@@ -333,6 +341,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
anonymCopy.mPlayerAttr = builder.build();
anonymCopy.mDeviceId = in.mDeviceId;
// anonymized data
+ anonymCopy.mMutedState = PLAYER_MUTE_INVALID;
anonymCopy.mPlayerType = PLAYER_TYPE_UNKNOWN;
anonymCopy.mClientUid = PLAYER_UPID_INVALID;
anonymCopy.mClientPid = PLAYER_UPID_INVALID;
@@ -393,6 +402,14 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* @hide
+ * @return the mute state as a combination of {@link PlayerMuteEvent} flags
+ */
+ @PlayerMuteEvent public int getMutedState() {
+ return mMutedState;
+ }
+
+ /**
+ * @hide
* Return the type of player linked to this configuration.
* <br>Note that player types not exposed in the system API will be represented as
* {@link #PLAYER_TYPE_UNKNOWN}.
@@ -471,7 +488,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* @hide
- * Handle a change of audio session Id
+ * Handle a change of audio session ID
* @param sessionId the audio session ID
*/
public boolean handleSessionIdEvent(int sessionId) {
@@ -482,6 +499,18 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* @hide
+ * Handle a change of the muted state
+ * @param mutedState the mute reason as a combination of {@link PlayerMuteEvent} flags
+ * @return true if the state changed, false otherwise
+ */
+ public boolean handleMutedEvent(@PlayerMuteEvent int mutedState) {
+ final boolean changed = mMutedState != mutedState;
+ mMutedState = mutedState;
+ return changed;
+ }
+
+ /**
+ * @hide
* Handle a player state change
* @param event
* @param deviceId active device id or {@Code PLAYER_DEVICEID_INVALID}
@@ -531,16 +560,17 @@ public final class AudioPlaybackConfiguration implements Parcelable {
/**
* @hide
- * Returns true if the player is considered "active", i.e. actively playing, and thus
- * in a state that should make it considered for the list public (sanitized) active playback
- * configurations
+ * Returns true if the player is considered "active", i.e. actively playing with unmuted
+ * volume, and thus in a state that should make it considered for the list public (sanitized)
+ * active playback configurations
* @return true if active
*/
@SystemApi
public boolean isActive() {
switch (mPlayerState) {
case PLAYER_STATE_STARTED:
- return true;
+ return mMutedState == 0
+ || mMutedState == PLAYER_MUTE_INVALID; // only send true if not muted
case PLAYER_STATE_UNKNOWN:
case PLAYER_STATE_RELEASED:
case PLAYER_STATE_IDLE:
@@ -577,7 +607,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mPlayerIId, mDeviceId, mPlayerType, mClientUid, mClientPid,
+ return Objects.hash(mPlayerIId, mDeviceId, mMutedState, mPlayerType, mClientUid, mClientPid,
mSessionId);
}
@@ -590,6 +620,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mPlayerIId);
dest.writeInt(mDeviceId);
+ dest.writeInt(mMutedState);
dest.writeInt(mPlayerType);
dest.writeInt(mClientUid);
dest.writeInt(mClientPid);
@@ -606,6 +637,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
private AudioPlaybackConfiguration(Parcel in) {
mPlayerIId = in.readInt();
mDeviceId = in.readInt();
+ mMutedState = in.readInt();
mPlayerType = in.readInt();
mClientUid = in.readInt();
mClientPid = in.readInt();
@@ -625,6 +657,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
return ((mPlayerIId == that.mPlayerIId)
&& (mDeviceId == that.mDeviceId)
+ && (mMutedState == that.mMutedState)
&& (mPlayerType == that.mPlayerType)
&& (mClientUid == that.mClientUid)
&& (mClientPid == that.mClientPid))
@@ -639,7 +672,13 @@ public final class AudioPlaybackConfiguration implements Parcelable {
+ " u/pid:" + mClientUid + "/" + mClientPid
+ " state:" + toLogFriendlyPlayerState(mPlayerState)
+ " attr:" + mPlayerAttr
- + " sessionId:" + mSessionId;
+ + " sessionId:" + mSessionId
+ + " mutedState:"
+ + " muteFromMasterMute=" + ((mMutedState & PLAYER_MUTE_MASTER) != 0)
+ + " muteFromStreamVolume=" + ((mMutedState & PLAYER_MUTE_STREAM_VOLUME) != 0)
+ + " muteFromStreamMuted=" + ((mMutedState & PLAYER_MUTE_STREAM_MUTED) != 0)
+ + " muteFromPlaybackRestricted=" + ((mMutedState & PLAYER_MUTE_PLAYBACK_RESTRICTED)
+ != 0);
}
//=====================================================================
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index e722f76a61da..9ff72d3ea7f6 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -1443,8 +1443,18 @@ public final class PlaybackActivityMonitor
}
@PlayerMuteEvent int eventValue = extras.getInt(EXTRA_PLAYER_EVENT_MUTE);
- sEventLogger.log(new PlayerEvent(/*piid=*/msg.arg1, PLAYER_UPDATE_MUTED,
- eventValue));
+ synchronized (mPlayerLock) {
+ int piid = msg.arg1;
+
+ sEventLogger.log(
+ new PlayerEvent(piid, PLAYER_UPDATE_MUTED, eventValue));
+
+ final AudioPlaybackConfiguration apc = mPlayers.get(piid);
+ if (apc == null || !apc.handleMutedEvent(eventValue)) {
+ break; // do not dispatch
+ }
+ dispatchPlaybackChange(/* iplayerReleased= */false);
+ }
break;
case MSG_L_CLEAR_PORTS_FOR_PIID:
int piid = msg.arg1;