com.tascape.qa.th.android.driver.AdbDevice Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2015 - 2016 Nebula Bay.
*
* 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.tascape.qa.th.android.driver;
import com.android.uiautomator.stub.IUiDevice;
import com.google.common.collect.Lists;
import com.tascape.qa.th.driver.EntityDriver;
import com.tascape.qa.th.android.comm.Adb;
import com.tascape.qa.th.exception.EntityDriverException;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author linsong wang
*/
class AdbDevice extends EntityDriver {
private static final Logger LOG = LoggerFactory.getLogger(AdbDevice.class);
private Adb adb;
private String version;
public void setAdb(Adb adb) throws IOException {
this.adb = adb;
}
public Adb getAdb() {
return adb;
}
@Override
public String getName() {
try {
return getPropValue("ro.product.brand") + "-" + getPropValue("ro.product.model");
} catch (IOException ex) {
LOG.warn(ex.getMessage());
return "na";
}
}
@Override
public String getVersion() {
if (StringUtils.isBlank(version)) {
try {
return getPropValue("ro.build.version.release") + "-" + getPropValue("ro.build.version.sdk ");
} catch (IOException ex) {
LOG.warn(ex.getMessage());
version = "";
}
}
return version;
}
public List getProp() throws IOException {
List props = this.adb.shell(Lists.newArrayList("getprop"));
props.forEach(p -> LOG.debug(p));
return props;
}
public boolean grantPermission(String packageName, String permission) throws IOException {
List res = this.adb.shell(Lists.newArrayList("pm", packageName, permission));
LOG.debug("{}", res);
return res.stream().filter(l -> l.contains("Success")).findAny().isPresent();
}
public boolean uninstall(String packageName) throws IOException {
List res = this.adb.adb(Lists.newArrayList("uninstall", packageName));
LOG.debug("{}", res);
return res.stream().filter(l -> l.contains("Success")).findAny().isPresent();
}
public String getAppVersion(String packageName) throws IOException, EntityDriverException {
List res = this.adb.shell(Lists.newArrayList("dumpsys", "package", packageName));
res.forEach(l -> LOG.debug(l));
String versionName = "";
String versionCode = "";
for (int i = 0, j = res.size(); i < j; i++) {
String line = res.get(i);
if (line.contains("versionName")) {
versionName = line.trim().split("=")[1];
} else if (line.contains("versionCode")) {
versionCode = line.trim().split(" ")[0].split("=")[1];
}
if (!versionName.isEmpty() && !versionCode.isEmpty()) {
break;
}
}
if (versionName.isEmpty() || versionCode.isEmpty()) {
throw new EntityDriverException("Cannot find app version");
}
return versionName + "-" + versionCode;
}
public String getSystemLanguage() throws IOException {
List res = this.getProp("persist.sys.language");
res.addAll(this.getProp("ro.product.locale.language"));
return res.stream().filter(s -> StringUtils.isNotBlank(s)).findFirst().get();
}
public List getProp(String name) throws IOException {
List res = this.adb.shell(Lists.newArrayList("getprop", name));
LOG.debug("{}", res);
return res;
}
public String getPropValue(String name) throws IOException {
List res = this.getProp(name);
return res.stream().filter(s -> !(s.startsWith("*") && s.endsWith("*"))).findFirst().get();
}
/**
* Gets event output lines.
*
* @param device such as /dev/input/event0
*
* @return output event log lines
*
* @throws IOException in case of IO issue
*/
public List logTouchEvents(String device) throws IOException {
return this.adb.shell(Arrays.asList(new Object[]{"getevent", "-lt", device}));
}
public String recordScreen(int seconds, int bitRate) throws IOException {
String mp4 = "sr-" + UUID.randomUUID() + ".mp4";
this.adb.shellAsync(Arrays.asList(new Object[]{"screenrecord", "--time-limit", seconds, IUiDevice.TMP_DIR + mp4,
"--bit-rate", bitRate}), seconds * 1000L);
return mp4;
}
public File getScreenRecord(String name) throws IOException {
File mp4 = this.getLogPath().resolve(name).toFile();
// todo
this.getAdb().pull(IUiDevice.TMP_DIR + name, mp4);
return mp4;
}
/**
* Dumps window hierarchy into xml file. This does not work when 'uiautomator' process is running on device.
*
* @return the hierarchy xml file
*
* @throws IOException any error
*/
public File dumpWindowHierarchy() throws IOException {
String f = "/data/local/tmp/uidump.xml";
adb.shell(Lists.newArrayList("rm", f)).forEach(l -> LOG.debug(l));
adb.shell(Lists.newArrayList("uiautomator", "dump", f)).forEach(l -> LOG.debug(l));
File xml = this.getLogPath().resolve("ui-" + System.currentTimeMillis() + ".xml").toFile();
this.adb.pull(f, xml);
LOG.debug("Save WindowHierarchy into {}", xml.getAbsolutePath());
return xml;
}
/**
* The input macro can emulate all sort of events, as described in its documentation.
*
* Usage: input [source] command [arg...]
*
* The sources are:
* trackball
* joystick
* touchnavigation
* mouse
* keyboard
* gamepad
* touchpad
* dpad
* stylus
* touchscreen
*
* The commands and default sources are:
* text 'string' (Default: touchscreen) [delay]
* keyevent [--longpress] 'key code number or name' ... (Default: keyboard)
* tap x y (Default: touchscreen)
* swipe x1 y1 x2 y2 [duration(ms)] (Default: touchscreen)
* press (Default: trackball)
* roll dx dy (Default: trackball)
*
*
* @param arguments arguments
*
* @return adb stdout
*
* @throws IOException in case of any issue
*/
public List input(final List