1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * <p>http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * <p>Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 * express or implied. See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14package com.android.voicemail.impl.mail.utils;
15
16import android.net.Uri;
17import android.support.annotation.VisibleForTesting;
18import android.text.TextUtils;
19import android.util.Log;
20import com.android.voicemail.impl.VvmLog;
21import java.util.List;
22
23public class LogUtils {
24  public static final String TAG = "Email Log";
25
26  private static final String ACCOUNT_PREFIX = "account:";
27
28  /** Priority constant for the println method; use LogUtils.v. */
29  public static final int VERBOSE = Log.VERBOSE;
30
31  /** Priority constant for the println method; use LogUtils.d. */
32  public static final int DEBUG = Log.DEBUG;
33
34  /** Priority constant for the println method; use LogUtils.i. */
35  public static final int INFO = Log.INFO;
36
37  /** Priority constant for the println method; use LogUtils.w. */
38  public static final int WARN = Log.WARN;
39
40  /** Priority constant for the println method; use LogUtils.e. */
41  public static final int ERROR = Log.ERROR;
42
43  /**
44   * Used to enable/disable logging that we don't want included in production releases. This should
45   * be set to DEBUG for production releases, and VERBOSE for internal builds.
46   */
47  private static final int MAX_ENABLED_LOG_LEVEL = DEBUG;
48
49  private static Boolean debugLoggingEnabledForTests = null;
50
51  /** Enable debug logging for unit tests. */
52  @VisibleForTesting
53  public static void setDebugLoggingEnabledForTests(boolean enabled) {
54    setDebugLoggingEnabledForTestsInternal(enabled);
55  }
56
57  protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) {
58    debugLoggingEnabledForTests = Boolean.valueOf(enabled);
59  }
60
61  /** Returns true if the build configuration prevents debug logging. */
62  @VisibleForTesting
63  public static boolean buildPreventsDebugLogging() {
64    return MAX_ENABLED_LOG_LEVEL > VERBOSE;
65  }
66
67  /** Returns a boolean indicating whether debug logging is enabled. */
68  protected static boolean isDebugLoggingEnabled(String tag) {
69    if (buildPreventsDebugLogging()) {
70      return false;
71    }
72    if (debugLoggingEnabledForTests != null) {
73      return debugLoggingEnabledForTests.booleanValue();
74    }
75    return Log.isLoggable(tag, Log.DEBUG) || Log.isLoggable(TAG, Log.DEBUG);
76  }
77
78  /**
79   * Returns a String for the specified content provider uri. This will do sanitation of the uri to
80   * remove PII if debug logging is not enabled.
81   */
82  public static String contentUriToString(final Uri uri) {
83    return contentUriToString(TAG, uri);
84  }
85
86  /**
87   * Returns a String for the specified content provider uri. This will do sanitation of the uri to
88   * remove PII if debug logging is not enabled.
89   */
90  public static String contentUriToString(String tag, Uri uri) {
91    if (isDebugLoggingEnabled(tag)) {
92      // Debug logging has been enabled, so log the uri as is
93      return uri.toString();
94    } else {
95      // Debug logging is not enabled, we want to remove the email address from the uri.
96      List<String> pathSegments = uri.getPathSegments();
97
98      Uri.Builder builder =
99          new Uri.Builder()
100              .scheme(uri.getScheme())
101              .authority(uri.getAuthority())
102              .query(uri.getQuery())
103              .fragment(uri.getFragment());
104
105      // This assumes that the first path segment is the account
106      final String account = pathSegments.get(0);
107
108      builder = builder.appendPath(sanitizeAccountName(account));
109      for (int i = 1; i < pathSegments.size(); i++) {
110        builder.appendPath(pathSegments.get(i));
111      }
112      return builder.toString();
113    }
114  }
115
116  /** Sanitizes an account name. If debug logging is not enabled, a sanitized name is returned. */
117  public static String sanitizeAccountName(String accountName) {
118    if (TextUtils.isEmpty(accountName)) {
119      return "";
120    }
121
122    return ACCOUNT_PREFIX + sanitizeName(TAG, accountName);
123  }
124
125  public static String sanitizeName(final String tag, final String name) {
126    if (TextUtils.isEmpty(name)) {
127      return "";
128    }
129
130    if (isDebugLoggingEnabled(tag)) {
131      return name;
132    }
133
134    return String.valueOf(name.hashCode());
135  }
136
137  /**
138   * Checks to see whether or not a log for the specified tag is loggable at the specified level.
139   */
140  public static boolean isLoggable(String tag, int level) {
141    if (MAX_ENABLED_LOG_LEVEL > level) {
142      return false;
143    }
144    return Log.isLoggable(tag, level) || Log.isLoggable(TAG, level);
145  }
146
147  /**
148   * Send a {@link #VERBOSE} log message.
149   *
150   * @param tag Used to identify the source of a log message. It usually identifies the class or
151   *     activity where the log call occurs.
152   * @param format the format string (see {@link java.util.Formatter#format})
153   * @param args the list of arguments passed to the formatter. If there are more arguments than
154   *     required by {@code format}, additional arguments are ignored.
155   */
156  public static void v(String tag, String format, Object... args) {
157    if (isLoggable(tag, VERBOSE)) {
158      VvmLog.v(tag, String.format(format, args));
159    }
160  }
161
162  /**
163   * Send a {@link #VERBOSE} log message.
164   *
165   * @param tag Used to identify the source of a log message. It usually identifies the class or
166   *     activity where the log call occurs.
167   * @param tr An exception to log
168   * @param format the format string (see {@link java.util.Formatter#format})
169   * @param args the list of arguments passed to the formatter. If there are more arguments than
170   *     required by {@code format}, additional arguments are ignored.
171   */
172  public static void v(String tag, Throwable tr, String format, Object... args) {
173    if (isLoggable(tag, VERBOSE)) {
174      VvmLog.v(tag, String.format(format, args), tr);
175    }
176  }
177
178  /**
179   * Send a {@link #DEBUG} log message.
180   *
181   * @param tag Used to identify the source of a log message. It usually identifies the class or
182   *     activity where the log call occurs.
183   * @param format the format string (see {@link java.util.Formatter#format})
184   * @param args the list of arguments passed to the formatter. If there are more arguments than
185   *     required by {@code format}, additional arguments are ignored.
186   */
187  public static void d(String tag, String format, Object... args) {
188    if (isLoggable(tag, DEBUG)) {
189      VvmLog.d(tag, String.format(format, args));
190    }
191  }
192
193  /**
194   * Send a {@link #DEBUG} log message.
195   *
196   * @param tag Used to identify the source of a log message. It usually identifies the class or
197   *     activity where the log call occurs.
198   * @param tr An exception to log
199   * @param format the format string (see {@link java.util.Formatter#format})
200   * @param args the list of arguments passed to the formatter. If there are more arguments than
201   *     required by {@code format}, additional arguments are ignored.
202   */
203  public static void d(String tag, Throwable tr, String format, Object... args) {
204    if (isLoggable(tag, DEBUG)) {
205      VvmLog.d(tag, String.format(format, args), tr);
206    }
207  }
208
209  /**
210   * Send a {@link #INFO} log message.
211   *
212   * @param tag Used to identify the source of a log message. It usually identifies the class or
213   *     activity where the log call occurs.
214   * @param format the format string (see {@link java.util.Formatter#format})
215   * @param args the list of arguments passed to the formatter. If there are more arguments than
216   *     required by {@code format}, additional arguments are ignored.
217   */
218  public static void i(String tag, String format, Object... args) {
219    if (isLoggable(tag, INFO)) {
220      VvmLog.i(tag, String.format(format, args));
221    }
222  }
223
224  /**
225   * Send a {@link #INFO} log message.
226   *
227   * @param tag Used to identify the source of a log message. It usually identifies the class or
228   *     activity where the log call occurs.
229   * @param tr An exception to log
230   * @param format the format string (see {@link java.util.Formatter#format})
231   * @param args the list of arguments passed to the formatter. If there are more arguments than
232   *     required by {@code format}, additional arguments are ignored.
233   */
234  public static void i(String tag, Throwable tr, String format, Object... args) {
235    if (isLoggable(tag, INFO)) {
236      VvmLog.i(tag, String.format(format, args), tr);
237    }
238  }
239
240  /**
241   * Send a {@link #WARN} log message.
242   *
243   * @param tag Used to identify the source of a log message. It usually identifies the class or
244   *     activity where the log call occurs.
245   * @param format the format string (see {@link java.util.Formatter#format})
246   * @param args the list of arguments passed to the formatter. If there are more arguments than
247   *     required by {@code format}, additional arguments are ignored.
248   */
249  public static void w(String tag, String format, Object... args) {
250    if (isLoggable(tag, WARN)) {
251      VvmLog.w(tag, String.format(format, args));
252    }
253  }
254
255  /**
256   * Send a {@link #WARN} log message.
257   *
258   * @param tag Used to identify the source of a log message. It usually identifies the class or
259   *     activity where the log call occurs.
260   * @param tr An exception to log
261   * @param format the format string (see {@link java.util.Formatter#format})
262   * @param args the list of arguments passed to the formatter. If there are more arguments than
263   *     required by {@code format}, additional arguments are ignored.
264   */
265  public static void w(String tag, Throwable tr, String format, Object... args) {
266    if (isLoggable(tag, WARN)) {
267      VvmLog.w(tag, String.format(format, args), tr);
268    }
269  }
270
271  /**
272   * Send a {@link #ERROR} log message.
273   *
274   * @param tag Used to identify the source of a log message. It usually identifies the class or
275   *     activity where the log call occurs.
276   * @param format the format string (see {@link java.util.Formatter#format})
277   * @param args the list of arguments passed to the formatter. If there are more arguments than
278   *     required by {@code format}, additional arguments are ignored.
279   */
280  public static void e(String tag, String format, Object... args) {
281    if (isLoggable(tag, ERROR)) {
282      VvmLog.e(tag, String.format(format, args));
283    }
284  }
285
286  /**
287   * Send a {@link #ERROR} log message.
288   *
289   * @param tag Used to identify the source of a log message. It usually identifies the class or
290   *     activity where the log call occurs.
291   * @param tr An exception to log
292   * @param format the format string (see {@link java.util.Formatter#format})
293   * @param args the list of arguments passed to the formatter. If there are more arguments than
294   *     required by {@code format}, additional arguments are ignored.
295   */
296  public static void e(String tag, Throwable tr, String format, Object... args) {
297    if (isLoggable(tag, ERROR)) {
298      VvmLog.e(tag, String.format(format, args), tr);
299    }
300  }
301
302  /**
303   * What a Terrible Failure: Report a condition that should never happen. The error will always be
304   * logged at level ASSERT with the call stack. Depending on system configuration, a report may be
305   * added to the {@link android.os.DropBoxManager} and/or the process may be terminated immediately
306   * with an error dialog.
307   *
308   * @param tag Used to identify the source of a log message. It usually identifies the class or
309   *     activity where the log call occurs.
310   * @param format the format string (see {@link java.util.Formatter#format})
311   * @param args the list of arguments passed to the formatter. If there are more arguments than
312   *     required by {@code format}, additional arguments are ignored.
313   */
314  public static void wtf(String tag, String format, Object... args) {
315    VvmLog.wtf(tag, String.format(format, args), new Error());
316  }
317
318  /**
319   * What a Terrible Failure: Report a condition that should never happen. The error will always be
320   * logged at level ASSERT with the call stack. Depending on system configuration, a report may be
321   * added to the {@link android.os.DropBoxManager} and/or the process may be terminated immediately
322   * with an error dialog.
323   *
324   * @param tag Used to identify the source of a log message. It usually identifies the class or
325   *     activity where the log call occurs.
326   * @param tr An exception to log
327   * @param format the format string (see {@link java.util.Formatter#format})
328   * @param args the list of arguments passed to the formatter. If there are more arguments than
329   *     required by {@code format}, additional arguments are ignored.
330   */
331  public static void wtf(String tag, Throwable tr, String format, Object... args) {
332    VvmLog.wtf(tag, String.format(format, args), tr);
333  }
334
335  public static String byteToHex(int b) {
336    return byteToHex(new StringBuilder(), b).toString();
337  }
338
339  public static StringBuilder byteToHex(StringBuilder sb, int b) {
340    b &= 0xFF;
341    sb.append("0123456789ABCDEF".charAt(b >> 4));
342    sb.append("0123456789ABCDEF".charAt(b & 0xF));
343    return sb;
344  }
345}
346