1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 18:29:17 +02:00

Update with new service features.

This commit is contained in:
Simo Kinnunen 2014-05-01 17:04:54 +09:00
parent 2379acae5d
commit a915aea9ea
9 changed files with 440 additions and 109 deletions

View file

@ -117,6 +117,65 @@ dbapi.setDeviceAbsent = function(serial) {
})) }))
} }
dbapi.setDeviceAirplaneMode = function(serial, enabled) {
return db.run(r.table('devices').get(serial).update({
airplaneMode: enabled
}))
}
dbapi.setDeviceBattery = function(serial, battery) {
return db.run(r.table('devices').get(serial).update({
battery: {
status: battery.status
, health: battery.health
, source: battery.source
, level: battery.level
, scale: battery.scale
, temp: battery.temp
, voltage: battery.voltage
}
}))
}
dbapi.setDeviceBrowser = function(serial, browser) {
return db.run(r.table('devices').get(serial).update({
browser: {
selected: browser.selected
, apps: browser.apps
}
}))
}
dbapi.setDeviceConnectivity = function(serial, connectivity) {
return db.run(r.table('devices').get(serial).update({
network: {
connected: connectivity.connected
, type: connectivity.type
, subtype: connectivity.subtype
, failover: !!connectivity.failover
, roaming: !!connectivity.roaming
}
}))
}
dbapi.setDevicePhoneState = function(serial, state) {
return db.run(r.table('devices').get(serial).update({
network: {
state: state.state
, manual: state.manual
, operator: state.operator
}
}))
}
dbapi.setDeviceRotation = function(serial, rotation) {
return db.run(r.table('devices').get(serial).update({
display: {
orientation: rotation
}
}))
}
dbapi.setDeviceChannel = function(serial, channel) { dbapi.setDeviceChannel = function(serial, channel) {
return db.run(r.table('devices').get(serial).update({ return db.run(r.table('devices').get(serial).update({
channel: channel channel: channel

View file

@ -330,6 +330,52 @@ module.exports = function(options) {
.on(wire.DeviceLogcatEntryMessage, function(channel, message) { .on(wire.DeviceLogcatEntryMessage, function(channel, message) {
socket.emit('logcat.entry', message) socket.emit('logcat.entry', message)
}) })
.on(wire.AirplaneModeEvent, function(channel, message) {
socket.emit('device.change', {
serial: message.serial
, airplaneMode: message.enabled
})
})
.on(wire.BatteryEvent, function(channel, message) {
var serial = message.serial
delete message.serial
socket.emit('device.change', {
serial: serial
, battery: message
})
})
.on(wire.BrowserPackageEvent, function(channel, message) {
var serial = message.serial
delete message.serial
socket.emit('device.change', {
serial: serial
, browser: message
})
})
.on(wire.ConnectivityEvent, function(channel, message) {
var serial = message.serial
delete message.serial
socket.emit('device.change', {
serial: serial
, network: message
})
})
.on(wire.PhoneStateEvent, function(channel, message) {
var serial = message.serial
delete message.serial
socket.emit('device.change', {
serial: serial
, network: message
})
})
.on(wire.RotationEvent, function(channel, message) {
socket.emit('device.change', {
serial: message.serial
, display: {
orientation: message.rotation
}
})
})
.handler() .handler()
// Global messages // Global messages

View file

@ -2,6 +2,7 @@ var util = require('util')
var syrup = require('syrup') var syrup = require('syrup')
var Promise = require('bluebird') var Promise = require('bluebird')
var _ = require('lodash')
var wire = require('../../../wire') var wire = require('../../../wire')
var wireutil = require('../../../wire/util') var wireutil = require('../../../wire/util')
@ -12,6 +13,22 @@ var logger = require('../../../util/logger')
var ms = require('../../../wire/messagestream') var ms = require('../../../wire/messagestream')
var lifecycle = require('../../../util/lifecycle') var lifecycle = require('../../../util/lifecycle')
function MessageResolver() {
this.resolvers = Object.create(null)
this.await = function(id, resolver) {
this.resolvers[id] = resolver
return resolver.promise
}
this.resolve = function(id, value) {
var resolver = this.resolvers[id]
delete this.resolvers[id]
resolver.resolve(value)
return resolver.promise
}
}
module.exports = syrup.serial() module.exports = syrup.serial()
.dependency(require('../support/adb')) .dependency(require('../support/adb'))
.dependency(require('../support/router')) .dependency(require('../support/router'))
@ -19,7 +36,7 @@ module.exports = syrup.serial()
.dependency(require('../resources/service')) .dependency(require('../resources/service'))
.define(function(options, adb, router, push, apk) { .define(function(options, adb, router, push, apk) {
var log = logger.createLogger('device:plugins:input') var log = logger.createLogger('device:plugins:input')
var serviceQueue = [] var messageResolver = new MessageResolver()
var agent = { var agent = {
socket: null socket: null
@ -142,35 +159,117 @@ module.exports = syrup.serial()
.then(function(conn) { .then(function(conn) {
service.socket = conn service.socket = conn
service.reader = conn.pipe(new ms.DelimitedStream()) service.reader = conn.pipe(new ms.DelimitedStream())
service.reader.on('data', function(data) { service.reader.on('data', handleEnvelope)
if (serviceQueue.length) {
var resolver = serviceQueue.shift()
resolver.resolve(data)
}
else {
log.warn('Unexpected data from service', data)
}
})
service.writer = new ms.DelimitingStream() service.writer = new ms.DelimitingStream()
service.writer.pipe(conn) service.writer.pipe(conn)
lifecycle.share('InputService connection', conn) lifecycle.share('InputService connection', conn)
}) })
} }
function handleEnvelope(data) {
var envelope = apk.wire.Envelope.decode(data)
if (envelope.id !== null) {
messageResolver.resolve(envelope.id, envelope.message)
}
else {
switch (envelope.type) {
case apk.wire.MessageType.EVENT_AIRPLANE_MODE:
var message = apk.wire.AirplaneModeEvent.decode(envelope.message)
push.send([
wireutil.global
, wireutil.envelope(new wire.AirplaneModeEvent(
options.serial
, message.enabled
))
])
break
case apk.wire.MessageType.EVENT_BATTERY:
var message = apk.wire.BatteryEvent.decode(envelope.message)
push.send([
wireutil.global
, wireutil.envelope(new wire.BatteryEvent(
options.serial
, message.status
, message.health
, message.source
, message.level
, message.scale
, message.temp
, message.voltage
))
])
break
case apk.wire.MessageType.EVENT_BROWSER_PACKAGE:
var message = apk.wire.BrowserPackageEvent.decode(envelope.message)
push.send([
wireutil.global
, wireutil.envelope(new wire.BrowserPackageEvent(
options.serial
, message.selected
, message.apps.map(function(app) {
return new wire.BrowserApp(
app.name
, app.component
, app.selected
)
})
))
])
break
case apk.wire.MessageType.EVENT_CONNECTIVITY:
var message = apk.wire.ConnectivityEvent.decode(envelope.message)
push.send([
wireutil.global
, wireutil.envelope(new wire.ConnectivityEvent(
options.serial
, message.connected
, message.type
, message.subtype
, message.failover
, message.roaming
))
])
break
case apk.wire.MessageType.EVENT_PHONE_STATE:
var message = apk.wire.PhoneStateEvent.decode(envelope.message)
push.send([
wireutil.global
, wireutil.envelope(new wire.PhoneStateEvent(
options.serial
, message.state
, message.manual
, message.operator
))
])
break
case apk.wire.MessageType.EVENT_ROTATION:
var message = apk.wire.RotationEvent.decode(envelope.message)
push.send([
wireutil.global
, wireutil.envelope(new wire.RotationEvent(
options.serial
, message.rotation
))
])
break
}
}
}
function stopService() { function stopService() {
return callService(util.format("-a '%s'", apk.stopAction)) return callService(util.format("-a '%s'", apk.stopAction))
} }
function keyEvent(data) { function keyEvent(data) {
return runAgentCommand( return runAgentCommand(
apk.wire.RequestType.KEYEVENT apk.wire.MessageType.DO_KEYEVENT
, new apk.wire.KeyEventRequest(data) , new apk.wire.KeyEventRequest(data)
) )
} }
function type(text) { function type(text) {
return runAgentCommand( return runAgentCommand(
apk.wire.RequestType.TYPE apk.wire.MessageType.DO_TYPE
, new apk.wire.TypeRequest(text) , new apk.wire.TypeRequest(text)
) )
} }
@ -179,7 +278,7 @@ module.exports = syrup.serial()
return setClipboard(text) return setClipboard(text)
.then(function() { .then(function() {
keyEvent({ keyEvent({
event: apk.wire.KeyEvent.PRESS event: apk.wire.MessageType.DO_PRESS
, keyCode: adb.Keycode.KEYCODE_V , keyCode: adb.Keycode.KEYCODE_V
, ctrlKey: true , ctrlKey: true
}) })
@ -188,33 +287,33 @@ module.exports = syrup.serial()
function wake() { function wake() {
return runAgentCommand( return runAgentCommand(
apk.wire.RequestType.WAKE apk.wire.MessageType.DO_WAKE
, new apk.wire.WakeRequest() , new apk.wire.WakeRequest()
) )
} }
function freezeRotation(rotation) { function freezeRotation(rotation) {
return runAgentCommand( return runAgentCommand(
apk.wire.RequestType.SET_ROTATION apk.wire.MessageType.SET_ROTATION
, new apk.wire.SetRotationRequest(rotation, true) , new apk.wire.SetRotationRequest(rotation, true)
) )
} }
function thawRotation() { function thawRotation() {
return runAgentCommand( return runAgentCommand(
apk.wire.RequestType.SET_ROTATION apk.wire.MessageType.SET_ROTATION
, new apk.wire.SetRotationRequest(0, false) , new apk.wire.SetRotationRequest(0, false)
) )
} }
function version() { function version() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.VERSION apk.wire.MessageType.GET_VERSION
, new apk.wire.VersionRequest() , new apk.wire.GetVersionRequest()
) )
.timeout(10000) .timeout(10000)
.then(function(data) { .then(function(data) {
var response = apk.wire.VersionResponse.decode(data) var response = apk.wire.GetVersionResponse.decode(data)
if (response.success) { if (response.success) {
return response.version return response.version
} }
@ -224,7 +323,7 @@ module.exports = syrup.serial()
function unlock() { function unlock() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.SET_KEYGUARD_STATE apk.wire.MessageType.SET_KEYGUARD_STATE
, new apk.wire.SetKeyguardStateRequest(false) , new apk.wire.SetKeyguardStateRequest(false)
) )
.timeout(10000) .timeout(10000)
@ -238,7 +337,7 @@ module.exports = syrup.serial()
function lock() { function lock() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.SET_KEYGUARD_STATE apk.wire.MessageType.SET_KEYGUARD_STATE
, new apk.wire.SetKeyguardStateRequest(true) , new apk.wire.SetKeyguardStateRequest(true)
) )
.timeout(10000) .timeout(10000)
@ -252,7 +351,7 @@ module.exports = syrup.serial()
function acquireWakeLock() { function acquireWakeLock() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.SET_WAKE_LOCK apk.wire.MessageType.SET_WAKE_LOCK
, new apk.wire.SetWakeLockRequest(true) , new apk.wire.SetWakeLockRequest(true)
) )
.timeout(10000) .timeout(10000)
@ -266,7 +365,7 @@ module.exports = syrup.serial()
function releaseWakeLock() { function releaseWakeLock() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.SET_WAKE_LOCK apk.wire.MessageType.SET_WAKE_LOCK
, new apk.wire.SetWakeLockRequest(false) , new apk.wire.SetWakeLockRequest(false)
) )
.timeout(10000) .timeout(10000)
@ -280,12 +379,12 @@ module.exports = syrup.serial()
function identity() { function identity() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.IDENTIFY apk.wire.MessageType.DO_IDENTIFY
, new apk.wire.IdentifyRequest(options.serial) , new apk.wire.DoIdentifyRequest(options.serial)
) )
.timeout(10000) .timeout(10000)
.then(function(data) { .then(function(data) {
var response = apk.wire.IdentifyResponse.decode(data) var response = apk.wire.DoIdentifyResponse.decode(data)
if (!response.success) { if (!response.success) {
throw new Error('Unable to identify device') throw new Error('Unable to identify device')
} }
@ -294,7 +393,7 @@ module.exports = syrup.serial()
function setClipboard(text) { function setClipboard(text) {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.SET_CLIPBOARD apk.wire.MessageType.SET_CLIPBOARD
, new apk.wire.SetClipboardRequest( , new apk.wire.SetClipboardRequest(
apk.wire.ClipboardType.TEXT apk.wire.ClipboardType.TEXT
, text , text
@ -311,7 +410,7 @@ module.exports = syrup.serial()
function getClipboard() { function getClipboard() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.GET_CLIPBOARD apk.wire.MessageType.GET_CLIPBOARD
, new apk.wire.GetClipboardRequest( , new apk.wire.GetClipboardRequest(
apk.wire.ClipboardType.TEXT apk.wire.ClipboardType.TEXT
) )
@ -331,7 +430,7 @@ module.exports = syrup.serial()
function getBrowsers() { function getBrowsers() {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.GET_BROWSERS apk.wire.MessageType.GET_BROWSERS
, new apk.wire.GetBrowsersRequest() , new apk.wire.GetBrowsersRequest()
) )
.timeout(15000) .timeout(15000)
@ -347,7 +446,7 @@ module.exports = syrup.serial()
function getProperties(properties) { function getProperties(properties) {
return runServiceCommand( return runServiceCommand(
apk.wire.RequestType.GET_PROPERTIES apk.wire.MessageType.GET_PROPERTIES
, new apk.wire.GetPropertiesRequest(properties) , new apk.wire.GetPropertiesRequest(properties)
) )
.timeout(15000) .timeout(15000)
@ -366,16 +465,17 @@ module.exports = syrup.serial()
function runServiceCommand(type, cmd) { function runServiceCommand(type, cmd) {
var resolver = Promise.defer() var resolver = Promise.defer()
service.writer.write(new apk.wire.RequestEnvelope( var id = Math.floor(Math.random() * 0xFFFFFF)
type service.writer.write(new apk.wire.Envelope(
id
, type
, cmd.encodeNB() , cmd.encodeNB()
).encodeNB()) ).encodeNB())
serviceQueue.push(resolver) return messageResolver.await(id, resolver)
return resolver.promise
} }
function runAgentCommand(type, cmd) { function runAgentCommand(type, cmd) {
agent.writer.write(new apk.wire.RequestEnvelope( agent.writer.write(new apk.wire.Envelope(
type type
, cmd.encodeNB() , cmd.encodeNB()
).encodeNB()) ).encodeNB())

View file

@ -15,13 +15,13 @@ module.exports = syrup.serial()
var log = logger.createLogger('device:resources:service') var log = logger.createLogger('device:resources:service')
var resource = { var resource = {
requiredVersion: '0.5.1' requiredVersion: '0.6.2'
, pkg: 'jp.co.cyberagent.stf' , pkg: 'jp.co.cyberagent.stf'
, main: 'jp.co.cyberagent.stf.Agent' , main: 'jp.co.cyberagent.stf.Agent'
, apk: pathutil.vendor('STFService/STFService.apk') , apk: pathutil.vendor('STFService/STFService.apk')
, wire: ProtoBuf.loadProtoFile( , wire: ProtoBuf.loadProtoFile(
pathutil.vendor('STFService/wire.proto') pathutil.vendor('STFService/wire.proto')
).build().jp.co.cyberagent.stf ).build().jp.co.cyberagent.stf.proto
, startAction: 'jp.co.cyberagent.stf.ACTION_START' , startAction: 'jp.co.cyberagent.stf.ACTION_START'
, stopAction: 'jp.co.cyberagent.stf.ACTION_STOP' , stopAction: 'jp.co.cyberagent.stf.ACTION_STOP'
} }

View file

@ -94,6 +94,30 @@ module.exports = function(options) {
.on(wire.DeviceLogcatEntryMessage, function(channel, message, data) { .on(wire.DeviceLogcatEntryMessage, function(channel, message, data) {
appDealer.send([channel, data]) appDealer.send([channel, data])
}) })
.on(wire.AirplaneModeEvent, function(channel, message, data) {
dbapi.setDeviceAirplaneMode(message.serial, message.enabled)
appDealer.send([channel, data])
})
.on(wire.BatteryEvent, function(channel, message, data) {
dbapi.setDeviceBattery(message.serial, message)
appDealer.send([channel, data])
})
.on(wire.BrowserPackageEvent, function(channel, message, data) {
dbapi.setDeviceBrowser(message.serial, message)
appDealer.send([channel, data])
})
.on(wire.ConnectivityEvent, function(channel, message, data) {
dbapi.setDeviceConnectivity(message.serial, message)
appDealer.send([channel, data])
})
.on(wire.PhoneStateEvent, function(channel, message, data) {
dbapi.setDevicePhoneState(message.serial, message)
appDealer.send([channel, data])
})
.on(wire.RotationEvent, function(channel, message, data) {
dbapi.setDeviceRotation(message.serial, message.rotation)
appDealer.send([channel, data])
})
.handler()) .handler())
lifecycle.observe(function() { lifecycle.observe(function() {

View file

@ -43,6 +43,12 @@ enum MessageType {
LogcatStopMessage = 40; LogcatStopMessage = 40;
BrowserOpenMessage = 41; BrowserOpenMessage = 41;
BrowserClearMessage = 42; BrowserClearMessage = 42;
AirplaneModeEvent = 43;
BatteryEvent = 44;
BrowserPackageEvent = 45;
ConnectivityEvent = 46;
PhoneStateEvent = 47;
RotationEvent = 48;
} }
message Envelope { message Envelope {
@ -387,3 +393,54 @@ message BrowserOpenMessage {
message BrowserClearMessage { message BrowserClearMessage {
optional string browser = 1; optional string browser = 1;
} }
// Events, these must be kept in sync with STFService/wire.proto
message AirplaneModeEvent {
required string serial = 1;
required bool enabled = 2;
}
message BatteryEvent {
required string serial = 1;
required string status = 2;
required string health = 3;
required string source = 4;
required uint32 level = 5;
required uint32 scale = 6;
required double temp = 7;
required double voltage = 8;
}
message BrowserApp {
required string name = 1;
required string component = 2;
required bool selected = 3;
}
message BrowserPackageEvent {
required string serial = 1;
required bool selected = 2;
repeated BrowserApp apps = 3;
}
message ConnectivityEvent {
required string serial = 1;
required bool connected = 2;
optional string type = 3;
optional string subtype = 4;
optional bool failover = 5;
optional bool roaming = 6;
}
message PhoneStateEvent {
required string serial = 1;
required string state = 2;
required bool manual = 3;
optional string operator = 4;
}
message RotationEvent {
required string serial = 1;
required int32 rotation = 2;
}

View file

@ -74,7 +74,7 @@ module.exports = function DeviceServiceFactory($http, socket) {
} }
function modify(data, newData) { function modify(data, newData) {
_.assign(data, newData) _.merge(data, newData)
sync(data) sync(data)
notify() notify()
} }

Binary file not shown.

View file

@ -1,33 +1,85 @@
package jp.co.cyberagent.stf; package jp.co.cyberagent.stf.proto;
option java_outer_classname = "Wire"; option java_outer_classname = "Wire";
enum RequestType { enum MessageType {
VERSION = 0; DO_IDENTIFY = 1;
SET_KEYGUARD_STATE = 1; DO_KEYEVENT = 2;
SET_WAKE_LOCK = 2; DO_TYPE = 3;
SET_CLIPBOARD = 3; DO_WAKE = 4;
GET_CLIPBOARD = 4;
GET_BROWSERS = 5; GET_BROWSERS = 5;
GET_PROPERTIES = 6; GET_CLIPBOARD = 6;
IDENTIFY = 7; GET_PROPERTIES = 7;
KEYEVENT = 8; GET_VERSION = 8;
TYPE = 9; SET_CLIPBOARD = 9;
WAKE = 10; SET_KEYGUARD_STATE = 10;
SET_ROTATION = 11; SET_WAKE_LOCK = 11;
SET_ROTATION = 12;
EVENT_AIRPLANE_MODE = 13;
EVENT_BATTERY = 14;
EVENT_CONNECTIVITY = 15;
EVENT_PHONE_STATE = 16;
EVENT_ROTATION = 17;
EVENT_BROWSER_PACKAGE = 18;
} }
message RequestEnvelope { message Envelope {
required RequestType type = 1; optional uint32 id = 1;
required bytes request = 2; required MessageType type = 2;
required bytes message = 3;
}
// Events
message AirplaneModeEvent {
required bool enabled = 1;
}
message BatteryEvent {
required string status = 1;
required string health = 2;
required string source = 3;
required uint32 level = 4;
required uint32 scale = 5;
required double temp = 6;
required double voltage = 7;
}
message BrowserApp {
required string name = 1;
required string component = 2;
required bool selected = 3;
}
message BrowserPackageEvent {
required bool selected = 1;
repeated BrowserApp apps = 2;
}
message ConnectivityEvent {
required bool connected = 1;
optional string type = 2;
optional string subtype = 3;
optional bool failover = 4;
optional bool roaming = 5;
}
message PhoneStateEvent {
required string state = 1;
required bool manual = 2;
optional string operator = 3;
}
message RotationEvent {
required int32 rotation = 1;
} }
// Service // Service
message VersionRequest { message GetVersionRequest {
} }
message VersionResponse { message GetVersionResponse {
required bool success = 1; required bool success = 1;
optional string version = 2; optional string version = 2;
} }
@ -71,13 +123,6 @@ message GetClipboardResponse {
optional string text = 3; 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 GetBrowsersRequest {
} }
@ -101,11 +146,11 @@ message GetPropertiesResponse {
repeated Property properties = 2; repeated Property properties = 2;
} }
message IdentifyRequest { message DoIdentifyRequest {
required string serial = 1; required string serial = 1;
} }
message IdentifyResponse { message DoIdentifyResponse {
required bool success = 1; required bool success = 1;
} }
@ -131,7 +176,7 @@ message KeyEventRequest {
optional bool numLockKey = 11; optional bool numLockKey = 11;
} }
message TypeRequest { message DoTypeRequest {
required string text = 1; required string text = 1;
} }
@ -140,5 +185,5 @@ message SetRotationRequest {
required bool lock = 2; required bool lock = 2;
} }
message WakeRequest { message DoWakeRequest {
} }