1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 10:19:30 +02:00
OpenSTF/lib/util/devutil.js
2019-05-03 22:00:55 +02:00

185 lines
5.4 KiB
JavaScript

var util = require('util')
var split = require('split')
var Promise = require('bluebird')
var androidDeviceList = require('android-device-list')
var devutil = module.exports = Object.create(null)
function closedError(err) {
return err.message.indexOf('closed') !== -1
}
devutil.ensureUnusedLocalSocket = function(adb, serial, sock) {
return adb.openLocal(serial, sock)
.then(function(conn) {
conn.end()
throw new Error(util.format('Local socket "%s" should be unused', sock))
})
.catch(closedError, function() {
return Promise.resolve(sock)
})
}
devutil.waitForLocalSocket = function(adb, serial, sock) {
return adb.openLocal(serial, sock)
.then(function(conn) {
conn.sock = sock
return conn
})
.catch(closedError, function() {
return Promise.delay(100)
.then(function() {
return devutil.waitForLocalSocket(adb, serial, sock)
})
})
}
devutil.listPidsByComm = function(adb, serial, comm, bin) {
var users = {
shell: true
}
var findProcess = function(out) {
return new Promise(function(resolve) {
var header = true
var pids = []
var showTotalPid = false
out.pipe(split())
.on('data', function(chunk) {
if (header) {
header = false
}
else {
var cols = chunk.toString().split(/\s+/)
if (!showTotalPid && cols[0] === 'root') {
showTotalPid = true
}
// last column of output would be command name containing absolute path like '/data/local/tmp/minicap'
// or just binary name like 'minicap', it depends on device/ROM
var lastCol = cols.pop()
if ((lastCol === comm || lastCol === bin) && users[cols[0]]) {
pids.push(Number(cols[1]))
}
}
})
.on('end', function() {
resolve({showTotalPid: showTotalPid, pids: pids})
})
})
}
return adb.shell(serial, 'ps 2>/dev/null')
.then(findProcess)
.then(function(res) {
// return pids if process can be found in the output of 'ps' command
// or 'ps' command has already displayed all the processes including processes launched by root user
if (res.showTotalPid || res.pids.length > 0) {
return Promise.resolve(res.pids)
}
// otherwise try to run 'ps -elf'
else {
return adb.shell(serial, 'ps -lef 2>/dev/null')
.then(findProcess)
.then(function(res) {
return Promise.resolve(res.pids)
})
}
})
}
devutil.waitForProcsToDie = function(adb, serial, comm, bin) {
return devutil.listPidsByComm(adb, serial, comm, bin)
.then(function(pids) {
if (pids.length) {
return Promise.delay(100)
.then(function() {
return devutil.waitForProcsToDie(adb, serial, comm, bin)
})
}
})
}
devutil.killProcsByComm = function(adb, serial, comm, bin, mode) {
return devutil.listPidsByComm(adb, serial, comm, bin, mode)
.then(function(pids) {
if (!pids.length) {
return Promise.resolve()
}
return adb.shell(serial, ['kill', mode || -15].concat(pids))
.then(function(out) {
return new Promise(function(resolve) {
out.on('end', resolve)
})
})
.then(function() {
return devutil.waitForProcsToDie(adb, serial, comm, bin)
})
.timeout(2000)
.catch(function() {
return devutil.killProcsByComm(adb, serial, comm, bin, -9)
})
})
}
devutil.makeIdentity = function(serial, properties) {
var model = properties['ro.product.model']
var brand = properties['ro.product.brand']
var manufacturer = properties['ro.product.manufacturer']
var operator = properties['gsm.sim.operator.alpha'] ||
properties['gsm.operator.alpha']
var version = properties['ro.build.version.release']
var sdk = properties['ro.build.version.sdk']
var abi = properties['ro.product.cpu.abi']
var product = properties['ro.product.name']
var cpuPlatform = properties['ro.board.platform']
var openGLESVersion = properties['ro.opengles.version']
var marketName = properties['ro.product.device']
openGLESVersion = parseInt(openGLESVersion, 10)
if (isNaN(openGLESVersion)) {
openGLESVersion = '0.0'
}
else {
var openGLESVersionMajor = (openGLESVersion & 0xffff0000) >> 16
var openGLESVersionMinor = (openGLESVersion & 0xffff)
openGLESVersion = openGLESVersionMajor + '.' + openGLESVersionMinor
}
// Remove brand prefix for consistency. Note that some devices (e.g. TPS650)
// do not expose the brand property.
if (brand && model.substr(0, brand.length) === brand) {
model = model.substr(brand.length)
}
// Remove manufacturer prefix for consistency
if (model.substr(0, manufacturer.length) === manufacturer) {
model = model.substr(manufacturer.length)
}
if (marketName) {
var devices = androidDeviceList.getDevicesByDeviceId(marketName)
if (devices.length > 0) {
marketName = devices[0].name
}
}
// Clean up remaining model name
// model = model.replace(/[_ ]/g, '')
return {
serial: serial
, platform: 'Android'
, manufacturer: manufacturer.toUpperCase()
, operator: operator || null
, model: model
, version: version
, abi: abi
, sdk: sdk
, product: product
, cpuPlatform: cpuPlatform
, openGLESVersion: openGLESVersion
, marketName: marketName
}
}