1 /* 2 * Copyright (C) 2014 The Android Open Source Project 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 17 package com.android.camera.debug; 18 19 import android.os.Build; 20 21 import com.android.camera.util.ReleaseHelper; 22 23 public class Log { 24 /** 25 * All Camera logging using this class will use this tag prefix. 26 * Additionally, the prefix itself is checked in isLoggable and 27 * serves as an override. So, to toggle all logs allowed by the 28 * current {@link Configuration}, you can set properties: 29 * 30 * adb shell setprop log.tag.CAM_ VERBOSE 31 * adb shell setprop log.tag.CAM_ "" 32 */ 33 public static final String CAMERA_LOGTAG_PREFIX = "CAM_"; 34 private static final Log.Tag TAG = new Log.Tag("Log"); 35 36 private static boolean sSuppressForTesting = false; 37 38 /** 39 * This class restricts the length of the log tag to be less than the 40 * framework limit and also prepends the common tag prefix defined by 41 * {@code CAMERA_LOGTAG_PREFIX}. 42 */ 43 public static final class Tag { 44 45 // The length limit from Android framework is 23. 46 private static final int MAX_TAG_LEN = 23 - CAMERA_LOGTAG_PREFIX.length(); 47 48 final String mValue; 49 Tag(String tag)50 public Tag(String tag) { 51 final int lenDiff = tag.length() - MAX_TAG_LEN; 52 if (lenDiff > 0) { 53 w(TAG, "Tag " + tag + " is " + lenDiff + " chars longer than limit."); 54 } 55 mValue = CAMERA_LOGTAG_PREFIX + (lenDiff > 0 ? tag.substring(0, MAX_TAG_LEN) : tag); 56 } 57 58 @Override toString()59 public String toString() { 60 return mValue; 61 } 62 } 63 d(Tag tag, String msg)64 public static void d(Tag tag, String msg) { 65 if (isLoggable(tag, android.util.Log.DEBUG)) { 66 android.util.Log.d(tag.toString(), msg); 67 } 68 } 69 d(Tag tag, Object instance, String msg)70 public static void d(Tag tag, Object instance, String msg) { 71 if (isLoggable(tag, android.util.Log.DEBUG)) { 72 android.util.Log.d(tag.toString(), LogUtil.addTags(instance, msg)); 73 } 74 } 75 d(Tag tag, Object instance, String msg, String tags)76 public static void d(Tag tag, Object instance, String msg, String tags) { 77 if (isLoggable(tag, android.util.Log.DEBUG)) { 78 android.util.Log.d(tag.toString(), LogUtil.addTags(instance, msg, tags)); 79 } 80 } 81 d(Tag tag, String msg, Throwable tr)82 public static void d(Tag tag, String msg, Throwable tr) { 83 if (isLoggable(tag, android.util.Log.DEBUG)) { 84 android.util.Log.d(tag.toString(), msg, tr); 85 } 86 } 87 e(Tag tag, String msg)88 public static void e(Tag tag, String msg) { 89 if (isLoggable(tag, android.util.Log.ERROR)) { 90 android.util.Log.e(tag.toString(), msg); 91 } 92 } 93 e(Tag tag, Object instance, String msg)94 public static void e(Tag tag, Object instance, String msg) { 95 if (isLoggable(tag, android.util.Log.ERROR)) { 96 android.util.Log.e(tag.toString(), LogUtil.addTags(instance, msg)); 97 } 98 } 99 e(Tag tag, Object instance, String msg, String tags)100 public static void e(Tag tag, Object instance, String msg, String tags) { 101 if (isLoggable(tag, android.util.Log.DEBUG)) { 102 android.util.Log.e(tag.toString(), LogUtil.addTags(instance, msg, tags)); 103 } 104 } 105 e(Tag tag, String msg, Throwable tr)106 public static void e(Tag tag, String msg, Throwable tr) { 107 if (isLoggable(tag, android.util.Log.ERROR)) { 108 android.util.Log.e(tag.toString(), msg, tr); 109 } 110 } 111 i(Tag tag, String msg)112 public static void i(Tag tag, String msg) { 113 if (isLoggable(tag, android.util.Log.INFO)) { 114 android.util.Log.i(tag.toString(), msg); 115 } 116 } 117 i(Tag tag, Object instance, String msg)118 public static void i(Tag tag, Object instance, String msg) { 119 if (isLoggable(tag, android.util.Log.INFO)) { 120 android.util.Log.i(tag.toString(), LogUtil.addTags(instance, msg)); 121 } 122 } 123 i(Tag tag, Object instance, String msg, String tags)124 public static void i(Tag tag, Object instance, String msg, String tags) { 125 if (isLoggable(tag, android.util.Log.DEBUG)) { 126 android.util.Log.i(tag.toString(), LogUtil.addTags(instance, msg, tags)); 127 } 128 } 129 i(Tag tag, String msg, Throwable tr)130 public static void i(Tag tag, String msg, Throwable tr) { 131 if (isLoggable(tag, android.util.Log.INFO)) { 132 android.util.Log.i(tag.toString(), msg, tr); 133 } 134 } 135 v(Tag tag, String msg)136 public static void v(Tag tag, String msg) { 137 if (isLoggable(tag, android.util.Log.VERBOSE)) { 138 android.util.Log.v(tag.toString(), msg); 139 } 140 } 141 v(Tag tag, Object instance, String msg)142 public static void v(Tag tag, Object instance, String msg) { 143 if (isLoggable(tag, android.util.Log.VERBOSE)) { 144 android.util.Log.v(tag.toString(), LogUtil.addTags(instance, msg)); 145 } 146 } 147 v(Tag tag, Object instance, String msg, String tags)148 public static void v(Tag tag, Object instance, String msg, String tags) { 149 if (isLoggable(tag, android.util.Log.DEBUG)) { 150 android.util.Log.v(tag.toString(), LogUtil.addTags(instance, msg, tags)); 151 } 152 } 153 v(Tag tag, String msg, Throwable tr)154 public static void v(Tag tag, String msg, Throwable tr) { 155 if (isLoggable(tag, android.util.Log.VERBOSE)) { 156 android.util.Log.v(tag.toString(), msg, tr); 157 } 158 } 159 w(Tag tag, String msg)160 public static void w(Tag tag, String msg) { 161 if (isLoggable(tag, android.util.Log.WARN)) { 162 android.util.Log.w(tag.toString(), msg); 163 } 164 } 165 w(Tag tag, Object instance, String msg)166 public static void w(Tag tag, Object instance, String msg) { 167 if (isLoggable(tag, android.util.Log.WARN)) { 168 android.util.Log.w(tag.toString(), LogUtil.addTags(instance, msg)); 169 } 170 } 171 w(Tag tag, Object instance, String msg, String tags)172 public static void w(Tag tag, Object instance, String msg, String tags) { 173 if (isLoggable(tag, android.util.Log.DEBUG)) { 174 android.util.Log.w(tag.toString(), LogUtil.addTags(instance, msg, tags)); 175 } 176 } 177 w(Tag tag, String msg, Throwable tr)178 public static void w(Tag tag, String msg, Throwable tr) { 179 if (isLoggable(tag, android.util.Log.WARN)) { 180 android.util.Log.w(tag.toString(), msg, tr); 181 } 182 } 183 184 /** 185 * If suppressed, logs will not output and won't execute Android framework 186 * classes. 187 * 188 * @param suppress if true, suppress log output 189 */ suppressLogsForTesting(boolean suppress)190 public static void suppressLogsForTesting(boolean suppress) { 191 sSuppressForTesting = suppress; 192 } 193 isLoggable(Tag tag, int level)194 private static boolean isLoggable(Tag tag, int level) { 195 if (sSuppressForTesting) { 196 return false; 197 } 198 try { 199 if (LogHelper.instance().getOverrideLevel() != 0) { 200 // Override system log level and output. VERBOSE is smaller than 201 // ERROR, so the comparison checks that the override value is smaller 202 // than the desired output level. This applies to all tags. 203 return LogHelper.instance().getOverrideLevel() <= level; 204 } else { 205 return ReleaseHelper.shouldLogVerbose() || 206 isDebugOsBuild() || shouldLog(tag, level); 207 } 208 } catch (IllegalArgumentException ex) { 209 e(TAG, "Tag too long:" + tag); 210 return false; 211 } 212 } 213 shouldLog(Tag tag, int level)214 private static boolean shouldLog(Tag tag, int level) { 215 // The prefix can be used as an override tag to see all camera logs 216 return android.util.Log.isLoggable(CAMERA_LOGTAG_PREFIX, level) 217 || android.util.Log.isLoggable(tag.toString(), level); 218 } 219 isDebugOsBuild()220 private static boolean isDebugOsBuild() { 221 return "userdebug".equals(Build.TYPE) || "eng".equals(Build.TYPE); 222 } 223 } 224