mirror of
https://github.com/openstf/stf
synced 2025-10-04 18:29:17 +02:00
166 lines
4.7 KiB
JavaScript
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()
|
|
})
|
|
})
|
|
})
|