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