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     /**
     27      * <p>Filters objects against the <code>ANDROID_OBJECT_FILTER</code>
     28      * environment variable. This environment variable can filter objects
     29      * based on their class name and attribute values.</p>
     30      *
     31      * <p>Here is the syntax for <code>ANDROID_OBJECT_FILTER</code>:</p>
     32      *
     33      * <p><code>ClassName@attribute1=value1@attribute2=value2...</code></p>
     34      *
     35      * <p>Examples:</p>
     36      * <ul>
     37      * <li>Select TextView instances: <code>TextView</code></li>
     38      * <li>Select TextView instances of text "Loading" and bottom offset of 22:
     39      * <code>TextView@text=Loading.*@bottom=22</code></li>
     40      * </ul>
     41      *
     42      * <p>The class name and the values are regular expressions.</p>
     43      *
     44      * <p>This class is useful for debugging and logging purpose:</p>
     45      * <pre>
     46      * if (DEBUG) {
     47      *   if (DebugUtils.isObjectSelected(childView) && LOGV_ENABLED) {
     48      *     Log.v(TAG, "Object " + childView + " logged!");
     49      *   }
     50      * }
     51      * </pre>
     52      *
     53      * <p><strong>NOTE</strong>: This method is very expensive as it relies
     54      * heavily on regular expressions and reflection. Calls to this method
     55      * should always be stripped out of the release binaries and avoided
     56      * as much as possible in debug mode.</p>
     57      *
     58      * @param object any object to match against the ANDROID_OBJECT_FILTER
     59      *        environement variable
     60      * @return true if object is selected by the ANDROID_OBJECT_FILTER
     61      *         environment variable, false otherwise
     62      */
     63     public static boolean isObjectSelected(Object object) {
     64         boolean match = false;
     65         String s = System.getenv("ANDROID_OBJECT_FILTER");
     66         if (s != null && s.length() > 0) {
     67             String[] selectors = s.split("@");
     68             // first selector == class name
     69             if (object.getClass().getSimpleName().matches(selectors[0])) {
     70                 // check potential attributes
     71                 for (int i = 1; i < selectors.length; i++) {
     72                     String[] pair = selectors[i].split("=");
     73                     Class<?> klass = object.getClass();
     74                     try {
     75                         Method declaredMethod = null;
     76                         Class<?> parent = klass;
     77                         do {
     78                             declaredMethod = parent.getDeclaredMethod("get" +
     79                                     pair[0].substring(0, 1).toUpperCase() +
     80                                     pair[0].substring(1),
     81                                     (Class[]) null);
     82                         } while ((parent = klass.getSuperclass()) != null &&
     83                                 declaredMethod == null);
     84 
     85                         if (declaredMethod != null) {
     86                             Object value = declaredMethod
     87                                     .invoke(object, (Object[])null);
     88                             match |= (value != null ?
     89                                     value.toString() : "null").matches(pair[1]);
     90                         }
     91                     } catch (NoSuchMethodException e) {
     92                         e.printStackTrace();
     93                     } catch (IllegalAccessException e) {
     94                         e.printStackTrace();
     95                     } catch (InvocationTargetException e) {
     96                         e.printStackTrace();
     97                     }
     98                 }
     99             }
    100         }
    101         return match;
    102     }
    103 
    104 }
    105