1 /* 2 * Copyright (C) 2019 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.soundtrigger; 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 /** 27 * Constructor SoundTriggerLogger class 28 */ 29 public class SoundTriggerLogger { 30 31 // ring buffer of events to log. 32 private final LinkedList<Event> mEvents; 33 34 private final String mTitle; 35 36 // the maximum number of events to keep in log 37 private final int mMemSize; 38 39 /** 40 * Constructor for Event class. 41 */ 42 public abstract static class Event { 43 // formatter for timestamps 44 private static final SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 45 46 private final long mTimestamp; 47 Event()48 Event() { 49 mTimestamp = System.currentTimeMillis(); 50 } 51 52 /** 53 * Convert event to String 54 * @return StringBuilder 55 */ toString()56 public String toString() { 57 return (new StringBuilder(sFormat.format(new Date(mTimestamp)))) 58 .append(" ").append(eventToString()).toString(); 59 } 60 61 /** 62 * Causes the string message for the event to appear in the logcat. 63 * Here is an example of how to create a new event (a StringEvent), adding it to the logger 64 * (an instance of SoundTriggerLogger) while also making it show in the logcat: 65 * <pre> 66 * myLogger.log( 67 * (new StringEvent("something for logcat and logger")).printLog(MyClass.TAG) ); 68 * </pre> 69 * @param tag the tag for the android.util.Log.v 70 * @return the same instance of the event 71 */ printLog(String tag)72 public Event printLog(String tag) { 73 Log.i(tag, eventToString()); 74 return this; 75 } 76 77 /** 78 * Convert event to String. 79 * This method is only called when the logger history is about to the dumped, 80 * so this method is where expensive String conversions should be made, not when the Event 81 * subclass is created. 82 * Timestamp information will be automatically added, do not include it. 83 * @return a string representation of the event that occurred. 84 */ eventToString()85 public abstract String eventToString(); 86 } 87 88 /** 89 * Constructor StringEvent class 90 */ 91 public static class StringEvent extends Event { 92 private final String mMsg; 93 StringEvent(String msg)94 public StringEvent(String msg) { 95 mMsg = msg; 96 } 97 98 @Override eventToString()99 public String eventToString() { 100 return mMsg; 101 } 102 } 103 104 /** 105 * Constructor for logger. 106 * @param size the maximum number of events to keep in log 107 * @param title the string displayed before the recorded log 108 */ SoundTriggerLogger(int size, String title)109 public SoundTriggerLogger(int size, String title) { 110 mEvents = new LinkedList<Event>(); 111 mMemSize = size; 112 mTitle = title; 113 } 114 115 /** 116 * Constructor for logger. 117 * @param evt the maximum number of events to keep in log 118 */ log(Event evt)119 public synchronized void log(Event evt) { 120 if (mEvents.size() >= mMemSize) { 121 mEvents.removeFirst(); 122 } 123 mEvents.add(evt); 124 } 125 126 /** 127 * Constructor for logger. 128 * @param pw the maximum number of events to keep in log 129 */ dump(PrintWriter pw)130 public synchronized void dump(PrintWriter pw) { 131 pw.println("ST Event log: " + mTitle); 132 for (Event evt : mEvents) { 133 pw.println(evt.toString()); 134 } 135 } 136 } 137