blob: afb397e274fdbc80a8afd9da99d0b6fa4d56cd3e [file] [log] [blame]
var syrup = require('stf-syrup')
var browsers = require('stf-browser-db')
var logger = require('../../../util/logger')
var wire = require('../../../wire')
var wireutil = require('../../../wire/util')
var mapping = (function() {
var list = Object.create(null)
Object.keys(browsers).forEach(function(id) {
var browser = browsers[id]
if (browser.platforms.android) {
list[browser.platforms.android.package] = id
}
})
return list
})()
module.exports = syrup.serial()
.dependency(require('../support/router'))
.dependency(require('../support/push'))
.dependency(require('../support/adb'))
.dependency(require('./service'))
.define(function(options, router, push, adb, service) {
var log = logger.createLogger('device:plugins:browser')
function pkg(component) {
return component.split('/', 1)[0]
}
function appReducer(acc, app) {
var packageName = pkg(app.component)
var browserId = mapping[packageName]
if (!browserId) {
log.warn('Unmapped browser "%s"', packageName)
return acc
}
acc.push({
id: app.component
, type: browserId
, name: browsers[browserId].name
, selected: app.selected
, system: app.system
})
return acc
}
function compareIgnoreCase(a, b) {
var la = (a || '').toLowerCase()
var lb = (b || '').toLowerCase()
if (la === lb) {
return 0
}
else if (la < lb) {
return -1
}
else {
return 1
}
}
function updateBrowsers(data) {
log.info('Updating browser list')
push.send([
wireutil.global
, wireutil.envelope(new wire.DeviceBrowserMessage(
options.serial
, data.selected
, data.apps.reduce(appReducer, []).sort(function(appA, appB) {
return compareIgnoreCase(appA.name, appB.name)
})
))
])
}
function loadBrowsers() {
log.info('Loading browser list')
return service.getBrowsers()
.then(updateBrowsers)
}
function ensureHttpProtocol(url) {
// Check for '://' because a protocol-less URL might include
// a username:password combination.
return (url.indexOf('://') === -1 ? 'http://' : '') + url
}
service.on('browserPackageChange', updateBrowsers)
router.on(wire.BrowserOpenMessage, function(channel, message) {
message.url = ensureHttpProtocol(message.url)
if (message.browser) {
log.info('Opening "%s" in "%s"', message.url, message.browser)
}
else {
log.info('Opening "%s"', message.url)
}
var reply = wireutil.reply(options.serial)
adb.startActivity(options.serial, {
action: 'android.intent.action.VIEW'
, component: message.browser
, data: message.url
})
.then(function() {
push.send([
channel
, reply.okay()
])
})
.catch(function(err) {
if (message.browser) {
log.error(
'Failed to open "%s" in "%s"'
, message.url
, message.browser
, err.stack
)
}
else {
log.error('Failed to open "%s"', message.url, err.stack)
}
push.send([
channel
, reply.fail()
])
})
})
router.on(wire.BrowserClearMessage, function(channel, message) {
log.info('Clearing "%s"', message.browser)
var reply = wireutil.reply(options.serial)
adb.clear(options.serial, pkg(message.browser))
.then(function() {
push.send([
channel
, reply.okay()
])
})
.catch(function(err) {
log.error('Failed to clear "%s"', message.browser, err.stack)
push.send([
channel
, reply.fail()
])
})
})
return loadBrowsers()
})