Merge "Handle the mute events"
This commit is contained in:
@@ -172,6 +172,11 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
* The state used to update port id, does not actually change the state of the player
|
||||
*/
|
||||
public static final int PLAYER_UPDATE_PORT_ID = 6;
|
||||
/**
|
||||
* @hide
|
||||
* Used to update the mute state of a player through its port id
|
||||
*/
|
||||
public static final int PLAYER_UPDATE_MUTED = 7;
|
||||
|
||||
/** @hide */
|
||||
@IntDef({
|
||||
@@ -183,6 +188,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
PLAYER_STATE_STOPPED,
|
||||
PLAYER_UPDATE_DEVICE_ID,
|
||||
PLAYER_UPDATE_PORT_ID,
|
||||
PLAYER_UPDATE_MUTED,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PlayerState {}
|
||||
@@ -198,11 +204,50 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
case PLAYER_STATE_STOPPED: return "PLAYER_STATE_STOPPED";
|
||||
case PLAYER_UPDATE_DEVICE_ID: return "PLAYER_UPDATE_DEVICE_ID";
|
||||
case PLAYER_UPDATE_PORT_ID: return "PLAYER_UPDATE_PORT_ID";
|
||||
case PLAYER_UPDATE_MUTED: return "PLAYER_UPDATE_MUTED";
|
||||
default:
|
||||
return "invalid state " + state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Used to update the mute state of a player through its port ID. Must be kept in sync with
|
||||
* frameworks/native/include/audiomanager/AudioManager.h
|
||||
*/
|
||||
public static final String EXTRA_PLAYER_EVENT_MUTE =
|
||||
"android.media.extra.PLAYER_EVENT_MUTE";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by master volume.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_MASTER = (1 << 0);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by stream volume.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_STREAM_VOLUME = (1 << 1);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when muted by stream mute.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_STREAM_MUTED = (1 << 2);
|
||||
/**
|
||||
* @hide
|
||||
* Flag used when playback is restricted by AppOps manager with OP_PLAY_AUDIO.
|
||||
*/
|
||||
public static final int PLAYER_MUTE_PLAYBACK_RESTRICTED = (1 << 3);
|
||||
|
||||
/** @hide */
|
||||
@IntDef(
|
||||
flag = true,
|
||||
value = {PLAYER_MUTE_MASTER, PLAYER_MUTE_STREAM_VOLUME, PLAYER_MUTE_STREAM_MUTED,
|
||||
PLAYER_MUTE_PLAYBACK_RESTRICTED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PlayerMuteEvent {
|
||||
}
|
||||
|
||||
// immutable data
|
||||
private final int mPlayerIId;
|
||||
|
||||
@@ -678,6 +723,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
|
||||
case PLAYER_STATE_STOPPED: return "stopped";
|
||||
case PLAYER_UPDATE_DEVICE_ID: return "device updated";
|
||||
case PLAYER_UPDATE_PORT_ID: return "port updated";
|
||||
case PLAYER_UPDATE_MUTED: return "muted updated";
|
||||
default:
|
||||
return "unknown player state - FIXME";
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ import android.media.audiopolicy.AudioVolumeGroup;
|
||||
import android.media.audiopolicy.IAudioPolicyCallback;
|
||||
import android.media.projection.IMediaProjection;
|
||||
import android.net.Uri;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.UserHandle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
@@ -86,6 +87,8 @@ interface IAudioService {
|
||||
|
||||
oneway void playerSessionId(in int piid, in int sessionId);
|
||||
|
||||
oneway void portEvent(in int portId, in int event, in @nullable PersistableBundle extras);
|
||||
|
||||
// Java-only methods below.
|
||||
void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage);
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ import android.os.HwBinder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteCallbackList;
|
||||
@@ -11141,6 +11142,16 @@ public class AudioService extends IAudioService.Stub
|
||||
mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update event for port id
|
||||
* @param portId Port id to update
|
||||
* @param event The new event for the given port
|
||||
* @param extras Bundle of extra values to describe the event
|
||||
*/
|
||||
public void portEvent(int portId, int event, @Nullable PersistableBundle extras) {
|
||||
mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid());
|
||||
}
|
||||
|
||||
public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
|
||||
mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
package com.android.server.audio;
|
||||
|
||||
import static android.media.AudioPlaybackConfiguration.EXTRA_PLAYER_EVENT_MUTE;
|
||||
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_PIID_INVALID;
|
||||
import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_MUTED;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
@@ -24,6 +32,7 @@ import android.media.AudioAttributes;
|
||||
import android.media.AudioDeviceAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioPlaybackConfiguration;
|
||||
import android.media.AudioPlaybackConfiguration.PlayerMuteEvent;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.IPlaybackConfigDispatcher;
|
||||
import android.media.PlayerBase;
|
||||
@@ -33,7 +42,9 @@ import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -349,6 +360,56 @@ public final class PlaybackActivityMonitor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update event for port
|
||||
* @param portId Port id to update
|
||||
* @param event The new port event
|
||||
* @param extras The values associated with this event
|
||||
* @param binderUid Calling binder uid
|
||||
*/
|
||||
public void portEvent(int portId, int event, @Nullable PersistableBundle extras,
|
||||
int binderUid) {
|
||||
if (!UserHandle.isCore(binderUid)) {
|
||||
Log.e(TAG, "Forbidden operation from uid " + binderUid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, TextUtils.formatSimple("portEvent(portId=%d, event=%s, extras=%s)",
|
||||
portId, AudioPlaybackConfiguration.playerStateToString(event), extras));
|
||||
}
|
||||
|
||||
synchronized (mPlayerLock) {
|
||||
int piid = mPortIdToPiid.get(portId, PLAYER_PIID_INVALID);
|
||||
if (piid == PLAYER_PIID_INVALID) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "No piid assigned for invalid/internal port id " + portId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final AudioPlaybackConfiguration apc = mPlayers.get(piid);
|
||||
if (apc == null) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "No AudioPlaybackConfiguration assigned for piid " + piid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (apc.getPlayerType()
|
||||
== AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
|
||||
// FIXME SoundPool not ready for state reporting
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == AudioPlaybackConfiguration.PLAYER_UPDATE_MUTED) {
|
||||
mEventHandler.sendMessage(
|
||||
mEventHandler.obtainMessage(MSG_L_UPDATE_PLAYER_MUTED_EVENT, piid,
|
||||
portId,
|
||||
extras));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio, int binderUid) {
|
||||
// no check on UID yet because this is only for logging at the moment
|
||||
sEventLogger.log(new PlayerOpPlayAudioEvent(piid, hasOpPlayAudio, binderUid));
|
||||
@@ -1062,18 +1123,32 @@ public final class PlaybackActivityMonitor
|
||||
|
||||
@Override
|
||||
public String eventToString() {
|
||||
if (mEvent == AudioPlaybackConfiguration.PLAYER_UPDATE_PORT_ID) {
|
||||
return AudioPlaybackConfiguration.toLogFriendlyPlayerState(mEvent) + " portId:"
|
||||
+ mEventValue + " mapped to player piid:" + mPlayerIId;
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder("player piid:").append(mPlayerIId).append(
|
||||
" state:")
|
||||
" event:")
|
||||
.append(AudioPlaybackConfiguration.toLogFriendlyPlayerState(mEvent));
|
||||
if (mEventValue != 0) {
|
||||
builder.append(" DeviceId:").append(mEventValue);
|
||||
|
||||
switch (mEvent) {
|
||||
case AudioPlaybackConfiguration.PLAYER_UPDATE_PORT_ID:
|
||||
return AudioPlaybackConfiguration.toLogFriendlyPlayerState(mEvent) + " portId:"
|
||||
+ mEventValue + " mapped to player piid:" + mPlayerIId;
|
||||
case AudioPlaybackConfiguration.PLAYER_UPDATE_DEVICE_ID:
|
||||
if (mEventValue != 0) {
|
||||
builder.append(" deviceId:").append(mEventValue);
|
||||
}
|
||||
return builder.toString();
|
||||
case AudioPlaybackConfiguration.PLAYER_UPDATE_MUTED:
|
||||
builder.append(" muteFromMasterMute:").append(
|
||||
(mEventValue & PLAYER_MUTE_MASTER) != 0);
|
||||
builder.append(" muteFromStreamVolume:").append(
|
||||
(mEventValue & PLAYER_MUTE_STREAM_VOLUME) != 0);
|
||||
builder.append(" muteFromStreamMute:").append(
|
||||
(mEventValue & PLAYER_MUTE_STREAM_MUTED) != 0);
|
||||
builder.append(" muteFromPlaybackRestricted:").append(
|
||||
(mEventValue & PLAYER_MUTE_PLAYBACK_RESTRICTED) != 0);
|
||||
return builder.toString();
|
||||
default:
|
||||
return builder.toString();
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1322,12 +1397,22 @@ public final class PlaybackActivityMonitor
|
||||
*/
|
||||
private static final int MSG_L_UPDATE_PORT_EVENT = 2;
|
||||
|
||||
/**
|
||||
* event for player getting muted
|
||||
* args:
|
||||
* msg.arg1: piid
|
||||
* msg.arg2: port id
|
||||
* msg.obj: extras describing the mute reason
|
||||
* type: PersistableBundle
|
||||
*/
|
||||
private static final int MSG_L_UPDATE_PLAYER_MUTED_EVENT = 3;
|
||||
|
||||
/**
|
||||
* clear all ports assigned to a given piid
|
||||
* args:
|
||||
* msg.arg1: the piid
|
||||
*/
|
||||
private static final int MSG_L_CLEAR_PORTS_FOR_PIID = 3;
|
||||
private static final int MSG_L_CLEAR_PORTS_FOR_PIID = 4;
|
||||
|
||||
private void initEventHandler() {
|
||||
mEventThread = new HandlerThread(TAG);
|
||||
@@ -1349,6 +1434,18 @@ public final class PlaybackActivityMonitor
|
||||
mPortIdToPiid.put(/*portId*/msg.arg1, /*piid*/msg.arg2);
|
||||
}
|
||||
break;
|
||||
case MSG_L_UPDATE_PLAYER_MUTED_EVENT:
|
||||
// TODO: replace PersistableBundle with own struct
|
||||
PersistableBundle extras = (PersistableBundle) msg.obj;
|
||||
if (extras == null) {
|
||||
Log.w(TAG, "Received mute event with no extras");
|
||||
break;
|
||||
}
|
||||
@PlayerMuteEvent int eventValue = extras.getInt(EXTRA_PLAYER_EVENT_MUTE);
|
||||
|
||||
sEventLogger.log(new PlayerEvent(/*piid=*/msg.arg1, PLAYER_UPDATE_MUTED,
|
||||
eventValue));
|
||||
break;
|
||||
case MSG_L_CLEAR_PORTS_FOR_PIID:
|
||||
int piid = msg.arg1;
|
||||
if (piid == AudioPlaybackConfiguration.PLAYER_PIID_INVALID) {
|
||||
|
||||
Reference in New Issue
Block a user