APC: expose the mute state for system APIs
Add the possibility for system APIs to query if an app is muted and what are the sources that are muting a specific player/track. Test: atest android.media.audio.cts.AudioPlaybackConfigurationTest Bug: 248145607 Change-Id: If40faa860c2663c9ca8436df0e7b8c10464d535b
This commit is contained in:
@@ -6345,12 +6345,21 @@ package android.media {
|
||||
public final class AudioPlaybackConfiguration implements android.os.Parcelable {
|
||||
method public int getClientPid();
|
||||
method public int getClientUid();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMutedBy();
|
||||
method public int getPlayerInterfaceId();
|
||||
method public android.media.PlayerProxy getPlayerProxy();
|
||||
method public int getPlayerState();
|
||||
method public int getPlayerType();
|
||||
method @IntRange(from=0) public int getSessionId();
|
||||
method public boolean isActive();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean isMuted();
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_APP_OPS = 8; // 0x8
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_CLIENT_VOLUME = 16; // 0x10
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_MASTER = 1; // 0x1
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_STREAM_MUTED = 4; // 0x4
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_STREAM_VOLUME = 2; // 0x2
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_UNKNOWN = -1; // 0xffffffff
|
||||
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int MUTED_BY_VOLUME_SHAPER = 32; // 0x20
|
||||
field public static final int PLAYER_STATE_IDLE = 1; // 0x1
|
||||
field public static final int PLAYER_STATE_PAUSED = 3; // 0x3
|
||||
field public static final int PLAYER_STATE_RELEASED = 0; // 0x0
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.annotation.IntDef;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
@@ -220,46 +221,59 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Mute state used for anonymization.
|
||||
* Mute state used for the initial state and when API is accessed without permission.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_INVALID = -1;
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_UNKNOWN = -1;
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by master volume.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_MASTER = (1 << 0);
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_MASTER = (1 << 0);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by stream volume.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_STREAM_VOLUME = (1 << 1);
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_STREAM_VOLUME = (1 << 1);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by stream mute.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_STREAM_MUTED = (1 << 2);
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_STREAM_MUTED = (1 << 2);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when playback is restricted by AppOps manager with OP_PLAY_AUDIO.
|
||||
* Flag used when playback is muted by AppOpsManager#OP_PLAY_AUDIO.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_PLAYBACK_RESTRICTED = (1 << 3);
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_APP_OPS = (1 << 3);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by client volume.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_CLIENT_VOLUME = (1 << 4);
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_CLIENT_VOLUME = (1 << 4);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by volume shaper.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_VOLUME_SHAPER = (1 << 5);
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public static final int MUTED_BY_VOLUME_SHAPER = (1 << 5);
|
||||
|
||||
/** @hide */
|
||||
@IntDef(
|
||||
flag = true,
|
||||
value = {PLAYER_MUTE_MASTER, PLAYER_MUTE_STREAM_VOLUME, PLAYER_MUTE_STREAM_MUTED,
|
||||
PLAYER_MUTE_PLAYBACK_RESTRICTED, PLAYER_MUTE_CLIENT_VOLUME,
|
||||
PLAYER_MUTE_VOLUME_SHAPER})
|
||||
value = {MUTED_BY_MASTER, MUTED_BY_STREAM_VOLUME, MUTED_BY_STREAM_MUTED,
|
||||
MUTED_BY_APP_OPS, MUTED_BY_CLIENT_VOLUME, MUTED_BY_VOLUME_SHAPER})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PlayerMuteEvent {
|
||||
}
|
||||
@@ -303,7 +317,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
mPlayerType = pic.mPlayerType;
|
||||
mClientUid = uid;
|
||||
mClientPid = pid;
|
||||
mMutedState = PLAYER_MUTE_INVALID;
|
||||
mMutedState = MUTED_BY_UNKNOWN;
|
||||
mDeviceId = PLAYER_DEVICEID_INVALID;
|
||||
mPlayerState = PLAYER_STATE_IDLE;
|
||||
mPlayerAttr = pic.mAttributes;
|
||||
@@ -352,7 +366,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
anonymCopy.mPlayerAttr = builder.build();
|
||||
anonymCopy.mDeviceId = in.mDeviceId;
|
||||
// anonymized data
|
||||
anonymCopy.mMutedState = PLAYER_MUTE_INVALID;
|
||||
anonymCopy.mMutedState = MUTED_BY_UNKNOWN;
|
||||
anonymCopy.mPlayerType = PLAYER_TYPE_UNKNOWN;
|
||||
anonymCopy.mClientUid = PLAYER_UPID_INVALID;
|
||||
anonymCopy.mClientPid = PLAYER_UPID_INVALID;
|
||||
@@ -413,9 +427,27 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return the mute state as a combination of {@link PlayerMuteEvent} flags
|
||||
* Used for determining if the current player is muted.
|
||||
* <br>Note that if this result is true then {@link #getMutedBy} will be > 0.
|
||||
* @return {@code true} if the player associated with this configuration has been muted (by any
|
||||
* given MUTED_BY_* source event) or {@code false} otherwise.
|
||||
*/
|
||||
@PlayerMuteEvent public int getMutedState() {
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public boolean isMuted() {
|
||||
return mMutedState != 0 && mMutedState != MUTED_BY_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Returns a bitmask expressing the mute state as a combination of MUTED_BY_* flags.
|
||||
* <br>Note that if the mute state is not set the result will be {@link #MUTED_BY_UNKNOWN}. A
|
||||
* value of 0 represents a player which is not muted.
|
||||
* @return the mute state.
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
@PlayerMuteEvent public int getMutedBy() {
|
||||
return mMutedState;
|
||||
}
|
||||
|
||||
@@ -570,14 +602,14 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
}
|
||||
|
||||
private boolean isMuteAffectingActiveState() {
|
||||
if (mMutedState == PLAYER_MUTE_INVALID) {
|
||||
if (mMutedState == MUTED_BY_UNKNOWN) {
|
||||
// mute state is not set, therefore it will not affect the active state
|
||||
return false;
|
||||
}
|
||||
|
||||
return (mMutedState & PLAYER_MUTE_CLIENT_VOLUME) != 0
|
||||
|| (mMutedState & PLAYER_MUTE_VOLUME_SHAPER) != 0
|
||||
|| (mMutedState & PLAYER_MUTE_PLAYBACK_RESTRICTED) != 0;
|
||||
return (mMutedState & MUTED_BY_CLIENT_VOLUME) != 0
|
||||
|| (mMutedState & MUTED_BY_VOLUME_SHAPER) != 0
|
||||
|| (mMutedState & MUTED_BY_APP_OPS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -694,27 +726,27 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
"/").append(mClientPid).append(" state:").append(
|
||||
toLogFriendlyPlayerState(mPlayerState)).append(" attr:").append(mPlayerAttr).append(
|
||||
" sessionId:").append(mSessionId).append(" mutedState:");
|
||||
if (mMutedState == PLAYER_MUTE_INVALID) {
|
||||
apcToString.append("invalid ");
|
||||
if (mMutedState == MUTED_BY_UNKNOWN) {
|
||||
apcToString.append("unknown ");
|
||||
} else if (mMutedState == 0) {
|
||||
apcToString.append("none ");
|
||||
} else {
|
||||
if ((mMutedState & PLAYER_MUTE_MASTER) != 0) {
|
||||
if ((mMutedState & MUTED_BY_MASTER) != 0) {
|
||||
apcToString.append("master ");
|
||||
}
|
||||
if ((mMutedState & PLAYER_MUTE_STREAM_VOLUME) != 0) {
|
||||
if ((mMutedState & MUTED_BY_STREAM_VOLUME) != 0) {
|
||||
apcToString.append("streamVolume ");
|
||||
}
|
||||
if ((mMutedState & PLAYER_MUTE_STREAM_MUTED) != 0) {
|
||||
if ((mMutedState & MUTED_BY_STREAM_MUTED) != 0) {
|
||||
apcToString.append("streamMute ");
|
||||
}
|
||||
if ((mMutedState & PLAYER_MUTE_PLAYBACK_RESTRICTED) != 0) {
|
||||
apcToString.append("playbackRestricted ");
|
||||
if ((mMutedState & MUTED_BY_APP_OPS) != 0) {
|
||||
apcToString.append("appOps ");
|
||||
}
|
||||
if ((mMutedState & PLAYER_MUTE_CLIENT_VOLUME) != 0) {
|
||||
if ((mMutedState & MUTED_BY_CLIENT_VOLUME) != 0) {
|
||||
apcToString.append("clientVolume ");
|
||||
}
|
||||
if ((mMutedState & PLAYER_MUTE_VOLUME_SHAPER) != 0) {
|
||||
if ((mMutedState & MUTED_BY_VOLUME_SHAPER) != 0) {
|
||||
apcToString.append("volumeShaper ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package com.android.server.audio;
|
||||
|
||||
import static android.media.AudioPlaybackConfiguration.EXTRA_PLAYER_EVENT_MUTE;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_MUTE_CLIENT_VOLUME;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_MUTE_MASTER;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_MUTE_PLAYBACK_RESTRICTED;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_MUTE_STREAM_MUTED;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_MUTE_STREAM_VOLUME;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_MUTE_VOLUME_SHAPER;
|
||||
import static android.media.AudioPlaybackConfiguration.MUTED_BY_APP_OPS;
|
||||
import static android.media.AudioPlaybackConfiguration.MUTED_BY_CLIENT_VOLUME;
|
||||
import static android.media.AudioPlaybackConfiguration.MUTED_BY_MASTER;
|
||||
import static android.media.AudioPlaybackConfiguration.MUTED_BY_STREAM_MUTED;
|
||||
import static android.media.AudioPlaybackConfiguration.MUTED_BY_STREAM_VOLUME;
|
||||
import static android.media.AudioPlaybackConfiguration.MUTED_BY_VOLUME_SHAPER;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_PIID_INVALID;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_MUTED;
|
||||
|
||||
@@ -1155,22 +1155,22 @@ public final class PlaybackActivityMonitor
|
||||
if (mEventValue <= 0) {
|
||||
builder.append("none ");
|
||||
} else {
|
||||
if ((mEventValue & PLAYER_MUTE_MASTER) != 0) {
|
||||
if ((mEventValue & MUTED_BY_MASTER) != 0) {
|
||||
builder.append("masterMute ");
|
||||
}
|
||||
if ((mEventValue & PLAYER_MUTE_STREAM_VOLUME) != 0) {
|
||||
if ((mEventValue & MUTED_BY_STREAM_VOLUME) != 0) {
|
||||
builder.append("streamVolume ");
|
||||
}
|
||||
if ((mEventValue & PLAYER_MUTE_STREAM_MUTED) != 0) {
|
||||
if ((mEventValue & MUTED_BY_STREAM_MUTED) != 0) {
|
||||
builder.append("streamMute ");
|
||||
}
|
||||
if ((mEventValue & PLAYER_MUTE_PLAYBACK_RESTRICTED) != 0) {
|
||||
builder.append("playbackRestricted ");
|
||||
if ((mEventValue & MUTED_BY_APP_OPS) != 0) {
|
||||
builder.append("appOps ");
|
||||
}
|
||||
if ((mEventValue & PLAYER_MUTE_CLIENT_VOLUME) != 0) {
|
||||
if ((mEventValue & MUTED_BY_CLIENT_VOLUME) != 0) {
|
||||
builder.append("clientVolume ");
|
||||
}
|
||||
if ((mEventValue & PLAYER_MUTE_VOLUME_SHAPER) != 0) {
|
||||
if ((mEventValue & MUTED_BY_VOLUME_SHAPER) != 0) {
|
||||
builder.append("volumeShaper ");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user