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

Commit cf17036a authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioService: log volume commands and origin

Add volume logger for volume events.
Move AudioService event definitions to separate file.

Test: change volume with volume buttons and dumpsys audio
Bug: 64470715

Change-Id: I25db849bffb4a41a737d226cfc40e2c6f7e0ecc0
parent 61492c85
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -397,6 +397,19 @@ public class AudioManager {
     */
    public static final int ADJUST_TOGGLE_MUTE = 101;

    /** @hide */
    public static final String adjustToString(int adj) {
        switch (adj) {
            case ADJUST_RAISE: return "ADJUST_RAISE";
            case ADJUST_LOWER: return "ADJUST_LOWER";
            case ADJUST_SAME: return "ADJUST_SAME";
            case ADJUST_MUTE: return "ADJUST_MUTE";
            case ADJUST_UNMUTE: return "ADJUST_UNMUTE";
            case ADJUST_TOGGLE_MUTE: return "ADJUST_TOGGLE_MUTE";
            default: return new StringBuilder("unknown adjust mode ").append(adj).toString();
        }
    }

    // Flags should be powers of 2!

    /**
+20 −58
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.server.audio;

import com.android.server.audio.AudioServiceEvents.ForceUseEvent;
import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
import com.android.server.audio.AudioServiceEvents.VolumeEvent;
import com.android.server.audio.AudioServiceEvents.WiredDevConnectEvent;

import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK;
import static android.media.AudioManager.RINGER_MODE_NORMAL;
import static android.media.AudioManager.RINGER_MODE_SILENT;
@@ -1310,6 +1315,9 @@ public class AudioService extends IAudioService.Stub
                + ", flags=" + flags + ", caller=" + caller
                + ", volControlStream=" + mVolumeControlStream
                + ", userSelect=" + mUserSelectedVolumeControlStream);
        mVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
                direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
                        .append("/").append(caller).append(" uid:").append(uid).toString()));
        final int streamType;
        if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
            streamType = mVolumeControlStream;
@@ -1359,6 +1367,8 @@ public class AudioService extends IAudioService.Stub
                    + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
            return;
        }
        mVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
                direction/*val1*/, flags/*val2*/, callingPackage));
        adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
                Binder.getCallingUid());
    }
@@ -1675,6 +1685,8 @@ public class AudioService extends IAudioService.Stub
                    + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
            return;
        }
        mVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
                index/*val1*/, flags/*val2*/, callingPackage));
        setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
                Binder.getCallingUid());
    }
@@ -4017,7 +4029,7 @@ public class AudioService extends IAudioService.Stub
    /*
     * A class just for packaging up a set of connection parameters.
     */
    private class WiredDeviceConnectionState {
    class WiredDeviceConnectionState {
        public final int mType;
        public final int mState;
        public final String mAddress;
@@ -6372,63 +6384,7 @@ public class AudioService extends IAudioService.Stub
    final int LOG_NB_EVENTS_PHONE_STATE = 20;
    final int LOG_NB_EVENTS_WIRED_DEV_CONNECTION = 30;
    final int LOG_NB_EVENTS_FORCE_USE = 20;

    final private static class PhoneStateEvent extends AudioEventLogger.Event {
        final String mPackage;
        final int mPid;
        final int mMode;

        PhoneStateEvent(String callingPackage, int pid, int mode) {
            mPackage = callingPackage;
            mPid = pid;
            mMode = mode;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("setMode(").append(AudioSystem.modeToString(mMode))
                    .append(") from package=").append(mPackage)
                    .append(" pid=").append(mPid).toString();
        }
    }

    final private static class WiredDevConnectEvent extends AudioEventLogger.Event {
        final WiredDeviceConnectionState mState;

        WiredDevConnectEvent(WiredDeviceConnectionState state) {
            mState = state;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("setWiredDeviceConnectionState(")
                    .append(" type:").append(Integer.toHexString(mState.mType))
                    .append(" state:").append(AudioSystem.deviceStateToString(mState.mState))
                    .append(" addr:").append(mState.mAddress)
                    .append(" name:").append(mState.mName)
                    .append(") from ").append(mState.mCaller).toString();
        }
    }

    final private static class ForceUseEvent extends AudioEventLogger.Event {
        final int mUsage;
        final int mConfig;
        final String mReason;

        ForceUseEvent(int usage, int config, String reason) {
            mUsage = usage;
            mConfig = config;
            mReason = reason;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("setForceUse(")
                    .append(AudioSystem.forceUseUsageToString(mUsage))
                    .append(", ").append(AudioSystem.forceUseConfigToString(mConfig))
                    .append(") due to ").append(mReason).toString();
        }
    }
    final int LOG_NB_EVENTS_VOLUME = 40;

    final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
            "phone state (logged after successfull call to AudioSystem.setPhoneState(int))");
@@ -6442,6 +6398,9 @@ public class AudioService extends IAudioService.Stub
            LOG_NB_EVENTS_FORCE_USE,
            "force use (logged before setForceUse() is executed)");

    final private AudioEventLogger mVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
            "volume changes (logged when command received by AudioService)");

    private static final String[] RINGER_MODE_NAMES = new String[] {
            "SILENT",
            "VIBRATE",
@@ -6513,12 +6472,15 @@ public class AudioService extends IAudioService.Stub

        mRecordMonitor.dump(pw);

        pw.println("\n");
        pw.println("\nEvent logs:");
        mModeLogger.dump(pw);
        pw.println("\n");
        mWiredDevLogger.dump(pw);
        pw.println("\n");
        mForceUseLogger.dump(pw);
        pw.println("\n");
        mVolumeLogger.dump(pw);
    }

    private static String safeMediaVolumeStateToString(Integer state) {
+131 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.audio;

import android.media.AudioManager;
import android.media.AudioSystem;

import com.android.server.audio.AudioService.WiredDeviceConnectionState;


public class AudioServiceEvents {

    final static class PhoneStateEvent extends AudioEventLogger.Event {
        final String mPackage;
        final int mPid;
        final int mMode;

        PhoneStateEvent(String callingPackage, int pid, int mode) {
            mPackage = callingPackage;
            mPid = pid;
            mMode = mode;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("setMode(").append(AudioSystem.modeToString(mMode))
                    .append(") from package=").append(mPackage)
                    .append(" pid=").append(mPid).toString();
        }
    }

    final static class WiredDevConnectEvent extends AudioEventLogger.Event {
        final WiredDeviceConnectionState mState;

        WiredDevConnectEvent(WiredDeviceConnectionState state) {
            mState = state;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("setWiredDeviceConnectionState(")
                    .append(" type:").append(Integer.toHexString(mState.mType))
                    .append(" state:").append(AudioSystem.deviceStateToString(mState.mState))
                    .append(" addr:").append(mState.mAddress)
                    .append(" name:").append(mState.mName)
                    .append(") from ").append(mState.mCaller).toString();
        }
    }

    final static class ForceUseEvent extends AudioEventLogger.Event {
        final int mUsage;
        final int mConfig;
        final String mReason;

        ForceUseEvent(int usage, int config, String reason) {
            mUsage = usage;
            mConfig = config;
            mReason = reason;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("setForceUse(")
                    .append(AudioSystem.forceUseUsageToString(mUsage))
                    .append(", ").append(AudioSystem.forceUseConfigToString(mConfig))
                    .append(") due to ").append(mReason).toString();
        }
    }

    final static class VolumeEvent extends AudioEventLogger.Event {
        final static int VOL_ADJUST_SUGG_VOL = 0;
        final static int VOL_ADJUST_STREAM_VOL = 1;
        final static int VOL_SET_STREAM_VOL = 2;

        final int mOp;
        final int mStream;
        final int mVal1;
        final int mVal2;
        final String mCaller;

        VolumeEvent(int op, int stream, int val1, int val2, String caller) {
            mOp = op;
            mStream = stream;
            mVal1 = val1;
            mVal2 = val2;
            mCaller = caller;
        }

        @Override
        public String eventToString() {
            switch (mOp) {
                case VOL_ADJUST_SUGG_VOL:
                    return new StringBuilder("adjustSuggestedStreamVolume(sugg:")
                            .append(AudioSystem.streamToString(mStream))
                            .append(" dir:").append(AudioManager.adjustToString(mVal1))
                            .append(" flags:0x").append(Integer.toHexString(mVal2))
                            .append(") from ").append(mCaller)
                            .toString();
                case VOL_ADJUST_STREAM_VOL:
                    return new StringBuilder("adjustStreamVolume(stream:")
                            .append(AudioSystem.streamToString(mStream))
                            .append(" dir:").append(AudioManager.adjustToString(mVal1))
                            .append(" flags:0x").append(Integer.toHexString(mVal2))
                            .append(") from ").append(mCaller)
                            .toString();
                case VOL_SET_STREAM_VOL:
                    return new StringBuilder("setStreamVolume(stream:")
                            .append(AudioSystem.streamToString(mStream))
                            .append(" index:").append(mVal1)
                            .append(" flags:0x").append(Integer.toHexString(mVal2))
                            .append(") from ").append(mCaller)
                            .toString();
               default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
            }
        }
    }
}