Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ead8130b authored by Vlad Popa's avatar Vlad Popa
Browse files

Handle the mute events

For now just log the events for dumpsys. This should be extended in the
future to notify the clients of a change.

Test: dumpsys audio
Bug: 235521198
Change-Id: I4f5dac7cde400eeac24b2bdf22d366ac3e2e0dc2
parent cc4d221e
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -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";
        }
+3 −0
Original line number Diff line number Diff line
@@ -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);

+11 −0
Original line number Diff line number Diff line
@@ -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());
    }
+107 −10
Original line number Diff line number Diff line
@@ -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));

            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);
                        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();
            }
        }
    }

@@ -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) {