| 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() |
| }) |