• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 android.util;
18 
19 import java.lang.reflect.Method;
20 import java.lang.reflect.InvocationTargetException;
21 
22 /**
23  * <p>Various utilities for debugging and logging.</p>
24  */
25 public class DebugUtils {
DebugUtils()26     /** @hide */ public DebugUtils() {}
27 
28     /**
29      * <p>Filters objects against the <code>ANDROID_OBJECT_FILTER</code>
30      * environment variable. This environment variable can filter objects
31      * based on their class name and attribute values.</p>
32      *
33      * <p>Here is the syntax for <code>ANDROID_OBJECT_FILTER</code>:</p>
34      *
35      * <p><code>ClassName@attribute1=value1@attribute2=value2...</code></p>
36      *
37      * <p>Examples:</p>
38      * <ul>
39      * <li>Select TextView instances: <code>TextView</code></li>
40      * <li>Select TextView instances of text "Loading" and bottom offset of 22:
41      * <code>TextView@text=Loading.*@bottom=22</code></li>
42      * </ul>
43      *
44      * <p>The class name and the values are regular expressions.</p>
45      *
46      * <p>This class is useful for debugging and logging purpose:</p>
47      * <pre>
48      * if (DEBUG) {
49      *   if (DebugUtils.isObjectSelected(childView) && LOGV_ENABLED) {
50      *     Log.v(TAG, "Object " + childView + " logged!");
51      *   }
52      * }
53      * </pre>
54      *
55      * <p><strong>NOTE</strong>: This method is very expensive as it relies
56      * heavily on regular expressions and reflection. Calls to this method
57      * should always be stripped out of the release binaries and avoided
58      * as much as possible in debug mode.</p>
59      *
60      * @param object any object to match against the ANDROID_OBJECT_FILTER
61      *        environement variable
62      * @return true if object is selected by the ANDROID_OBJECT_FILTER
63      *         environment variable, false otherwise
64      */
isObjectSelected(Object object)65     public static boolean isObjectSelected(Object object) {
66         boolean match = false;
67         String s = System.getenv("ANDROID_OBJECT_FILTER");
68         if (s != null && s.length() > 0) {
69             String[] selectors = s.split("@");
70             // first selector == class name
71             if (object.getClass().getSimpleName().matches(selectors[0])) {
72                 // check potential attributes
73                 for (int i = 1; i < selectors.length; i++) {
74                     String[] pair = selectors[i].split("=");
75                     Class<?> klass = object.getClass();
76                     try {
77                         Method declaredMethod = null;
78                         Class<?> parent = klass;
79                         do {
80                             declaredMethod = parent.getDeclaredMethod("get" +
81                                     pair[0].substring(0, 1).toUpperCase() +
82                                     pair[0].substring(1),
83                                     (Class[]) null);
84                         } while ((parent = klass.getSuperclass()) != null &&
85                                 declaredMethod == null);
86 
87                         if (declaredMethod != null) {
88                             Object value = declaredMethod
89                                     .invoke(object, (Object[])null);
90                             match |= (value != null ?
91                                     value.toString() : "null").matches(pair[1]);
92                         }
93                     } catch (NoSuchMethodException e) {
94                         e.printStackTrace();
95                     } catch (IllegalAccessException e) {
96                         e.printStackTrace();
97                     } catch (InvocationTargetException e) {
98                         e.printStackTrace();
99                     }
100                 }
101             }
102         }
103         return match;
104     }
105 
106     /** @hide */
buildShortClassTag(Object cls, StringBuilder out)107     public static void buildShortClassTag(Object cls, StringBuilder out) {
108         if (cls == null) {
109             out.append("null");
110         } else {
111             String simpleName = cls.getClass().getSimpleName();
112             if (simpleName == null || simpleName.isEmpty()) {
113                 simpleName = cls.getClass().getName();
114                 int end = simpleName.lastIndexOf('.');
115                 if (end > 0) {
116                     simpleName = simpleName.substring(end+1);
117                 }
118             }
119             out.append(simpleName);
120             out.append('{');
121             out.append(Integer.toHexString(System.identityHashCode(cls)));
122         }
123     }
124 
125 }
126