Home | History | Annotate | Download | only in audio
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.audio;
     18 
     19 import android.util.Log;
     20 
     21 import java.io.PrintWriter;
     22 import java.text.SimpleDateFormat;
     23 import java.util.Date;
     24 import java.util.LinkedList;
     25 
     26 public class AudioEventLogger {
     27 
     28     // ring buffer of events to log.
     29     private final LinkedList<Event> mEvents;
     30 
     31     private final String mTitle;
     32 
     33     // the maximum number of events to keep in log
     34     private final int mMemSize;
     35 
     36     public static abstract class Event {
     37         // formatter for timestamps
     38         private final static SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
     39 
     40         private final long mTimestamp;
     41 
     42         Event() {
     43             mTimestamp = System.currentTimeMillis();
     44         }
     45 
     46         public String toString() {
     47             return (new StringBuilder(sFormat.format(new Date(mTimestamp))))
     48                     .append(" ").append(eventToString()).toString();
     49         }
     50 
     51         /**
     52          * Causes the string message for the event to appear in the logcat.
     53          * Here is an example of how to create a new event (a StringEvent), adding it to the logger
     54          * (an instance of AudioEventLogger) while also making it show in the logcat:
     55          * <pre>
     56          *     myLogger.log(
     57          *         (new StringEvent("something for logcat and logger")).printLog(MyClass.TAG) );
     58          * </pre>
     59          * @param tag the tag for the android.util.Log.v
     60          * @return the same instance of the event
     61          */
     62         public Event printLog(String tag) {
     63             Log.i(tag, eventToString());
     64             return this;
     65         }
     66 
     67         /**
     68          * Convert event to String.
     69          * This method is only called when the logger history is about to the dumped,
     70          * so this method is where expensive String conversions should be made, not when the Event
     71          * subclass is created.
     72          * Timestamp information will be automatically added, do not include it.
     73          * @return a string representation of the event that occurred.
     74          */
     75         abstract public String eventToString();
     76     }
     77 
     78     public static class StringEvent extends Event {
     79         private final String mMsg;
     80 
     81         public StringEvent(String msg) {
     82             mMsg = msg;
     83         }
     84 
     85         @Override
     86         public String eventToString() {
     87             return mMsg;
     88         }
     89     }
     90 
     91     /**
     92      * Constructor for logger.
     93      * @param size the maximum number of events to keep in log
     94      * @param title the string displayed before the recorded log
     95      */
     96     public AudioEventLogger(int size, String title) {
     97         mEvents = new LinkedList<Event>();
     98         mMemSize = size;
     99         mTitle = title;
    100     }
    101 
    102     public synchronized void log(Event evt) {
    103         if (mEvents.size() >= mMemSize) {
    104             mEvents.removeFirst();
    105         }
    106         mEvents.add(evt);
    107     }
    108 
    109     public synchronized void dump(PrintWriter pw) {
    110         pw.println("Audio event log: " + mTitle);
    111         for (Event evt : mEvents) {
    112             pw.println(evt.toString());
    113         }
    114     }
    115 }
    116