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  */
14 package com.android.voicemail.impl.mail.utils;
15 
16 import android.net.Uri;
17 import android.support.annotation.VisibleForTesting;
18 import android.text.TextUtils;
19 import android.util.Log;
20 import com.android.voicemail.impl.VvmLog;
21 import java.util.List;
22 
23 public 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
setDebugLoggingEnabledForTests(boolean enabled)53   public static void setDebugLoggingEnabledForTests(boolean enabled) {
54     setDebugLoggingEnabledForTestsInternal(enabled);
55   }
56 
setDebugLoggingEnabledForTestsInternal(boolean enabled)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
buildPreventsDebugLogging()63   public static boolean buildPreventsDebugLogging() {
64     return MAX_ENABLED_LOG_LEVEL > VERBOSE;
65   }
66 
67   /** Returns a boolean indicating whether debug logging is enabled. */
isDebugLoggingEnabled(String tag)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    */
contentUriToString(final Uri uri)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    */
contentUriToString(String tag, Uri uri)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. */
sanitizeAccountName(String accountName)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 
sanitizeName(final String tag, final String name)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    */
isLoggable(String tag, int level)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    */
v(String tag, String format, Object... args)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    */
v(String tag, Throwable tr, String format, Object... args)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    */
d(String tag, String format, Object... args)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    */
d(String tag, Throwable tr, String format, Object... args)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    */
i(String tag, String format, Object... args)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    */
i(String tag, Throwable tr, String format, Object... args)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    */
w(String tag, String format, Object... args)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    */
w(String tag, Throwable tr, String format, Object... args)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    */
e(String tag, String format, Object... args)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    */
e(String tag, Throwable tr, String format, Object... args)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    */
wtf(String tag, String format, Object... args)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    */
wtf(String tag, Throwable tr, String format, Object... args)331   public static void wtf(String tag, Throwable tr, String format, Object... args) {
332     VvmLog.wtf(tag, String.format(format, args), tr);
333   }
334 
byteToHex(int b)335   public static String byteToHex(int b) {
336     return byteToHex(new StringBuilder(), b).toString();
337   }
338 
byteToHex(StringBuilder sb, int b)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