From 3280af097618408a7d0be001db77530f4f16584e Mon Sep 17 00:00:00 2001 From: codeskyblue Date: Tue, 14 May 2024 17:17:58 +0800 Subject: [PATCH] add maxDepth for dumpWindowHierarchy --- .../stub/AccessibilityNodeInfoDumper.java | 51 ++++++++++--------- .../uiautomator/stub/AutomatorService.java | 17 +++---- .../stub/AutomatorServiceImpl.java | 18 ++----- .../uiautomator/stub/ConfiguratorInfo.java | 5 ++ .../github/uiautomator/stub/DeviceInfo.java | 3 +- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/AccessibilityNodeInfoDumper.java b/app/src/androidTest/java/com/github/uiautomator/stub/AccessibilityNodeInfoDumper.java index 380069a..bee8075 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/AccessibilityNodeInfoDumper.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/AccessibilityNodeInfoDumper.java @@ -34,7 +34,7 @@ class AccessibilityNodeInfoDumper { private AccessibilityNodeInfoDumper() { } - public static void dumpWindowHierarchy(UiDevice device, OutputStream out) throws IOException { + public static void dumpWindowHierarchy(UiDevice device, OutputStream out, int maxDepth) throws IOException { try (Section ignored = Traces.trace("AccessibilityNodeInfoDumper.dumpWindowHierarchy")) { XmlSerializer serializer = Xml.newSerializer(); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); @@ -45,13 +45,8 @@ public static void dumpWindowHierarchy(UiDevice device, OutputStream out) throws serializer.attribute("", "rotation", Integer.toString(device.getDisplayRotation())); for (AccessibilityNodeInfo root : getWindowRoots(device)) { - try { - dumpNodeRec(root, serializer, 0, device.getDisplayWidth(), - device.getDisplayHeight()); - } catch (IllegalArgumentException e) { - // java.lang.IllegalArgumentException: Illegal character (U+0) - e.printStackTrace(); - } + dumpNodeRec(root, serializer, 0, device.getDisplayWidth(), + device.getDisplayHeight(), maxDepth); } serializer.endTag("", "hierarchy"); @@ -104,16 +99,22 @@ private static List getWindows(UiAutomation uiAutomatio } private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index, - int width, int height) throws IOException { + int width, int height, int maxDepth) throws IOException { serializer.startTag("", "node"); if (!nafExcludedClass(node) && !nafCheck(node)) serializer.attribute("", "NAF", Boolean.toString(true)); serializer.attribute("", "index", Integer.toString(index)); - serializer.attribute("", "text", safeCharSeqToString(node.getText())); - serializer.attribute("", "resource-id", safeCharSeqToString(node.getViewIdResourceName())); - serializer.attribute("", "class", safeCharSeqToString(node.getClassName())); - serializer.attribute("", "package", safeCharSeqToString(node.getPackageName())); - serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription())); + try { + serializer.attribute("", "text", safeCharSeqToString(node.getText())); + serializer.attribute("", "resource-id", safeCharSeqToString(node.getViewIdResourceName())); + serializer.attribute("", "class", safeCharSeqToString(node.getClassName())); + serializer.attribute("", "package", safeCharSeqToString(node.getPackageName())); + serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription())); + } catch (IllegalArgumentException e) { + // java.lang.IllegalArgumentException: Illegal character (U+0) + // TODO: maybe the best way is to update safeCharSeqToString + e.printStackTrace(); + } serializer.attribute("", "checkable", Boolean.toString(node.isCheckable())); serializer.attribute("", "checked", Boolean.toString(node.isChecked())); serializer.attribute("", "clickable", Boolean.toString(node.isClickable())); @@ -138,18 +139,20 @@ private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serial serializer.attribute("", "display-id", Integer.toString(Api30Impl.getDisplayId(node))); } - int count = node.getChildCount(); - for (int i = 0; i < count; i++) { - AccessibilityNodeInfo child = node.getChild(i); - if (child != null) { - if (child.isVisibleToUser()) { - dumpNodeRec(child, serializer, i, width, height); - child.recycle(); + if (maxDepth > 0) { + int count = node.getChildCount(); + for (int i = 0; i < count; i++) { + AccessibilityNodeInfo child = node.getChild(i); + if (child != null) { + if (child.isVisibleToUser()) { + dumpNodeRec(child, serializer, i, width, height, maxDepth-1); + child.recycle(); + } else { + Log.i(TAG, String.format("Skipping invisible child: %s", child)); + } } else { - Log.i(TAG, String.format("Skipping invisible child: %s", child)); + Log.i(TAG, String.format("Null child %d/%d, parent: %s", i, count, node)); } - } else { - Log.i(TAG, String.format("Null child %d/%d, parent: %s", i, count, node)); } } serializer.endTag("", "node"); diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorService.java b/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorService.java index 1432eb1..a0fe060 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorService.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorService.java @@ -161,22 +161,21 @@ public interface AutomatorService { boolean injectInputEvent(int action, float x, float y, int metaState); /** - * Helper method used for debugging to dump the current window's layout hierarchy. The file root location is /data/local/tmp + * Helper method used for debugging to dump the current window's layout hierarchy. * * @param compressed use compressed layout hierarchy or not using setCompressedLayoutHeirarchy method. Ignore the parameter in case the API level lt 18. - * @param filename the filename to be stored. - * @return the absolute path name of dumped file. + * @return xml content */ - @Deprecated - String dumpWindowHierarchy(boolean compressed, String filename); + String dumpWindowHierarchy(boolean compressed); /** - * Helper method used for debugging to dump the current window's layout hierarchy. + * Helper method used for debugging to dump the current window's layout hierarchy * - * @param compressed use compressed layout hierarchy or not using setCompressedLayoutHeirarchy method. Ignore the parameter in case the API level lt 18. - * @return the absolute path name of dumped file. + * @param compressed + * @param maxDepth + * @return xml content */ - String dumpWindowHierarchy(boolean compressed); + String dumpWindowHierarchy(boolean compressed, int maxDepth); /** * Take a screenshot of current window and store it as PNG The screenshot is adjusted per screen rotation diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java b/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java index e57910a..8525860 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java @@ -285,30 +285,22 @@ public boolean injectInputEvent(int action, float x, float y, int metaState) { } /** - * Helper method used for debugging to dump the current window's layout hierarchy. The file root location is /data/local/tmp + * Helper method used for debugging to dump the current window's layout hierarchy. * * @param compressed use compressed layout hierarchy or not using setCompressedLayoutHeirarchy method. Ignore the parameter in case the API level lt 18. - * @param filename the filename to be stored. @deprecated * @return the absolute path name of dumped file. */ - @Deprecated @Override - public String dumpWindowHierarchy(boolean compressed, String filename) { - return dumpWindowHierarchy(compressed); + public String dumpWindowHierarchy(boolean compressed) { + return dumpWindowHierarchy(compressed, 50); } - /** - * Helper method used for debugging to dump the current window's layout hierarchy. - * - * @param compressed use compressed layout hierarchy or not using setCompressedLayoutHeirarchy method. Ignore the parameter in case the API level lt 18. - * @return the absolute path name of dumped file. - */ @Override - public String dumpWindowHierarchy(boolean compressed) { + public String dumpWindowHierarchy(boolean compressed, int maxDepth) { device.setCompressedLayoutHierarchy(compressed); ByteArrayOutputStream os = new ByteArrayOutputStream(); try { - AccessibilityNodeInfoDumper.dumpWindowHierarchy(device, os); + AccessibilityNodeInfoDumper.dumpWindowHierarchy(device, os, maxDepth); // device.dumpWindowHierarchy(os); return os.toString("UTF-8"); } catch (IOException e) { diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/ConfiguratorInfo.java b/app/src/androidTest/java/com/github/uiautomator/stub/ConfiguratorInfo.java index 4e7f1fc..e81e54b 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/ConfiguratorInfo.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/ConfiguratorInfo.java @@ -37,6 +37,7 @@ public ConfiguratorInfo() { this._scrollAcknowledgmentTimeout = config.getScrollAcknowledgmentTimeout(); this._waitForIdleTimeout = config.getWaitForIdleTimeout(); this._waitForSelectorTimeout = config.getWaitForSelectorTimeout(); + this._uiAutomationFlags = config.getUiAutomationFlags(); } public long getActionAcknowledgmentTimeout() { @@ -79,6 +80,8 @@ public void setWaitForSelectorTimeout(long _waitForSelectorTimeout) { this._waitForSelectorTimeout = _waitForSelectorTimeout; } + public int getUiAutomationFlags() { return _uiAutomationFlags; } + public static void setConfigurator(ConfiguratorInfo info) { Configurator config = Configurator.getInstance(); config.setActionAcknowledgmentTimeout(info.getActionAcknowledgmentTimeout()); @@ -86,6 +89,7 @@ public static void setConfigurator(ConfiguratorInfo info) { config.setScrollAcknowledgmentTimeout(info.getScrollAcknowledgmentTimeout()); config.setWaitForIdleTimeout(info.getWaitForIdleTimeout()); config.setWaitForSelectorTimeout(info.getWaitForSelectorTimeout()); + config.setUiAutomationFlags(info.getUiAutomationFlags()); } private long _actionAcknowledgmentTimeout; @@ -93,4 +97,5 @@ public static void setConfigurator(ConfiguratorInfo info) { private long _scrollAcknowledgmentTimeout; private long _waitForIdleTimeout; private long _waitForSelectorTimeout; + private int _uiAutomationFlags; } diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/DeviceInfo.java b/app/src/androidTest/java/com/github/uiautomator/stub/DeviceInfo.java index 1f77bb9..d15ae9a 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/DeviceInfo.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/DeviceInfo.java @@ -24,7 +24,8 @@ package com.github.uiautomator.stub; import android.os.RemoteException; -import androidx.test.InstrumentationRegistry; + +import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.uiautomator.UiDevice; public class DeviceInfo {