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