1d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian/*
2d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Copyright (C) 2015 The Android Open Source Project
3d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
4d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * you may not use this file except in compliance with the License.
6d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * You may obtain a copy of the License at
7d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
8d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
10d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * See the License for the specific language governing permissions and
14d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * limitations under the License
15d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian */
16d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianpackage com.android.voicemail.impl;
17d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
18d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.common.LogUtil;
19d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport com.android.dialer.persistentlog.PersistentLogger;
20d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.voicemail.impl.utils.IndentingPrintWriter;
21d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.io.FileDescriptor;
22d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.io.PrintWriter;
23d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.util.ArrayDeque;
24d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.util.Calendar;
25d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.util.Deque;
26d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.util.Iterator;
27d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
28d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian/** Helper methods for adding to OMTP visual voicemail local logs. */
29d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianpublic class VvmLog {
30d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
31d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static final int MAX_OMTP_VVM_LOGS = 100;
32d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
33d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static final LocalLog sLocalLog = new LocalLog(MAX_OMTP_VVM_LOGS);
34d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
35d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void log(String tag, String log) {
36d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    PersistentLogger.logText(tag, log);
37d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
38d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
39d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) {
40d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(printwriter, "  ");
41d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    indentingPrintWriter.increaseIndent();
42d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    sLocalLog.dump(fd, indentingPrintWriter, args);
43d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    indentingPrintWriter.decreaseIndent();
44d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
45d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
46d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void e(String tag, String log) {
47d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log);
48d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.e(tag, log);
49d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
50d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
51d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void e(String tag, String log, Throwable e) {
52d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log + " " + e);
53d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.e(tag, log, e);
54d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
55d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
56d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void w(String tag, String log) {
57d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log);
58d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.w(tag, log);
59d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
60d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
61d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void w(String tag, String log, Throwable e) {
62d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log + " " + e);
63d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.w(tag, log, e);
64d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
65d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
66d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void i(String tag, String log) {
67d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log);
68d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.i(tag, log);
69d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
70d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
71d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void i(String tag, String log, Throwable e) {
72d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log + " " + e);
73d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.i(tag, log, e);
74d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
75d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
76d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void d(String tag, String log) {
77d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log);
78d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.d(tag, log);
79d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
80d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
81d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void d(String tag, String log, Throwable e) {
82d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log + " " + e);
83d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.d(tag, log, e);
84d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
85d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
86d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void v(String tag, String log) {
87d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log);
88d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.v(tag, log);
89d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
90d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
91d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void v(String tag, String log, Throwable e) {
92d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log + " " + e);
93d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.v(tag, log, e);
94d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
95d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
96d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void wtf(String tag, String log) {
97d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log);
98d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.e(tag, log);
99d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
100d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
101d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static void wtf(String tag, String log, Throwable e) {
102d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    log(tag, log + " " + e);
103d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.e(tag, log, e);
104d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
105d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
106d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  /**
107d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * Redact personally identifiable information for production users. If we are running in verbose
108d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * mode, return the original string, otherwise return a SHA-1 hash of the input string.
109d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   */
110d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static String pii(Object pii) {
111d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (pii == null) {
112d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return String.valueOf(pii);
113d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
114d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return "[PII]";
115d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
116d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
117d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static class LocalLog {
118d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
119d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    private final Deque<String> mLog;
120d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    private final int mMaxLines;
121d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
122d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    public LocalLog(int maxLines) {
123d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      mMaxLines = Math.max(0, maxLines);
124d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      mLog = new ArrayDeque<>(mMaxLines);
125d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
126d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
127d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    public void log(String msg) {
128d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      if (mMaxLines <= 0) {
129d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        return;
130d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
131d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      Calendar c = Calendar.getInstance();
132d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      c.setTimeInMillis(System.currentTimeMillis());
133d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      append(String.format("%tm-%td %tH:%tM:%tS.%tL - %s", c, c, c, c, c, c, msg));
134d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
135d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
136d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    private synchronized void append(String logLine) {
137d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      while (mLog.size() >= mMaxLines) {
138d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        mLog.remove();
139d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
140d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      mLog.add(logLine);
141d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
142d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
143d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
144d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      Iterator<String> itr = mLog.iterator();
145d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      while (itr.hasNext()) {
146d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        pw.println(itr.next());
147d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
148d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
149d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
150d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
151d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      Iterator<String> itr = mLog.descendingIterator();
152d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      while (itr.hasNext()) {
153d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        pw.println(itr.next());
154d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
155d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
156d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
157d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    public static class ReadOnlyLocalLog {
158d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
159d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      private final LocalLog mLog;
160d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
161d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      ReadOnlyLocalLog(LocalLog log) {
162d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        mLog = log;
163d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
164d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
165d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
166d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        mLog.dump(fd, pw, args);
167d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
168d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
169d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      public void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
170d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        mLog.reverseDump(fd, pw, args);
171d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
172d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
173d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
174d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    public ReadOnlyLocalLog readOnlyLocalLog() {
175d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return new ReadOnlyLocalLog(this);
176d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
177d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
178d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian}
179