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 */ 16 package com.android.voicemail.impl; 17 18 import com.android.dialer.common.LogUtil; 19 import com.android.dialer.persistentlog.PersistentLogger; 20 import com.android.voicemail.impl.utils.IndentingPrintWriter; 21 import java.io.FileDescriptor; 22 import java.io.PrintWriter; 23 import java.util.ArrayDeque; 24 import java.util.Calendar; 25 import java.util.Deque; 26 import java.util.Iterator; 27 28 /** Helper methods for adding to OMTP visual voicemail local logs. */ 29 public class VvmLog { 30 31 private static final int MAX_OMTP_VVM_LOGS = 100; 32 33 private static final LocalLog localLog = new LocalLog(MAX_OMTP_VVM_LOGS); 34 log(String tag, String log)35 public static void log(String tag, String log) { 36 PersistentLogger.logText(tag, log); 37 } 38 dump(FileDescriptor fd, PrintWriter printwriter, String[] args)39 public static void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) { 40 IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(printwriter, " "); 41 indentingPrintWriter.increaseIndent(); 42 localLog.dump(fd, indentingPrintWriter, args); 43 indentingPrintWriter.decreaseIndent(); 44 } 45 e(String tag, String log)46 public static void e(String tag, String log) { 47 log(tag, log); 48 LogUtil.e(tag, log); 49 } 50 e(String tag, String log, Throwable e)51 public static void e(String tag, String log, Throwable e) { 52 log(tag, log + " " + e); 53 LogUtil.e(tag, log, e); 54 } 55 w(String tag, String log)56 public static void w(String tag, String log) { 57 log(tag, log); 58 LogUtil.w(tag, log); 59 } 60 w(String tag, String log, Throwable e)61 public static void w(String tag, String log, Throwable e) { 62 log(tag, log + " " + e); 63 LogUtil.w(tag, log, e); 64 } 65 i(String tag, String log)66 public static void i(String tag, String log) { 67 log(tag, log); 68 LogUtil.i(tag, log); 69 } 70 i(String tag, String log, Throwable e)71 public static void i(String tag, String log, Throwable e) { 72 log(tag, log + " " + e); 73 LogUtil.i(tag, log, e); 74 } 75 d(String tag, String log)76 public static void d(String tag, String log) { 77 log(tag, log); 78 LogUtil.d(tag, log); 79 } 80 d(String tag, String log, Throwable e)81 public static void d(String tag, String log, Throwable e) { 82 log(tag, log + " " + e); 83 LogUtil.d(tag, log, e); 84 } 85 v(String tag, String log)86 public static void v(String tag, String log) { 87 log(tag, log); 88 LogUtil.v(tag, log); 89 } 90 v(String tag, String log, Throwable e)91 public static void v(String tag, String log, Throwable e) { 92 log(tag, log + " " + e); 93 LogUtil.v(tag, log, e); 94 } 95 wtf(String tag, String log)96 public static void wtf(String tag, String log) { 97 log(tag, log); 98 LogUtil.e(tag, log); 99 } 100 wtf(String tag, String log, Throwable e)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 */ pii(Object pii)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> log; 120 private final int maxLines; 121 LocalLog(int maxLines)122 public LocalLog(int maxLines) { 123 this.maxLines = Math.max(0, maxLines); 124 log = new ArrayDeque<>(this.maxLines); 125 } 126 log(String msg)127 public void log(String msg) { 128 if (maxLines <= 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 append(String logLine)136 private synchronized void append(String logLine) { 137 while (log.size() >= maxLines) { 138 log.remove(); 139 } 140 log.add(logLine); 141 } 142 dump(FileDescriptor fd, PrintWriter pw, String[] args)143 public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 144 Iterator<String> itr = log.iterator(); 145 while (itr.hasNext()) { 146 pw.println(itr.next()); 147 } 148 } 149 reverseDump(FileDescriptor fd, PrintWriter pw, String[] args)150 public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) { 151 Iterator<String> itr = log.descendingIterator(); 152 while (itr.hasNext()) { 153 pw.println(itr.next()); 154 } 155 } 156 157 public static class ReadOnlyLocalLog { 158 159 private final LocalLog log; 160 ReadOnlyLocalLog(LocalLog log)161 ReadOnlyLocalLog(LocalLog log) { 162 this.log = log; 163 } 164 dump(FileDescriptor fd, PrintWriter pw, String[] args)165 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 166 log.dump(fd, pw, args); 167 } 168 reverseDump(FileDescriptor fd, PrintWriter pw, String[] args)169 public void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) { 170 log.reverseDump(fd, pw, args); 171 } 172 } 173 readOnlyLocalLog()174 public ReadOnlyLocalLog readOnlyLocalLog() { 175 return new ReadOnlyLocalLog(this); 176 } 177 } 178 } 179