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