1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-04 18:29:17 +02:00
OpenSTF/lib/units/device/plugins/vnc/index.js
2015-09-15 04:25:21 +09:00

166 lines
4.7 KiB
JavaScript

var net = require('net')
var util = require('util')
var syrup = require('stf-syrup')
var Promise = require('bluebird')
var uuid = require('node-uuid')
var jpeg = require('jpeg-turbo')
var logger = require('../../../../util/logger')
var lifecycle = require('../../../../util/lifecycle')
var VncServer = require('./util/server')
var VncConnection = require('./util/connection')
var PointerTranslator = require('./util/pointertranslator')
module.exports = syrup.serial()
.dependency(require('../screen/stream'))
.dependency(require('../touch'))
.define(function(options, screenStream, touch) {
var log = logger.createLogger('device:plugins:vnc')
function createServer() {
log.info('Starting VNC server on port %d', options.vncPort)
var opts = {
name: options.serial
, width: options.vncInitialSize[0]
, height: options.vncInitialSize[1]
}
var vnc = new VncServer(net.createServer({
allowHalfOpen: true
}), opts)
var listeningListener, errorListener
return new Promise(function(resolve, reject) {
listeningListener = function() {
return resolve(vnc)
}
errorListener = function(err) {
return reject(err)
}
vnc.on('listening', listeningListener)
vnc.on('error', errorListener)
vnc.listen(options.vncPort)
})
.finally(function() {
vnc.removeListener('listening', listeningListener)
vnc.removeListener('error', errorListener)
})
}
return createServer()
.then(function(vnc) {
vnc.on('connection', function(conn) {
var id = util.format('vnc-%s', uuid.v4())
var connState = {
lastFrame: null
, lastFrameTime: null
, frameWidth: 0
, frameHeight: 0
, sentFrameTime: null
, updateRequests: 0
}
var pointerTranslator = new PointerTranslator()
pointerTranslator.on('touchdown', function(event) {
touch.touchDown(event)
})
pointerTranslator.on('touchmove', function(event) {
touch.touchMove(event)
})
pointerTranslator.on('touchup', function(event) {
touch.touchUp(event)
})
pointerTranslator.on('touchcommit', function() {
touch.touchCommit()
})
function vncStartListener(frameProducer) {
return new Promise(function(resolve/*, reject*/) {
connState.frameWidth = frameProducer.banner.virtualWidth
connState.frameHeight = frameProducer.banner.virtualHeight
resolve()
})
}
function vncFrameListener(frame) {
return new Promise(function(resolve/*, reject*/) {
connState.lastFrame = frame
connState.lastFrameTime = Date.now()
maybeSendFrame()
resolve()
})
}
function maybeSendFrame() {
if (!connState.updateRequests) {
return
}
if (!connState.lastFrame) {
return
}
if (connState.lastFrameTime === connState.sentFrameTime) {
return
}
var decoded = jpeg.decompressSync(connState.lastFrame)
conn.writeFramebufferUpdate([
{ xPosition: 0
, yPosition: 0
, width: decoded.width
, height: decoded.height
, encodingType: VncConnection.ENCODING_RAW
, data: decoded.data
}
, { xPosition: 0
, yPosition: 0
, width: decoded.width
, height: decoded.height
, encodingType: VncConnection.ENCODING_DESKTOPSIZE
}
])
connState.updateRequests = 0
connState.sentFrameTime = connState.lastFrameTime
}
conn.on('authenticated', function() {
screenStream.updateProjection(
options.vncInitialSize[0], options.vncInitialSize[1])
screenStream.broadcastSet.insert(id, {
onStart: vncStartListener
, onFrame: vncFrameListener
})
})
conn.on('fbupdaterequest', function() {
connState.updateRequests += 1
maybeSendFrame()
})
conn.on('pointer', function(event) {
pointerTranslator.push(event)
})
conn.on('close', function() {
screenStream.broadcastSet.remove(id)
})
})
lifecycle.observe(function() {
vnc.close()
})
})
})