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

Commit ee94d0af authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge "Audio event logging" into oc-mr1-dev am: 9961d696 am: 87dfc5bb"

parents c7065880 d2f450be
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");
}