blob: b2cfc5b808aa5a6e43f679a18c99ea92f0c79bb1 [file] [log] [blame]
Mindy Pereira7b56a612011-12-14 12:32:28 -08001/**
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 */
Andy Huang30e2c242012-01-06 18:14:30 -080016package com.android.mail.utils;
Mindy Pereira7b56a612011-12-14 12:32:28 -080017
18import android.net.Uri;
Mindy Pereira116e09e2012-01-30 12:48:43 -080019import android.text.TextUtils;
Mindy Pereira7b56a612011-12-14 12:32:28 -080020import android.util.Log;
Scott Kennedy32fc8e42013-07-30 11:50:42 -070021
Mindy Pereira7b56a612011-12-14 12:32:28 -080022import com.google.common.annotations.VisibleForTesting;
23
24import java.util.List;
Mindy Pereira116e09e2012-01-30 12:48:43 -080025import java.util.regex.Pattern;
Mindy Pereira7b56a612011-12-14 12:32:28 -080026
27public class LogUtils {
Mindy Pereira116e09e2012-01-30 12:48:43 -080028
Scott Kennedyb184bfe2013-05-25 21:29:22 -070029 public static final String TAG = LogTag.getLogTag();
Marc Blanka6c0cb32012-06-28 10:39:15 -070030
Mindy Pereira116e09e2012-01-30 12:48:43 -080031 // "GMT" + "+" or "-" + 4 digits
32 private static final Pattern DATE_CLEANUP_PATTERN_WRONG_TIMEZONE =
33 Pattern.compile("GMT([-+]\\d{4})$");
Mindy Pereira7b56a612011-12-14 12:32:28 -080034
Paul Westbrook19ea5682013-07-15 12:04:12 -070035 private static final String ACCOUNT_PREFIX = "account:";
36
Mindy Pereira7b56a612011-12-14 12:32:28 -080037 /**
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
Alice Yangc6952fc2013-04-18 17:10:14 -070064 * production releases. This should be set to DEBUG for production releases, and VERBOSE for
65 * internal builds.
Mindy Pereira7b56a612011-12-14 12:32:28 -080066 */
Andy Huang87f5b7a2013-12-11 15:30:27 -080067 // STOPSHIP: ship with DEBUG set
68 private static final int MAX_ENABLED_LOG_LEVEL = VERBOSE;
Mindy Pereira7b56a612011-12-14 12:32:28 -080069
Mindy Pereira7b56a612011-12-14 12:32:28 -080070 private static Boolean sDebugLoggingEnabledForTests = null;
71
72 /**
73 * Enable debug logging for unit tests.
74 */
75 @VisibleForTesting
Scott Kennedyb184bfe2013-05-25 21:29:22 -070076 public static void setDebugLoggingEnabledForTests(boolean enabled) {
Paul Westbrook28e1b9e2013-01-16 17:12:49 -080077 setDebugLoggingEnabledForTestsInternal(enabled);
78 }
79
80 protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) {
Mindy Pereira7b56a612011-12-14 12:32:28 -080081 sDebugLoggingEnabledForTests = Boolean.valueOf(enabled);
82 }
83
84 /**
85 * Returns true if the build configuration prevents debug logging.
86 */
87 @VisibleForTesting
Paul Westbrook4f0eaec2012-04-02 10:44:49 -070088 public static boolean buildPreventsDebugLogging() {
Mindy Pereira7b56a612011-12-14 12:32:28 -080089 return MAX_ENABLED_LOG_LEVEL > VERBOSE;
90 }
91
92 /**
93 * Returns a boolean indicating whether debug logging is enabled.
94 */
Paul Westbrookb334c902012-06-25 11:42:46 -070095 protected static boolean isDebugLoggingEnabled(String tag) {
Mindy Pereira7b56a612011-12-14 12:32:28 -080096 if (buildPreventsDebugLogging()) {
97 return false;
98 }
99 if (sDebugLoggingEnabledForTests != null) {
100 return sDebugLoggingEnabledForTests.booleanValue();
101 }
Scott Kennedyb184bfe2013-05-25 21:29:22 -0700102 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 */
109 public static String contentUriToString(final Uri uri) {
110 return contentUriToString(TAG, uri);
Mindy Pereira7b56a612011-12-14 12:32:28 -0800111 }
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 */
Paul Westbrookb334c902012-06-25 11:42:46 -0700117 public static String contentUriToString(String tag, Uri uri) {
Paul Westbrookb334c902012-06-25 11:42:46 -0700118 if (isDebugLoggingEnabled(tag)) {
Mindy Pereira7b56a612011-12-14 12:32:28 -0800119 // 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
Paul Westbrook19ea5682013-07-15 12:04:12 -0700134 builder = builder.appendPath(sanitizeAccountName(account));
Mindy Pereira7b56a612011-12-14 12:32:28 -0800135 for (int i = 1; i < pathSegments.size(); i++) {
136 builder.appendPath(pathSegments.get(i));
137 }
138 return builder.toString();
139 }
140 }
141
Mindy Pereira7b56a612011-12-14 12:32:28 -0800142 /**
Paul Westbrook19ea5682013-07-15 12:04:12 -0700143 * Sanitizes an account name. If debug logging is not enabled, a sanitized name
144 * is returned.
145 */
146 public static String sanitizeAccountName(String accountName) {
147 if (TextUtils.isEmpty(accountName)) {
148 return "";
149 }
150
Scott Kennedy32fc8e42013-07-30 11:50:42 -0700151 return ACCOUNT_PREFIX + sanitizeName(TAG, accountName);
Paul Westbrook19ea5682013-07-15 12:04:12 -0700152 }
153
Scott Kennedy32fc8e42013-07-30 11:50:42 -0700154 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 }
Paul Westbrook19ea5682013-07-15 12:04:12 -0700165
166 /**
Mindy Pereira7b56a612011-12-14 12:32:28 -0800167 * Checks to see whether or not a log for the specified tag is loggable at the specified level.
168 */
169 public static boolean isLoggable(String tag, int level) {
170 if (MAX_ENABLED_LOG_LEVEL > level) {
171 return false;
172 }
Scott Kennedyb184bfe2013-05-25 21:29:22 -0700173 return Log.isLoggable(tag, level) || Log.isLoggable(TAG, level);
Mindy Pereira7b56a612011-12-14 12:32:28 -0800174 }
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
365 public static int wtf(String tag, String format, Object... args) {
Paul Westbrooka9161912012-04-24 10:10:04 -0700366 return Log.wtf(tag, String.format(format, args), new Error());
Mindy Pereira7b56a612011-12-14 12:32:28 -0800367 }
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 */
384 public static int wtf(String tag, Throwable tr, String format, Object... args) {
385 return Log.wtf(tag, String.format(format, args), tr);
386 }
Mindy Pereira116e09e2012-01-30 12:48:43 -0800387
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 */
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
406 public static String byteToHex(int b) {
407 return byteToHex(new StringBuilder(), b).toString();
408 }
409
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
Mindy Pereira7b56a612011-12-14 12:32:28 -0800417}