1/* 2 * Copyright (C) 2015 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 */ 16package com.android.voicemail.impl; 17 18import com.android.dialer.common.LogUtil; 19import com.android.dialer.persistentlog.PersistentLogger; 20import com.android.voicemail.impl.utils.IndentingPrintWriter; 21import java.io.FileDescriptor; 22import java.io.PrintWriter; 23import java.util.ArrayDeque; 24import java.util.Calendar; 25import java.util.Deque; 26import java.util.Iterator; 27 28/** Helper methods for adding to OMTP visual voicemail local logs. */ 29public class VvmLog { 30 31 private static final int MAX_OMTP_VVM_LOGS = 100; 32 33 private static final LocalLog sLocalLog = new LocalLog(MAX_OMTP_VVM_LOGS); 34 35 public static void log(String tag, String log) { 36 PersistentLogger.logText(tag, log); 37 } 38 39 public static void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) { 40 IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(printwriter, " "); 41 indentingPrintWriter.increaseIndent(); 42 sLocalLog.dump(fd, indentingPrintWriter, args); 43 indentingPrintWriter.decreaseIndent(); 44 } 45 46 public static void e(String tag, String log) { 47 log(tag, log); 48 LogUtil.e(tag, log); 49 } 50 51 public static void e(String tag, String log, Throwable e) { 52 log(tag, log + " " + e); 53 LogUtil.e(tag, log, e); 54 } 55 56 public static void w(String tag, String log) { 57 log(tag, log); 58 LogUtil.w(tag, log); 59 } 60 61 public static void w(String tag, String log, Throwable e) { 62 log(tag, log + " " + e); 63 LogUtil.w(tag, log, e); 64 } 65 66 public static void i(String tag, String log) { 67 log(tag, log); 68 LogUtil.i(tag, log); 69 } 70 71 public static void i(String tag, String log, Throwable e) { 72 log(tag, log + " " + e); 73 LogUtil.i(tag, log, e); 74 } 75 76 public static void d(String tag, String log) { 77 log(tag, log); 78 LogUtil.d(tag, log); 79 } 80 81 public static void d(String tag, String log, Throwable e) { 82 log(tag, log + " " + e); 83 LogUtil.d(tag, log, e); 84 } 85 86 public static void v(String tag, String log) { 87 log(tag, log); 88 LogUtil.v(tag, log); 89 } 90 91 public static void v(String tag, String log, Throwable e) { 92 log(tag, log + " " + e); 93 LogUtil.v(tag, log, e); 94 } 95 96 public static void wtf(String tag, String log) { 97 log(tag, log); 98 LogUtil.e(tag, log); 99 } 100 101 public static void wtf(String tag, String log, Throwable e) { 102 log(tag, log + " " + e); 103 LogUtil.e(tag, log, e); 104 } 105 106 /** 107 * Redact personally identifiable information for production users. If we are running in verbose 108 * mode, return the original string, otherwise return a SHA-1 hash of the input string. 109 */ 110 public static String pii(Object pii) { 111 if (pii == null) { 112 return String.valueOf(pii); 113 } 114 return "[PII]"; 115 } 116 117 public static class LocalLog { 118 119 private final Deque<String> mLog; 120 private final int mMaxLines; 121 122 public LocalLog(int maxLines) { 123 mMaxLines = Math.max(0, maxLines); 124 mLog = new ArrayDeque<>(mMaxLines); 125 } 126 127 public void log(String msg) { 128 if (mMaxLines <= 0) { 129 return; 130 } 131 Calendar c = Calendar.getInstance(); 132 c.setTimeInMillis(System.currentTimeMillis()); 133 append(String.format("%tm-%td %tH:%tM:%tS.%tL - %s", c, c, c, c, c, c, msg)); 134 } 135 136 private synchronized void append(String logLine) { 137 while (mLog.size() >= mMaxLines) { 138 mLog.remove(); 139 } 140 mLog.add(logLine); 141 } 142 143 public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 144 Iterator<String> itr = mLog.iterator(); 145 while (itr.hasNext()) { 146 pw.println(itr.next()); 147 } 148 } 149 150 public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) { 151 Iterator<String> itr = mLog.descendingIterator(); 152 while (itr.hasNext()) { 153 pw.println(itr.next()); 154 } 155 } 156 157 public static class ReadOnlyLocalLog { 158 159 private final LocalLog mLog; 160 161 ReadOnlyLocalLog(LocalLog log) { 162 mLog = log; 163 } 164 165 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 166 mLog.dump(fd, pw, args); 167 } 168 169 public void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) { 170 mLog.reverseDump(fd, pw, args); 171 } 172 } 173 174 public ReadOnlyLocalLog readOnlyLocalLog() { 175 return new ReadOnlyLocalLog(this); 176 } 177 } 178} 179