Home | History | Annotate | Download | only in util
      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 {
     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      */
     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 */
    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