-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathapktool.js
More file actions
162 lines (156 loc) · 3.87 KB
/
apktool.js
File metadata and controls
162 lines (156 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
const util = require("util");
const execPromisefy = util.promisify(require("child_process").exec);
const path = require("path");
/**
* 枚举当前已连接安卓设备
*/
async function listDevices() {
console.log("listDevices");
const { error, stdout, stderr } = await adbRun("devices");
if (error) {
console.error("listDevices|error:", error);
throw error;
}
if (stderr) {
console.error("listDevices|stderr:", stderr);
throw error;
}
let deviceArray = [];
let deviceStateArray = [];
let deviceNameArray = [];
stdout.split("\n").forEach((line) => {
if ((line = line.trim()) && line.indexOf("List of devices attached") < 0) {
var deviceId = line.split(" ")[0];
var info = line.split(" ")[1];
deviceArray.push(deviceId);
deviceStateArray.push(info);
}
});
for (deviceId of deviceArray) {
try {
const deviceName = await getDeviceName(deviceId);
deviceNameArray.push(deviceName);
} catch (e) {
deviceNameArray.push("unknown");
}
}
console.log("devices info:", deviceArray, deviceStateArray, deviceNameArray);
return [deviceArray, deviceStateArray, deviceNameArray];
}
/**
* 检查是否有adb环境
*/
async function checkAdbEnv() {
const { error, stdout, stderr } = await adbRun("version");
if (error) {
console.error("checkAdbEnv|error:", error);
throw e;
}
if (stderr) {
console.error("checkAdbEnv|stderr:", stderr);
throw e;
}
return stdout;
}
/**
* 安装apk到指定设备
* 超时时间默认50s
* @param {*} deviceId
* @param {*} apkPath
*/
function installApk(deviceId, apkPath) {
console.log("install apk");
const installPromise = new Promise(async (resolve, reject) => {
try {
const { error, stdout, stderr } = await adbRun(
`-s ${deviceId} install ${apkPath}`
);
console.log("install", error, stdout, stderr);
if (error) {
console.error("adb install|error:", error);
reject(e);
}
if (stderr) {
console.log("adb install|stderr:", stderr);
if (stderr.trim() === "Success") {
resolve(stderr);
} else {
reject(stderr);
}
} else {
resolve(stdout);
}
} catch (e) {
console.error(e);
reject(e);
}
});
const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("timeout");
}, 50000);
});
return Promise.race([installPromise, timeoutPromise]);
}
/**
* 安装apk到一个或多个设备
* 超时时间默认50s
* @param {*} apkPath
* @param {*} deviceIds
*/
function installApkToDevices(apkPath, deviceIds, progress) {
return new Promise(async (resolve, reject) => {
var errors = [];
for (deviceId of deviceIds) {
progress && progress([0, deviceId]);
try {
await installApk(deviceId, apkPath);
progress && progress([1, deviceId]);
} catch (e) {
console.error(e);
errors.push(e);
progress && progress([2, deviceId, e]);
}
}
if (errors.length > 0) {
reject(errors);
} else {
resolve("success");
}
});
}
function getDeviceName(deivceId) {
return new Promise(async (r, j) => {
try {
const ret = await adbRun(
`-s "${deviceId}" shell getprop ro.product.model`
);
const stdout = ret["stdout"];
const stderr = ret["stderr"];
if (stdout) {
r(stdout);
} else {
j(stderr);
}
} catch (e) {
console.error("getDeviceName err", e);
j(e);
}
});
}
/**
* 执行adb包装
* @param {*} args
* @returns
*/
function adbRun(args) {
var adbPath = localStorage.getItem("adbPath");
if (adbPath) {
args = `"${adbPath}" ${args}`;
} else {
args = `adb ${args}`;
}
console.warn(`run:${args}`);
return execPromisefy(args);
}
module.exports = { listDevices, installApk, installApkToDevices, checkAdbEnv };