Home | History | Annotate | Download | only in uiautomation
      1 package com.android.testing.uiautomation;
      2 
      3 import org.xmlpull.v1.XmlSerializer;
      4 
      5 import android.graphics.Rect;
      6 import android.os.Environment;
      7 import android.os.SystemClock;
      8 import android.util.Log;
      9 import android.util.Xml;
     10 import android.view.accessibility.AccessibilityNodeInfo;
     11 
     12 import java.io.File;
     13 import java.io.FileWriter;
     14 import java.io.IOException;
     15 import java.io.StringWriter;
     16 import java.util.LinkedList;
     17 import java.util.Queue;
     18 
     19 public class AccessibilityNodeInfoHelper {
     20 
     21     private static final String LOGTAG = "AccessibilityNodeInfoHelper";
     22 
     23     public static void dumpWindowToFile(AccessibilityNodeInfo info) {
     24         AccessibilityNodeInfo root = getRootAccessibilityNodeInfo(info);
     25         if (root == null) {
     26             return;
     27         }
     28         final long startTime = SystemClock.uptimeMillis();
     29         try {
     30             File baseDir = new File(Environment.getDataDirectory(), "uidump");
     31             if (!baseDir.exists()) {
     32                 baseDir.mkdir();
     33                 baseDir.setExecutable(true, false);
     34                 baseDir.setWritable(true, false);
     35                 baseDir.setReadable(true, false);
     36             }
     37             FileWriter writer = new FileWriter(
     38                     new File(baseDir, "window_dump.xml"));
     39             XmlSerializer serializer = Xml.newSerializer();
     40             StringWriter stringWriter = new StringWriter();
     41             serializer.setOutput(stringWriter);
     42             serializer.startDocument("UTF-8", true);
     43             serializer.startTag("", "hierarchy");
     44             dumpNodeRec(root, serializer, 0);
     45             if (root != info)
     46                 root.recycle();
     47             serializer.endTag("", "hierarchy");
     48             serializer.endDocument();
     49             writer.write(stringWriter.toString());
     50             writer.close();
     51         } catch (IOException e) {
     52             Log.e(LOGTAG, "failed to dump window to file", e);
     53         }
     54         final long endTime = SystemClock.uptimeMillis();
     55         Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms");
     56     }
     57 
     58     public static  void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer, int index)
     59         throws IOException {
     60         serializer.startTag("", "node");
     61         serializer.attribute("", "index", Integer.toString(index));
     62         serializer.attribute("", "text", safeCharSeqToString(node.getText()));
     63         serializer.attribute("", "class", safeCharSeqToString(node.getClassName()));
     64         serializer.attribute("", "package", safeCharSeqToString(node.getPackageName()));
     65         serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription()));
     66         serializer.attribute("", "checkable", Boolean.toString(node.isCheckable()));
     67         serializer.attribute("", "checked", Boolean.toString(node.isChecked()));
     68         serializer.attribute("", "clickable", Boolean.toString(node.isClickable()));
     69         serializer.attribute("", "enabled", Boolean.toString(node.isEnabled()));
     70         serializer.attribute("", "focusable", Boolean.toString(node.isFocusable()));
     71         serializer.attribute("", "focused", Boolean.toString(node.isFocused()));
     72         serializer.attribute("", "long-clickable", Boolean.toString(node.isLongClickable()));
     73         serializer.attribute("", "password", Boolean.toString(node.isPassword()));
     74         serializer.attribute("", "selected", Boolean.toString(node.isSelected()));
     75         Rect bounds = new Rect();
     76         node.getBoundsInScreen(bounds);
     77         serializer.attribute("", "bounds", bounds.toShortString());
     78         for (int i = 0; i < node.getChildCount(); i++) {
     79             AccessibilityNodeInfo child = node.getChild(i);
     80             if (child != null) {
     81                 dumpNodeRec(child, serializer, i);
     82                 child.recycle();
     83             }
     84         }
     85         serializer.endTag("", "node");
     86     }
     87 
     88     public static  void dumpWindow(AccessibilityNodeInfo info) {
     89         AccessibilityNodeInfo root = getRootAccessibilityNodeInfo(info);
     90         if (root == null) {
     91             return;
     92         }
     93         final long startTime = SystemClock.uptimeMillis();
     94         Queue<AccessibilityNodeInfo> mFringe = new LinkedList<AccessibilityNodeInfo>();
     95         mFringe.add(root);
     96         int fetchedNodeCount = 0;
     97         while (!mFringe.isEmpty()) {
     98             AccessibilityNodeInfo current = mFringe.poll();
     99             Log.d(LOGTAG, String.format("class: %s; text: %s; content-desc: %s",
    100                     current.getClassName(),
    101                     current.getText(),
    102                     current.getContentDescription()));
    103             fetchedNodeCount++;
    104             final int childCount = current.getChildCount();
    105             for (int i = 0; i < childCount; i++) {
    106                 AccessibilityNodeInfo child = current.getChild(i);
    107                 if (child != null) {
    108                     mFringe.add(child);
    109                 }
    110             }
    111         }
    112         final long endTime = SystemClock.uptimeMillis();
    113         Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms; fetchedNodeCount: "
    114                 + fetchedNodeCount);
    115     }
    116 
    117     public static  void dumpNode(AccessibilityNodeInfo node) {
    118       Log.d(LOGTAG, String.format("class: %s; text: %s; content-desc: %s",
    119               node.getClassName(),
    120               node.getText(),
    121               node.getContentDescription()));
    122     }
    123 
    124     public static  void dumpChildren(AccessibilityNodeInfo node) {
    125         int count = node.getChildCount();
    126         for (int i = 0; i < count; i++) {
    127             AccessibilityNodeInfo child = node.getChild(i);
    128             dumpNode(child);
    129             child.recycle();
    130         }
    131     }
    132 
    133     public static  AccessibilityNodeInfo getRootAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    134         if (info == null)
    135             return null;
    136         AccessibilityNodeInfo root = info.getParent();
    137         while (root != null) {
    138             AccessibilityNodeInfo parent = root.getParent();
    139             if (parent != null) {
    140                 root.recycle();
    141                 root = parent;
    142             } else {
    143                 break;
    144             }
    145         }
    146         return root == null ? info : root;
    147     }
    148 
    149     public static String safeCharSeqToString(CharSequence cs) {
    150         if (cs == null)
    151             return "[null]";
    152         else
    153             return cs.toString();
    154     }
    155 }
    156