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