mirror of
https://github.com/openstf/stf
synced 2025-10-04 02:09:32 +02:00
Fix Galaxy S5's display information segfaulting by trying to use the public SDK methods first. SurfaceComposerClient's getDisplayInfo is practically unusable on Galaxy S5 due to weird memory corruption issues.
This commit is contained in:
parent
2f5a882099
commit
6bb07d7c34
16 changed files with 87 additions and 40 deletions
|
@ -174,7 +174,7 @@ dbapi.setDevicePhoneState = function(serial, state) {
|
||||||
dbapi.setDeviceRotation = function(serial, rotation) {
|
dbapi.setDeviceRotation = function(serial, rotation) {
|
||||||
return db.run(r.table('devices').get(serial).update({
|
return db.run(r.table('devices').get(serial).update({
|
||||||
display: {
|
display: {
|
||||||
orientation: rotation
|
rotation: rotation
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,10 @@ module.exports = function(options) {
|
||||||
log.info('Preparing device')
|
log.info('Preparing device')
|
||||||
return syrup.serial()
|
return syrup.serial()
|
||||||
.dependency(require('./device/plugins/solo'))
|
.dependency(require('./device/plugins/solo'))
|
||||||
.dependency(require('./device/plugins/display'))
|
|
||||||
.dependency(require('./device/plugins/screenshot'))
|
.dependency(require('./device/plugins/screenshot'))
|
||||||
.dependency(require('./device/plugins/http'))
|
.dependency(require('./device/plugins/http'))
|
||||||
.dependency(require('./device/plugins/service'))
|
.dependency(require('./device/plugins/service'))
|
||||||
|
.dependency(require('./device/plugins/display'))
|
||||||
.dependency(require('./device/plugins/browser'))
|
.dependency(require('./device/plugins/browser'))
|
||||||
.dependency(require('./device/plugins/store'))
|
.dependency(require('./device/plugins/store'))
|
||||||
.dependency(require('./device/plugins/clipboard'))
|
.dependency(require('./device/plugins/clipboard'))
|
||||||
|
|
|
@ -3,13 +3,22 @@ var syrup = require('syrup')
|
||||||
var logger = require('../../../util/logger')
|
var logger = require('../../../util/logger')
|
||||||
|
|
||||||
module.exports = syrup.serial()
|
module.exports = syrup.serial()
|
||||||
|
.dependency(require('./service'))
|
||||||
.dependency(require('./http'))
|
.dependency(require('./http'))
|
||||||
.define(function(options, http) {
|
.define(function(options, service, http) {
|
||||||
var log = logger.createLogger('device:plugins:display')
|
var log = logger.createLogger('device:plugins:display')
|
||||||
|
|
||||||
function fetch() {
|
function fetch() {
|
||||||
log.info('Fetching display info')
|
log.info('Fetching display info')
|
||||||
return http.getDisplay(0)
|
return service.getDisplay(0)
|
||||||
|
.catch(function() {
|
||||||
|
log.info('Falling back to HTTP API')
|
||||||
|
return http.getDisplay(0)
|
||||||
|
})
|
||||||
|
.then(function(display) {
|
||||||
|
display.url = http.getDisplayUrl(display.id)
|
||||||
|
return display
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch()
|
return fetch()
|
||||||
|
|
|
@ -123,14 +123,21 @@ module.exports = syrup.serial()
|
||||||
.then(function(args) {
|
.then(function(args) {
|
||||||
var display = args[1]
|
var display = args[1]
|
||||||
assert.ok('id' in display, 'Invalid response from HTTP API')
|
assert.ok('id' in display, 'Invalid response from HTTP API')
|
||||||
display.url = util.format(
|
// Fix rotation's old name
|
||||||
'%s/api/v1/displays/%d/screenshot.jpg'
|
if ('orientation' in display) {
|
||||||
, service.publicUrl
|
display.rotation = display.orientation
|
||||||
, id
|
delete display.orientation
|
||||||
)
|
}
|
||||||
return display
|
return display
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
, getDisplayUrl: function(id) {
|
||||||
|
return util.format(
|
||||||
|
'%s/api/v1/displays/%d/screenshot.jpg'
|
||||||
|
, service.publicUrl
|
||||||
|
, id
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -280,6 +280,31 @@ module.exports = syrup.serial()
|
||||||
return plugin.getClipboard()
|
return plugin.getClipboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugin.getDisplay = function(id) {
|
||||||
|
return runServiceCommand(
|
||||||
|
apk.wire.MessageType.GET_DISPLAY
|
||||||
|
, new apk.wire.GetDisplayRequest(id)
|
||||||
|
)
|
||||||
|
.timeout(10000)
|
||||||
|
.then(function(data) {
|
||||||
|
var response = apk.wire.GetDisplayResponse.decode(data)
|
||||||
|
if (response.success) {
|
||||||
|
return {
|
||||||
|
id: id
|
||||||
|
, width: response.width
|
||||||
|
, height: response.height
|
||||||
|
, xdpi: response.xdpi
|
||||||
|
, ydpi: response.ydpi
|
||||||
|
, fps: response.fps
|
||||||
|
, density: response.density
|
||||||
|
, rotation: response.rotation
|
||||||
|
, secure: response.secure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Unable to retrieve display information')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
plugin.wake = function() {
|
plugin.wake = function() {
|
||||||
return runAgentCommand(
|
return runAgentCommand(
|
||||||
apk.wire.MessageType.DO_WAKE
|
apk.wire.MessageType.DO_WAKE
|
||||||
|
|
|
@ -28,18 +28,7 @@ module.exports = syrup.serial()
|
||||||
, identity.version
|
, identity.version
|
||||||
, identity.abi
|
, identity.abi
|
||||||
, identity.sdk
|
, identity.sdk
|
||||||
, new wire.DeviceDisplayMessage(
|
, new wire.DeviceDisplayMessage(identity.display)
|
||||||
identity.display.id
|
|
||||||
, identity.display.width
|
|
||||||
, identity.display.height
|
|
||||||
, identity.display.orientation
|
|
||||||
, identity.display.xdpi
|
|
||||||
, identity.display.ydpi
|
|
||||||
, identity.display.fps
|
|
||||||
, identity.display.density
|
|
||||||
, identity.display.secure
|
|
||||||
, identity.display.url
|
|
||||||
)
|
|
||||||
, new wire.DevicePhoneMessage(identity.phone)
|
, new wire.DevicePhoneMessage(identity.phone)
|
||||||
))
|
))
|
||||||
])
|
])
|
||||||
|
|
|
@ -15,7 +15,7 @@ module.exports = syrup.serial()
|
||||||
var log = logger.createLogger('device:resources:service')
|
var log = logger.createLogger('device:resources:service')
|
||||||
|
|
||||||
var resource = {
|
var resource = {
|
||||||
requiredVersion: '0.7.3'
|
requiredVersion: '0.7.7'
|
||||||
, 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')
|
||||||
|
|
|
@ -236,7 +236,7 @@ module.exports = function(options) {
|
||||||
, data: {
|
, data: {
|
||||||
serial: message.serial
|
serial: message.serial
|
||||||
, display: {
|
, display: {
|
||||||
orientation: message.rotation
|
rotation: message.rotation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -33,7 +33,7 @@ module.exports.generate = function() {
|
||||||
, fps: 60
|
, fps: 60
|
||||||
, height: 1920
|
, height: 1920
|
||||||
, id: 0
|
, id: 0
|
||||||
, orientation: 0
|
, rotation: 0
|
||||||
, secure: true
|
, secure: true
|
||||||
, url: '/404.jpg'
|
, url: '/404.jpg'
|
||||||
, width: 1080
|
, width: 1080
|
||||||
|
|
|
@ -131,14 +131,14 @@ message DeviceStatusMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeviceDisplayMessage {
|
message DeviceDisplayMessage {
|
||||||
required uint32 id = 1;
|
required int32 id = 1;
|
||||||
required uint32 width = 2;
|
required int32 width = 2;
|
||||||
required uint32 height = 3;
|
required int32 height = 3;
|
||||||
required uint32 orientation = 4;
|
required int32 rotation = 4;
|
||||||
required uint32 xdpi = 5;
|
required float xdpi = 5;
|
||||||
required uint32 ydpi = 6;
|
required float ydpi = 6;
|
||||||
required double fps = 7;
|
required float fps = 7;
|
||||||
required double density = 8;
|
required float density = 8;
|
||||||
required bool secure = 9;
|
required bool secure = 9;
|
||||||
required string url = 10;
|
required string url = 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ module.exports = function DeviceScreenDirective($document, ScalingService, Vendo
|
||||||
function sendTouch(type, e) {
|
function sendTouch(type, e) {
|
||||||
var x = e.offsetX || e.layerX || 0
|
var x = e.offsetX || e.layerX || 0
|
||||||
var y = e.offsetY || e.layerY || 0
|
var y = e.offsetY || e.layerY || 0
|
||||||
var r = scope.device.display.orientation
|
var r = scope.device.display.rotation
|
||||||
|
|
||||||
if (BrowserInfo.touch) {
|
if (BrowserInfo.touch) {
|
||||||
if (e.touches && e.touches.length) {
|
if (e.touches && e.touches.length) {
|
||||||
|
@ -304,7 +304,7 @@ module.exports = function DeviceScreenDirective($document, ScalingService, Vendo
|
||||||
scope.$watch('device.using', checkEnabled)
|
scope.$watch('device.using', checkEnabled)
|
||||||
scope.$on('visibilitychange', checkEnabled)
|
scope.$on('visibilitychange', checkEnabled)
|
||||||
|
|
||||||
scope.$watch('device.display.orientation', function (r) {
|
scope.$watch('device.display.rotation', function (r) {
|
||||||
rotation = r || 0
|
rotation = r || 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -46,14 +46,14 @@ module.exports = function DeviceControlCtrl($scope, DeviceService, GroupService,
|
||||||
|
|
||||||
function isPortrait(value) {
|
function isPortrait(value) {
|
||||||
if (typeof value === 'undefined' && $scope.device) {
|
if (typeof value === 'undefined' && $scope.device) {
|
||||||
value = $scope.device.display.orientation
|
value = $scope.device.display.rotation
|
||||||
}
|
}
|
||||||
return (value === 0 || value === 180)
|
return (value === 0 || value === 180)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLandscape(value) {
|
function isLandscape(value) {
|
||||||
if (typeof value === 'undefined' && $scope.device) {
|
if (typeof value === 'undefined' && $scope.device) {
|
||||||
value = $scope.device.display.orientation
|
value = $scope.device.display.rotation
|
||||||
}
|
}
|
||||||
return (value === 90 || value === 270)
|
return (value === 90 || value === 270)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ module.exports = function DeviceControlCtrl($scope, DeviceService, GroupService,
|
||||||
|
|
||||||
$scope.currentRotation = 'portrait'
|
$scope.currentRotation = 'portrait'
|
||||||
|
|
||||||
$scope.$watch('device.display.orientation', function (newValue, oldValue) {
|
$scope.$watch('device.display.rotation', function (newValue, oldValue) {
|
||||||
if (isPortrait(newValue)) {
|
if (isPortrait(newValue)) {
|
||||||
$scope.currentRotation = 'portrait'
|
$scope.currentRotation = 'portrait'
|
||||||
} else if (isLandscape(newValue)) {
|
} else if (isLandscape(newValue)) {
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
.btn-group
|
.btn-group
|
||||||
label.btn-sm.btn-primary-outline(type='button', ng-click='tryToRotate("portrait")',
|
label.btn-sm.btn-primary-outline(type='button', ng-click='tryToRotate("portrait")',
|
||||||
ng-model='currentRotation', btn-radio='"portrait"').pointer
|
ng-model='currentRotation', btn-radio='"portrait"').pointer
|
||||||
i.fa.fa-mobile(tooltip='{{ "Portrait" | translate }} ({{ device.display.orientation }}°)', tooltip-placement='bottom')
|
i.fa.fa-mobile(tooltip='{{ "Portrait" | translate }} ({{ device.display.rotation }}°)', tooltip-placement='bottom')
|
||||||
label.btn-sm.btn-primary-outline(type='button', ng-click='tryToRotate("landscape")',
|
label.btn-sm.btn-primary-outline(type='button', ng-click='tryToRotate("landscape")',
|
||||||
ng-model='currentRotation', btn-radio='"landscape"').pointer
|
ng-model='currentRotation', btn-radio='"landscape"').pointer
|
||||||
i.fa.fa-mobile.fa-rotate-90(tooltip='{{ "Landscape" | translate }} ({{ device.display.orientation }}°)', tooltip-placement='bottom')
|
i.fa.fa-mobile.fa-rotate-90(tooltip='{{ "Landscape" | translate }} ({{ device.display.rotation }}°)', tooltip-placement='bottom')
|
||||||
.button-spacer
|
.button-spacer
|
||||||
// NOTE: ui-bootstrap bug: tooltip breaks btn-checkbox so don't put in the same button
|
// NOTE: ui-bootstrap bug: tooltip breaks btn-checkbox so don't put in the same button
|
||||||
button(type='button', ng-model='showScreen', btn-checkbox).btn.btn-sm.btn-danger
|
button(type='button', ng-model='showScreen', btn-checkbox).btn.btn-sm.btn-danger
|
||||||
|
|
|
@ -71,7 +71,7 @@ angular-packery='{draggable: true, draggableHandle: ".heading i"}')
|
||||||
td {{device.display.id}}
|
td {{device.display.id}}
|
||||||
tr
|
tr
|
||||||
td(translate) Orientation
|
td(translate) Orientation
|
||||||
td {{device.display.orientation}}°
|
td {{device.display.rotation}}°
|
||||||
tr
|
tr
|
||||||
td(translate) Encrypted
|
td(translate) Encrypted
|
||||||
td {{device.display.secure | humanizedBool}}
|
td {{device.display.secure | humanizedBool}}
|
||||||
|
|
BIN
vendor/STFService/STFService.apk
vendored
BIN
vendor/STFService/STFService.apk
vendored
Binary file not shown.
17
vendor/STFService/wire.proto
vendored
17
vendor/STFService/wire.proto
vendored
|
@ -9,6 +9,7 @@ enum MessageType {
|
||||||
DO_WAKE = 4;
|
DO_WAKE = 4;
|
||||||
GET_BROWSERS = 5;
|
GET_BROWSERS = 5;
|
||||||
GET_CLIPBOARD = 6;
|
GET_CLIPBOARD = 6;
|
||||||
|
GET_DISPLAY = 19;
|
||||||
GET_PROPERTIES = 7;
|
GET_PROPERTIES = 7;
|
||||||
GET_VERSION = 8;
|
GET_VERSION = 8;
|
||||||
SET_CLIPBOARD = 9;
|
SET_CLIPBOARD = 9;
|
||||||
|
@ -133,6 +134,22 @@ message GetBrowsersResponse {
|
||||||
repeated BrowserApp apps = 3;
|
repeated BrowserApp apps = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetDisplayRequest {
|
||||||
|
required int32 id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetDisplayResponse {
|
||||||
|
required bool success = 1;
|
||||||
|
optional int32 width = 2;
|
||||||
|
optional int32 height = 3;
|
||||||
|
optional float xdpi = 4;
|
||||||
|
optional float ydpi = 5;
|
||||||
|
optional float fps = 6;
|
||||||
|
optional float density = 7;
|
||||||
|
optional int32 rotation = 8;
|
||||||
|
optional bool secure = 9;
|
||||||
|
}
|
||||||
|
|
||||||
message Property {
|
message Property {
|
||||||
required string name = 1;
|
required string name = 1;
|
||||||
required string value = 2;
|
required string value = 2;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue