mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-03-25 03:59:11 +00:00
[framework/uiauto] Update uiauto library to move away from android.support and into androidx
Currently the uiauto library is built on top of the deprecated android.support libraries. Create an updated uiauto library (uiauto-androidx) using androidx and keep it alongside the old one for compatibility reasons. As we update workload-automation going forward, we should update the workloads to use the androidx version of uiauto. This has been tested with the latest gradle version available at the time (8.8).
This commit is contained in:
parent
412a785068
commit
510b344aa5
18
wa/framework/uiauto-androidx/app/build.gradle
Normal file
18
wa/framework/uiauto-androidx/app/build.gradle
Normal file
@ -0,0 +1,18 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
namespace "com.arm.wa.uiauto"
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 28
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'androidx.test:runner:1.6.1'
|
||||
implementation 'androidx.test:rules:1.6.1'
|
||||
implementation 'androidx.test.uiautomator:uiautomator-v18:2.2.0-alpha1'
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
</application>
|
||||
</manifest>
|
@ -0,0 +1,60 @@
|
||||
/* Copyright 2014-2018 ARM Limited
|
||||
*
|
||||
* 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.arm.wa.uiauto;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
/**
|
||||
* Basic marker API for workloads to generate start and end markers for
|
||||
* deliminating and timing actions. Markers are output to logcat with debug
|
||||
* priority. Actions represent a series of UI interactions to time.
|
||||
*
|
||||
* The marker API provides a way for instruments and output processors to hook into
|
||||
* per-action timings by parsing logcat logs produced per workload iteration.
|
||||
*
|
||||
* The marker output consists of a logcat tag 'UX_PERF' and a message. The
|
||||
* message consists of a name for the action and a timestamp. The timestamp
|
||||
* is separated by a single space from the name of the action.
|
||||
*
|
||||
* Typical usage:
|
||||
*
|
||||
* ActionLogger logger = ActionLogger("testTag", parameters);
|
||||
* logger.start();
|
||||
* // actions to be recorded
|
||||
* logger.stop();
|
||||
*/
|
||||
public class ActionLogger {
|
||||
|
||||
private String testTag;
|
||||
private boolean enabled;
|
||||
|
||||
public ActionLogger(String testTag, Bundle parameters) {
|
||||
this.testTag = testTag;
|
||||
this.enabled = parameters.getBoolean("markers_enabled");
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (enabled) {
|
||||
Log.d("UX_PERF", testTag + " start " + System.nanoTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() throws Exception {
|
||||
if (enabled) {
|
||||
Log.d("UX_PERF", testTag + " end " + System.nanoTime());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/* Copyright 2013-2017 ARM Limited
|
||||
*
|
||||
* 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.arm.wa.uiauto;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.test.uiautomator.UiObject;
|
||||
|
||||
/**
|
||||
* ApplaunchInterface.java
|
||||
* Interface used for enabling uxperfapplaunch workload.
|
||||
* This interface gets implemented by all workloads that support application launch
|
||||
* instrumentation.
|
||||
*/
|
||||
|
||||
public interface ApplaunchInterface {
|
||||
|
||||
/**
|
||||
* Sets the launchEndObject of a workload, which is a UiObject that marks
|
||||
* the end of the application launch.
|
||||
*/
|
||||
public UiObject getLaunchEndObject();
|
||||
|
||||
/**
|
||||
* Runs the Uiautomation methods for clearing the initial run
|
||||
* dialogues on the first time installation of an application package.
|
||||
*/
|
||||
public void runApplicationSetup() throws Exception;
|
||||
|
||||
/**
|
||||
* Provides the application launch command of the application which is
|
||||
* constructed as a string from the workload.
|
||||
*/
|
||||
public String getLaunchCommand();
|
||||
|
||||
/** Passes the workload parameters. */
|
||||
public void setWorkloadParameters(Bundle parameters);
|
||||
|
||||
/** Initialize the instrumentation for the workload */
|
||||
public void initialize_instrumentation();
|
||||
|
||||
}
|
@ -0,0 +1,725 @@
|
||||
/* Copyright 2013-2018 ARM Limited
|
||||
*
|
||||
* 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.arm.wa.uiauto;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObject;
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
import androidx.test.uiautomator.UiWatcher;
|
||||
import androidx.test.uiautomator.UiScrollable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getArguments;
|
||||
|
||||
public class BaseUiAutomation {
|
||||
|
||||
public enum FindByCriteria { BY_ID, BY_TEXT, BY_DESC };
|
||||
public enum Direction { UP, DOWN, LEFT, RIGHT, NULL };
|
||||
public enum ScreenOrientation { RIGHT, NATURAL, LEFT, PORTRAIT, LANDSCAPE };
|
||||
public enum PinchType { IN, OUT, NULL };
|
||||
|
||||
// Time in milliseconds
|
||||
public long uiAutoTimeout = 4 * 1000;
|
||||
|
||||
public static final int CLICK_REPEAT_INTERVAL_MINIMUM = 5;
|
||||
public static final int CLICK_REPEAT_INTERVAL_DEFAULT = 50;
|
||||
|
||||
public Instrumentation mInstrumentation;
|
||||
public Context mContext;
|
||||
public UiDevice mDevice;
|
||||
|
||||
@Before
|
||||
public void initialize_instrumentation() {
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mDevice = UiDevice.getInstance(mInstrumentation);
|
||||
mContext = mInstrumentation.getTargetContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setup() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runWorkload() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractResults() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void teardown() throws Exception {
|
||||
}
|
||||
|
||||
public void sleep(int second) {
|
||||
SystemClock.sleep(second * 1000);
|
||||
}
|
||||
|
||||
// Generate a package ID
|
||||
public String getPackageID(Bundle parameters) {
|
||||
String packageName = parameters.getString("package_name");
|
||||
return packageName + ":id/";
|
||||
}
|
||||
|
||||
public boolean takeScreenshot(String name) {
|
||||
Bundle params = getArguments();
|
||||
String png_dir = params.getString("workdir");
|
||||
|
||||
try {
|
||||
return mDevice.takeScreenshot(new File(png_dir, name + ".png"));
|
||||
} catch (NoSuchMethodError e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void waitText(String text) throws UiObjectNotFoundException {
|
||||
waitText(text, 600);
|
||||
}
|
||||
|
||||
public void waitText(String text, int second) throws UiObjectNotFoundException {
|
||||
UiSelector selector = new UiSelector();
|
||||
UiObject text_obj = mDevice.findObject(selector.text(text)
|
||||
.className("android.widget.TextView"));
|
||||
waitObject(text_obj, second);
|
||||
}
|
||||
|
||||
public void waitObject(UiObject obj) throws UiObjectNotFoundException {
|
||||
waitObject(obj, 600);
|
||||
}
|
||||
|
||||
public void waitObject(UiObject obj, int second) throws UiObjectNotFoundException {
|
||||
if (!obj.waitForExists(second * 1000)) {
|
||||
throw new UiObjectNotFoundException("UiObject is not found: "
|
||||
+ obj.getSelector().toString());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean waitUntilNoObject(UiObject obj, int second) {
|
||||
return obj.waitUntilGone(second * 1000);
|
||||
}
|
||||
|
||||
public void clearLogcat() throws Exception {
|
||||
Runtime.getRuntime().exec("logcat -c");
|
||||
}
|
||||
|
||||
public void waitForLogcatText(String searchText, long timeout) throws Exception {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Process process = Runtime.getRuntime().exec("logcat");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
boolean found = false;
|
||||
while ((currentTime - startTime) < timeout) {
|
||||
sleep(2); // poll every two seconds
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains(searchText)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
currentTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
process.destroy();
|
||||
|
||||
if ((currentTime - startTime) >= timeout) {
|
||||
throw new TimeoutException("Timed out waiting for Logcat text \"%s\"".format(searchText));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerWatcher(String name, UiWatcher watcher) {
|
||||
mDevice.registerWatcher(name, watcher);
|
||||
}
|
||||
|
||||
public void runWatchers() {
|
||||
mDevice.runWatchers();
|
||||
}
|
||||
|
||||
public void removeWatcher(String name) {
|
||||
mDevice.removeWatcher(name);
|
||||
}
|
||||
|
||||
public void setScreenOrientation(ScreenOrientation orientation) throws Exception {
|
||||
int width = mDevice.getDisplayWidth();
|
||||
int height = mDevice.getDisplayHeight();
|
||||
switch (orientation) {
|
||||
case RIGHT:
|
||||
mDevice.setOrientationRight();
|
||||
break;
|
||||
case NATURAL:
|
||||
mDevice.setOrientationNatural();
|
||||
break;
|
||||
case LEFT:
|
||||
mDevice.setOrientationLeft();
|
||||
break;
|
||||
case LANDSCAPE:
|
||||
if (mDevice.isNaturalOrientation()){
|
||||
if (height > width){
|
||||
mDevice.setOrientationRight();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (height > width){
|
||||
mDevice.setOrientationNatural();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PORTRAIT:
|
||||
if (mDevice.isNaturalOrientation()){
|
||||
if (height < width){
|
||||
mDevice.setOrientationRight();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (height < width){
|
||||
mDevice.setOrientationNatural();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No orientation specified");
|
||||
}
|
||||
}
|
||||
|
||||
public void unsetScreenOrientation() throws Exception {
|
||||
mDevice.unfreezeRotation();
|
||||
}
|
||||
|
||||
public void uiObjectPerformLongClick(UiObject view, int steps) throws Exception {
|
||||
Rect rect = view.getBounds();
|
||||
mDevice.swipe(rect.centerX(), rect.centerY(),
|
||||
rect.centerX(), rect.centerY(), steps);
|
||||
}
|
||||
|
||||
public int getDisplayHeight() {
|
||||
return mDevice.getDisplayHeight();
|
||||
}
|
||||
|
||||
public int getDisplayWidth() {
|
||||
return mDevice.getDisplayWidth();
|
||||
}
|
||||
|
||||
public int getDisplayCentreWidth() {
|
||||
return getDisplayWidth() / 2;
|
||||
}
|
||||
|
||||
public int getDisplayCentreHeight() {
|
||||
return getDisplayHeight() / 2;
|
||||
}
|
||||
|
||||
public void tapDisplayCentre() {
|
||||
tapDisplay(getDisplayCentreWidth(), getDisplayCentreHeight());
|
||||
}
|
||||
|
||||
public void tapDisplay(int x, int y) {
|
||||
mDevice.click(x, y);
|
||||
}
|
||||
|
||||
public void pressEnter() {
|
||||
mDevice.pressEnter();
|
||||
}
|
||||
|
||||
public void pressHome() {
|
||||
mDevice.pressHome();
|
||||
}
|
||||
|
||||
public void pressBack() {
|
||||
mDevice.pressBack();
|
||||
}
|
||||
|
||||
public void uiObjectSwipe(UiObject view, Direction direction, int steps) throws Exception {
|
||||
switch (direction) {
|
||||
case UP:
|
||||
view.swipeUp(steps);
|
||||
break;
|
||||
case DOWN:
|
||||
view.swipeDown(steps);
|
||||
break;
|
||||
case LEFT:
|
||||
view.swipeLeft(steps);
|
||||
break;
|
||||
case RIGHT:
|
||||
view.swipeRight(steps);
|
||||
break;
|
||||
case NULL:
|
||||
throw new Exception("No direction specified");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void uiDeviceSwipeVertical(int startY, int endY, int xCoordinate, int steps) {
|
||||
mDevice.swipe(xCoordinate, startY, xCoordinate, endY, steps);
|
||||
}
|
||||
|
||||
public void uiDeviceSwipeHorizontal(int startX, int endX, int yCoordinate, int steps) {
|
||||
mDevice.swipe(startX, yCoordinate, endX, yCoordinate, steps);
|
||||
}
|
||||
|
||||
public void uiObjectVertPinchIn(UiObject view, int steps, int percent) throws Exception {
|
||||
final int FINGER_TOUCH_HALF_WIDTH = 20;
|
||||
|
||||
// Make value between 1 and 100
|
||||
int nPercent = (percent < 0) ? 1 : (percent > 100) ? 100 : percent;
|
||||
float percentage = nPercent / 100f;
|
||||
|
||||
Rect rect = view.getVisibleBounds();
|
||||
|
||||
if (rect.width() <= FINGER_TOUCH_HALF_WIDTH * 2) {
|
||||
throw new IllegalStateException("Object width is too small for operation");
|
||||
}
|
||||
|
||||
// Start at the top-center and bottom-center of the control
|
||||
Point startPoint1 = new Point(rect.centerX(), rect.centerY()
|
||||
+ (int) ((rect.height() / 2) * percentage));
|
||||
Point startPoint2 = new Point(rect.centerX(), rect.centerY()
|
||||
- (int) ((rect.height() / 2) * percentage));
|
||||
|
||||
// End at the same point at the center of the control
|
||||
Point endPoint1 = new Point(rect.centerX(), rect.centerY() + FINGER_TOUCH_HALF_WIDTH);
|
||||
Point endPoint2 = new Point(rect.centerX(), rect.centerY() - FINGER_TOUCH_HALF_WIDTH);
|
||||
|
||||
view.performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps);
|
||||
}
|
||||
|
||||
public void uiObjectVertPinchOut(UiObject view, int steps, int percent) throws Exception {
|
||||
final int FINGER_TOUCH_HALF_WIDTH = 20;
|
||||
|
||||
// Make value between 1 and 100
|
||||
int nPercent = (percent < 0) ? 1 : (percent > 100) ? 100 : percent;
|
||||
float percentage = nPercent / 100f;
|
||||
|
||||
Rect rect = view.getVisibleBounds();
|
||||
|
||||
if (rect.width() <= FINGER_TOUCH_HALF_WIDTH * 2) {
|
||||
throw new IllegalStateException("Object width is too small for operation");
|
||||
}
|
||||
|
||||
// Start from the same point at the center of the control
|
||||
Point startPoint1 = new Point(rect.centerX(), rect.centerY() + FINGER_TOUCH_HALF_WIDTH);
|
||||
Point startPoint2 = new Point(rect.centerX(), rect.centerY() - FINGER_TOUCH_HALF_WIDTH);
|
||||
|
||||
// End at the top-center and bottom-center of the control
|
||||
Point endPoint1 = new Point(rect.centerX(), rect.centerY()
|
||||
+ (int) ((rect.height() / 2) * percentage));
|
||||
Point endPoint2 = new Point(rect.centerX(), rect.centerY()
|
||||
- (int) ((rect.height() / 2) * percentage));
|
||||
|
||||
view.performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps);
|
||||
}
|
||||
|
||||
public void uiObjectVertPinch(UiObject view, PinchType direction,
|
||||
int steps, int percent) throws Exception {
|
||||
if (direction.equals(PinchType.IN)) {
|
||||
uiObjectVertPinchIn(view, steps, percent);
|
||||
} else if (direction.equals(PinchType.OUT)) {
|
||||
uiObjectVertPinchOut(view, steps, percent);
|
||||
}
|
||||
}
|
||||
|
||||
public void uiDeviceSwipeUp(int steps) {
|
||||
mDevice.swipe(
|
||||
getDisplayCentreWidth(),
|
||||
(getDisplayCentreHeight() + (getDisplayCentreHeight() / 2)),
|
||||
getDisplayCentreWidth(),
|
||||
(getDisplayCentreHeight() / 2),
|
||||
steps);
|
||||
}
|
||||
|
||||
public void uiDeviceSwipeDown(int steps) {
|
||||
mDevice.swipe(
|
||||
getDisplayCentreWidth(),
|
||||
(getDisplayCentreHeight() / 2),
|
||||
getDisplayCentreWidth(),
|
||||
(getDisplayCentreHeight() + (getDisplayCentreHeight() / 2)),
|
||||
steps);
|
||||
}
|
||||
|
||||
public void uiDeviceSwipeLeft(int steps) {
|
||||
mDevice.swipe(
|
||||
(getDisplayCentreWidth() + (getDisplayCentreWidth() / 2)),
|
||||
getDisplayCentreHeight(),
|
||||
(getDisplayCentreWidth() / 2),
|
||||
getDisplayCentreHeight(),
|
||||
steps);
|
||||
}
|
||||
|
||||
public void uiDeviceSwipeRight(int steps) {
|
||||
mDevice.swipe(
|
||||
(getDisplayCentreWidth() / 2),
|
||||
getDisplayCentreHeight(),
|
||||
(getDisplayCentreWidth() + (getDisplayCentreWidth() / 2)),
|
||||
getDisplayCentreHeight(),
|
||||
steps);
|
||||
}
|
||||
|
||||
public void uiDeviceSwipe(Direction direction, int steps) throws Exception {
|
||||
switch (direction) {
|
||||
case UP:
|
||||
uiDeviceSwipeUp(steps);
|
||||
break;
|
||||
case DOWN:
|
||||
uiDeviceSwipeDown(steps);
|
||||
break;
|
||||
case LEFT:
|
||||
uiDeviceSwipeLeft(steps);
|
||||
break;
|
||||
case RIGHT:
|
||||
uiDeviceSwipeRight(steps);
|
||||
break;
|
||||
case NULL:
|
||||
throw new Exception("No direction specified");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void repeatClickUiObject(UiObject view, int repeatCount, int intervalInMillis) throws Exception {
|
||||
int repeatInterval = intervalInMillis > CLICK_REPEAT_INTERVAL_MINIMUM
|
||||
? intervalInMillis : CLICK_REPEAT_INTERVAL_DEFAULT;
|
||||
if (repeatCount < 1 || !view.isClickable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < repeatCount; ++i) {
|
||||
view.click();
|
||||
SystemClock.sleep(repeatInterval); // in order to register as separate click
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public UiObject clickUiObject(FindByCriteria criteria, String matching) throws Exception {
|
||||
return clickUiObject(criteria, matching, null, false);
|
||||
}
|
||||
|
||||
public UiObject clickUiObject(FindByCriteria criteria, String matching, boolean wait) throws Exception {
|
||||
return clickUiObject(criteria, matching, null, wait);
|
||||
}
|
||||
|
||||
public UiObject clickUiObject(FindByCriteria criteria, String matching, String clazz) throws Exception {
|
||||
return clickUiObject(criteria, matching, clazz, false);
|
||||
}
|
||||
|
||||
public UiObject clickUiObject(FindByCriteria criteria, String matching, String clazz, boolean wait) throws Exception {
|
||||
UiObject view;
|
||||
|
||||
switch (criteria) {
|
||||
case BY_ID:
|
||||
view = (clazz == null)
|
||||
? getUiObjectByResourceId(matching) : getUiObjectByResourceId(matching, clazz);
|
||||
break;
|
||||
case BY_DESC:
|
||||
view = (clazz == null)
|
||||
? getUiObjectByDescription(matching) : getUiObjectByDescription(matching, clazz);
|
||||
break;
|
||||
case BY_TEXT:
|
||||
default:
|
||||
view = (clazz == null)
|
||||
? getUiObjectByText(matching) : getUiObjectByText(matching, clazz);
|
||||
break;
|
||||
}
|
||||
|
||||
if (wait) {
|
||||
view.clickAndWaitForNewWindow();
|
||||
} else {
|
||||
view.click();
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByResourceId(String resourceId, String className) throws Exception {
|
||||
return getUiObjectByResourceId(resourceId, className, uiAutoTimeout);
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByResourceId(String resourceId, String className, long timeout) throws Exception {
|
||||
UiObject object = mDevice.findObject(new UiSelector().resourceId(resourceId)
|
||||
.className(className));
|
||||
if (!object.waitForExists(timeout)) {
|
||||
throw new UiObjectNotFoundException(String.format("Could not find \"%s\" \"%s\"",
|
||||
resourceId, className));
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByResourceId(String id) throws Exception {
|
||||
UiObject object = mDevice.findObject(new UiSelector().resourceId(id));
|
||||
|
||||
if (!object.waitForExists(uiAutoTimeout)) {
|
||||
throw new UiObjectNotFoundException("Could not find view with resource ID: " + id);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByDescription(String description, String className) throws Exception {
|
||||
return getUiObjectByDescription(description, className, uiAutoTimeout);
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByDescription(String description, String className, long timeout) throws Exception {
|
||||
UiObject object = mDevice.findObject(new UiSelector().descriptionContains(description)
|
||||
.className(className));
|
||||
if (!object.waitForExists(timeout)) {
|
||||
throw new UiObjectNotFoundException(String.format("Could not find \"%s\" \"%s\"",
|
||||
description, className));
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByDescription(String desc) throws Exception {
|
||||
UiObject object = mDevice.findObject(new UiSelector().descriptionContains(desc));
|
||||
|
||||
if (!object.waitForExists(uiAutoTimeout)) {
|
||||
throw new UiObjectNotFoundException("Could not find view with description: " + desc);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByText(String text, String className) throws Exception {
|
||||
return getUiObjectByText(text, className, uiAutoTimeout);
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByText(String text, String className, long timeout) throws Exception {
|
||||
UiObject object = mDevice.findObject(new UiSelector().textContains(text)
|
||||
.className(className));
|
||||
if (!object.waitForExists(timeout)) {
|
||||
throw new UiObjectNotFoundException(String.format("Could not find \"%s\" \"%s\"",
|
||||
text, className));
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public UiObject getUiObjectByText(String text) throws Exception {
|
||||
UiObject object = mDevice.findObject(new UiSelector().textContains(text));
|
||||
|
||||
if (!object.waitForExists(uiAutoTimeout)) {
|
||||
throw new UiObjectNotFoundException("Could not find view with text: " + text);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
// Helper to select a folder in the gallery
|
||||
public void selectGalleryFolder(String directory) throws Exception {
|
||||
UiObject workdir =
|
||||
mDevice.findObject(new UiSelector().text(directory)
|
||||
.className("android.widget.TextView"));
|
||||
UiScrollable scrollView =
|
||||
new UiScrollable(new UiSelector().scrollable(true));
|
||||
|
||||
// If the folder is not present wait for a short time for
|
||||
// the media server to refresh its index.
|
||||
boolean discovered = workdir.waitForExists(TimeUnit.SECONDS.toMillis(10));
|
||||
if (!discovered && scrollView.exists()) {
|
||||
// First check if the directory is visible on the first
|
||||
// screen and if not scroll to the bottom of the screen to look for it.
|
||||
discovered = scrollView.scrollIntoView(workdir);
|
||||
|
||||
// If still not discovered scroll back to the top of the screen and
|
||||
// wait for a longer amount of time for the media server to refresh
|
||||
// its index.
|
||||
if (!discovered) {
|
||||
// scrollView.scrollToBeggining() doesn't work for this
|
||||
// particular scrollable view so use device method instead
|
||||
for (int i = 0; i < 10; i++) {
|
||||
uiDeviceSwipeUp(20);
|
||||
}
|
||||
discovered = workdir.waitForExists(TimeUnit.SECONDS.toMillis(60));
|
||||
|
||||
// Scroll to the bottom of the screen one last time
|
||||
if (!discovered) {
|
||||
discovered = scrollView.scrollIntoView(workdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (discovered) {
|
||||
workdir.clickAndWaitForNewWindow();
|
||||
} else {
|
||||
throw new UiObjectNotFoundException("Could not find folder : " + directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If an an app is not designed for running on the latest version of android
|
||||
// (currently Q) an additional screen can popup asking to confirm permissions.
|
||||
public void dismissAndroidPermissionPopup() throws Exception {
|
||||
UiObject permissionAccess =
|
||||
mDevice.findObject(new UiSelector().textMatches(
|
||||
".*Choose what to allow .* to access"));
|
||||
UiObject continueButton =
|
||||
mDevice.findObject(new UiSelector().resourceId("com.android.permissioncontroller:id/continue_button")
|
||||
.textContains("Continue"));
|
||||
if (permissionAccess.exists() && continueButton.exists()) {
|
||||
continueButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If an an app is not designed for running on the latest version of android
|
||||
// (currently Q) dissmiss the warning popup if present.
|
||||
public void dismissAndroidVersionPopup() throws Exception {
|
||||
|
||||
// Ensure we have dissmied any permission screens before looking for the version popup
|
||||
dismissAndroidPermissionPopup();
|
||||
|
||||
UiObject warningText =
|
||||
mDevice.findObject(new UiSelector().textContains(
|
||||
"This app was built for an older version of Android"));
|
||||
UiObject acceptButton =
|
||||
mDevice.findObject(new UiSelector().resourceId("android:id/button1")
|
||||
.className("android.widget.Button"));
|
||||
if (warningText.exists() && acceptButton.exists()) {
|
||||
acceptButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If Chrome is a fresh install then these popups may be presented
|
||||
// dismiss them if visible.
|
||||
public void dismissChromePopup() throws Exception {
|
||||
UiObject accept =
|
||||
mDevice.findObject(new UiSelector().resourceId("com.android.chrome:id/terms_accept")
|
||||
.className("android.widget.Button"));
|
||||
if (accept.waitForExists(3000)){
|
||||
accept.click();
|
||||
UiObject negative =
|
||||
mDevice.findObject(new UiSelector().resourceId("com.android.chrome:id/negative_button")
|
||||
.className("android.widget.Button"));
|
||||
if (negative.waitForExists(10000)) {
|
||||
negative.click();
|
||||
}
|
||||
}
|
||||
UiObject lite =
|
||||
mDevice.findObject(new UiSelector().resourceId("com.android.chrome:id/button_secondary")
|
||||
.className("android.widget.Button"));
|
||||
if (lite.exists()){
|
||||
lite.click();
|
||||
}
|
||||
}
|
||||
|
||||
// Override getParams function to decode a url encoded parameter bundle before
|
||||
// passing it to workloads.
|
||||
public Bundle getParams() {
|
||||
// Get the original parameter bundle
|
||||
Bundle parameters = getArguments();
|
||||
|
||||
// Decode each parameter in the bundle, except null values and "class", as this
|
||||
// used to control instrumentation and therefore not encoded.
|
||||
for (String key : parameters.keySet()) {
|
||||
String param = parameters.getString(key);
|
||||
if (param != null && !key.equals("class")) {
|
||||
param = android.net.Uri.decode(param);
|
||||
parameters = decode(parameters, key, param);
|
||||
}
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
// Helper function to decode a string and insert it as an appropriate type
|
||||
// into a provided bundle with its key.
|
||||
// Each bundle parameter will be a urlencoded string with 2 characters prefixed to the value
|
||||
// used to store the original type information, e.g. 'fl' -> list of floats.
|
||||
private Bundle decode(Bundle parameters, String key, String value) {
|
||||
char value_type = value.charAt(0);
|
||||
char value_dimension = value.charAt(1);
|
||||
String param = value.substring(2);
|
||||
|
||||
if (value_dimension == 's') {
|
||||
if (value_type == 's') {
|
||||
parameters.putString(key, param);
|
||||
} else if (value_type == 'f') {
|
||||
parameters.putFloat(key, Float.parseFloat(param));
|
||||
} else if (value_type == 'd') {
|
||||
parameters.putDouble(key, Double.parseDouble(param));
|
||||
} else if (value_type == 'b') {
|
||||
parameters.putBoolean(key, Boolean.parseBoolean(param));
|
||||
} else if (value_type == 'i') {
|
||||
parameters.putInt(key, Integer.parseInt(param));
|
||||
} else if (value_type == 'n') {
|
||||
parameters.putString(key, "None");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Error decoding:" + key + value
|
||||
+ " - unknown format");
|
||||
}
|
||||
} else if (value_dimension == 'l') {
|
||||
return decodeArray(parameters, key, value_type, param);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Error decoding:" + key + value
|
||||
+ " - unknown format");
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
// Helper function to deal with decoding arrays and update the bundle with
|
||||
// an appropriate array type. The string "0newelement0" is used to distinguish
|
||||
// each element from each other in the array when encoded.
|
||||
private Bundle decodeArray(Bundle parameters, String key, char type, String value) {
|
||||
String[] string_list = value.split("0newelement0");
|
||||
if (type == 's') {
|
||||
parameters.putStringArray(key, string_list);
|
||||
}
|
||||
else if (type == 'i') {
|
||||
int[] int_list = new int[string_list.length];
|
||||
for (int i = 0; i < string_list.length; i++){
|
||||
int_list[i] = Integer.parseInt(string_list[i]);
|
||||
}
|
||||
parameters.putIntArray(key, int_list);
|
||||
} else if (type == 'f') {
|
||||
float[] float_list = new float[string_list.length];
|
||||
for (int i = 0; i < string_list.length; i++){
|
||||
float_list[i] = Float.parseFloat(string_list[i]);
|
||||
}
|
||||
parameters.putFloatArray(key, float_list);
|
||||
} else if (type == 'd') {
|
||||
double[] double_list = new double[string_list.length];
|
||||
for (int i = 0; i < string_list.length; i++){
|
||||
double_list[i] = Double.parseDouble(string_list[i]);
|
||||
}
|
||||
parameters.putDoubleArray(key, double_list);
|
||||
} else if (type == 'b') {
|
||||
boolean[] boolean_list = new boolean[string_list.length];
|
||||
for (int i = 0; i < string_list.length; i++){
|
||||
boolean_list[i] = Boolean.parseBoolean(string_list[i]);
|
||||
}
|
||||
parameters.putBooleanArray(key, boolean_list);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Error decoding array: " +
|
||||
value + " - unknown format");
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* Copyright 2013-2017 ARM Limited
|
||||
*
|
||||
* 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.arm.wa.uiauto;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
public final class UiAutoUtils {
|
||||
|
||||
/** Construct launch command of an application. */
|
||||
public static String createLaunchCommand(Bundle parameters) {
|
||||
String launchCommand;
|
||||
String activityName = parameters.getString("launch_activity");
|
||||
String packageName = parameters.getString("package_name");
|
||||
if (activityName.equals("None")) {
|
||||
launchCommand = String.format("am start --user -3 %s", packageName);
|
||||
}
|
||||
else {
|
||||
launchCommand = String.format("am start --user -3 -n %s/%s", packageName, activityName);
|
||||
}
|
||||
return launchCommand;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/* Copyright 2013-2017 ARM Limited
|
||||
*
|
||||
* 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.arm.wa.uiauto;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.arm.wa.uiauto.BaseUiAutomation.Direction;
|
||||
import com.arm.wa.uiauto.BaseUiAutomation.PinchType;
|
||||
|
||||
|
||||
public class UxPerfUiAutomation {
|
||||
|
||||
private Logger logger = Logger.getLogger(UxPerfUiAutomation.class.getName());
|
||||
|
||||
public enum GestureType { UIDEVICE_SWIPE, UIOBJECT_SWIPE, PINCH };
|
||||
|
||||
public static class GestureTestParams {
|
||||
public GestureType gestureType;
|
||||
public Direction gestureDirection;
|
||||
public PinchType pinchType;
|
||||
public int percent;
|
||||
public int steps;
|
||||
|
||||
public GestureTestParams(GestureType gesture, Direction direction, int steps) {
|
||||
this.gestureType = gesture;
|
||||
this.gestureDirection = direction;
|
||||
this.pinchType = PinchType.NULL;
|
||||
this.steps = steps;
|
||||
this.percent = 0;
|
||||
}
|
||||
|
||||
public GestureTestParams(GestureType gesture, PinchType pinchType, int steps, int percent) {
|
||||
this.gestureType = gesture;
|
||||
this.gestureDirection = Direction.NULL;
|
||||
this.pinchType = pinchType;
|
||||
this.steps = steps;
|
||||
this.percent = percent;
|
||||
}
|
||||
}
|
||||
}
|
25
wa/framework/uiauto-androidx/build.gradle
Normal file
25
wa/framework/uiauto-androidx/build.gradle
Normal file
@ -0,0 +1,25 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.5.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
32
wa/framework/uiauto-androidx/build.sh
Executable file
32
wa/framework/uiauto-androidx/build.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2013-2017 ARM Limited
|
||||
#
|
||||
# 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 -e
|
||||
|
||||
# Ensure gradelw exists before starting
|
||||
if [[ ! -f gradlew ]]; then
|
||||
echo 'gradlew file not found! Check that you are in the right directory.'
|
||||
exit 9
|
||||
fi
|
||||
|
||||
# Build and return appropriate exit code if failed
|
||||
./gradlew clean :app:assembleDebug
|
||||
exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo "ERROR: 'gradle build' exited with code $exit_code"
|
||||
exit $exit_code
|
||||
fi
|
||||
|
||||
cp app/build/outputs/aar/app-debug.aar ./uiauto.aar
|
1
wa/framework/uiauto-androidx/gradle.properties
Normal file
1
wa/framework/uiauto-androidx/gradle.properties
Normal file
@ -0,0 +1 @@
|
||||
android.useAndroidX=true
|
BIN
wa/framework/uiauto-androidx/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
wa/framework/uiauto-androidx/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
wa/framework/uiauto-androidx/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
wa/framework/uiauto-androidx/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Wed May 03 15:42:44 BST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
|
160
wa/framework/uiauto-androidx/gradlew
vendored
Executable file
160
wa/framework/uiauto-androidx/gradlew
vendored
Executable file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
wa/framework/uiauto-androidx/gradlew.bat
vendored
Normal file
90
wa/framework/uiauto-androidx/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
1
wa/framework/uiauto-androidx/settings.gradle
Normal file
1
wa/framework/uiauto-androidx/settings.gradle
Normal file
@ -0,0 +1 @@
|
||||
include ':app'
|
BIN
wa/framework/uiauto-androidx/uiauto.aar
Normal file
BIN
wa/framework/uiauto-androidx/uiauto.aar
Normal file
Binary file not shown.
@ -2,7 +2,8 @@ apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion '28.0.3'
|
||||
// buildToolsVersion is no longer used/accepted.
|
||||
// buildToolsVersion '28.0.3'
|
||||
defaultConfig {
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 28
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||
@ -16,8 +16,8 @@ buildscript {
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user