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

Commit 9961d696 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Audio event logging" into oc-mr1-dev

parents 8f5c9de9 011f39e7
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -113,6 +113,17 @@ public class AudioSystem
    public static final int MODE_IN_COMMUNICATION   = 3;
    public static final int NUM_MODES               = 4;

    public static String modeToString(int mode) {
        switch (mode) {
            case MODE_CURRENT: return "MODE_CURRENT";
            case MODE_IN_CALL: return "MODE_IN_CALL";
            case MODE_IN_COMMUNICATION: return "MODE_IN_COMMUNICATION";
            case MODE_INVALID: return "MODE_INVALID";
            case MODE_NORMAL: return "MODE_NORMAL";
            case MODE_RINGTONE: return "MODE_RINGTONE";
            default: return "unknown mode (" + mode + ")";
        }
    }

    /* Routing bits for the former setRouting/getRouting API */
    /** @deprecated */
@@ -498,6 +509,14 @@ public class AudioSystem
    public static final int DEVICE_STATE_AVAILABLE = 1;
    private static final int NUM_DEVICE_STATES = 1;

    public static String deviceStateToString(int state) {
        switch (state) {
            case DEVICE_STATE_UNAVAILABLE: return "DEVICE_STATE_UNAVAILABLE";
            case DEVICE_STATE_AVAILABLE: return "DEVICE_STATE_AVAILABLE";
            default: return "unknown state (" + state + ")";
        }
    }

    public static final String DEVICE_OUT_EARPIECE_NAME = "earpiece";
    public static final String DEVICE_OUT_SPEAKER_NAME = "speaker";
    public static final String DEVICE_OUT_WIRED_HEADSET_NAME = "headset";
@@ -693,6 +712,27 @@ public class AudioSystem
    public static final int NUM_FORCE_CONFIG = 15;
    public static final int FORCE_DEFAULT = FORCE_NONE;

    public static String forceUseConfigToString(int config) {
        switch (config) {
            case FORCE_NONE: return "FORCE_NONE";
            case FORCE_SPEAKER: return "FORCE_SPEAKER";
            case FORCE_HEADPHONES: return "FORCE_HEADPHONES";
            case FORCE_BT_SCO: return "FORCE_BT_SCO";
            case FORCE_BT_A2DP: return "FORCE_BT_A2DP";
            case FORCE_WIRED_ACCESSORY: return "FORCE_WIRED_ACCESSORY";
            case FORCE_BT_CAR_DOCK: return "FORCE_BT_CAR_DOCK";
            case FORCE_BT_DESK_DOCK: return "FORCE_BT_DESK_DOCK";
            case FORCE_ANALOG_DOCK: return "FORCE_ANALOG_DOCK";
            case FORCE_DIGITAL_DOCK: return "FORCE_DIGITAL_DOCK";
            case FORCE_NO_BT_A2DP: return "FORCE_NO_BT_A2DP";
            case FORCE_SYSTEM_ENFORCED: return "FORCE_SYSTEM_ENFORCED";
            case FORCE_HDMI_SYSTEM_AUDIO_ENFORCED: return "FORCE_HDMI_SYSTEM_AUDIO_ENFORCED";
            case FORCE_ENCODED_SURROUND_NEVER: return "FORCE_ENCODED_SURROUND_NEVER";
            case FORCE_ENCODED_SURROUND_ALWAYS: return "FORCE_ENCODED_SURROUND_ALWAYS";
            default: return "unknown config (" + config + ")" ;
        }
    }

    // usage for setForceUse, must match audio_policy_force_use_t
    public static final int FOR_COMMUNICATION = 0;
    public static final int FOR_MEDIA = 1;
@@ -703,6 +743,19 @@ public class AudioSystem
    public static final int FOR_ENCODED_SURROUND = 6;
    private static final int NUM_FORCE_USE = 7;

    public static String forceUseUsageToString(int usage) {
        switch (usage) {
            case FOR_COMMUNICATION: return "FOR_COMMUNICATION";
            case FOR_MEDIA: return "FOR_MEDIA";
            case FOR_RECORD: return "FOR_RECORD";
            case FOR_DOCK: return "FOR_DOCK";
            case FOR_SYSTEM: return "FOR_SYSTEM";
            case FOR_HDMI_SYSTEM_AUDIO: return "FOR_HDMI_SYSTEM_AUDIO";
            case FOR_ENCODED_SURROUND: return "FOR_ENCODED_SURROUND";
            default: return "unknown usage (" + usage + ")" ;
        }
    }

    // usage for AudioRecord.startRecordingSync(), must match AudioSystem::sync_event_t
    public static final int SYNC_EVENT_NONE = 0;
    public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1;
+97 −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 java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;

public class AudioEventLogger {

    // ring buffer of events to log.
    private final LinkedList<Event> mEvents;

    private final String mTitle;

    // the maximum number of events to keep in log
    private final int mMemSize;

    public static abstract class Event {
        // formatter for timestamps
        private final static SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");

        private final long mTimestamp;

        Event() {
            mTimestamp = System.currentTimeMillis();
        }

        public String toString() {
            return (new StringBuilder(sFormat.format(new Date(mTimestamp))))
                    .append(" ").append(eventToString()).toString();
        }

        /**
         * Convert event to String.
         * This method is only called when the logger history is about to the dumped,
         * so this method is where expensive String conversions should be made, not when the Event
         * subclass is created.
         * Timestamp information will be automatically added, do not include it.
         * @return a string representation of the event that occurred.
         */
        abstract public String eventToString();
    }

    public static class StringEvent extends Event {
        private final String mMsg;

        public StringEvent(String msg) {
            mMsg = msg;
        }

        @Override
        public String eventToString() {
            return mMsg;
        }
    }

    /**
     * Constructor for logger.
     * @param size the maximum number of events to keep in log
     * @param title the string displayed before the recorded log
     */
    public AudioEventLogger(int size, String title) {
        mEvents = new LinkedList<Event>();
        mMemSize = size;
        mTitle = title;
    }

    public synchronized void log(Event evt) {
        if (mEvents.size() >= mMemSize) {
            mEvents.removeFirst();
        }
        mEvents.add(evt);
    }

    public synchronized void dump(PrintWriter pw) {
        pw.println("Audio event log: " + mTitle);
        for (Event evt : mEvents) {
            pw.println(evt.toString());
        }
    }
}
+162 −42

File changed.

Preview size limit exceeded, changes collapsed.

+76 −0
Original line number Diff line number Diff line
@@ -104,6 +104,9 @@ public final class PlaybackActivityMonitor
            final int index = mBannedUids.indexOf(new Integer(uid));
            if (index >= 0) {
                if (!disable) {
                    if (DEBUG) { // hidden behind DEBUG, too noisy otherwise
                        mEventLogger.log(new AudioEventLogger.StringEvent("unbanning uid:" + uid));
                    }
                    mBannedUids.remove(index);
                    // nothing else to do, future playback requests from this uid are ok
                } // no else to handle, uid already present, so disabling again is no-op
@@ -112,6 +115,9 @@ public final class PlaybackActivityMonitor
                    for (AudioPlaybackConfiguration apc : mPlayers.values()) {
                        checkBanPlayer(apc, uid);
                    }
                    if (DEBUG) { // hidden behind DEBUG, too noisy otherwise
                        mEventLogger.log(new AudioEventLogger.StringEvent("banning uid:" + uid));
                    }
                    mBannedUids.add(new Integer(uid));
                } // no else to handle, uid already not in list, so enabling again is no-op
            }
@@ -145,6 +151,7 @@ public final class PlaybackActivityMonitor
                new AudioPlaybackConfiguration(pic, newPiid,
                        Binder.getCallingUid(), Binder.getCallingPid());
        apc.init();
        mEventLogger.log(new NewPlayerEvent(apc));
        synchronized(mPlayerLock) {
            mPlayers.put(newPiid, apc);
        }
@@ -156,6 +163,7 @@ public final class PlaybackActivityMonitor
        synchronized(mPlayerLock) {
            final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
            if (checkConfigurationCaller(piid, apc, binderUid)) {
                mEventLogger.log(new AudioAttrEvent(piid, attr));
                change = apc.handleAudioAttributesEvent(attr);
            } else {
                Log.e(TAG, "Error updating audio attributes");
@@ -175,10 +183,13 @@ public final class PlaybackActivityMonitor
            if (apc == null) {
                return;
            }
            mEventLogger.log(new PlayerEvent(piid, event));
            if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
                for (Integer uidInteger: mBannedUids) {
                    if (checkBanPlayer(apc, uidInteger.intValue())) {
                        // player was banned, do not update its state
                        mEventLogger.log(new AudioEventLogger.StringEvent(
                                "not starting piid:" + piid + " ,is banned"));
                        return;
                    }
                }
@@ -208,6 +219,8 @@ public final class PlaybackActivityMonitor
        synchronized(mPlayerLock) {
            final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
            if (checkConfigurationCaller(piid, apc, binderUid)) {
                mEventLogger.log(new AudioEventLogger.StringEvent(
                        "releasing player piid:" + piid));
                mPlayers.remove(new Integer(piid));
                mDuckingManager.removeReleased(apc);
            }
@@ -250,6 +263,8 @@ public final class PlaybackActivityMonitor
                pw.print(" " + uid);
            }
            pw.println();
            // log
            mEventLogger.dump(pw);
        }
    }

@@ -672,4 +687,65 @@ public final class PlaybackActivityMonitor
            }
        }
    }

    //=================================================================
    // For logging
    private final static class PlayerEvent extends AudioEventLogger.Event {
        // only keeping the player interface ID as it uniquely identifies the player in the event
        final int mPlayerIId;
        final int mState;

        PlayerEvent(int piid, int state) {
            mPlayerIId = piid;
            mState = state;
        }

        @Override
        public String eventToString() {
            return new String("player piid:" + mPlayerIId + " state:"
                    + AudioPlaybackConfiguration.toLogFriendlyPlayerState(mState));
        }
    }

    private final static class NewPlayerEvent extends AudioEventLogger.Event {
        private final int mPlayerIId;
        private final int mPlayerType;
        private final int mClientUid;
        private final int mClientPid;
        private final AudioAttributes mPlayerAttr;

        NewPlayerEvent(AudioPlaybackConfiguration apc) {
            mPlayerIId = apc.getPlayerInterfaceId();
            mPlayerType = apc.getPlayerType();
            mClientUid = apc.getClientUid();
            mClientPid = apc.getClientPid();
            mPlayerAttr = apc.getAudioAttributes();
        }

        @Override
        public String eventToString() {
            return new String("new player piid:" + mPlayerIId + " uid/pid:" + mClientUid + "/"
                    + mClientPid + " type:"
                    + AudioPlaybackConfiguration.toLogFriendlyPlayerType(mPlayerType)
                    + " attr:" + mPlayerAttr);
        }
    }

    private final static class AudioAttrEvent extends AudioEventLogger.Event {
        private final int mPlayerIId;
        private final AudioAttributes mPlayerAttr;

        AudioAttrEvent(int piid, AudioAttributes attr) {
            mPlayerIId = piid;
            mPlayerAttr = attr;
        }

        @Override
        public String eventToString() {
            return new String("player piid:" + mPlayerIId + " new AudioAttributes:" + mPlayerAttr);
        }
    }

    private final AudioEventLogger mEventLogger = new AudioEventLogger(100,
            "playback activity as reported through PlayerBase");
}