Loading cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java +26 −12 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.commands.uiautomator; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.UiAutomation; import android.graphics.Point; import android.hardware.display.DisplayManagerGlobal; Loading Loading @@ -61,11 +62,14 @@ public class DumpCommand extends Command { public void run(String[] args) { File dumpFile = DEFAULT_DUMP_FILE; boolean verboseMode = true; boolean allWindows = false; for (String arg : args) { if (arg.equals("--compressed")) verboseMode = false; else if (!arg.startsWith("-")) { else if (arg.equals("--windows")) { allWindows = true; } else if (!arg.startsWith("-")) { dumpFile = new File(arg); } } Loading @@ -85,6 +89,14 @@ public class DumpCommand extends Command { try { UiAutomation uiAutomation = automationWrapper.getUiAutomation(); uiAutomation.waitForIdle(1000, 1000 * 10); if (allWindows) { AccessibilityServiceInfo info = uiAutomation.getServiceInfo(); info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS; uiAutomation.setServiceInfo(info); AccessibilityNodeInfoDumper.dumpWindowsToFile( uiAutomation.getWindowsOnAllDisplays(), dumpFile, DisplayManagerGlobal.getInstance()); } else { AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow(); if (info == null) { System.err.println("ERROR: null root node returned by UiTestAutomationBridge."); Loading @@ -96,7 +108,9 @@ public class DumpCommand extends Command { int rotation = display.getRotation(); Point size = new Point(); display.getSize(size); AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y); AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y); } } catch (TimeoutException re) { System.err.println("ERROR: could not get idle state."); return; Loading cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java +96 −0 Original line number Diff line number Diff line Loading @@ -16,11 +16,17 @@ package com.android.uiautomator.core; import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; import android.os.Environment; import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; import android.util.Xml; import android.view.Display; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import org.xmlpull.v1.XmlSerializer; Loading @@ -28,6 +34,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; import java.util.List; /** * Loading Loading @@ -98,6 +105,95 @@ public class AccessibilityNodeInfoDumper { Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms"); } /** * Using {@link AccessibilityWindowInfo} this method will dump some window information and * then walk the layout hierarchy of it's * and generates an xml dump to the location specified by <code>dumpFile</code> * @param allWindows All windows indexed by display-id. * @param dumpFile The file to dump to. */ public static void dumpWindowsToFile(SparseArray<List<AccessibilityWindowInfo>> allWindows, File dumpFile, DisplayManagerGlobal displayManager) { if (allWindows.size() == 0) { return; } final long startTime = SystemClock.uptimeMillis(); try { FileWriter writer = new FileWriter(dumpFile); XmlSerializer serializer = Xml.newSerializer(); StringWriter stringWriter = new StringWriter(); serializer.setOutput(stringWriter); serializer.startDocument("UTF-8", true); serializer.startTag("", "displays"); for (int d = 0, nd = allWindows.size(); d < nd; ++d) { int displayId = allWindows.keyAt(d); Display display = displayManager.getRealDisplay(displayId); if (display == null) { continue; } final List<AccessibilityWindowInfo> windows = allWindows.valueAt(d); if (windows.isEmpty()) { continue; } serializer.startTag("", "display"); serializer.attribute("", "id", Integer.toString(displayId)); int rotation = display.getRotation(); Point size = new Point(); display.getSize(size); for (int i = 0, n = windows.size(); i < n; ++i) { dumpWindowRec(windows.get(i), serializer, i, size.x, size.y, rotation); } serializer.endTag("", "display"); } serializer.endTag("", "displays"); serializer.endDocument(); writer.write(stringWriter.toString()); writer.close(); } catch (IOException e) { Log.e(LOGTAG, "failed to dump window to file", e); } final long endTime = SystemClock.uptimeMillis(); Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms"); } private static void dumpWindowRec(AccessibilityWindowInfo winfo, XmlSerializer serializer, int index, int width, int height, int rotation) throws IOException { serializer.startTag("", "window"); serializer.attribute("", "index", Integer.toString(index)); final CharSequence title = winfo.getTitle(); serializer.attribute("", "title", title != null ? title.toString() : ""); final Rect tmpBounds = new Rect(); winfo.getBoundsInScreen(tmpBounds); serializer.attribute("", "bounds", tmpBounds.toShortString()); serializer.attribute("", "active", Boolean.toString(winfo.isActive())); serializer.attribute("", "focused", Boolean.toString(winfo.isFocused())); serializer.attribute("", "accessibility-focused", Boolean.toString(winfo.isAccessibilityFocused())); serializer.attribute("", "id", Integer.toString(winfo.getId())); serializer.attribute("", "layer", Integer.toString(winfo.getLayer())); serializer.attribute("", "type", AccessibilityWindowInfo.typeToString(winfo.getType())); int count = winfo.getChildCount(); for (int i = 0; i < count; ++i) { AccessibilityWindowInfo child = winfo.getChild(i); if (child == null) { Log.i(LOGTAG, String.format("Null window child %d/%d, parent: %s", i, count, winfo.getTitle())); continue; } dumpWindowRec(child, serializer, i, width, height, rotation); child.recycle(); } AccessibilityNodeInfo root = winfo.getRoot(); if (root != null) { serializer.startTag("", "hierarchy"); serializer.attribute("", "rotation", Integer.toString(rotation)); dumpNodeRec(root, serializer, 0, width, height); root.recycle(); serializer.endTag("", "hierarchy"); } serializer.endTag("", "window"); } private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index, int width, int height) throws IOException { serializer.startTag("", "node"); Loading core/java/android/content/IntentFilter.java +8 −4 Original line number Diff line number Diff line Loading @@ -1183,7 +1183,8 @@ public class IntentFilter implements Parcelable { return NO_MATCH_DATA; } } if (mPort >= 0) { // if we're dealing with wildcard support, we ignore ports if (!wildcardSupported && mPort >= 0) { if (mPort != data.getPort()) { return NO_MATCH_DATA; } Loading Loading @@ -1580,12 +1581,13 @@ public class IntentFilter implements Parcelable { * @param wildcardSupported if true, will allow parameters to use wildcards */ private int matchData(String type, String scheme, Uri data, boolean wildcardSupported) { final ArrayList<String> types = mDataTypes; final boolean wildcardWithMimegroups = wildcardSupported && countMimeGroups() != 0; final List<String> types = mDataTypes; final ArrayList<String> schemes = mDataSchemes; int match = MATCH_CATEGORY_EMPTY; if (types == null && schemes == null) { if (!wildcardWithMimegroups && types == null && schemes == null) { return ((type == null && data == null) ? (MATCH_CATEGORY_EMPTY+MATCH_ADJUSTMENT_NORMAL) : NO_MATCH_DATA); } Loading Loading @@ -1640,7 +1642,9 @@ public class IntentFilter implements Parcelable { } } if (types != null) { if (wildcardWithMimegroups) { return MATCH_CATEGORY_TYPE; } else if (types != null) { if (findMimeType(type)) { match = MATCH_CATEGORY_TYPE; } else { Loading core/java/android/hardware/camera2/CameraCharacteristics.java +4 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ import java.util.Set; * through the {@link CameraManager CameraManager} * interface with {@link CameraManager#getCameraCharacteristics}.</p> * * <p>When obtained by a client that does not hold the CAMERA permission, some metadata values are * not included. The list of keys that require the permission is given by * {@link #getKeysNeedingPermission}.</p> * * <p>{@link CameraCharacteristics} objects are immutable.</p> * * @see CameraDevice Loading core/java/android/hardware/camera2/CameraManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -362,6 +362,11 @@ public final class CameraManager { * cameras that can only be used as part of logical multi-camera. These cameras cannot be * opened directly via {@link #openCamera}</p> * * <p>Also starting with API level 29, while most basic camera information is still available * even without the CAMERA permission, some values are not available to apps that do not hold * that permission. The keys not available are listed by * {@link CameraCharacteristics#getKeysNeedingPermission}.</p> * * @param cameraId The id of the camera device to query. This could be either a standalone * camera ID which can be directly opened by {@link #openCamera}, or a physical camera ID that * can only used as part of a logical multi-camera. Loading Loading
cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java +26 −12 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.commands.uiautomator; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.UiAutomation; import android.graphics.Point; import android.hardware.display.DisplayManagerGlobal; Loading Loading @@ -61,11 +62,14 @@ public class DumpCommand extends Command { public void run(String[] args) { File dumpFile = DEFAULT_DUMP_FILE; boolean verboseMode = true; boolean allWindows = false; for (String arg : args) { if (arg.equals("--compressed")) verboseMode = false; else if (!arg.startsWith("-")) { else if (arg.equals("--windows")) { allWindows = true; } else if (!arg.startsWith("-")) { dumpFile = new File(arg); } } Loading @@ -85,6 +89,14 @@ public class DumpCommand extends Command { try { UiAutomation uiAutomation = automationWrapper.getUiAutomation(); uiAutomation.waitForIdle(1000, 1000 * 10); if (allWindows) { AccessibilityServiceInfo info = uiAutomation.getServiceInfo(); info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS; uiAutomation.setServiceInfo(info); AccessibilityNodeInfoDumper.dumpWindowsToFile( uiAutomation.getWindowsOnAllDisplays(), dumpFile, DisplayManagerGlobal.getInstance()); } else { AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow(); if (info == null) { System.err.println("ERROR: null root node returned by UiTestAutomationBridge."); Loading @@ -96,7 +108,9 @@ public class DumpCommand extends Command { int rotation = display.getRotation(); Point size = new Point(); display.getSize(size); AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y); AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y); } } catch (TimeoutException re) { System.err.println("ERROR: could not get idle state."); return; Loading
cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java +96 −0 Original line number Diff line number Diff line Loading @@ -16,11 +16,17 @@ package com.android.uiautomator.core; import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; import android.os.Environment; import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; import android.util.Xml; import android.view.Display; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import org.xmlpull.v1.XmlSerializer; Loading @@ -28,6 +34,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; import java.util.List; /** * Loading Loading @@ -98,6 +105,95 @@ public class AccessibilityNodeInfoDumper { Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms"); } /** * Using {@link AccessibilityWindowInfo} this method will dump some window information and * then walk the layout hierarchy of it's * and generates an xml dump to the location specified by <code>dumpFile</code> * @param allWindows All windows indexed by display-id. * @param dumpFile The file to dump to. */ public static void dumpWindowsToFile(SparseArray<List<AccessibilityWindowInfo>> allWindows, File dumpFile, DisplayManagerGlobal displayManager) { if (allWindows.size() == 0) { return; } final long startTime = SystemClock.uptimeMillis(); try { FileWriter writer = new FileWriter(dumpFile); XmlSerializer serializer = Xml.newSerializer(); StringWriter stringWriter = new StringWriter(); serializer.setOutput(stringWriter); serializer.startDocument("UTF-8", true); serializer.startTag("", "displays"); for (int d = 0, nd = allWindows.size(); d < nd; ++d) { int displayId = allWindows.keyAt(d); Display display = displayManager.getRealDisplay(displayId); if (display == null) { continue; } final List<AccessibilityWindowInfo> windows = allWindows.valueAt(d); if (windows.isEmpty()) { continue; } serializer.startTag("", "display"); serializer.attribute("", "id", Integer.toString(displayId)); int rotation = display.getRotation(); Point size = new Point(); display.getSize(size); for (int i = 0, n = windows.size(); i < n; ++i) { dumpWindowRec(windows.get(i), serializer, i, size.x, size.y, rotation); } serializer.endTag("", "display"); } serializer.endTag("", "displays"); serializer.endDocument(); writer.write(stringWriter.toString()); writer.close(); } catch (IOException e) { Log.e(LOGTAG, "failed to dump window to file", e); } final long endTime = SystemClock.uptimeMillis(); Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms"); } private static void dumpWindowRec(AccessibilityWindowInfo winfo, XmlSerializer serializer, int index, int width, int height, int rotation) throws IOException { serializer.startTag("", "window"); serializer.attribute("", "index", Integer.toString(index)); final CharSequence title = winfo.getTitle(); serializer.attribute("", "title", title != null ? title.toString() : ""); final Rect tmpBounds = new Rect(); winfo.getBoundsInScreen(tmpBounds); serializer.attribute("", "bounds", tmpBounds.toShortString()); serializer.attribute("", "active", Boolean.toString(winfo.isActive())); serializer.attribute("", "focused", Boolean.toString(winfo.isFocused())); serializer.attribute("", "accessibility-focused", Boolean.toString(winfo.isAccessibilityFocused())); serializer.attribute("", "id", Integer.toString(winfo.getId())); serializer.attribute("", "layer", Integer.toString(winfo.getLayer())); serializer.attribute("", "type", AccessibilityWindowInfo.typeToString(winfo.getType())); int count = winfo.getChildCount(); for (int i = 0; i < count; ++i) { AccessibilityWindowInfo child = winfo.getChild(i); if (child == null) { Log.i(LOGTAG, String.format("Null window child %d/%d, parent: %s", i, count, winfo.getTitle())); continue; } dumpWindowRec(child, serializer, i, width, height, rotation); child.recycle(); } AccessibilityNodeInfo root = winfo.getRoot(); if (root != null) { serializer.startTag("", "hierarchy"); serializer.attribute("", "rotation", Integer.toString(rotation)); dumpNodeRec(root, serializer, 0, width, height); root.recycle(); serializer.endTag("", "hierarchy"); } serializer.endTag("", "window"); } private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index, int width, int height) throws IOException { serializer.startTag("", "node"); Loading
core/java/android/content/IntentFilter.java +8 −4 Original line number Diff line number Diff line Loading @@ -1183,7 +1183,8 @@ public class IntentFilter implements Parcelable { return NO_MATCH_DATA; } } if (mPort >= 0) { // if we're dealing with wildcard support, we ignore ports if (!wildcardSupported && mPort >= 0) { if (mPort != data.getPort()) { return NO_MATCH_DATA; } Loading Loading @@ -1580,12 +1581,13 @@ public class IntentFilter implements Parcelable { * @param wildcardSupported if true, will allow parameters to use wildcards */ private int matchData(String type, String scheme, Uri data, boolean wildcardSupported) { final ArrayList<String> types = mDataTypes; final boolean wildcardWithMimegroups = wildcardSupported && countMimeGroups() != 0; final List<String> types = mDataTypes; final ArrayList<String> schemes = mDataSchemes; int match = MATCH_CATEGORY_EMPTY; if (types == null && schemes == null) { if (!wildcardWithMimegroups && types == null && schemes == null) { return ((type == null && data == null) ? (MATCH_CATEGORY_EMPTY+MATCH_ADJUSTMENT_NORMAL) : NO_MATCH_DATA); } Loading Loading @@ -1640,7 +1642,9 @@ public class IntentFilter implements Parcelable { } } if (types != null) { if (wildcardWithMimegroups) { return MATCH_CATEGORY_TYPE; } else if (types != null) { if (findMimeType(type)) { match = MATCH_CATEGORY_TYPE; } else { Loading
core/java/android/hardware/camera2/CameraCharacteristics.java +4 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ import java.util.Set; * through the {@link CameraManager CameraManager} * interface with {@link CameraManager#getCameraCharacteristics}.</p> * * <p>When obtained by a client that does not hold the CAMERA permission, some metadata values are * not included. The list of keys that require the permission is given by * {@link #getKeysNeedingPermission}.</p> * * <p>{@link CameraCharacteristics} objects are immutable.</p> * * @see CameraDevice Loading
core/java/android/hardware/camera2/CameraManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -362,6 +362,11 @@ public final class CameraManager { * cameras that can only be used as part of logical multi-camera. These cameras cannot be * opened directly via {@link #openCamera}</p> * * <p>Also starting with API level 29, while most basic camera information is still available * even without the CAMERA permission, some values are not available to apps that do not hold * that permission. The keys not available are listed by * {@link CameraCharacteristics#getKeysNeedingPermission}.</p> * * @param cameraId The id of the camera device to query. This could be either a standalone * camera ID which can be directly opened by {@link #openCamera}, or a physical camera ID that * can only used as part of a logical multi-camera. Loading