Code Monkey home page Code Monkey logo

atx-agent's Introduction

atx-agent

Build Status

这个项目的主要目的是为了屏蔽不同安卓机器的差异,然后开放出统一的HTTP接口供 openatx/uiautomator2使用。项目最终会发布成一个二进制程序,运行在Android系统的后台。

这个项目是如何屏蔽不同机器的差异的呢?举个例子来说,截图这个操作,大概需要3次判断才行。

  1. 先判断minicap是否安装可用,然后minicap截图。毕竟minicap截图速度最快
  2. 使用uiautomator2提供的接口截图。(模拟器除外)
  3. 使用screencap截图,然后根据屏幕的旋转调整旋转方向。(一般只有模拟器用这种方式截图)

正是Android手机不同的表现形式,才导致了需要这么多的判断。而atx-agent就是为了将这些操作帮你处理了。然后提供统一的HTTP接口(GET /screenshot)供你使用。

Develop

这个项目是用Go语言写成的。编译的时候的需要你有一点Go语言的基础。 更多内容查看 DEVELOP.md

Installation

https://github.com/openatx/atx-agent/releases下载以linux_armv7.tar.gz结尾的二进制包。绝大部分手机都是linux-arm架构的。

解压出atx-agent文件,然后打开控制台

$ adb push atx-agent /data/local/tmp
$ adb shell chmod 755 /data/local/tmp/atx-agent
# launch atx-agent in daemon mode
$ adb shell /data/local/tmp/atx-agent server -d

# stop already running atx-agent and start daemon
$ adb shell /data/local/tmp/atx-agent server -d --stop

默认监听的端口是7912。

常用接口

假设手机的地址是$DEVICE_URL (eg: http://10.0.0.1:7912)

获取手机截图

# jpeg format image
$ curl $DEVICE_URL/screenshot

# 使用内置的uiautomator截图
$ curl "$DEVICE_URL/screenshot/0?minicap=false"

获取当前程序版本

$ curl $DEVICE_URL/version
# expect example: 0.0.2

获取设备信息

$ curl $DEVICE_URL/info
{
    "udid": "bf755cab-ff:ff:ff:ff:ff:ff-SM901",
    "serial": "bf755cab",
    "brand": "SMARTISAN",
    "model": "SM901",
    "hwaddr": "ff:ff:ff:ff:ff:ff",
    "agentVersion": "dev"
}

获取Hierarchy

这个接口目前比较高级,当跟uiautomator通信失败的时候,它会在后台启动uiautomator这个服务,等它恢复正常了,在返回数据。

$ curl $DEVICE_URL/dump/hierarchy
{
    "jsonrpc":"2.0",
    "id":1559113464,
    "result": "<?xml version='1.0> ... hierarchy ..."
}

# 停止掉uiautomator
$ curl -X DELETE $DEVICE_URL/uiautomator
Success

# 再次调用, 依然OK,只是可能要等个7~8s
$ curl $DEVICE_URL/dump/hierarchy
{
    "jsonrpc": "2.0",
    ...
}

安装应用

$ curl -X POST -d url="http://some-host/some.apk" $DEVICE_URL/install
# expect install id
2
# get install progress
$ curl -X GET $DEVICE_URL/install/1
{
    "id": "2",
    "titalSize": 770571,
    "copiedSize": 770571,
    "message": "success installed"
}

Shell命令

$ curl -X POST -d command="pwd" $DEVICE_URL/shell
{
    "output": "/",
    "error": null
}

后台Shell命令(可以在后台持续运行,不会被杀掉)

$ curl -X POST -d command="pwd" $DEVICE_URL/shell/background
{
    "success": true,
}

Webview相关

$ curl -X GET $DEVICE_URL/webviews
[
    "webview_devtools_remote_m6x_21074",
    "webview_devtools_remote_m6x_27681",
    "chrome_devtools_remote"
]

App信息获取

# 获取所有运行的应用
$ curl $DEVICE_URL/proc/list
[
    {
        "cmdline": ["/system/bin/adbd", "--root_seclabel=u:r:su:s0"],
        "name": "adbd",
        "pid": 16177
    },
    {
        "cmdline": ["com.netease.cloudmusic"],
        "name": "com.netease.cloudmusic",
        "pid": 15532
    }
]

# 获取应用的内存信息(数据仅供参考),单位KB,total代表应用的PSS
$ curl $DEVICE_URL/proc/com.netease.cloudmusic/meminfo
{
    "code": 17236,
    "graphics": 20740,
    "java heap": 22288,
    "native heap": 20576,
    "private other": 10632,
    "stack": 48,
    "system": 110925,
    "total": 202445,
    "total swap pss": 88534
}

# 获取应用以及其所有子进程的内存数据
$ curl $DEVICE_URL/proc/com.netease.cloudmusic/meminfo/all
{
    "com.netease.cloudmusic": {
        "code": 15952,
        "graphics": 19328,
        "java heap": 45488,
        "native heap": 20840,
        "private other": 4056,
        "stack": 956,
        "system": 18652,
        "total": 125272
    },
    "com.netease.cloudmusic:browser": {
        "code": 848,
        "graphics": 12,
        "java heap": 6580,
        "native heap": 5428,
        "private other": 1592,
        "stack": 336,
        "system": 10603,
        "total": 25399
    }
}

获取CPU信息

如果进程是多线程运行的话,且机器是多核的,返回的CPU Percent可能会大于100%

curl $DEVICE_URL/proc/<package or pid>/cpuinfo
# success return
{
    "pid": 1122,
    "user": 288138,
    "system": 73457,
    "percent": 50.0,
    "systemPercent": 88.372,
    "coreCount": 4,
}
# failure return
410 Gone, Or 500 Internal error

下载文件

$ curl $DEVICE_URL/raw/sdcard/tmp.txt

上传文件

# 上传到/sdcard目录下 (url以/结尾)
$ curl -F "[email protected]" $DEVICE_URL/upload/sdcard/

# 上传到/sdcard/tmp.txt
$ curl -F "[email protected]" $DEVICE_URL/upload/sdcard/tmp.txt

上传目录(url必须以/结尾)

$ curl -F [email protected] -F dir=true $DEVICE_URL/upload/sdcard/

获取文件和目录信息

# 文件
$ curl -X GET $DEVICE_URL/finfo/data/local/tmp/tmp.txt
{
	"name": "tmp.txt",
	"path": "/data/local/tmp/tmp.txt",
	"isDirectory": false,
	"size": 15232,
}

# 目录
$ curl -X GET $DEVICE_URL/finfo/data/local/tmp
{
	"name": "tmp",
	"path": "/data/local/tmp",
	"isDirectory": true,
	"size": 8192,
	"files": [
		{
			"name": "tmp.txt", 
			"path": "/data/local/tmp/tmp.txt"
			"isDirectory": false,
		}
	]
}

相当于将some.zip上传到手机,然后执行unzip some.zip -d /sdcard, 最后将some.zip删除

离线下载

# 离线下载,返回ID
$ curl -F url=https://.... -F filepath=/sdcard/some.txt -F mode=0644 $DEVICE_URL/download
1
# 通过返回的ID查看下载状态
$ curl $DEVICE_URL/download/1
{
    "message": "downloading",
    "progress": {
        "totalSize": 15000,
        "copiedSize": 10000
    }
}

uiautomator起停

# 启动
$ curl -X POST $DEVICE_URL/uiautomator
Success

# 停止
$ curl -X DELETE $DEVICE_URL/uiautomator
Success

# 再次停止
$ curl -X DELETE $DEVICE_URL/uiautomator
Already stopped

# 获取uiautomator状态
$ curl $DEVICE/uiautomator
{
    "running": true
}

启动应用

# timeout 代表 am start -n 的超时时间
# flags 默认为 -S -W
$ http POST $DEVICE_URL/session/{com.cleanmaster.mguard_cn} timeout==10s flags=="-S"
{
    "mainActivity": "com.keniu.security.main.MainActivity",
    "output": "Stopping: com.cleanmaster.mguard_cn\nStarting: Intent { cmp=com.cleanmaster.mguard_cn/com.keniu.security.main.MainActivity }\n",
    "success": true
}

获取包信息

$ http GET $DEVICE_URL/packages/{packageName}/info
{
    "success": true,
    "data": {
        "mainActivity": "com.github.uiautomator.MainActivity",
        "label": "ATX",
        "versionName": "1.1.7",
        "versionCode": 1001007,
        "size":1760809
    }
}

其中size单位为字节

获取包的图标

$ curl -XGET $DEVICE_URL/packages/{packageName}/icon
# 返回包的图标文件
# 失败的情况 status code != 200

获取所有包的信息

该接口速度有点慢,大约需要3s。

原理是通过pm list packages -3 -f获取包的信息,然后在用androidbinary库对包进行解析

$ http GET $DEVICE_URL/packages
[
    {
        "packageName": "com.github.uiautomator",
        "mainActivity": "com.github.uiautomator.MainActivity",
        "label": "ATX",
        "versionName": "1.1.7-2-361182f-dirty",
        "versionCode": 1001007,
        "size": 1639366
    },
    {
        "packageName": "com.smartisanos.payment",
        "mainActivity": "",
        "label": "",
        "versionName": "1.1",
        "versionCode": 1,
        "size": 3910826
    },
    ...
]

调整uiautomator自动停止时间 (默认3分钟)

$ curl -X POST 10.0.0.1:7912/newCommandTimeout --data 300
{
    "success": true,
    "description":"newCommandTimeout updated to 5m0s"
}

程序自升级(暂时不能用了)

升级程序从gihub releases里面直接下载,升级完后自动重启

升级到最新版

$ curl 10.0.0.1:7912/upgrade

指定升级的版本

$ curl "10.0.0.1:7912/upgrade?version=0.0.2"

修复minicap, minitouch程序

# Fix minicap 
$ curl -XPUT 10.0.0.1:7912/minicap

# Fix minitouch
$ curl -XPUT 10.0.0.1:7912/minitouch

视频录制(不推荐用)

开始录制

$ curl -X POST 10.0.0.1:7912/screenrecord

停止录制并获取录制结果

$ curl -X PUT 10.0.0.1:7912/screenrecord
{
    "videos": [
        "/sdcard/screenrecords/0.mp4",
        "/sdcard/screenrecords/1.mp4"
    ]
}

之后再下载到本地

$ curl -X GET 10.0.0.1:7912/raw/sdcard/screenrecords/0.mp4

Minitouch操作方法

感谢 openstf/minitouch

Websocket连接 $DEVICE_URL/minitouch, 一行行的按照JSON的格式写入

注: 坐标原点始终是手机正放时候的左上角,使用者需要自己处理旋转的变化

请先详细阅读minitouch的Usage文档,再来看下面的部分

  • Touch Down

    坐标(X: 50%, Y: 50%), index代表第几个手指, pressure是可选的。

    {"operation": "d", "index": 0, "xP": 0.5, "yP": 0.5, "pressure": 50}
  • Touch Commit

    {"operation": "c"}
  • Touch Move

    {"operation": "m", "index": 0, "xP": 0.5, "yP": 0.5, "pressure": 50}
  • Touch Up

    {"operation": "u", "index": 0}
  • 点击x:20%, y:20,滑动到x:40%, y:50%

    {"operation": "d", "index": 0, "xP": 0.20, "yP": 0.20, "pressure": 50}
    {"operation": "c"}
    {"operation": "m", "index": 0, "xP": 0.40, "yP": 0.50, "pressure": 50}
    {"operation": "c"}
    {"operation": "u", "index": 0}
    {"operation": "c"}

TODO

  1. 目前安全性还是个问题,以后再想办法改善
  2. 补全接口文档
  3. 内置的网页adb shell的安全问题

Logs

log path /sdcard/atx-agent.log

TODO

LICENSE

MIT

atx-agent's People

Contributors

codeskyblue avatar mastrolube avatar mrx1203 avatar testwill avatar zhangminvip avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

atx-agent's Issues

经常出现500,502的问题,在执行截图时

查看日志如下
2018/05/30 11:53:51 main.go:1292: Ignore SIGHUP
2018/05/30 11:53:51 main.go:1296: Kill server
2018/05/30 11:53:51 main.go:1302: Get http://127.0.0.1:7912/stop: dial tcp 127.0.0.1:7912: connect: connection refused
atx-agent version 0.3.0
Listen on http://10.70.111.53:7912
2018/05/30 11:53:52 cmdctrl.go:27: DEBUG start args: [am instrument -w -r -e debug false -e class com.github.uiautomator.stub.Stub com.github.uiautomator.test/android.support.test.runner.AndroidJUnitRunner], env: []
2018/05/30 11:53:52 cmdctrl.go:27: DEBUG program pid: 27574
INSTRUMENTATION_STATUS: numtests=1
INSTRUMENTATION_STATUS: stream=
com.github.uiautomator.stub.Stub:
INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
INSTRUMENTATION_STATUS: test=testUIAutomatorStub
INSTRUMENTATION_STATUS: class=com.github.uiautomator.stub.Stub
INSTRUMENTATION_STATUS: current=1
INSTRUMENTATION_STATUS_CODE: 1
2018/05/30 11:56:20 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:56:28 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:56:34 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:56:40 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:56:45 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:56:46 main.go:1203: screenshot[minicap] error: exit status 127
2018/05/30 11:56:51 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:57:01 main.go:1203: screenshot[minicap] error: exit status 127
2018/05/30 11:57:06 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout
2018/05/30 11:57:18 reverseproxy.go:321: http: proxy error: dial tcp 127.0.0.1:9008: i/o timeout

获取agent info有点小问题,不知道我的修改是否存在问题。

http://{AgentIP}:7912/info
访问这个接口时battery信息并未每次更新。查看了getDeviceInfo()方法,获取过了一次后,以后就不再更新了,除非重启agent才会重新获取。
调整了battery 代码顺序如下:
image

同时health的值没有正确显示,一直显示为0。在Battery.go下面的update()方法里加上了health的case后就显示正常了。
不知道这么修改有没有问题,请帮我看看。
谢谢

HOME和MENU键点击响应太慢,需要900多ms

image
如题,atx-agent.log上看只需要39ms
image

atx2-android-provider上是看着是tcpproxy.js代理tcp转发的;技术不精,现在不知道从哪入手 看为咋慢了;
为咋atx我卸了,atx-agent装上去的还是0.5.5

限制帧率 参考代码

Experiment
	ticker := time.NewTicker(time.Millisecond * 200) // 20fps
	defer ticker.Stop()
	var jpgData []byte
SEND_LOOP:
	for {
		select {
		case <-ticker.C:
			if jpgData != nil { // jpeg data
				if err := wsWrite(websocket.BinaryMessage, jpgData); err != nil {
					break SEND_LOOP
				}
				jpgData = nil
			}
		case data := <-dataC:
			if string(data[:2]) == "\xff\xd8" {
				jpgData = data
			} else {
				if err := wsWrite(websocket.TextMessage, data); err != nil {
					break SEND_LOOP
				}
			}
		}
	}

too many open files报错

atx-agent.log

018/10/30 04:58:14 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:15 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:16 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:17 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:18 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:19 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:20 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:21 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:22 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:23 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:24 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s
2018/10/30 04:58:25 http: Accept error: accept tcp [::]:7912: accept4: too many open files; retrying in 1s

README.md错别字

运行Android手机上的http服务器,旨在希望通过Wifi控制手机,完成手机的自动化功能。

修复minicap接口命令执行报错 dns.go优化建议

在某些内部局域网WiFi网络环境下,手机获取的DNS有三个,DNS1为ipv6本地地址,但是现阶段公网IPv6没有普及,导致下载minicap、minitouch时DNS报错:

Get https://github.com/codeskyblue/stf-binaries/raw/master/node_modules/minicap-prebuilt/prebuilt/arm64-v8a/bin/minicap: dial tcp: lookup github.com on [::1]:53: dial udp: address fe80::5e63:bfff:fed0:77ff:53: too many colons in address

手机DNS如下(爱快软路由+UBNT UAP-AC-LITE):

shell@A59:/ $ getprop | grep net.dns
[net.dns1]: [fe80::5e63:bfff:fed0:77ff]
[net.dns2]: [211.140.13.188]
[net.dns3]: [211.140.188.188]
shell@A59:/ $
shell@A59:/ $

因为不是每个测试人员都可以去维护修改公司网络,是否可以优化dns.go的这个逻辑(现有通过getprop获得net.dns1,dns1不为空情况下,使用手机的dns1。没学过go语言:(,不知理解是否有误。):

func (c *dnsSmartClient) Dial(ctx context.Context, network, address string) (conn net.Conn, err error) {
	dns1 := getProperty("net.dns1")
	if dns1 == "" {
		// 国内DNS列表: https://www.zhihu.com/question/32229915
		dns1 = "114.114.114.114"
	}
	log.Println("dns resolve", dns1)
	return c.dialer.DialContext(ctx, "udp", dns1+":53")
}

建议加个正则(或地址有冒号)判断dns1是否为ipv6,是的话,使用114DNS或者当net.dns1位IPV6地址时增加net.dns2的判断。

临时解决方案:
1、通过移动数据安装minicap(需手机adb shell支持curl);
2、或找个手机发移动热点,手机和电脑连接同一个数据热点,执行curl命令安装minicap。

长时间运行后,agent无法访问,使用shell命令无法激活

vivo Z3 Android 8.1.0
agent 使用的自己编译的版本

手机长时间放置后,出现 agent 无法访问的情况,重新使用 shell 命令启动输出正常,但也无法访问;log 中存在大量 runtime_pollWait,查看 agent 进程信息如下

USER           PID  PPID     VSZ    RSS WCHAN            ADDR S NAME
shell        20618     1  805524   6704 futex_wait_queue_me 0 S atx-agent

完整 log:atx-agent.log

start atx-agent failed with msg “Unable to find instrumentation info for: ComponentInfo{com.github.uiautomator.test/android.support.test.runner.AndroidJUnitRunner}

when starting agent in xiaomi 3, got the error msg "Unable to find instrumentation info for: ComponentInfo{com.github.uiautomator.test/android.support.test.runner.AndroidJUnitRunner}

here is the whole msg log:
shell@pisces:/ $ cat /storage/sdcard0/atx-agent.log
2017/10/18 10:34:17 main.go:541: Ignore SIGUP
2017/10/18 10:34:17 main.go:545: Kill server
2017/10/18 10:34:17 main.go:551: Get http://127.0.0.1:7912/stop: dial tcp 127.0.0.1:7912: getsockopt: connection refused
IP: 172.18.31.22
INSTRUMENTATION_STATUS: id=ActivityManagerService
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.github.uiautomator.test/android.support.test.runner.AndroidJUnitRunner}
INSTRUMENTATION_STATUS_CODE: -1
android.util.AndroidException: INSTRUMENTATION_FAILED: com.github.uiautomator.test/android.support.test.runner.AndroidJUnitRunner
at com.android.commands.am.Am.runInstrument(Am.java:865)
at com.android.commands.am.Am.onRun(Am.java:282)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
at com.android.commands.am.Am.main(Am.java:76)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:247)
at dalvik.system.NativeStart.main(Native Method)
2017/10/18 10:34:18 main.go:188: uiautomator quit: exit status 1

I used agent with version "https://github.com/openatx/atx-agent/releases/download/0.0.5/atx-agent_0.0.5_linux_armv7.tar.gz"

my xiaomi version is MIUI 9.7.10.12 with android version 4.4.4(4.1+)

cpuinfo:
shell@pisces:/ $ cat /proc/cpuinfo
Processor : ARMv7 Processor rev 2 (v7l)
processor : 0
BogoMIPS : 1176.57

processor : 1
BogoMIPS : 1176.57

processor : 2
BogoMIPS : 1176.57

processor : 3
BogoMIPS : 1176.57

Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x2
CPU part : 0xc0f
CPU revision : 2

Hardware : pisces
Revision : 0000
Serial : 062c006403430200

重启手机后,连接不上atx-server

首先很感谢大佬把手机换ip的问题用heartbeat修复了。但是发现手机重启后,仍然需要init一次。所以想uiautomator.apk上是否可以新增一个重新连接atx-server的按钮呢。
我试了启动atx-agent命令,可以启动atx-agent,但是不能重新再连接上atx-server了:adb shell /data/local/tmp/atx-agent -d,是否我还需要执行其他命令才能重新连接上。
1
2

只要手机的ip变了,就必须要init一次,特别麻烦

agent有没有机制,可以让手机的ip变了就直接重新获取ip,然后发送给server。看了只要ip变了,手机后台监听就从一个ip直接变成0.0.0.0了。
不然的话手机ip变一次也要init,重启也要init,真的感觉很麻烦

github.com/qiniu/log库找不到,无法编译

按照安装文档步骤执行,报如下错误
$ git clone https://github.com/openatx/atx-agent
$ cd atx-agent
$ export GO111MODULE=on
$ go generate
go: finding github.com/qiniu/log v0.0.0-20140728010919-a304a74568d6
go: github.com/qiniu/[email protected]: git fetch -f https://github.com/qiniu/log refs/heads/:refs/heads/ refs/tags/:refs/tags/ in D:\mygo\pkg\mod\cache\vcs\0fdd75578a3b407f676ed893d01f93d14d2c857ed66a82a1deffa8f5b4014197: exit status 128:
remote: Repository not found.
fatal: repository 'https://github.com/qiniu/log/' not found
go: error loading module requirements

Unable to operate Mi-4c phone

For Mi-4c(Android 7.0), after successfully connected to atx-server, tap on use, a new tab opens and perform some operations like swipe and click, nothing happens.

Here is log from atx-agent(version 0.3.2):

2018/05/31 07:58:18 tunnelproxy.go:159: res err -------------------
<nil> Post http://10.2.200.84:8000/devices/69512948-20:82:c0:65:09:28-Mi-4c/info: EOF
2018/05/31 07:58:29 main.go:953: minitouch connection: 10.2.200.84:55765
2018/05/31 07:58:29 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG start args: [/data/local/tmp/minitouch], env: []
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG program pid: 1770
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG cmd wait err: exit status 1
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG idle for 500ms
2018/05/31 07:58:29 main.go:1033: minicap connection: 10.2.200.84:55766
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG start args: [/data/local/tmp/minicap -S -P 1080x1920@800x800/0], env: [LD_LIBRARY_PATH=/data/local/tmp]
2018/05/31 07:58:29 main.go:1049: dial @minicap err: dial unix @minicap: connect: connection refused, wait 0.5s
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG program pid: 1771
2018/05/31 07:58:29 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG start args: [/data/local/tmp/minitouch], env: []
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG program pid: 1790
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG cmd wait err: exit status 1
2018/05/31 07:58:29 cmdctrl.go:27: DEBUG idle for 500ms
2018/05/31 07:58:30 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG start args: [/data/local/tmp/minitouch], env: []
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG program pid: 1795
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG cmd wait err: exit status 1
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG idle for 500ms
2018/05/31 07:58:30 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG start args: [/data/local/tmp/minitouch], env: []
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG program pid: 1795
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG cmd wait err: exit status 1
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG idle for 500ms
2018/05/31 07:58:30 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG start args: [/data/local/tmp/minitouch], env: []
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG program pid: 1796
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG cmd wait err: exit status 1
2018/05/31 07:58:30 cmdctrl.go:27: DEBUG idle for 500ms
2018/05/31 07:58:31 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:31 cmdctrl.go:27: DEBUG program finished
2018/05/31 07:58:31 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:32 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:32 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:33 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:33 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s
2018/05/31 07:58:34 main.go:972: dial @minitouch error: dial unix @minitouch: connect: connection refused, wait 0.5s

start failed with error msg "INSTRUMENTATION_RESULT: shortMsg=Process crashed."

when trying to start atx-agent on huawei honor 7 with processor Hisilicon Kirin 935, it starts failed with full error msg as following:
2017/10/18 03:19:27 main.go:541: Ignore SIGUP
2017/10/18 03:19:27 main.go:545: Kill server
2017/10/18 03:19:27 main.go:551: Get http://127.0.0.1:7912/stop: dial tcp 127.0.0.1:7912: getsockopt: connection refused
IP: 172.18.29.8
INSTRUMENTATION_STATUS: numtests=1
INSTRUMENTATION_STATUS: stream=
com.github.uiautomator.stub.Stub:
INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
INSTRUMENTATION_STATUS: test=testUIAutomatorStub
INSTRUMENTATION_STATUS: class=com.github.uiautomator.stub.Stub
INSTRUMENTATION_STATUS: current=1
INSTRUMENTATION_STATUS_CODE: 1
INSTRUMENTATION_RESULT: shortMsg=Process crashed.
INSTRUMENTATION_CODE: 0

I am not sure whether this is related to processor arch, since huawei processor is aarch for arm8, and my release version is arm7.

The error is related to port usages. After killing the atx-agent, the port is available. Although I got this error, the agent was still running with port 7912.

Too much power conumption 耗电量大

I am considering power test over ATX agent, but when I analyzed systrace, saddly the "NanoHttpd Reque" thread is always in top3 cpu usage.
could ATX be optimized for power consumpution?

Test scenario: click popup window when installing APK

image

image

权限问题

当我意图用 atx-gent 中shell 去启动 uiautomator2 的service时出现了权限不够的问题 ,adb的权限高于应用,在用adb shell 中可以正常拉起的服务,在atx-gent 的shell中却不能拉起

希望作者提供可以无线拉起 uiautomator服务的方法 ,因为可能需要在 手机中运行 自动化脚本

或许在手机端提供一个 adbserver 是一个方案 ,以下项目是adb协议的python 实现
https://github.com/google/python-adb/blob/master/adb/adb_protocol.py

log:

curl -X POST -d command="am startservice -n com.github.uiautomator/.Service" http://10.0.100.228:7912/shell

{"error":{"Stderr":null},"exitCode":255,"output":"Starting service: Intent { cmp=com.github.uiautomator/.Service }\nSecurity exception: 

Permission Denial: service asks to run as user -2 but is calling from user 0; 

this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS\n\njava.lang.SecurityException: Permission Denial: service asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS\n\tat com.android.server.am.UserController.handleIncomingUser(Unknown Source:232)\n\tat com.android.server.am.ActiveServices.retrieveServiceLocked(Unknown Source:83)\n\tat com.android.server.am.ActiveServices.startServiceLocked(Unknown Source:172)\n\tat com.android.server.am.ActivityManagerService.startService(Unknown Source:124)\n\tat com.android.server.am.ActivityManagerShellCommand.runStartService(Unknown Source:81)\n\tat com.android.server.am.ActivityManagerShellCommand.onCommand(Unknown Source:47)\n\tat android.os.ShellCommand.exec(Unknown Source:35)\n\tat com.android.server.am.ActivityManagerService.onShellCommand(Unknown Source:13)\n\tat android.os.Binder.shellCommand(Unknown Source:0)\n\tat android.os.Binder.onTransact(Unknown Source:127)\n\tat android.app.IActivityManager$Stub.onTransact(Unknown Source:5)\n\tat com.android.server.am.ActivityManagerService.onTransact(Unknown Source:129)\n\tat android.os.Binder.transact(Unknown Source:6)\n\tat com.daniu.O0OO0.OO00.OO0.onTransact(SourceFile:128)\n\tat android.os.Binder.execTransact(Unknown Source:63)\n"}

在长时间运行之后,会出现自动退出atx-agent现象

长时间运行,抛出错误,查看了下,进程也已经退出,也就是daemon没有进行自动重启。

下面是详细日志,我分析了下,感觉都没太大问题,不知道是不是哪里的锁冲突了。


10.10.10.166 - - [07/Dec/2018:16:38:52 +0800] "POST /jsonrpc/0 HTTP/1.1" 200 89
2018/12/07 16:38:52 startservice com.github.uiautomator/.Service
fatal error: schedule: holding locks

runtime stack:
runtime.throw(0x51fe29, 0x17)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/panic.go:608 +0x5c
runtime.schedule()
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/proc.go:2561 +0x2f0
runtime.park_m(0x2a808c0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/proc.go:2676 +0x8c
runtime.mcall(0x28383c0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/asm_arm.s:289 +0x5c

goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x98365fc0, 0x72, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x28a6334, 0x72, 0x2919c00, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x7c
internal/poll.(*pollDesc).waitRead(0x28a6334, 0xffffff00, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Accept(0x28a6320, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_unix.go:384 +0x17c
net.(*netFD).accept(0x28a6320, 0x2b06b60, 0x2ae2000, 0x29de0d8)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/fd_unix.go:238 +0x20
net.(*TCPListener).accept(0x280cf20, 0x2ae2040, 0xa319900, 0x4335c)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/tcpsock_posix.go:139 +0x20
net.(*TCPListener).Accept(0x280cf20, 0x2ca0ca4, 0xc, 0x28000e0, 0x29fa00)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/tcpsock.go:260 +0x3c
net/http.(*Server).Serve(0x29d6680, 0x5bfb38, 0x280cf20, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/server.go:2826 +0x1e0
main.(*Server).Serve(0x29b2138, 0x5bfb38, 0x280cf20, 0x281aa5d, 0x29b2138)
	/home/travis/gopath/src/github.com/openatx/atx-agent/restapi.go:956 +0x30
main.main()
	/home/travis/gopath/src/github.com/openatx/atx-agent/main.go:608 +0x12e8

goroutine 5 [syscall, 3020 minutes]:
os/signal.signal_recv(0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/sigqueue.go:139 +0x130
os/signal.loop()
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/signal/signal_unix.go:23 +0x14
created by os/signal.init.0
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/signal/signal_unix.go:29 +0x30

goroutine 14 [syscall, 3020 minutes]:
syscall.Syscall6(0x118, 0x1, 0x374a, 0x2837eb4, 0x1000004, 0x0, 0x0, 0x2801b68, 0x2, 0x3)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/syscall/asm_linux_arm.s:45 +0x8
os.(*Process).blockUntilWaitable(0x28a4240, 0x1, 0x4a5601, 0x18ea8)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/wait_waitid.go:31 +0x64
os.(*Process).wait(0x28a4240, 0x280a998, 0x2837fdc, 0x29a0000)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec_unix.go:22 +0x2c
os.(*Process).Wait(0x28a4240, 0x0, 0x2907b40, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec.go:125 +0x1c
os/exec.(*Cmd).Wait(0x2884840, 0x3179c4, 0x1)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec/exec.go:465 +0x40
os/exec.(*Cmd).Wait-fm(0x2907bc0, 0x2837fdc)
	/home/travis/gopath/src/github.com/openatx/atx-agent/cmdctrl/cmdctrl.go:228 +0x1c
github.com/openatx/atx-agent/cmdctrl.goFunc.func1(0x2907c80, 0x280d110)
	/home/travis/gopath/src/github.com/openatx/atx-agent/cmdctrl/cmdctrl.go:34 +0x1c
created by github.com/openatx/atx-agent/cmdctrl.goFunc
	/home/travis/gopath/src/github.com/openatx/atx-agent/cmdctrl/cmdctrl.go:33 +0x48

goroutine 19 [select, 3020 minutes]:
github.com/openatx/atx-agent/cmdctrl.(*processKeeper).start.func1(0x29d6500)
	/home/travis/gopath/src/github.com/openatx/atx-agent/cmdctrl/cmdctrl.go:229 +0x3cc
created by github.com/openatx/atx-agent/cmdctrl.(*processKeeper).start
	/home/travis/gopath/src/github.com/openatx/atx-agent/cmdctrl/cmdctrl.go:208 +0xd0

goroutine 33 [select]:
github.com/codeskyblue/heartbeat.(*Client).beatLoop(0x2926060, 0x5c0038, 0x29260e0, 0x540be400, 0x2, 0x2ad6030, 0xa, 0x0, 0x0)
	/home/travis/gopath/pkg/mod/github.com/codeskyblue/[email protected]/heartbeat.go:197 +0x124
github.com/codeskyblue/heartbeat.(*Client).Beat.func1(0x2926060, 0x540be400, 0x2, 0x5c0038, 0x29260e0)
	/home/travis/gopath/pkg/mod/github.com/codeskyblue/[email protected]/heartbeat.go:178 +0x94
created by github.com/codeskyblue/heartbeat.(*Client).Beat
	/home/travis/gopath/pkg/mod/github.com/codeskyblue/[email protected]/heartbeat.go:159 +0xac

goroutine 21 [syscall]:
syscall.Syscall6(0x118, 0x1, 0x7dc4, 0x2d675ac, 0x1000004, 0x0, 0x0, 0x4f03c0, 0x13b3c, 0x2afcfa8)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/syscall/asm_linux_arm.s:45 +0x8
os.(*Process).blockUntilWaitable(0x29fc150, 0x29fc150, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/wait_waitid.go:31 +0x64
os.(*Process).wait(0x29fc150, 0x1, 0x2afcfa0, 0x2a69840)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec_unix.go:22 +0x2c
os.(*Process).Wait(0x29fc150, 0x53b5c8, 0x53b5cc, 0x53b5c4)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec.go:125 +0x1c
os/exec.(*Cmd).Wait(0x2c33340, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec/exec.go:465 +0x40
os/exec.(*Cmd).Run(0x2c33340, 0x53b8b4, 0x2af90e0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec/exec.go:309 +0x44
main.Command.Run(0x2a69820, 0x4, 0x4, 0xb2c97000, 0x8b, 0x1, 0x5bcba8, 0x2ae2060, 0x5bcba8, 0x2ae2060, ...)
	/home/travis/gopath/src/github.com/openatx/atx-agent/utils.go:86 +0x78
main.Command.CombinedOutput(0x2a69820, 0x4, 0x4, 0xb2c97000, 0x8b, 0x1, 0x5bcba8, 0x2ae2060, 0x5bcba8, 0x2ae2060, ...)
	/home/travis/gopath/src/github.com/openatx/atx-agent/utils.go:101 +0x48
main.runShell(0x2a69820, 0x4, 0x4, 0x2afa000, 0x41, 0x600, 0x0, 0x0)
	/home/travis/gopath/src/github.com/openatx/atx-agent/utils.go:117 +0x5c
main.(*Server).initHTTPServer.func17(0x29ac570)
	/home/travis/gopath/src/github.com/openatx/atx-agent/restapi.go:367 +0x48
created by main.(*Server).initHTTPServer
	/home/travis/gopath/src/github.com/openatx/atx-agent/restapi.go:364 +0x698

goroutine 38 [chan receive, 3020 minutes]:
main.main.func3(0x2a8bc40, 0x281aa5d, 0x29b2138)
	/home/travis/gopath/src/github.com/openatx/atx-agent/main.go:587 +0x74
created by main.main
	/home/travis/gopath/src/github.com/openatx/atx-agent/main.go:586 +0x12cc

goroutine 650701 [IO wait]:
internal/poll.runtime_pollWait(0x981f1a00, 0x72, 0xe4938)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x2cb8154, 0x72, 0xffffff01, 0x5be4c8, 0x8f0160)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x7c
internal/poll.(*pollDesc).waitRead(0x2cb8154, 0x2ad2401, 0x200, 0x200)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Read(0x2cb8140, 0x2ad2400, 0x200, 0x200, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_unix.go:169 +0x14c
os.(*File).read(0x2afcf88, 0x2ad2400, 0x200, 0x200, 0x2ad2400, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/file_unix.go:249 +0x3c
os.(*File).Read(0x2afcf88, 0x2ad2400, 0x200, 0x200, 0x98321018, 0x1, 0x1)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/file.go:108 +0x4c
bytes.(*Buffer).ReadFrom(0x2ae2060, 0x5bd838, 0x2afcf88, 0x98321018, 0x2ae2060, 0x2a80901, 0x2d747c4)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bytes/buffer.go:206 +0xa8
io.copyBuffer(0x5bcba8, 0x2ae2060, 0x5bd838, 0x2afcf88, 0x0, 0x0, 0x0, 0x2d747ac, 0x2d747a4, 0x2, ...)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/io/io.go:388 +0x300
io.Copy(0x5bcba8, 0x2ae2060, 0x5bd838, 0x2afcf88, 0x1, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/io/io.go:364 +0x48
os/exec.(*Cmd).writerDescriptor.func1(0x65aec, 0x53b6dc)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec/exec.go:279 +0x38
os/exec.(*Cmd).Start.func1(0x2c33340, 0x29ac870)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec/exec.go:400 +0x1c
created by os/exec.(*Cmd).Start
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/os/exec/exec.go:399 +0x414

goroutine 650706 [IO wait]:
internal/poll.runtime_pollWait(0x981f1e80, 0x72, 0xe4938)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x2b6c154, 0x72, 0xffffff00, 0x5be4c8, 0x8f0160)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x7c
internal/poll.(*pollDesc).waitRead(0x2b6c154, 0x2982000, 0x1000, 0x1000)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Read(0x2b6c140, 0x2982000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_unix.go:169 +0x14c
net.(*netFD).Read(0x2b6c140, 0x2982000, 0x1000, 0x1000, 0x2c35180, 0x4, 0x141a4)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/fd_unix.go:202 +0x38
net.(*conn).Read(0x29d4088, 0x2982000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/net.go:177 +0x58
net/http.(*persistConn).Read(0x2b88140, 0x2982000, 0x1000, 0x1000, 0x2b1570, 0x2b41a80, 0x2ba3620)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1497 +0x170
bufio.(*Reader).fill(0x29ae120)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bufio/bufio.go:100 +0x10c
bufio.(*Reader).Peek(0x29ae120, 0x1, 0x0, 0x0, 0x1, 0x2ace140, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bufio/bufio.go:132 +0x2c
net/http.(*persistConn).readLoop(0x2b88140)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1645 +0x164
created by net/http.(*Transport).dialConn
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1338 +0x7f8

goroutine 619202 [IO wait]:
internal/poll.runtime_pollWait(0x981f1e00, 0x72, 0xe4938)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x28a6424, 0x72, 0xffffff00, 0x5be4c8, 0x8f0160)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x7c
internal/poll.(*pollDesc).waitRead(0x28a6424, 0x2be6000, 0x1000, 0x1000)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Read(0x28a6410, 0x2be6000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_unix.go:169 +0x14c
net.(*netFD).Read(0x28a6410, 0x2be6000, 0x1000, 0x1000, 0x291c540, 0x4, 0x141a4)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/fd_unix.go:202 +0x38
net.(*conn).Read(0x2a322e8, 0x2be6000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/net.go:177 +0x58
net/http.(*persistConn).Read(0x2b880a0, 0x2be6000, 0x1000, 0x1000, 0x2b1570, 0x2b41180, 0x288de20)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1497 +0x170
bufio.(*Reader).fill(0x2d64330)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bufio/bufio.go:100 +0x10c
bufio.(*Reader).Peek(0x2d64330, 0x1, 0x0, 0x0, 0x1, 0x2b41780, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bufio/bufio.go:132 +0x2c
net/http.(*persistConn).readLoop(0x2b880a0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1645 +0x164
created by net/http.(*Transport).dialConn
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1338 +0x7f8

goroutine 650707 [select]:
net/http.(*persistConn).writeLoop(0x2b88140)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1885 +0xb8
created by net/http.(*Transport).dialConn
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1339 +0x814

goroutine 650690 [IO wait]:
internal/poll.runtime_pollWait(0x98365f40, 0x72, 0xe4938)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/runtime/netpoll.go:173 +0x44
internal/poll.(*pollDesc).wait(0x2a96834, 0x72, 0xffffff00, 0x5be4c8, 0x8f0160)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x7c
internal/poll.(*pollDesc).waitRead(0x2a96834, 0x2b9c000, 0x1000, 0x1000)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x2c
internal/poll.(*FD).Read(0x2a96820, 0x2b9c000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/internal/poll/fd_unix.go:169 +0x14c
net.(*netFD).Read(0x2a96820, 0x2b9c000, 0x1000, 0x1000, 0xffffffff, 0x0, 0x2977e4)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/fd_unix.go:202 +0x38
net.(*conn).Read(0x2afcb90, 0x2b9c000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/net.go:177 +0x58
net/http.(*connReader).Read(0x2c5a060, 0x2b9c000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/server.go:786 +0x14c
bufio.(*Reader).fill(0x29ae000)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bufio/bufio.go:100 +0x10c
bufio.(*Reader).Peek(0x29ae000, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/bufio/bufio.go:132 +0x2c
net/http.(*conn).readRequest(0x2ae2000, 0x5c0038, 0x2c5a020, 0x0, 0x0, 0x0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/server.go:963 +0xa84
net/http.(*conn).serve(0x2ae2000, 0x5c0038, 0x2c5a020)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/server.go:1788 +0x3f0
created by net/http.(*Server).Serve
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/server.go:2851 +0x290

goroutine 619203 [select]:
net/http.(*persistConn).writeLoop(0x2b880a0)
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1885 +0xb8
created by net/http.(*Transport).dialConn
	/home/travis/.gimme/versions/go1.11.linux.amd64/src/net/http/transport.go:1339 +0x814

请问获取控件的API是什么

提个建议,个人感觉应该着重atx-agent的开发,脚本端用户可以根据自己情况使用各种语言编写测试脚本即可。作者不必对脚本端做太多封装(主要小弟不会py,虽然作者用py对脚本端做了很多封装,对我来说使用起来还是有一定学习成本,所以还是准备用自己熟悉的js或这java编写测试脚本)

调用 install 接口报错

我将 atx-agent 运行到本地,然后通过postman 调用install接口,在安装的时候报错,如下:

 "avc:  denied  { read } for  scontext=u:r:system_server:s0 tcontext=u:object_r:sdcardfs:s0 tclass=file permissive=0\nSystem server has no access to read file context u:object_r:sdcardfs:s0 (from path /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk, context u:r:system_server:s0)\nError: Unable to open file: /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk\nConsider using a file under /data/local/tmp/\nError: Can't open file: /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk\n\nException occurred while executing:\njava.lang.IllegalArgumentException: Error: Can't open file: /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk\n\tat com.android.server.pm.PackageManagerShellCommand.setParamsSize(PackageManagerShellCommand.java:328)\n\tat com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:906)\n\tat com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:158)\n\tat android.os.ShellCommand.exec(ShellCommand.java:103)\n\tat com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:21260)\n\tat android.os.Binder.shellCommand(Binder.java:634)\n\tat android.os.Binder.onTransact(Binder.java:532)\n\tat android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2796)\n\tat com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3856)\n\tat android.os.Binder.execTransact(Binder.java:731)\n: exit status 255",

安装调用:
image

报错调用:
image

Releases 0.4.4 atx-agent 无法启动

下载包 atx-agent_0.4.4_linux_armv7.tar.gz
运行

$adb shell /data/local/tmp/atx-agent -d
usage: atx-agent [<flags>] <command> [<args> ...]

Flags:
  -h, --help           Show context-sensitive help (also try --help-long and
                       --help-man).
  -d, --daemon         run in daemon mode
  -p, --port=7912      listen port
      --stop           stop server
      --log=LOG        log file path when in daemon mode
  -t, --server=SERVER  server url
      --nouia          do not start uiautoamtor when start
  -v, --version        Show application version.

Commands:
  help [<command>...]
    Show help.

  curl [<flags>] <url>
    simulate curl command

同样环境下 0.4.3版本正常

DISCUSS: wrap every http handle func in a recoverwrap seems to enhance stableness of agent

Hi,
I'm performing a heavy install/uninstall app tests with atx-agent, which involves lots of repeatedly push/install/uninstall operation. Usually atx-agent die with no more than 100 apps, today after I added a recoverwrap func around every http handler, agent keeps alive after 1000 apps and it's still working.

I can't figure out why, maybe lust lucky time. I posted it here, hope someone else could also give it a try, as agents stableness appears to be a problem when trying to run some CI tasks with atx-agents. Even after upgrade to 0.4.0 with new go daemon, it dies from time to time.

The wrap method:
func RecoverWrap(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
//var err error
defer func() {
if e := recover(); e != nil {
log.Println("Detect panic !!!", e)
ioutil.WriteFile("/sdcard/atx-panic.txt", []byte(fmt.Sprintf(
"Time: %s\n%v", time.Now().Format("2006-01-02 15:04:05"),
e)), 0644)
}
}()
f(w, r)
}
}

func RecoverWrapNew(f func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn)) func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn) {
return func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn){
//var err error
defer func() {
if e := recover(); e != nil {
log.Println("Detect panic !!!", e)
ioutil.WriteFile("/sdcard/atx-panic.txt", []byte(fmt.Sprintf(
"Time: %s\n%v", time.Now().Format("2006-01-02 15:04:05"),
e)), 0644)
}
}()
f(w, r, ws)
}
}

And I use it like this(attempt to collect more info):
m.HandleFunc("/version", RecoverWrap(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, version)
}))

    m.HandleFunc("/upload/{target:.*}", RecoverWrap(func(w http.ResponseWriter, r *http.Request) {

...

m.HandleFunc("/minitouch", singleFightNewerWebsocket(RecoverWrapNew(func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn) {

......

BTW, during my tests there is no atx-panic.txt created, so there should be no panic captured, and the RecoveWrap seems to have no effect. (Could it because of defer()?).

I'll do more tests tomorrow.

Cheers.

传输分辨率和图像质量问题

atx-agent启动minicap时设置的分辨率为800*800,图像质量为80,操作正常。

但是当我把分辨率设为1920*1080,图像质量设置为100时,画面就有点卡顿了,请问你那边有这个问题吗?谢谢~

手机调用install安装apk会报错

atx-agent 运行在手机上,通过curl调用install接口安装apk报错:
"avc: denied { read } for scontext=u:r:system_server:s0 tcontext=u:object_r:sdcardfs:s0 tclass=file permissive=0\nSystem server has no access to read file context u:object_r:sdcardfs:s0 (from path /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk, context u:r:system_server:s0)\nError: Unable to open file: /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk\nConsider using a file under /data/local/tmp/\nError: Can't open file: /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk\n\nException occurred while executing:\njava.lang.IllegalArgumentException: Error: Can't open file: /sdcard/tmp/2022eb3db5459adebe28e8781fee02fe.apk\n\tat com.android.server.pm.PackageManagerShellCommand.setParamsSize(PackageManagerShellCommand.java:328)\n\tat com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:906)\n\tat com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:158)\n\tat android.os.ShellCommand.exec(ShellCommand.java:103)\n\tat com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:21260)\n\tat android.os.Binder.shellCommand(Binder.java:634)\n\tat android.os.Binder.onTransact(Binder.java:532)\n\tat android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2796)\n\tat com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3856)\n\tat android.os.Binder.execTransact(Binder.java:731)\n: exit status 255",

DNS Error

Hi.

I got an error with atx-agent when I try to test code using uiautomator2.

When I use app_install method, the error is :

Traceback (most recent call last):
  File "example.py", line 11, in <module>
    d.app_install('http://example.org/AliExpress%20Smarter%20Shopping%20Better%20Living_v6.15.0_apkpure.com.apk')
  File "C:\Python27\lib\site-packages\uiautomator2\__init__.py", line 689, in app_install
    return self._wait_install_finished(id, installing_callback)
  File "C:\Python27\lib\site-packages\uiautomator2\__init__.py", line 744, in _wait_install_finished
    raise RuntimeError("error", jdata.get('error'))
RuntimeError: ('error', u'Get http://example.org/AliExpress%20Smarter%20Shopping%20Better%20Living_v6.15.0_apkpure.com.apk: dial tcp: lookup example.org on [::1]:53: read udp [::1]:42576->[::1]:53: read: connection refused')

Is there any solution about this?

I saw the dns server has been fixed at /dns.go. Is it related with the error?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.