diff --git a/lib/cli.js b/lib/cli.js index f5c8ccfa..3b2d1490 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -33,9 +33,9 @@ program , Number , 7400) .option('--max-port ' - , 'maximum port number for worker use' + , 'maximum port number for worker use (total must be multiple of 3)' , Number - , 7800) + , 7700) .option('--public-ip ' , 'public ip for global access' , String diff --git a/lib/db/api.js b/lib/db/api.js index 5e47343b..d96e6312 100644 --- a/lib/db/api.js +++ b/lib/db/api.js @@ -114,6 +114,7 @@ dbapi.saveDeviceIdentity = function(serial, identity) { , abi: identity.abi , sdk: identity.sdk , display: identity.display + , browsers: identity.browsers })) } diff --git a/lib/roles/device/plugins/browsers.js b/lib/roles/device/plugins/browsers.js new file mode 100644 index 00000000..f4d3f429 --- /dev/null +++ b/lib/roles/device/plugins/browsers.js @@ -0,0 +1,51 @@ +var util = require('util') + +var syrup = require('syrup') + +var logger = require('../../../util/logger') + +module.exports = syrup() + .dependency(require('../support/http')) + .dependency(require('./input')) + .define(function(options, http, input) { + var log = logger.createLogger('device:plugins:browsers') + + log.info('Fetching browser list') + return input.getBrowsers() + .then(function(browsers) { + var icons = Object.create(null) + + browsers.apps.forEach(function(app) { + icons[app.component] = app.icon.toBuffer() + app.icon = util.format( + '%s/api/v1/browsers/%s/icon' + , http.get('public url') + , app.component + ) + }) + + http.get( + '/api/v1/browsers/:package/:activity/icon' + , function(req, res) { + var component = util.format( + '%s/%s' + , req.params.package + , req.params.activity + ) + + var icon = icons[component] + + if (icon) { + res.set('Content-Type', 'image/png') + res.set('Content-Length', icon.length) + res.send(200, icon) + } + else { + res.send(404) + } + } + ) + + return browsers + }) + }) diff --git a/lib/roles/device/plugins/identity.js b/lib/roles/device/plugins/identity.js index 9eb288e3..5fd861b6 100644 --- a/lib/roles/device/plugins/identity.js +++ b/lib/roles/device/plugins/identity.js @@ -6,13 +6,15 @@ var logger = require('../../../util/logger') module.exports = syrup.serial() .dependency(require('../support/properties')) .dependency(require('./display')) - .define(function(options, properties, display) { + .dependency(require('./browsers')) + .define(function(options, properties, display, browsers) { var log = logger.createLogger('device:plugins:identity') function solve() { log.info('Solving identity') var identity = devutil.makeIdentity(options.serial, properties) identity.display = display + identity.browsers = browsers return identity } diff --git a/lib/roles/device/plugins/input.js b/lib/roles/device/plugins/input.js index 34f0ad92..e86f6f0a 100644 --- a/lib/roles/device/plugins/input.js +++ b/lib/roles/device/plugins/input.js @@ -293,6 +293,21 @@ module.exports = syrup.serial() }) } + function getBrowsers() { + return runServiceCommand( + apk.serviceProto.RequestType.GET_BROWSERS + , new apk.serviceProto.GetBrowsersRequest() + ) + .then(function(data) { + var response = apk.serviceProto.GetBrowsersResponse.decode(data) + if (response.success) { + delete response.success + return response + } + throw new Error('Unable to get browser list') + }) + } + function runServiceCommand(type, cmd) { var resolver = Promise.defer() service.writer.write(new apk.serviceProto.RequestEnvelope( @@ -361,6 +376,7 @@ module.exports = syrup.serial() }) } , copy: getClipboard + , getBrowsers: getBrowsers } }) }) diff --git a/lib/roles/device/plugins/solo.js b/lib/roles/device/plugins/solo.js index 67332984..22e42bfe 100644 --- a/lib/roles/device/plugins/solo.js +++ b/lib/roles/device/plugins/solo.js @@ -42,6 +42,17 @@ module.exports = syrup.serial() , identity.display.secure , identity.display.url ) + , new wire.DeviceBrowsersMessage( + identity.browsers.selected + , identity.browsers.apps.map(function(app) { + return new wire.DeviceBrowserAppMessage( + app.name + , app.component + , app.selected + , app.icon + ) + }) + ) )) ]) }) diff --git a/lib/roles/device/support/http.js b/lib/roles/device/support/http.js new file mode 100644 index 00000000..361865c2 --- /dev/null +++ b/lib/roles/device/support/http.js @@ -0,0 +1,29 @@ +var http = require('http') +var util = require('util') + +var syrup = require('syrup') +var express = require('express') + +var logger = require('../../../util/logger') + +module.exports = syrup() + .define(function(options) { + var log = logger.createLogger('device:support:http') + , port = options.ports.pop() + , app = express() + , server = http.createServer(app) + + app.set('strict routing', true) + app.set('case sensitive routing', true) + app.set('public url', util.format( + 'http://%s:%s' + , options.publicIp + , port + )) + + server.listen(port) + + log.info('Listening on %s', app.get('public url')) + + return app + }) diff --git a/lib/roles/provider.js b/lib/roles/provider.js index 55591833..ff254d6d 100644 --- a/lib/roles/provider.js +++ b/lib/roles/provider.js @@ -253,7 +253,7 @@ module.exports = function(options) { // Spawn a device worker function spawn() { - var ports = options.ports.splice(0, 2) + var ports = options.ports.splice(0, 3) , proc = options.fork(device, ports) , resolver = Promise.defer() diff --git a/lib/wire/wire.proto b/lib/wire/wire.proto index c5a1cc6d..9dbeca96 100644 --- a/lib/wire/wire.proto +++ b/lib/wire/wire.proto @@ -127,6 +127,18 @@ message DeviceDisplayMessage { required string url = 10; } +message DeviceBrowserAppMessage { + required string name = 1; + required string component = 2; + required bool selected = 3; + required string icon = 4; +} + +message DeviceBrowsersMessage { + required bool selected = 1; + repeated DeviceBrowserAppMessage apps = 2; +} + message DeviceIdentityMessage { required string serial = 1; required string platform = 2; @@ -137,6 +149,7 @@ message DeviceIdentityMessage { required string abi = 7; required string sdk = 8; required DeviceDisplayMessage display = 9; + required DeviceBrowsersMessage browsers = 10; } message DeviceProperty { diff --git a/vendor/STFService/STFService.apk b/vendor/STFService/STFService.apk index 8f310863..87069b29 100644 Binary files a/vendor/STFService/STFService.apk and b/vendor/STFService/STFService.apk differ diff --git a/vendor/STFService/proto/service.proto b/vendor/STFService/proto/service.proto index 6a951da6..7921e7c9 100644 --- a/vendor/STFService/proto/service.proto +++ b/vendor/STFService/proto/service.proto @@ -8,6 +8,7 @@ enum RequestType { SET_WAKE_LOCK = 2; SET_CLIPBOARD = 3; GET_CLIPBOARD = 4; + GET_BROWSERS = 5; GET_PROPERTIES = 6; IDENTIFY = 7; } @@ -17,11 +18,6 @@ message RequestEnvelope { required bytes request = 2; } -message ResponseEnvelope { - required bool success = 1; - required bytes response = 2; -} - message VersionRequest { } @@ -69,6 +65,22 @@ message GetClipboardResponse { optional string text = 3; } +message BrowserApp { + required string name = 1; + required string component = 2; + required bool selected = 3; + required bytes icon = 4; +} + +message GetBrowsersRequest { +} + +message GetBrowsersResponse { + required bool success = 1; + required bool selected = 2; + repeated BrowserApp apps = 3; +} + message Property { required string name = 1; required string value = 2;