• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2011, Google Inc.
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.mail.utils;
17 
18 import android.net.Uri;
19 import android.text.TextUtils;
20 import android.util.Log;
21 
22 import com.google.common.annotations.VisibleForTesting;
23 
24 import java.util.List;
25 import java.util.regex.Pattern;
26 
27 public class LogUtils {
28 
29     public static final String TAG = LogTag.getLogTag();
30 
31     // "GMT" + "+" or "-" + 4 digits
32     private static final Pattern DATE_CLEANUP_PATTERN_WRONG_TIMEZONE =
33             Pattern.compile("GMT([-+]\\d{4})$");
34 
35     private static final String ACCOUNT_PREFIX = "account:";
36 
37     /**
38      * Priority constant for the println method; use LogUtils.v.
39      */
40     public static final int VERBOSE = Log.VERBOSE;
41 
42     /**
43      * Priority constant for the println method; use LogUtils.d.
44      */
45     public static final int DEBUG = Log.DEBUG;
46 
47     /**
48      * Priority constant for the println method; use LogUtils.i.
49      */
50     public static final int INFO = Log.INFO;
51 
52     /**
53      * Priority constant for the println method; use LogUtils.w.
54      */
55     public static final int WARN = Log.WARN;
56 
57     /**
58      * Priority constant for the println method; use LogUtils.e.
59      */
60     public static final int ERROR = Log.ERROR;
61 
62     /**
63      * Used to enable/disable logging that we don't want included in
64      * production releases.  This should be set to DEBUG for production releases, and VERBOSE for
65      * internal builds.
66      */
67     // STOPSHIP: ship with DEBUG set
68     private static final int MAX_ENABLED_LOG_LEVEL = VERBOSE;
69 
70     private static Boolean sDebugLoggingEnabledForTests = null;
71 
72     /**
73      * Enable debug logging for unit tests.
74      */
75     @VisibleForTesting
setDebugLoggingEnabledForTests(boolean enabled)76     public static void setDebugLoggingEnabledForTests(boolean enabled) {
77         setDebugLoggingEnabledForTestsInternal(enabled);
78     }
79 
setDebugLoggingEnabledForTestsInternal(boolean enabled)80     protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) {
81         sDebugLoggingEnabledForTests = Boolean.valueOf(enabled);
82     }
83 
84     /**
85      * Returns true if the build configuration prevents debug logging.
86      */
87     @VisibleForTesting
buildPreventsDebugLogging()88     public static boolean buildPreventsDebugLogging() {
89         return MAX_ENABLED_LOG_LEVEL > VERBOSE;
90     }
91 
92     /**
93      * Returns a boolean indicating whether debug logging is enabled.
94      */
isDebugLoggingEnabled(String tag)95     protected static boolean isDebugLoggingEnabled(String tag) {
96         if (buildPreventsDebugLogging()) {
97             return false;
98         }
99         if (sDebugLoggingEnabledForTests != null) {
100             return sDebugLoggingEnabledForTests.booleanValue();
101         }
102         return Log.isLoggable(tag, Log.DEBUG) || Log.isLoggable(TAG, Log.DEBUG);
103     }
104 
105     /**
106      * Returns a String for the specified content provider uri.  This will do
107      * sanitation of the uri to remove PII if debug logging is not enabled.
108      */
contentUriToString(final Uri uri)109     public static String contentUriToString(final Uri uri) {
110         return contentUriToString(TAG, uri);
111     }
112 
113     /**
114      * Returns a String for the specified content provider uri.  This will do
115      * sanitation of the uri to remove PII if debug logging is not enabled.
116      */
contentUriToString(String tag, Uri uri)117     public static String contentUriToString(String tag, Uri uri) {
118         if (isDebugLoggingEnabled(tag)) {
119             // Debug logging has been enabled, so log the uri as is
120             return uri.toString();
121         } else {
122             // Debug logging is not enabled, we want to remove the email address from the uri.
123             List<String> pathSegments = uri.getPathSegments();
124 
125             Uri.Builder builder = new Uri.Builder()
126                     .scheme(uri.getScheme())
127                     .authority(uri.getAuthority())
128                     .query(uri.getQuery())
129                     .fragment(uri.getFragment());
130 
131             // This assumes that the first path segment is the account
132             final String account = pathSegments.get(0);
133 
134             builder = builder.appendPath(sanitizeAccountName(account));
135             for (int i = 1; i < pathSegments.size(); i++) {
136                 builder.appendPath(pathSegments.get(i));
137             }
138             return builder.toString();
139         }
140     }
141 
142     /**
143      * Sanitizes an account name.  If debug logging is not enabled, a sanitized name
144      * is returned.
145      */
sanitizeAccountName(String accountName)146     public static String sanitizeAccountName(String accountName) {
147         if (TextUtils.isEmpty(accountName)) {
148             return "";
149         }
150 
151         return ACCOUNT_PREFIX + sanitizeName(TAG, accountName);
152     }
153 
sanitizeName(final String tag, final String name)154     public static String sanitizeName(final String tag, final String name) {
155         if (TextUtils.isEmpty(name)) {
156             return "";
157         }
158 
159         if (isDebugLoggingEnabled(tag)) {
160             return name;
161         }
162 
163         return String.valueOf(name.hashCode());
164     }
165 
166     /**
167      * Checks to see whether or not a log for the specified tag is loggable at the specified level.
168      */
isLoggable(String tag, int level)169     public static boolean isLoggable(String tag, int level) {
170         if (MAX_ENABLED_LOG_LEVEL > level) {
171             return false;
172         }
173         return Log.isLoggable(tag, level) || Log.isLoggable(TAG, level);
174     }
175 
176     /**
177      * Send a {@link #VERBOSE} log message.
178      * @param tag Used to identify the source of a log message.  It usually identifies
179      *        the class or activity where the log call occurs.
180      * @param format the format string (see {@link java.util.Formatter#format})
181      * @param args
182      *            the list of arguments passed to the formatter. If there are
183      *            more arguments than required by {@code format},
184      *            additional arguments are ignored.
185      */
v(String tag, String format, Object... args)186     public static int v(String tag, String format, Object... args) {
187         if (isLoggable(tag, VERBOSE)) {
188             return Log.v(tag, String.format(format, args));
189         }
190         return 0;
191     }
192 
193     /**
194      * Send a {@link #VERBOSE} log message.
195      * @param tag Used to identify the source of a log message.  It usually identifies
196      *        the class or activity where the log call occurs.
197      * @param tr An exception to log
198      * @param format the format string (see {@link java.util.Formatter#format})
199      * @param args
200      *            the list of arguments passed to the formatter. If there are
201      *            more arguments than required by {@code format},
202      *            additional arguments are ignored.
203      */
v(String tag, Throwable tr, String format, Object... args)204     public static int v(String tag, Throwable tr, String format, Object... args) {
205         if (isLoggable(tag, VERBOSE)) {
206             return Log.v(tag, String.format(format, args), tr);
207         }
208         return 0;
209     }
210 
211     /**
212      * Send a {@link #DEBUG} log message.
213      * @param tag Used to identify the source of a log message.  It usually identifies
214      *        the class or activity where the log call occurs.
215      * @param format the format string (see {@link java.util.Formatter#format})
216      * @param args
217      *            the list of arguments passed to the formatter. If there are
218      *            more arguments than required by {@code format},
219      *            additional arguments are ignored.
220      */
d(String tag, String format, Object... args)221     public static int d(String tag, String format, Object... args) {
222         if (isLoggable(tag, DEBUG)) {
223             return Log.d(tag, String.format(format, args));
224         }
225         return 0;
226     }
227 
228     /**
229      * Send a {@link #DEBUG} log message.
230      * @param tag Used to identify the source of a log message.  It usually identifies
231      *        the class or activity where the log call occurs.
232      * @param tr An exception to log
233      * @param format the format string (see {@link java.util.Formatter#format})
234      * @param args
235      *            the list of arguments passed to the formatter. If there are
236      *            more arguments than required by {@code format},
237      *            additional arguments are ignored.
238      */
d(String tag, Throwable tr, String format, Object... args)239     public static int d(String tag, Throwable tr, String format, Object... args) {
240         if (isLoggable(tag, DEBUG)) {
241             return Log.d(tag, String.format(format, args), tr);
242         }
243         return 0;
244     }
245 
246     /**
247      * Send a {@link #INFO} log message.
248      * @param tag Used to identify the source of a log message.  It usually identifies
249      *        the class or activity where the log call occurs.
250      * @param format the format string (see {@link java.util.Formatter#format})
251      * @param args
252      *            the list of arguments passed to the formatter. If there are
253      *            more arguments than required by {@code format},
254      *            additional arguments are ignored.
255      */
i(String tag, String format, Object... args)256     public static int i(String tag, String format, Object... args) {
257         if (isLoggable(tag, INFO)) {
258             return Log.i(tag, String.format(format, args));
259         }
260         return 0;
261     }
262 
263     /**
264      * Send a {@link #INFO} log message.
265      * @param tag Used to identify the source of a log message.  It usually identifies
266      *        the class or activity where the log call occurs.
267      * @param tr An exception to log
268      * @param format the format string (see {@link java.util.Formatter#format})
269      * @param args
270      *            the list of arguments passed to the formatter. If there are
271      *            more arguments than required by {@code format},
272      *            additional arguments are ignored.
273      */
i(String tag, Throwable tr, String format, Object... args)274     public static int i(String tag, Throwable tr, String format, Object... args) {
275         if (isLoggable(tag, INFO)) {
276             return Log.i(tag, String.format(format, args), tr);
277         }
278         return 0;
279     }
280 
281     /**
282      * Send a {@link #WARN} log message.
283      * @param tag Used to identify the source of a log message.  It usually identifies
284      *        the class or activity where the log call occurs.
285      * @param format the format string (see {@link java.util.Formatter#format})
286      * @param args
287      *            the list of arguments passed to the formatter. If there are
288      *            more arguments than required by {@code format},
289      *            additional arguments are ignored.
290      */
w(String tag, String format, Object... args)291     public static int w(String tag, String format, Object... args) {
292         if (isLoggable(tag, WARN)) {
293             return Log.w(tag, String.format(format, args));
294         }
295         return 0;
296     }
297 
298     /**
299      * Send a {@link #WARN} log message.
300      * @param tag Used to identify the source of a log message.  It usually identifies
301      *        the class or activity where the log call occurs.
302      * @param tr An exception to log
303      * @param format the format string (see {@link java.util.Formatter#format})
304      * @param args
305      *            the list of arguments passed to the formatter. If there are
306      *            more arguments than required by {@code format},
307      *            additional arguments are ignored.
308      */
w(String tag, Throwable tr, String format, Object... args)309     public static int w(String tag, Throwable tr, String format, Object... args) {
310         if (isLoggable(tag, WARN)) {
311             return Log.w(tag, String.format(format, args), tr);
312         }
313         return 0;
314     }
315 
316     /**
317      * Send a {@link #ERROR} log message.
318      * @param tag Used to identify the source of a log message.  It usually identifies
319      *        the class or activity where the log call occurs.
320      * @param format the format string (see {@link java.util.Formatter#format})
321      * @param args
322      *            the list of arguments passed to the formatter. If there are
323      *            more arguments than required by {@code format},
324      *            additional arguments are ignored.
325      */
e(String tag, String format, Object... args)326     public static int e(String tag, String format, Object... args) {
327         if (isLoggable(tag, ERROR)) {
328             return Log.e(tag, String.format(format, args));
329         }
330         return 0;
331     }
332 
333     /**
334      * Send a {@link #ERROR} log message.
335      * @param tag Used to identify the source of a log message.  It usually identifies
336      *        the class or activity where the log call occurs.
337      * @param tr An exception to log
338      * @param format the format string (see {@link java.util.Formatter#format})
339      * @param args
340      *            the list of arguments passed to the formatter. If there are
341      *            more arguments than required by {@code format},
342      *            additional arguments are ignored.
343      */
e(String tag, Throwable tr, String format, Object... args)344     public static int e(String tag, Throwable tr, String format, Object... args) {
345         if (isLoggable(tag, ERROR)) {
346             return Log.e(tag, String.format(format, args), tr);
347         }
348         return 0;
349     }
350 
351     /**
352      * What a Terrible Failure: Report a condition that should never happen.
353      * The error will always be logged at level ASSERT with the call stack.
354      * Depending on system configuration, a report may be added to the
355      * {@link android.os.DropBoxManager} and/or the process may be terminated
356      * immediately with an error dialog.
357      * @param tag Used to identify the source of a log message.  It usually identifies
358      *        the class or activity where the log call occurs.
359      * @param format the format string (see {@link java.util.Formatter#format})
360      * @param args
361      *            the list of arguments passed to the formatter. If there are
362      *            more arguments than required by {@code format},
363      *            additional arguments are ignored.
364      */
wtf(String tag, String format, Object... args)365     public static int wtf(String tag, String format, Object... args) {
366         return Log.wtf(tag, String.format(format, args), new Error());
367     }
368 
369     /**
370      * What a Terrible Failure: Report a condition that should never happen.
371      * The error will always be logged at level ASSERT with the call stack.
372      * Depending on system configuration, a report may be added to the
373      * {@link android.os.DropBoxManager} and/or the process may be terminated
374      * immediately with an error dialog.
375      * @param tag Used to identify the source of a log message.  It usually identifies
376      *        the class or activity where the log call occurs.
377      * @param tr An exception to log
378      * @param format the format string (see {@link java.util.Formatter#format})
379      * @param args
380      *            the list of arguments passed to the formatter. If there are
381      *            more arguments than required by {@code format},
382      *            additional arguments are ignored.
383      */
wtf(String tag, Throwable tr, String format, Object... args)384     public static int wtf(String tag, Throwable tr, String format, Object... args) {
385         return Log.wtf(tag, String.format(format, args), tr);
386     }
387 
388 
389     /**
390      * Try to make a date MIME(RFC 2822/5322)-compliant.
391      *
392      * It fixes:
393      * - "Thu, 10 Dec 09 15:08:08 GMT-0700" to "Thu, 10 Dec 09 15:08:08 -0700"
394      *   (4 digit zone value can't be preceded by "GMT")
395      *   We got a report saying eBay sends a date in this format
396      */
cleanUpMimeDate(String date)397     public static String cleanUpMimeDate(String date) {
398         if (TextUtils.isEmpty(date)) {
399             return date;
400         }
401         date = DATE_CLEANUP_PATTERN_WRONG_TIMEZONE.matcher(date).replaceFirst("$1");
402         return date;
403     }
404 
405 
byteToHex(int b)406     public static String byteToHex(int b) {
407         return byteToHex(new StringBuilder(), b).toString();
408     }
409 
byteToHex(StringBuilder sb, int b)410     public static StringBuilder byteToHex(StringBuilder sb, int b) {
411         b &= 0xFF;
412         sb.append("0123456789ABCDEF".charAt(b >> 4));
413         sb.append("0123456789ABCDEF".charAt(b & 0xF));
414         return sb;
415     }
416 
417 }
418