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