resolved conflicts for merge of 9858df8b to jb-dev-plus-aosp
cherry-picked from AOSP
"""
removing uiautomatorviewer from frameworks/testing
It is to be moved into sdk
"""
Change-Id: I8b2fc6bcdceda0705d7e2f337a7dc71c3451c26c
diff --git a/uiautomator/utils/uiautomatorviewer/Android.mk b/uiautomator/utils/uiautomatorviewer/Android.mk
deleted file mode 100644
index a5bc768..0000000
--- a/uiautomator/utils/uiautomatorviewer/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_RESOURCE_DIRS := src
-
-LOCAL_JAR_MANIFEST := etc/manifest.txt
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := \
- swt \
- org.eclipse.jface_3.6.2.M20110210-1200 \
- org.eclipse.core.commands_3.6.0.I20100512-1500 \
- org.eclipse.equinox.common_3.6.0.v20100503
-
-LOCAL_MODULE := uiautomatorviewer
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/uiautomator/utils/uiautomatorviewer/etc/Android.mk b/uiautomator/utils/uiautomatorviewer/etc/Android.mk
deleted file mode 100644
index 55f326d..0000000
--- a/uiautomator/utils/uiautomatorviewer/etc/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PREBUILT_EXECUTABLES := uiautomatorviewer
-include $(BUILD_HOST_PREBUILT)
diff --git a/uiautomator/utils/uiautomatorviewer/etc/manifest.txt b/uiautomator/utils/uiautomatorviewer/etc/manifest.txt
deleted file mode 100644
index a606962..0000000
--- a/uiautomator/utils/uiautomatorviewer/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.uiautomatorviewer.UiAutomatorViewer
-Class-Path: org.eclipse.jface_3.6.2.M20110210-1200.jar org.eclipse.core.commands_3.6.0.I20100512-1500.jar org.eclipse.equinox.common_3.6.0.v20100503.jar
diff --git a/uiautomator/utils/uiautomatorviewer/etc/uiautomatorviewer b/uiautomator/utils/uiautomatorviewer/etc/uiautomatorviewer
deleted file mode 100755
index 605b81c..0000000
--- a/uiautomator/utils/uiautomatorviewer/etc/uiautomatorviewer
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/bin/sh
-# Copyright 2012, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=uiautomatorviewer.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/tools/lib
- libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/framework
- libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- echo `basename "$prog"`": can't find $jarfile"
- exit 1
-fi
-
-javaCmd="java"
-
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
- os_opts="-XstartOnFirstThread"
-else
- os_opts=
-fi
-
-if [ `uname` = "Linux" ]; then
- export GDK_NATIVE_WINDOWS=true
-fi
-
-jarpath="$frameworkdir/$jarfile"
-
-# Figure out the path to the swt.jar for the current architecture.
-# if ANDROID_SWT is defined, then just use this.
-# else, if running in the Android source tree, then look for the correct swt folder in prebuilt
-# else, look for the correct swt folder in the SDK under tools/lib/
-swtpath=""
-if [ -n "$ANDROID_SWT" ]; then
- swtpath="$ANDROID_SWT"
-else
- vmarch=`${javaCmd} -jar "${frameworkdir}"/archquery.jar`
- if [ -n "$ANDROID_BUILD_TOP" ]; then
- osname=`uname -s | tr A-Z a-z`
- swtpath="${ANDROID_BUILD_TOP}/prebuilts/tools/${osname}-${vmarch}/swt"
- else
- swtpath="${frameworkdir}/${vmarch}"
- fi
-fi
-
-if [ ! -d "$swtpath" ]; then
- echo "SWT folder '${swtpath}' does not exist."
- echo "Please export ANDROID_SWT to point to the folder containing swt.jar for your platform."
- exit 1
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec "$javaCmd" \
- -Xmx512M $os_opts $java_debug \
- -classpath "$jarpath:$swtpath/swt.jar" \
- com.android.uiautomator.UiAutomatorViewer "$@"
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/OpenDialog.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/OpenDialog.java
deleted file mode 100644
index a2a042d..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/OpenDialog.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-import java.io.File;
-
-/**
- * Implements a file selection dialog for both screen shot and xml dump file
- *
- * "OK" button won't be enabled unless both files are selected
- * It also has a convenience feature such that if one file has been picked, and the other
- * file path is empty, then selection for the other file will start from the same base folder
- *
- */
-public class OpenDialog extends Dialog {
-
- private static final int FIXED_TEXT_FIELD_WIDTH = 300;
- private static final int DEFAULT_LAYOUT_SPACING = 10;
- private Text mScreenshotText;
- private Text mXmlText;
- private File mScreenshotFile;
- private File mXmlDumpFile;
- private boolean mFileChanged = false;
- private Button mOkButton;
-
- /**
- * Create the dialog.
- * @param parentShell
- */
- public OpenDialog(Shell parentShell) {
- super(parentShell);
- setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
- }
-
- /**
- * Create contents of the dialog.
- * @param parent
- */
- @Override
- protected Control createDialogArea(Composite parent) {
- loadDataFromModel();
-
- Composite container = (Composite) super.createDialogArea(parent);
- GridLayout gl_container = new GridLayout(1, false);
- gl_container.verticalSpacing = DEFAULT_LAYOUT_SPACING;
- gl_container.horizontalSpacing = DEFAULT_LAYOUT_SPACING;
- gl_container.marginWidth = DEFAULT_LAYOUT_SPACING;
- gl_container.marginHeight = DEFAULT_LAYOUT_SPACING;
- container.setLayout(gl_container);
-
- Group openScreenshotGroup = new Group(container, SWT.NONE);
- openScreenshotGroup.setLayout(new GridLayout(2, false));
- openScreenshotGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- openScreenshotGroup.setText("Screenshot");
-
- mScreenshotText = new Text(openScreenshotGroup, SWT.BORDER | SWT.READ_ONLY);
- if (mScreenshotFile != null) {
- mScreenshotText.setText(mScreenshotFile.getAbsolutePath());
- }
- GridData gd_screenShotText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
- gd_screenShotText.minimumWidth = FIXED_TEXT_FIELD_WIDTH;
- gd_screenShotText.widthHint = FIXED_TEXT_FIELD_WIDTH;
- mScreenshotText.setLayoutData(gd_screenShotText);
-
- Button openScreenshotButton = new Button(openScreenshotGroup, SWT.NONE);
- openScreenshotButton.setText("...");
- openScreenshotButton.addListener(SWT.Selection, new Listener() {
- @Override
- public void handleEvent(Event event) {
- handleOpenScreenshotFile();
- }
- });
-
- Group openXmlGroup = new Group(container, SWT.NONE);
- openXmlGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- openXmlGroup.setText("UI XML Dump");
- openXmlGroup.setLayout(new GridLayout(2, false));
-
- mXmlText = new Text(openXmlGroup, SWT.BORDER | SWT.READ_ONLY);
- mXmlText.setEditable(false);
- if (mXmlDumpFile != null) {
- mXmlText.setText(mXmlDumpFile.getAbsolutePath());
- }
- GridData gd_xmlText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
- gd_xmlText.minimumWidth = FIXED_TEXT_FIELD_WIDTH;
- gd_xmlText.widthHint = FIXED_TEXT_FIELD_WIDTH;
- mXmlText.setLayoutData(gd_xmlText);
-
- Button openXmlButton = new Button(openXmlGroup, SWT.NONE);
- openXmlButton.setText("...");
- openXmlButton.addListener(SWT.Selection, new Listener() {
- @Override
- public void handleEvent(Event event) {
- handleOpenXmlDumpFile();
- }
- });
-
- return container;
- }
-
- /**
- * Create contents of the button bar.
- * @param parent
- */
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- mOkButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
- createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
- updateButtonState();
- }
-
- /**
- * Return the initial size of the dialog.
- */
- @Override
- protected Point getInitialSize() {
- return new Point(368, 233);
- }
-
- @Override
- protected void configureShell(Shell newShell) {
- super.configureShell(newShell);
- newShell.setText("Open UI Dump Files");
- }
-
- private void loadDataFromModel() {
- mScreenshotFile = UiAutomatorModel.getModel().getScreenshotFile();
- mXmlDumpFile = UiAutomatorModel.getModel().getXmlDumpFile();
- }
-
- private void handleOpenScreenshotFile() {
- FileDialog fd = new FileDialog(getShell(), SWT.OPEN);
- fd.setText("Open Screenshot File");
- File initialFile = mScreenshotFile;
- // if file has never been selected before, try to base initial path on the mXmlDumpFile
- if (initialFile == null && mXmlDumpFile != null && mXmlDumpFile.isFile()) {
- initialFile = mXmlDumpFile.getParentFile();
- }
- if (initialFile != null) {
- if (initialFile.isFile()) {
- fd.setFileName(initialFile.getAbsolutePath());
- } else if (initialFile.isDirectory()) {
- fd.setFilterPath(initialFile.getAbsolutePath());
- }
- }
- String[] filter = {"*.png"};
- fd.setFilterExtensions(filter);
- String selected = fd.open();
- if (selected != null) {
- mScreenshotFile = new File(selected);
- mScreenshotText.setText(selected);
- mFileChanged = true;
- }
- updateButtonState();
- }
-
- private void handleOpenXmlDumpFile() {
- FileDialog fd = new FileDialog(getShell(), SWT.OPEN);
- fd.setText("Open UI Dump XML File");
- File initialFile = mXmlDumpFile;
- // if file has never been selected before, try to base initial path on the mScreenshotFile
- if (initialFile == null && mScreenshotFile != null && mScreenshotFile.isFile()) {
- initialFile = mScreenshotFile.getParentFile();
- }
- if (initialFile != null) {
- if (initialFile.isFile()) {
- fd.setFileName(initialFile.getAbsolutePath());
- } else if (initialFile.isDirectory()) {
- fd.setFilterPath(initialFile.getAbsolutePath());
- }
- }
- String initialPath = mXmlText.getText();
- if (initialPath.isEmpty() && mScreenshotFile != null && mScreenshotFile.isFile()) {
- initialPath = mScreenshotFile.getParentFile().getAbsolutePath();
- }
- String[] filter = {"*.xml"};
- fd.setFilterExtensions(filter);
- String selected = fd.open();
- if (selected != null) {
- mXmlDumpFile = new File(selected);
- mXmlText.setText(selected);
- mFileChanged = true;
- }
- updateButtonState();
- }
-
- private void updateButtonState() {
- mOkButton.setEnabled(mScreenshotFile != null && mXmlDumpFile != null
- && mScreenshotFile.isFile() && mXmlDumpFile.isFile());
- }
-
- public boolean hasFileChanged() {
- return mFileChanged;
- }
-
- public File getScreenshotFile() {
- return mScreenshotFile;
- }
-
- public File getXmlDumpFile() {
- return mXmlDumpFile;
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorModel.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorModel.java
deleted file mode 100644
index 0a1fab0..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorModel.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator;
-
-import com.android.uiautomator.tree.BasicTreeNode;
-import com.android.uiautomator.tree.BasicTreeNode.IFindNodeListener;
-import com.android.uiautomator.tree.UiHierarchyXmlLoader;
-import com.android.uiautomator.tree.UiNode;
-
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.ImageLoader;
-import org.eclipse.swt.graphics.Rectangle;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-public class UiAutomatorModel {
-
- private static UiAutomatorModel inst = null;
-
- private File mScreenshotFile, mXmlDumpFile;
- private UiAutomatorViewer mView;
- private Image mScreenshot;
- private BasicTreeNode mRootNode;
- private BasicTreeNode mSelectedNode;
- private Rectangle mCurrentDrawingRect;
- private List<Rectangle> mNafNodes;
- private List<File> mTmpDirs;
-
- // determines whether we lookup the leaf UI node on mouse move of screenshot image
- private boolean mExploreMode = true;
-
- private boolean mShowNafNodes = false;
-
- private UiAutomatorModel(UiAutomatorViewer view) {
- mView = view;
- mTmpDirs = new ArrayList<File>();
- }
-
- public static UiAutomatorModel createInstance(UiAutomatorViewer view) {
- if (inst != null) {
- throw new IllegalStateException("instance already created!");
- }
- inst = new UiAutomatorModel(view);
- return inst;
- }
-
- public static UiAutomatorModel getModel() {
- if (inst == null) {
- throw new IllegalStateException("instance not created yet!");
- }
- return inst;
- }
-
- public File getScreenshotFile() {
- return mScreenshotFile;
- }
-
- public File getXmlDumpFile() {
- return mXmlDumpFile;
- }
-
- public boolean loadScreenshotAndXmlDump(File screenshotFile, File xmlDumpFile) {
- if (screenshotFile != null && xmlDumpFile != null
- && screenshotFile.isFile() && xmlDumpFile.isFile()) {
- ImageData[] data = null;
- Image img = null;
- try {
- // use SWT's ImageLoader to read png from path
- data = new ImageLoader().load(screenshotFile.getAbsolutePath());
- } catch (SWTException e) {
- e.printStackTrace();
- return false;
- }
- // "data" is an array, probably used to handle images that has multiple frames
- // i.e. gifs or icons, we just care if it has at least one here
- if (data.length < 1) return false;
- UiHierarchyXmlLoader loader = new UiHierarchyXmlLoader();
- BasicTreeNode rootNode = loader.parseXml(xmlDumpFile
- .getAbsolutePath());
- if (rootNode == null) {
- System.err.println("null rootnode after parsing.");
- return false;
- }
- mNafNodes = loader.getNafNodes();
- try {
- // Image is tied to ImageData and a Display, so we only need to create once
- // per new image
- img = new Image(mView.getShell().getDisplay(), data[0]);
- } catch (SWTException e) {
- e.printStackTrace();
- return false;
- }
- // only update screenhot and xml if both are loaded successfully
- if (mScreenshot != null) {
- mScreenshot.dispose();
- }
- mScreenshot = img;
- if (mRootNode != null) {
- mRootNode.clearAllChildren();
- }
- // TODO: we should verify here if the coordinates in the XML matches the png
- // or not: think loading a phone screenshot with a tablet XML dump
- mRootNode = rootNode;
- mScreenshotFile = screenshotFile;
- mXmlDumpFile = xmlDumpFile;
- mExploreMode = true;
- mView.loadScreenshotAndXml();
- return true;
- }
- return false;
- }
-
- public BasicTreeNode getXmlRootNode() {
- return mRootNode;
- }
-
- public Image getScreenshot() {
- return mScreenshot;
- }
-
- public BasicTreeNode getSelectedNode() {
- return mSelectedNode;
- }
-
- /**
- * change node selection in the Model recalculate the rect to highlight,
- * also notifies the View to refresh accordingly
- *
- * @param node
- */
- public void setSelectedNode(BasicTreeNode node) {
- mSelectedNode = node;
- if (mSelectedNode != null && mSelectedNode instanceof UiNode) {
- UiNode uiNode = (UiNode) mSelectedNode;
- mCurrentDrawingRect = new Rectangle(uiNode.x, uiNode.y, uiNode.width, uiNode.height);
- } else {
- mCurrentDrawingRect = null;
- }
- mView.updateScreenshot();
- if (mSelectedNode != null) {
- mView.loadAttributeTable();
- }
- }
-
- public Rectangle getCurrentDrawingRect() {
- return mCurrentDrawingRect;
- }
-
- /**
- * Do a search in tree to find a leaf node or deepest parent node containing the coordinate
- *
- * @param x
- * @param y
- */
- public void updateSelectionForCoordinates(int x, int y) {
- if (mRootNode == null)
- return;
- MinAreaFindNodeListener listener = new MinAreaFindNodeListener();
- boolean found = mRootNode.findLeafMostNodesAtPoint(x, y, listener);
- if (found && listener.mNode != null && !listener.mNode.equals(mSelectedNode)) {
- mView.updateTreeSelection(listener.mNode);
- }
- }
-
- public boolean isExploreMode() {
- return mExploreMode;
- }
-
- public void toggleExploreMode() {
- mExploreMode = !mExploreMode;
- mView.updateScreenshot();
- }
-
- public void setExploreMode(boolean exploreMode) {
- mExploreMode = exploreMode;
- }
-
- private static class MinAreaFindNodeListener implements IFindNodeListener {
- BasicTreeNode mNode = null;
- @Override
- public void onFoundNode(BasicTreeNode node) {
- if (mNode == null) {
- mNode = node;
- } else {
- if ((node.height * node.width) < (mNode.height * mNode.width)) {
- mNode = node;
- }
- }
- }
- }
-
- public List<Rectangle> getNafNodes() {
- return mNafNodes;
- }
-
- public void toggleShowNaf() {
- mShowNafNodes = !mShowNafNodes;
- mView.updateScreenshot();
- }
-
- public boolean shouldShowNafNodes() {
- return mShowNafNodes;
- }
-
- /**
- * Registers a temporary directory for deletion when app exists
- *
- * @param tmpDir
- */
- public void registerTempDirectory(File tmpDir) {
- mTmpDirs.add(tmpDir);
- }
-
- /**
- * Performs cleanup tasks when the app is exiting
- */
- public void cleanUp() {
- for (File dir : mTmpDirs) {
- Utils.deleteRecursive(dir);
- }
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java
deleted file mode 100644
index 9f758ae..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/UiAutomatorViewer.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator;
-
-import com.android.uiautomator.actions.ExpandAllAction;
-import com.android.uiautomator.actions.OpenFilesAction;
-import com.android.uiautomator.actions.ScreenshotAction;
-import com.android.uiautomator.actions.ToggleNafAction;
-import com.android.uiautomator.tree.AttributePair;
-import com.android.uiautomator.tree.BasicTreeNode;
-import com.android.uiautomator.tree.BasicTreeNodeContentProvider;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.layout.TableColumnLayout;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ColumnWeightData;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TextCellEditor;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.window.ApplicationWindow;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.graphics.Transform;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Tree;
-
-public class UiAutomatorViewer extends ApplicationWindow {
-
- private static final int IMG_BORDER = 2;
-
- private Canvas mScreenshotCanvas;
- private TreeViewer mTreeViewer;
-
- private Action mOpenFilesAction;
- private Action mExpandAllAction;
- private Action mScreenshotAction;
- private Action mToggleNafAction;
- private TableViewer mTableViewer;
-
- private float mScale = 1.0f;
- private int mDx, mDy;
-
- /**
- * Create the application window.
- */
- public UiAutomatorViewer() {
- super(null);
- UiAutomatorModel.createInstance(this);
- createActions();
- }
-
- /**
- * Create contents of the application window.
- *
- * @param parent
- */
- @Override
- protected Control createContents(Composite parent) {
- SashForm baseSash = new SashForm(parent, SWT.HORIZONTAL | SWT.NONE);
- // draw the canvas with border, so the divider area for sash form can be highlighted
- mScreenshotCanvas = new Canvas(baseSash, SWT.BORDER);
- mScreenshotCanvas.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseUp(MouseEvent e) {
- UiAutomatorModel.getModel().toggleExploreMode();
- }
- });
- mScreenshotCanvas.setBackground(
- getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
- mScreenshotCanvas.addPaintListener(new PaintListener() {
- @Override
- public void paintControl(PaintEvent e) {
- Image image = UiAutomatorModel.getModel().getScreenshot();
- if (image != null) {
- updateScreenshotTransformation();
- // shifting the image here, so that there's a border around screen shot
- // this makes highlighting red rectangles on the screen shot edges more visible
- Transform t = new Transform(e.gc.getDevice());
- t.translate(mDx, mDy);
- t.scale(mScale, mScale);
- e.gc.setTransform(t);
- e.gc.drawImage(image, 0, 0);
- // this resets the transformation to identity transform, i.e. no change
- // we don't use transformation here because it will cause the line pattern
- // and line width of highlight rect to be scaled, causing to appear to be blurry
- e.gc.setTransform(null);
- if (UiAutomatorModel.getModel().shouldShowNafNodes()) {
- // highlight the "Not Accessibility Friendly" nodes
- e.gc.setForeground(e.gc.getDevice().getSystemColor(SWT.COLOR_YELLOW));
- e.gc.setBackground(e.gc.getDevice().getSystemColor(SWT.COLOR_YELLOW));
- for (Rectangle r : UiAutomatorModel.getModel().getNafNodes()) {
- e.gc.setAlpha(50);
- e.gc.fillRectangle(mDx + getScaledSize(r.x), mDy + getScaledSize(r.y),
- getScaledSize(r.width), getScaledSize(r.height));
- e.gc.setAlpha(255);
- e.gc.setLineStyle(SWT.LINE_SOLID);
- e.gc.setLineWidth(2);
- e.gc.drawRectangle(mDx + getScaledSize(r.x), mDy + getScaledSize(r.y),
- getScaledSize(r.width), getScaledSize(r.height));
- }
- }
- // draw the mouseover rects
- Rectangle rect = UiAutomatorModel.getModel().getCurrentDrawingRect();
- if (rect != null) {
- e.gc.setForeground(e.gc.getDevice().getSystemColor(SWT.COLOR_RED));
- if (UiAutomatorModel.getModel().isExploreMode()) {
- // when we highlight nodes dynamically on mouse move,
- // use dashed borders
- e.gc.setLineStyle(SWT.LINE_DASH);
- e.gc.setLineWidth(1);
- } else {
- // when highlighting nodes on tree node selection,
- // use solid borders
- e.gc.setLineStyle(SWT.LINE_SOLID);
- e.gc.setLineWidth(2);
- }
- e.gc.drawRectangle(mDx + getScaledSize(rect.x), mDy + getScaledSize(rect.y),
- getScaledSize(rect.width), getScaledSize(rect.height));
- }
- }
- }
- });
- mScreenshotCanvas.addMouseMoveListener(new MouseMoveListener() {
- @Override
- public void mouseMove(MouseEvent e) {
- if (UiAutomatorModel.getModel().isExploreMode()) {
- UiAutomatorModel.getModel().updateSelectionForCoordinates(
- getInverseScaledSize(e.x - mDx),
- getInverseScaledSize(e.y - mDy));
- }
- }
- });
-
- // right sash is split into 2 parts: upper-right and lower-right
- // both are composites with borders, so that the horizontal divider can be highlighted by
- // the borders
- SashForm rightSash = new SashForm(baseSash, SWT.VERTICAL);
-
- // upper-right base contains the toolbar and the tree
- Composite upperRightBase = new Composite(rightSash, SWT.BORDER);
- upperRightBase.setLayout(new GridLayout(1, false));
- ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
- toolBarManager.add(mOpenFilesAction);
- toolBarManager.add(mExpandAllAction);
- toolBarManager.add(mScreenshotAction);
- toolBarManager.add(mToggleNafAction);
- toolBarManager.createControl(upperRightBase);
-
- mTreeViewer = new TreeViewer(upperRightBase, SWT.NONE);
- mTreeViewer.setContentProvider(new BasicTreeNodeContentProvider());
- // default LabelProvider uses toString() to generate text to display
- mTreeViewer.setLabelProvider(new LabelProvider());
- mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- if (event.getSelection().isEmpty()) {
- UiAutomatorModel.getModel().setSelectedNode(null);
- } else if (event.getSelection() instanceof IStructuredSelection) {
- IStructuredSelection selection = (IStructuredSelection) event.getSelection();
- Object o = selection.toArray()[0];
- if (o instanceof BasicTreeNode) {
- UiAutomatorModel.getModel().setSelectedNode((BasicTreeNode)o);
- }
- }
- }
- });
- Tree tree = mTreeViewer.getTree();
- tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
- // move focus so that it's not on tool bar (looks weird)
- tree.setFocus();
-
- // lower-right base contains the detail group
- Composite lowerRightBase = new Composite(rightSash, SWT.BORDER);
- lowerRightBase.setLayout(new FillLayout());
- Group grpNodeDetail = new Group(lowerRightBase, SWT.NONE);
- grpNodeDetail.setLayout(new FillLayout(SWT.HORIZONTAL));
- grpNodeDetail.setText("Node Detail");
-
- Composite tableContainer = new Composite(grpNodeDetail, SWT.NONE);
-
- TableColumnLayout columnLayout = new TableColumnLayout();
- tableContainer.setLayout(columnLayout);
-
- mTableViewer = new TableViewer(tableContainer, SWT.NONE | SWT.FULL_SELECTION);
- Table table = mTableViewer.getTable();
- table.setLinesVisible(true);
- // use ArrayContentProvider here, it assumes the input to the TableViewer
- // is an array, where each element represents a row in the table
- mTableViewer.setContentProvider(new ArrayContentProvider());
-
- TableViewerColumn tableViewerColumnKey = new TableViewerColumn(mTableViewer, SWT.NONE);
- TableColumn tblclmnKey = tableViewerColumnKey.getColumn();
- tableViewerColumnKey.setLabelProvider(new ColumnLabelProvider() {
- @Override
- public String getText(Object element) {
- if (element instanceof AttributePair) {
- // first column, shows the attribute name
- return ((AttributePair)element).key;
- }
- return super.getText(element);
- }
- });
- columnLayout.setColumnData(tblclmnKey,
- new ColumnWeightData(1, ColumnWeightData.MINIMUM_WIDTH, true));
-
- TableViewerColumn tableViewerColumnValue = new TableViewerColumn(mTableViewer, SWT.NONE);
- tableViewerColumnValue.setEditingSupport(new AttributeTableEditingSupport(mTableViewer));
- TableColumn tblclmnValue = tableViewerColumnValue.getColumn();
- columnLayout.setColumnData(tblclmnValue,
- new ColumnWeightData(2, ColumnWeightData.MINIMUM_WIDTH, true));
- tableViewerColumnValue.setLabelProvider(new ColumnLabelProvider() {
- @Override
- public String getText(Object element) {
- if (element instanceof AttributePair) {
- // second column, shows the attribute value
- return ((AttributePair)element).value;
- }
- return super.getText(element);
- }
- });
- // sets the ratio of the vertical split: left 5 vs right 3
- baseSash.setWeights(new int[]{5, 3});
- return baseSash;
- }
-
- /**
- * Create the actions.
- */
- private void createActions() {
- mOpenFilesAction = new OpenFilesAction(this);
- mExpandAllAction = new ExpandAllAction(this);
- mScreenshotAction = new ScreenshotAction(this);
- mToggleNafAction = new ToggleNafAction();
- }
-
- /**
- * Launch the application.
- *
- * @param args
- */
- public static void main(String args[]) {
- try {
- UiAutomatorViewer window = new UiAutomatorViewer();
- window.setBlockOnOpen(true);
- window.open();
- UiAutomatorModel.getModel().cleanUp();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Configure the shell.
- *
- * @param newShell
- */
- @Override
- protected void configureShell(Shell newShell) {
- super.configureShell(newShell);
- newShell.setText("UI Automator Viewer");
- }
-
-
- /**
- * Asks the Model for screenshot and xml tree data, then populates the screenshot
- * area and tree view accordingly
- */
- public void loadScreenshotAndXml() {
- mScreenshotCanvas.redraw();
- // load xml into tree
- BasicTreeNode wrapper = new BasicTreeNode();
- // putting another root node on top of existing root node
- // because Tree seems to like to hide the root node
- wrapper.addChild(UiAutomatorModel.getModel().getXmlRootNode());
- mTreeViewer.setInput(wrapper);
- mTreeViewer.getTree().setFocus();
- }
-
- /*
- * Causes a redraw of the canvas.
- *
- * The drawing code of canvas will handle highlighted nodes and etc based on data
- * retrieved from Model
- */
- public void updateScreenshot() {
- mScreenshotCanvas.redraw();
- }
-
- public void expandAll() {
- mTreeViewer.expandAll();
- }
-
- public void updateTreeSelection(BasicTreeNode node) {
- mTreeViewer.setSelection(new StructuredSelection(node), true);
- }
-
- public void loadAttributeTable() {
- // udpate the lower right corner table to show the attributes of the node
- mTableViewer.setInput(
- UiAutomatorModel.getModel().getSelectedNode().getAttributesArray());
- }
-
- @Override
- protected Point getInitialSize() {
- return new Point(800, 600);
- }
-
- private void updateScreenshotTransformation() {
- Rectangle canvas = mScreenshotCanvas.getBounds();
- Rectangle image = UiAutomatorModel.getModel().getScreenshot().getBounds();
- float scaleX = (canvas.width - 2 * IMG_BORDER - 1) / (float)image.width;
- float scaleY = (canvas.height - 2 * IMG_BORDER - 1) / (float)image.height;
- // use the smaller scale here so that we can fit the entire screenshot
- mScale = Math.min(scaleX, scaleY);
- // calculate translation values to center the image on the canvas
- mDx = (canvas.width - getScaledSize(image.width) - IMG_BORDER * 2) / 2 + IMG_BORDER;
- mDy = (canvas.height - getScaledSize(image.height) - IMG_BORDER * 2) / 2 + IMG_BORDER;
- }
-
- private int getScaledSize(int size) {
- if (mScale == 1.0f) {
- return size;
- } else {
- return new Double(Math.floor((size * mScale))).intValue();
- }
- }
-
- private int getInverseScaledSize(int size) {
- if (mScale == 1.0f) {
- return size;
- } else {
- return new Double(Math.floor((size / mScale))).intValue();
- }
- }
-
- private class AttributeTableEditingSupport extends EditingSupport {
-
- private TableViewer mViewer;
-
- public AttributeTableEditingSupport(TableViewer viewer) {
- super(viewer);
- mViewer = viewer;
- }
-
- @Override
- protected boolean canEdit(Object arg0) {
- return true;
- }
-
- @Override
- protected CellEditor getCellEditor(Object arg0) {
- return new TextCellEditor(mViewer.getTable());
- }
-
- @Override
- protected Object getValue(Object o) {
- return ((AttributePair)o).value;
- }
-
- @Override
- protected void setValue(Object arg0, Object arg1) {
- }
-
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/Utils.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/Utils.java
deleted file mode 100644
index 5306fe3..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/Utils.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator;
-
-import java.io.File;
-
-public class Utils {
- public static void deleteRecursive(File file) {
- if (file.isDirectory()) {
- File[] children = file.listFiles();
- for (File child : children) {
- if (!child.getName().startsWith("."))
- deleteRecursive(child);
- }
- }
- file.delete();
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ExpandAllAction.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ExpandAllAction.java
deleted file mode 100644
index 3c73fdc..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ExpandAllAction.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.actions;
-
-import com.android.uiautomator.UiAutomatorViewer;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.resource.ImageDescriptor;
-
-public class ExpandAllAction extends Action {
-
- UiAutomatorViewer mWindow;
-
- public ExpandAllAction(UiAutomatorViewer window) {
- super("&Expand All");
- mWindow = window;
- }
-
- @Override
- public ImageDescriptor getImageDescriptor() {
- return ImageHelper.loadImageDescriptorFromResource("images/expandall.png");
- }
-
- @Override
- public void run() {
- mWindow.expandAll();
- }
-
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ImageHelper.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ImageHelper.java
deleted file mode 100644
index c22f1fd..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ImageHelper.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.actions;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.ImageLoader;
-
-import java.io.InputStream;
-
-public class ImageHelper {
-
- public static ImageDescriptor loadImageDescriptorFromResource(String path) {
- InputStream is = ImageHelper.class.getClassLoader().getResourceAsStream(path);
- if (is != null) {
- ImageData[] data = null;
- try {
- data = new ImageLoader().load(is);
- } catch (SWTException e) {
- }
- if (data != null && data.length > 0) {
- return ImageDescriptor.createFromImageData(data[0]);
- }
- }
- return null;
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/OpenFilesAction.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/OpenFilesAction.java
deleted file mode 100644
index 3232857..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/OpenFilesAction.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.actions;
-
-import com.android.uiautomator.OpenDialog;
-import com.android.uiautomator.UiAutomatorModel;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.window.ApplicationWindow;
-
-public class OpenFilesAction extends Action {
-
- ApplicationWindow mWindow;
-
- public OpenFilesAction(ApplicationWindow window) {
- super("&Open");
- mWindow = window;
- }
-
- @Override
- public ImageDescriptor getImageDescriptor() {
- return ImageHelper.loadImageDescriptorFromResource("images/open-folder.png");
- }
-
- @Override
- public void run() {
- OpenDialog d = new OpenDialog(mWindow.getShell());
- if (d.open() == OpenDialog.OK) {
- UiAutomatorModel.getModel().loadScreenshotAndXmlDump(
- d.getScreenshotFile(), d.getXmlDumpFile());
- }
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java
deleted file mode 100644
index 7d1eaa3..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ScreenshotAction.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.actions;
-
-import com.android.uiautomator.UiAutomatorModel;
-import com.android.uiautomator.UiAutomatorViewer;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.resource.ImageDescriptor;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ScreenshotAction extends Action {
-
- UiAutomatorViewer mViewer;
-
- public ScreenshotAction(UiAutomatorViewer viewer) {
- super("&Device Screenshot");
- mViewer = viewer;
- }
-
- @Override
- public ImageDescriptor getImageDescriptor() {
- return ImageHelper.loadImageDescriptorFromResource("images/screenshot.png");
- }
-
- @Override
- public void run() {
- ProgressMonitorDialog dialog = new ProgressMonitorDialog(mViewer.getShell());
- try {
- dialog.run(true, false, new IRunnableWithProgress() {
- private void showError(final String msg, final Throwable t,
- IProgressMonitor monitor) {
- monitor.done();
- mViewer.getShell().getDisplay().syncExec(new Runnable() {
- @Override
- public void run() {
- Status s = new Status(IStatus.ERROR, "Screenshot", msg, t);
- ErrorDialog.openError(
- mViewer.getShell(), "Error", "Cannot take screenshot", s);
- }
- });
- }
-
- @Override
- public void run(IProgressMonitor monitor) throws InvocationTargetException,
- InterruptedException {
- ProcRunner procRunner = null;
- String serial = System.getenv("ANDROID_SERIAL");
- File tmpDir = null;
- File xmlDumpFile = null;
- File screenshotFile = null;
- int retCode = -1;
- try {
- tmpDir = File.createTempFile("uiautomatorviewer_", "");
- tmpDir.delete();
- if (!tmpDir.mkdirs())
- throw new IOException("Failed to mkdir");
- xmlDumpFile = File.createTempFile("dump_", ".xml", tmpDir);
- screenshotFile = File.createTempFile("screenshot_", ".png", tmpDir);
- } catch (IOException e) {
- e.printStackTrace();
- showError("Cannot get temp directory", e, monitor);
- return;
- }
- UiAutomatorModel.getModel().registerTempDirectory(tmpDir);
-
- // boiler plates to do a bunch of adb stuff to take XML snapshot and screenshot
- monitor.beginTask("Getting UI status dump from device...",
- IProgressMonitor.UNKNOWN);
- monitor.subTask("Detecting device...");
- procRunner = getAdbRunner(serial, "shell", "ls", "/system/bin/uiautomator");
- try {
- retCode = procRunner.run(30000);
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to detect device", e, monitor);
- return;
- }
- if (retCode != 0) {
- showError("No device or multiple devices connected. "
- + "Use ANDROID_SERIAL environment variable "
- + "if you have multiple devices", null, monitor);
- return;
- }
- if (procRunner.getOutputBlob().indexOf("No such file or directory") != -1) {
- showError("/system/bin/uiautomator not found on device", null, monitor);
- return;
- }
- monitor.subTask("Deleting old UI XML snapshot ...");
- procRunner = getAdbRunner(serial,
- "shell", "rm", "/sdcard/uidump.xml");
- try {
- retCode = procRunner.run(30000);
- if (retCode != 0) {
- throw new IOException(
- "Non-zero return code from \"rm\" xml dump command:\n"
- + procRunner.getOutputBlob());
- }
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to execute \"rm\" xml dump command.", e, monitor);
- return;
- }
-
- monitor.subTask("Taking UI XML snapshot...");
- procRunner = getAdbRunner(serial,
- "shell", "/system/bin/uiautomator", "dump", "/sdcard/uidump.xml");
- try {
- retCode = procRunner.run(30000);
- if (retCode != 0) {
- throw new IOException("Non-zero return code from dump command:\n"
- + procRunner.getOutputBlob());
- }
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to execute dump command.", e, monitor);
- return;
- }
- procRunner = getAdbRunner(serial,
- "pull", "/sdcard/uidump.xml", xmlDumpFile.getAbsolutePath());
- try {
- retCode = procRunner.run(30000);
- if (retCode != 0) {
- throw new IOException("Non-zero return code from pull command:\n"
- + procRunner.getOutputBlob());
- }
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to pull dump file.", e, monitor);
- return;
- }
-
- monitor.subTask("Deleting old device screenshot...");
- procRunner = getAdbRunner(serial,
- "shell", "rm", "/sdcard/screenshot.png");
- try {
- retCode = procRunner.run(30000);
- if (retCode != 0) {
- throw new IOException(
- "Non-zero return code from \"rm\" screenshot command:\n"
- + procRunner.getOutputBlob());
- }
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to execute \"rm\" screenshot command.", e, monitor);
- return;
- }
-
- monitor.subTask("Taking device screenshot...");
- procRunner = getAdbRunner(serial,
- "shell", "screencap", "-p", "/sdcard/screenshot.png");
- try {
- retCode = procRunner.run(30000);
- if (retCode != 0) {
- throw new IOException("Non-zero return code from screenshot command:\n"
- + procRunner.getOutputBlob());
- }
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to execute screenshot command.", e, monitor);
- return;
- }
- procRunner = getAdbRunner(serial,
- "pull", "/sdcard/screenshot.png", screenshotFile.getAbsolutePath());
- try {
- retCode = procRunner.run(30000);
- if (retCode != 0) {
- throw new IOException("Non-zero return code from pull command:\n"
- + procRunner.getOutputBlob());
- }
- } catch (IOException e) {
- e.printStackTrace();
- showError("Failed to pull dump file.", e, monitor);
- return;
- }
- final File png = screenshotFile, xml = xmlDumpFile;
- if(png.length() == 0) {
- showError("Screenshot file size is 0", null, monitor);
- return;
- } else {
- mViewer.getShell().getDisplay().syncExec(new Runnable() {
- @Override
- public void run() {
- UiAutomatorModel.getModel().loadScreenshotAndXmlDump(png, xml);
- }
- });
- }
- monitor.done();
- }
- });
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /*
- * Convenience function to construct an 'adb' command, e.g. use 'adb' or 'adb -s NNN'
- */
- private ProcRunner getAdbRunner(String serial, String... command) {
- List<String> cmd = new ArrayList<String>();
- cmd.add("adb");
- if (serial != null) {
- cmd.add("-s");
- cmd.add(serial);
- }
- for (String s : command) {
- cmd.add(s);
- }
- return new ProcRunner(cmd);
- }
-
- /**
- * Convenience class to run external process.
- *
- * Always redirects stderr into stdout, has timeout control
- *
- */
- private static class ProcRunner {
-
- ProcessBuilder mProcessBuilder;
-
- List<String> mOutput = new ArrayList<String>();
-
- public ProcRunner(List<String> command) {
- mProcessBuilder = new ProcessBuilder(command).redirectErrorStream(true);
- }
-
- public int run(long timeout) throws IOException {
- final Process p = mProcessBuilder.start();
- Thread t = new Thread() {
- @Override
- public void run() {
- String line;
- mOutput.clear();
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(
- p.getInputStream()));
- while ((line = br.readLine()) != null) {
- mOutput.add(line);
- }
- br.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- };
- };
- t.start();
- try {
- t.join(timeout);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (t.isAlive()) {
- throw new IOException("external process not terminating.");
- }
- try {
- return p.waitFor();
- } catch (InterruptedException e) {
- e.printStackTrace();
- throw new IOException(e);
- }
- }
-
- public String getOutputBlob() {
- StringBuilder sb = new StringBuilder();
- for (String line : mOutput) {
- sb.append(line);
- sb.append(System.getProperty("line.separator"));
- }
- return sb.toString();
- }
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ToggleNafAction.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ToggleNafAction.java
deleted file mode 100644
index afc422d..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/actions/ToggleNafAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.actions;
-
-import com.android.uiautomator.UiAutomatorModel;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.resource.ImageDescriptor;
-
-public class ToggleNafAction extends Action {
-
- public ToggleNafAction() {
- super("&Toggle NAF Nodes", IAction.AS_CHECK_BOX);
- setChecked(UiAutomatorModel.getModel().shouldShowNafNodes());
- }
-
- @Override
- public ImageDescriptor getImageDescriptor() {
- return ImageHelper.loadImageDescriptorFromResource("images/warning.png");
- }
-
- @Override
- public void run() {
- UiAutomatorModel.getModel().toggleShowNaf();
- setChecked(UiAutomatorModel.getModel().shouldShowNafNodes());
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/AttributePair.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/AttributePair.java
deleted file mode 100644
index ef59544..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/AttributePair.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.tree;
-
-public class AttributePair {
- public String key, value;
-
- public AttributePair(String key, String value) {
- this.key = key;
- this.value = value;
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/BasicTreeNode.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/BasicTreeNode.java
deleted file mode 100644
index 99434d1..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/BasicTreeNode.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.tree;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class BasicTreeNode {
-
- private static final BasicTreeNode[] CHILDREN_TEMPLATE = new BasicTreeNode[] {};
-
- protected BasicTreeNode mParent;
-
- protected final List<BasicTreeNode> mChildren = new ArrayList<BasicTreeNode>();
-
- public int x, y, width, height;
-
- // whether the boundary fields are applicable for the node or not
- // RootWindowNode has no bounds, but UiNodes should
- protected boolean mHasBounds = false;
-
- public void addChild(BasicTreeNode child) {
- if (child == null) {
- throw new NullPointerException("Cannot add null child");
- }
- if (mChildren.contains(child)) {
- throw new IllegalArgumentException("node already a child");
- }
- mChildren.add(child);
- child.mParent = this;
- }
-
- public List<BasicTreeNode> getChildrenList() {
- return Collections.unmodifiableList(mChildren);
- }
-
- public BasicTreeNode[] getChildren() {
- return mChildren.toArray(CHILDREN_TEMPLATE);
- }
-
- public BasicTreeNode getParent() {
- return mParent;
- }
-
- public boolean hasChild() {
- return mChildren.size() != 0;
- }
-
- public int getChildCount() {
- return mChildren.size();
- }
-
- public void clearAllChildren() {
- for (BasicTreeNode child : mChildren) {
- child.clearAllChildren();
- }
- mChildren.clear();
- }
-
- /**
- *
- * Find nodes in the tree containing the coordinate
- *
- * The found node should have bounds covering the coordinate, and none of its children's
- * bounds covers it. Depending on the layout, some app may have multiple nodes matching it,
- * the caller must provide a {@link IFindNodeListener} to receive all found nodes
- *
- * @param px
- * @param py
- * @return
- */
- public boolean findLeafMostNodesAtPoint(int px, int py, IFindNodeListener listener) {
- boolean foundInChild = false;
- for (BasicTreeNode node : mChildren) {
- foundInChild |= node.findLeafMostNodesAtPoint(px, py, listener);
- }
- // checked all children, if at least one child covers the point, return directly
- if (foundInChild) return true;
- // check self if the node has no children, or no child nodes covers the point
- if (mHasBounds) {
- if (x <= px && px <= x + width && y <= py && py <= y + height) {
- listener.onFoundNode(this);
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
- public Object[] getAttributesArray () {
- return null;
- };
-
- public static interface IFindNodeListener {
- void onFoundNode(BasicTreeNode node);
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/BasicTreeNodeContentProvider.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/BasicTreeNodeContentProvider.java
deleted file mode 100644
index d78ceea..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/BasicTreeNodeContentProvider.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.tree;
-
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-public class BasicTreeNodeContentProvider implements ITreeContentProvider {
-
- private static final Object[] EMPTY_ARRAY = {};
-
- @Override
- public void dispose() {
- }
-
- @Override
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return getChildren(inputElement);
- }
-
- @Override
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof BasicTreeNode) {
- return ((BasicTreeNode)parentElement).getChildren();
- }
- return EMPTY_ARRAY;
- }
-
- @Override
- public Object getParent(Object element) {
- if (element instanceof BasicTreeNode) {
- return ((BasicTreeNode)element).getParent();
- }
- return null;
- }
-
- @Override
- public boolean hasChildren(Object element) {
- if (element instanceof BasicTreeNode) {
- return ((BasicTreeNode) element).hasChild();
- }
- return false;
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/RootWindowNode.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/RootWindowNode.java
deleted file mode 100644
index 27a21e4..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/RootWindowNode.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.tree;
-
-
-
-public class RootWindowNode extends BasicTreeNode {
-
- private final String mWindowName;
- private Object[] mCachedAttributesArray;
-
- public RootWindowNode(String windowName) {
- mWindowName = windowName;
- }
-
- @Override
- public String toString() {
- return mWindowName;
- }
-
- @Override
- public Object[] getAttributesArray() {
- if (mCachedAttributesArray == null) {
- mCachedAttributesArray = new Object[]{new AttributePair("window-name", mWindowName)};
- }
- return mCachedAttributesArray;
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/UiHierarchyXmlLoader.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/UiHierarchyXmlLoader.java
deleted file mode 100644
index f2339d1..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/UiHierarchyXmlLoader.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.tree;
-
-import org.eclipse.swt.graphics.Rectangle;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-public class UiHierarchyXmlLoader {
-
- private BasicTreeNode mRootNode;
- private List<Rectangle> mNafNodes;
-
- public UiHierarchyXmlLoader() {
- }
-
- /**
- * Uses a SAX parser to process XML dump
- * @param xmlPath
- * @return
- */
- public BasicTreeNode parseXml(String xmlPath) {
- mRootNode = null;
- mNafNodes = new ArrayList<Rectangle>();
- // standard boilerplate to get a SAX parser
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser parser = null;
- try {
- parser = factory.newSAXParser();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- return null;
- } catch (SAXException e) {
- e.printStackTrace();
- return null;
- }
- // handler class for SAX parser to receiver standard parsing events:
- // e.g. on reading "<foo>", startElement is called, on reading "</foo>",
- // endElement is called
- DefaultHandler handler = new DefaultHandler(){
- BasicTreeNode mParentNode;
- BasicTreeNode mWorkingNode;
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- boolean nodeCreated = false;
- // starting an element implies that the element that has not yet been closed
- // will be the parent of the element that is being started here
- mParentNode = mWorkingNode;
- if ("hierarchy".equals(qName)) {
- mWorkingNode = new RootWindowNode(attributes.getValue("windowName"));
- nodeCreated = true;
- } else if ("node".equals(qName)) {
- UiNode tmpNode = new UiNode();
- for (int i = 0; i < attributes.getLength(); i++) {
- tmpNode.addAtrribute(attributes.getQName(i), attributes.getValue(i));
- }
- mWorkingNode = tmpNode;
- nodeCreated = true;
- // check if current node is NAF
- String naf = tmpNode.getAttribute("NAF");
- if ("true".equals(naf)) {
- mNafNodes.add(new Rectangle(tmpNode.x, tmpNode.y,
- tmpNode.width, tmpNode.height));
- }
- }
- // nodeCreated will be false if the element started is neither
- // "hierarchy" nor "node"
- if (nodeCreated) {
- if (mRootNode == null) {
- // this will only happen once
- mRootNode = mWorkingNode;
- }
- if (mParentNode != null) {
- mParentNode.addChild(mWorkingNode);
- }
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- //mParentNode should never be null here in a well formed XML
- if (mParentNode != null) {
- // closing an element implies that we are back to working on
- // the parent node of the element just closed, i.e. continue to
- // parse more child nodes
- mWorkingNode = mParentNode;
- mParentNode = mParentNode.getParent();
- }
- }
- };
- try {
- parser.parse(new File(xmlPath), handler);
- } catch (SAXException e) {
- e.printStackTrace();
- return null;
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- return mRootNode;
- }
-
- /**
- * Returns the list of "Not Accessibility Friendly" nodes found during parsing.
- *
- * Call this function after parsing
- *
- * @return
- */
- public List<Rectangle> getNafNodes() {
- return Collections.unmodifiableList(mNafNodes);
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/UiNode.java b/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/UiNode.java
deleted file mode 100644
index 4adebf4..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/com/android/uiautomator/tree/UiNode.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.uiautomator.tree;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class UiNode extends BasicTreeNode {
- private static final Pattern BOUNDS_PATTERN = Pattern
- .compile("\\[-?(\\d+),-?(\\d+)\\]\\[-?(\\d+),-?(\\d+)\\]");
- // use LinkedHashMap to preserve the order of the attributes
- private final Map<String, String> mAttributes = new LinkedHashMap<String, String>();
- private String mDisplayName = "ShouldNotSeeMe";
- private Object[] mCachedAttributesArray;
-
- public void addAtrribute(String key, String value) {
- mAttributes.put(key, value);
- updateDisplayName();
- if ("bounds".equals(key)) {
- updateBounds(value);
- }
- }
-
- public Map<String, String> getAttributes() {
- return Collections.unmodifiableMap(mAttributes);
- }
-
- /**
- * Builds the display name based on attributes of the node
- */
- private void updateDisplayName() {
- String className = mAttributes.get("class");
- if (className == null)
- return;
- String text = mAttributes.get("text");
- if (text == null)
- return;
- String contentDescription = mAttributes.get("content-desc");
- if (contentDescription == null)
- return;
- String index = mAttributes.get("index");
- if (index == null)
- return;
- String bounds = mAttributes.get("bounds");
- if (bounds == null) {
- return;
- }
- // shorten the standard class names, otherwise it takes up too much space on UI
- className = className.replace("android.widget.", "");
- className = className.replace("android.view.", "");
- StringBuilder builder = new StringBuilder();
- builder.append('(');
- builder.append(index);
- builder.append(") ");
- builder.append(className);
- if (!text.isEmpty()) {
- builder.append(':');
- builder.append(text);
- }
- if (!contentDescription.isEmpty()) {
- builder.append(" {");
- builder.append(contentDescription);
- builder.append('}');
- }
- builder.append(' ');
- builder.append(bounds);
- mDisplayName = builder.toString();
- }
-
- private void updateBounds(String bounds) {
- Matcher m = BOUNDS_PATTERN.matcher(bounds);
- if (m.matches()) {
- x = Integer.parseInt(m.group(1));
- y = Integer.parseInt(m.group(2));
- width = Integer.parseInt(m.group(3)) - x;
- height = Integer.parseInt(m.group(4)) - y;
- mHasBounds = true;
- } else {
- throw new RuntimeException("Invalid bounds: " + bounds);
- }
- }
-
- @Override
- public String toString() {
- return mDisplayName;
- }
-
- public String getAttribute(String key) {
- return mAttributes.get(key);
- }
-
- @Override
- public Object[] getAttributesArray() {
- // this approach means we do not handle the situation where an attribute is added
- // after this function is first called. This is currently not a concern because the
- // tree is supposed to be readonly
- if (mCachedAttributesArray == null) {
- mCachedAttributesArray = new Object[mAttributes.size()];
- int i = 0;
- for (String attr : mAttributes.keySet()) {
- mCachedAttributesArray[i++] = new AttributePair(attr, mAttributes.get(attr));
- }
- }
- return mCachedAttributesArray;
- }
-}
diff --git a/uiautomator/utils/uiautomatorviewer/src/images/expandall.png b/uiautomator/utils/uiautomatorviewer/src/images/expandall.png
deleted file mode 100644
index 7bdf83d..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/images/expandall.png
+++ /dev/null
Binary files differ
diff --git a/uiautomator/utils/uiautomatorviewer/src/images/open-folder.png b/uiautomator/utils/uiautomatorviewer/src/images/open-folder.png
deleted file mode 100644
index 8c4a2e1..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/images/open-folder.png
+++ /dev/null
Binary files differ
diff --git a/uiautomator/utils/uiautomatorviewer/src/images/screenshot.png b/uiautomator/utils/uiautomatorviewer/src/images/screenshot.png
deleted file mode 100644
index 423f781..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/images/screenshot.png
+++ /dev/null
Binary files differ
diff --git a/uiautomator/utils/uiautomatorviewer/src/images/warning.png b/uiautomator/utils/uiautomatorviewer/src/images/warning.png
deleted file mode 100644
index ca3b6ed..0000000
--- a/uiautomator/utils/uiautomatorviewer/src/images/warning.png
+++ /dev/null
Binary files differ