blob: 93493d07da3efa7ec4aee9ef5520df6fc8de2319 [file] [log] [blame]
var Promise = require('bluebird')
var syrup = require('stf-syrup')
var logger = require('../../../util/logger')
var wire = require('../../../wire')
var wireutil = require('../../../wire/util')
module.exports = syrup.serial()
.dependency(require('../support/adb'))
.dependency(require('../support/router'))
.dependency(require('../support/push'))
.dependency(require('../support/sub'))
.define(function(options, adb, router, push, sub) {
var log = logger.createLogger('device:plugins:shell')
router.on(wire.ShellCommandMessage, function(channel, message) {
var reply = wireutil.reply(options.serial)
log.info('Running shell command "%s"', message.command)
adb.shell(options.serial, message.command)
.timeout(10000)
.then(function(stream) {
var resolver = Promise.defer()
var timer
function forceStop() {
stream.end()
}
function keepAliveListener(channel, message) {
clearTimeout(timer)
timer = setTimeout(forceStop, message.timeout)
}
function readableListener() {
var chunk
while ((chunk = stream.read())) {
push.send([
channel
, reply.progress(chunk)
])
}
}
function endListener() {
push.send([
channel
, reply.okay(null)
])
resolver.resolve()
}
function errorListener(err) {
resolver.reject(err)
}
stream.setEncoding('utf8')
stream.on('readable', readableListener)
stream.on('end', endListener)
stream.on('error', errorListener)
sub.subscribe(channel)
router.on(wire.ShellKeepAliveMessage, keepAliveListener)
timer = setTimeout(forceStop, message.timeout)
return resolver.promise.finally(function() {
stream.removeListener('readable', readableListener)
stream.removeListener('end', endListener)
stream.removeListener('error', errorListener)
sub.unsubscribe(channel)
router.removeListener(wire.ShellKeepAliveMessage, keepAliveListener)
clearTimeout(timer)
})
})
.error(function(err) {
log.error('Shell command "%s" failed', message.command, err.stack)
push.send([
channel
, reply.fail(err.message)
])
})
})
})