blob: 5d845dbe1a4e4d1fd047a82b3be4304318dcc150 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/**
* @fileoverview Forwards messages to and from a nacl module.
* @private
*/
var extensionEventProxy = require('../browser/event-proxy');
var errors = require('../verror/index');
var Deferred = require('../lib/deferred');
var Proxy = require('./index');
var random = require('../lib/random');
var vlog = require('./../lib/vlog');
var byteUtil = require('../vdl/byte-util');
var vom = require('../vom');
module.exports = ProxyConnection;
/**
* A client for the vanadium service using postMessage. Connects to the vanadium
* browspr and performs RPCs.
* @constructor
* @private
*/
function ProxyConnection() {
var self = this;
this.instanceId = random.hex();
this.onBrowsprMsg = function(msg) {
var body;
try {
body = vom.decode(byteUtil.hex2Bytes(msg.body));
} catch (e) {
vlog.logger.warn('Failed to parse ' + msg.body);
return;
}
if (msg.instanceId === self.instanceId) {
self.process(body);
}
};
extensionEventProxy.on('browsprMsg', this.onBrowsprMsg);
// rethrow crash error when proxy fails.
this.onCrash = function(msg) {
self.emit('crash', new errors.ExtensionCrashError(msg));
};
extensionEventProxy.on('crash', this.onCrash);
var def = new Deferred();
Proxy.call(this, def.promise);
def.resolve(this);
}
ProxyConnection.prototype = Object.create(Proxy.prototype);
ProxyConnection.prototype.constructor = ProxyConnection;
ProxyConnection.prototype.send = function(msg) {
var wrappedMsg = {
instanceId: this.instanceId,
msg: msg
};
extensionEventProxy.send('browsprMsg', wrappedMsg);
};
ProxyConnection.prototype.close = function(cb) {
var self = this;
var defaultTimeout = 2000;
var deferred = new Deferred(cb);
extensionEventProxy.removeListener('crash', this.onCrash);
extensionEventProxy.send('browsprCleanup', {
instanceId: this.instanceId
});
var timedout = false;
var timeout = setTimeout(function reject() {
timedout = true;
extensionEventProxy.removeListener('browsprMsg', self.onBrowsprMsg);
var err = new Error('Timeout: Failed to close the runtime in ' +
defaultTimeout + ' ms');
deferred.reject(err);
}, defaultTimeout);
extensionEventProxy.once('browsprCleanupFinished', function() {
extensionEventProxy.removeListener('browsprMsg', self.onBrowsprMsg);
clearTimeout(timeout);
if(!timedout) {
deferred.resolve();
}
});
return deferred.promise;
};
ProxyConnection.prototype.createInstance = function(settings, cb) {
var msg = {
instanceId: this.instanceId,
settings: settings
};
extensionEventProxy.sendRpc('createInstance', msg, cb);
};