mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
218 lines
5.1 KiB
JavaScript
218 lines
5.1 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
|
|
|
|
var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
|
.getService(Ci.mozIJSSubScriptLoader);
|
|
|
|
/**
|
|
* Start a new RIL worker.
|
|
*
|
|
* @param custom_ns
|
|
* Namespace with symbols to be injected into the new worker
|
|
* namespace.
|
|
*
|
|
* @return an object that represents the worker's namespace.
|
|
*
|
|
* @note that this does not start an actual worker thread. The worker
|
|
* is executed on the main thread, within a separate namespace object.
|
|
*/
|
|
function newWorker(custom_ns) {
|
|
let worker_ns = {
|
|
importScripts: function() {
|
|
Array.slice(arguments).forEach(function(script) {
|
|
if (!script.startsWith("resource:")) {
|
|
script = "resource://gre/modules/" + script;
|
|
}
|
|
subscriptLoader.loadSubScript(script, this);
|
|
}, this);
|
|
},
|
|
|
|
postRILMessage: function(message) {
|
|
},
|
|
|
|
postMessage: function(message) {
|
|
},
|
|
|
|
// Define these variables inside the worker scope so ES5 strict mode
|
|
// doesn't flip out.
|
|
onmessage: undefined,
|
|
onerror: undefined,
|
|
|
|
DEBUG: true
|
|
};
|
|
// The 'self' variable in a worker points to the worker's own namespace.
|
|
worker_ns.self = worker_ns;
|
|
|
|
// Copy the custom definitions over.
|
|
for (let key in custom_ns) {
|
|
worker_ns[key] = custom_ns[key];
|
|
}
|
|
|
|
// fake require() for toolkit/components/workerloader/require.js
|
|
let require = (function() {
|
|
return function require(script) {
|
|
worker_ns.module = {};
|
|
worker_ns.importScripts(script);
|
|
return worker_ns;
|
|
}
|
|
})();
|
|
|
|
Object.freeze(require);
|
|
Object.defineProperty(worker_ns, "require", {
|
|
value: require,
|
|
enumerable: true,
|
|
configurable: false
|
|
});
|
|
|
|
// Load the RIL worker itself.
|
|
worker_ns.importScripts("ril_worker.js");
|
|
|
|
// Register at least one client.
|
|
worker_ns.ContextPool.registerClient({ clientId: 0 });
|
|
|
|
return worker_ns;
|
|
}
|
|
|
|
/**
|
|
* Create a buffered RIL worker.
|
|
*
|
|
* @return A worker object that stores sending octets in a internal buffer.
|
|
*/
|
|
function newUint8Worker() {
|
|
let worker = newWorker();
|
|
let index = 0; // index for read
|
|
let buf = [];
|
|
|
|
let context = worker.ContextPool._contexts[0];
|
|
context.Buf.writeUint8 = function(value) {
|
|
buf.push(value);
|
|
};
|
|
|
|
context.Buf.readUint8 = function() {
|
|
return buf[index++];
|
|
};
|
|
|
|
context.Buf.seekIncoming = function(offset) {
|
|
index += offset;
|
|
};
|
|
|
|
context.Buf.getReadAvailable = function() {
|
|
return buf.length - index;
|
|
};
|
|
|
|
worker.debug = do_print;
|
|
|
|
return worker;
|
|
}
|
|
|
|
/**
|
|
* Create a worker that keeps posted chrome message.
|
|
*/
|
|
function newInterceptWorker() {
|
|
let postedMessage;
|
|
let worker = newWorker({
|
|
postRILMessage: function(data) {
|
|
},
|
|
postMessage: function(message) {
|
|
postedMessage = message;
|
|
}
|
|
});
|
|
return {
|
|
get postedMessage() {
|
|
return postedMessage;
|
|
},
|
|
get worker() {
|
|
return worker;
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create a parcel suitable for postRILMessage().
|
|
*
|
|
* @param fakeParcelSize
|
|
* Value to be written to parcel size field for testing
|
|
* incorrect/incomplete parcel reading. Replaced with correct
|
|
* one determined length of data if negative.
|
|
* @param response
|
|
* Response code of the incoming parcel.
|
|
* @param request
|
|
* Request code of the incoming parcel.
|
|
* @param data
|
|
* Extra data to be appended.
|
|
*
|
|
* @return an Uint8Array carrying all parcel data.
|
|
*/
|
|
function newIncomingParcel(fakeParcelSize, response, request, data) {
|
|
const UINT32_SIZE = 4;
|
|
const PARCEL_SIZE_SIZE = 4;
|
|
|
|
let realParcelSize = data.length + 2 * UINT32_SIZE;
|
|
let buffer = new ArrayBuffer(realParcelSize + PARCEL_SIZE_SIZE);
|
|
let bytes = new Uint8Array(buffer);
|
|
|
|
let writeIndex = 0;
|
|
function writeUint8(value) {
|
|
bytes[writeIndex] = value;
|
|
++writeIndex;
|
|
}
|
|
|
|
function writeInt32(value) {
|
|
writeUint8(value & 0xff);
|
|
writeUint8((value >> 8) & 0xff);
|
|
writeUint8((value >> 16) & 0xff);
|
|
writeUint8((value >> 24) & 0xff);
|
|
}
|
|
|
|
function writeParcelSize(value) {
|
|
writeUint8((value >> 24) & 0xff);
|
|
writeUint8((value >> 16) & 0xff);
|
|
writeUint8((value >> 8) & 0xff);
|
|
writeUint8(value & 0xff);
|
|
}
|
|
|
|
if (fakeParcelSize < 0) {
|
|
fakeParcelSize = realParcelSize;
|
|
}
|
|
writeParcelSize(fakeParcelSize);
|
|
|
|
writeInt32(response);
|
|
writeInt32(request);
|
|
|
|
// write parcel data
|
|
for (let ii = 0; ii < data.length; ++ii) {
|
|
writeUint8(data[ii]);
|
|
}
|
|
|
|
return bytes;
|
|
}
|
|
|
|
/**
|
|
* Create a parcel buffer which represents the hex string.
|
|
*
|
|
* @param hexString
|
|
* The HEX string to be converted.
|
|
*
|
|
* @return an Uint8Array carrying all parcel data.
|
|
*/
|
|
function hexStringToParcelByteArrayData(hexString) {
|
|
let length = Math.ceil((hexString.length / 2));
|
|
let bytes = new Uint8Array(4 + length);
|
|
|
|
bytes[0] = length & 0xFF;
|
|
bytes[1] = (length >> 8) & 0xFF;
|
|
bytes[2] = (length >> 16) & 0xFF;
|
|
bytes[3] = (length >> 24) & 0xFF;
|
|
|
|
for (let i = 0; i < length; i ++) {
|
|
bytes[i + 4] = Number.parseInt(hexString.substr(i * 2, 2), 16);
|
|
}
|
|
|
|
return bytes;
|
|
}
|