mirror of
https://github.com/openstf/stf
synced 2025-10-05 02:29:26 +02:00
141 lines
3.6 KiB
JavaScript
141 lines
3.6 KiB
JavaScript
var util = require('util')
|
|
var path = require('path')
|
|
var http = require('http')
|
|
|
|
var Promise = require('bluebird')
|
|
var syrup = require('stf-syrup')
|
|
var httpProxy = require('http-proxy')
|
|
|
|
var logger = require('../../../util/logger')
|
|
var lifecycle = require('../../../util/lifecycle')
|
|
var streamutil = require('../../../util/streamutil')
|
|
|
|
module.exports = syrup.serial()
|
|
.dependency(require('../support/adb'))
|
|
.dependency(require('../resources/minicap'))
|
|
.define(function(options, adb, minicap) {
|
|
var log = logger.createLogger('device:plugins:screen')
|
|
var plugin = Object.create(null)
|
|
|
|
plugin.devicePort = 9002
|
|
|
|
plugin.privatePort = options.ports.pop()
|
|
plugin.privateUrl = util.format(
|
|
'ws://127.0.0.1:%s'
|
|
, plugin.privatePort
|
|
)
|
|
|
|
plugin.publicPort = options.ports.pop()
|
|
plugin.publicUrl = util.format(
|
|
'ws://%s:%s'
|
|
, options.publicIp
|
|
, plugin.publicPort
|
|
)
|
|
|
|
function run(cmd) {
|
|
return adb.shell(options.serial, util.format(
|
|
'LD_LIBRARY_PATH=%s exec %s %s'
|
|
, path.dirname(minicap.lib)
|
|
, minicap.bin
|
|
, cmd
|
|
))
|
|
}
|
|
|
|
function startService() {
|
|
log.info('Launching screen service')
|
|
return run(util.format('-p %d', plugin.devicePort))
|
|
.timeout(10000)
|
|
.then(function(out) {
|
|
lifecycle.share('Screen shell', out)
|
|
streamutil.talk(log, 'Screen shell says: "%s"', out)
|
|
})
|
|
}
|
|
|
|
function forwardService() {
|
|
log.info('Opening WebSocket service on port %d', plugin.privatePort)
|
|
return adb.forward(
|
|
options.serial
|
|
, util.format('tcp:%d', plugin.privatePort)
|
|
, util.format('tcp:%d', plugin.devicePort)
|
|
)
|
|
.timeout(10000)
|
|
}
|
|
|
|
function startProxy() {
|
|
log.info('Starting WebSocket proxy on %s', plugin.publicUrl)
|
|
|
|
var resolver = Promise.defer()
|
|
|
|
function resolve() {
|
|
lifecycle.share('Proxy server', proxyServer, {
|
|
end: false
|
|
})
|
|
resolver.resolve()
|
|
}
|
|
|
|
function reject(err) {
|
|
resolver.reject(err)
|
|
}
|
|
|
|
function ignore() {
|
|
// No-op
|
|
}
|
|
|
|
var proxy = httpProxy.createProxyServer({
|
|
target: plugin.privateUrl
|
|
, ws: true
|
|
, xfwd: false
|
|
})
|
|
|
|
proxy.on('error', ignore)
|
|
|
|
var proxyServer = http.createServer()
|
|
|
|
proxyServer.on('listening', resolve)
|
|
proxyServer.on('error', reject)
|
|
|
|
proxyServer.on('request', function(req, res) {
|
|
proxy.web(req, res)
|
|
})
|
|
|
|
proxyServer.on('upgrade', function(req, socket, head) {
|
|
proxy.ws(req, socket, head)
|
|
})
|
|
|
|
proxyServer.listen(plugin.publicPort)
|
|
|
|
return resolver.promise.finally(function() {
|
|
proxyServer.removeListener('listening', resolve)
|
|
proxyServer.removeListener('error', reject)
|
|
})
|
|
}
|
|
|
|
return startService()
|
|
.then(forwardService)
|
|
.then(startProxy)
|
|
.then(function() {
|
|
plugin.info = function(id) {
|
|
return run(util.format('-d %d -i', id))
|
|
.then(streamutil.readAll)
|
|
.then(function(out) {
|
|
var match
|
|
if ((match = /^ERROR: (.*)$/.exec(out))) {
|
|
throw new Error(match[1])
|
|
}
|
|
|
|
try {
|
|
var info = JSON.parse(out)
|
|
// Compat for now, remove eventually
|
|
info.rotation = 0
|
|
info.fps = 0
|
|
info.secure = false
|
|
return info
|
|
}
|
|
catch (e) {
|
|
throw new Error(out.toString())
|
|
}
|
|
})
|
|
}
|
|
})
|
|
.return(plugin)
|
|
})
|