|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 "use strict"; |
|
5 |
|
6 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; |
|
7 |
|
8 |
|
9 let subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"] |
|
10 .getService(Ci.mozIJSSubScriptLoader); |
|
11 |
|
12 /** |
|
13 * Start a new RIL worker. |
|
14 * |
|
15 * @param custom_ns |
|
16 * Namespace with symbols to be injected into the new worker |
|
17 * namespace. |
|
18 * |
|
19 * @return an object that represents the worker's namespace. |
|
20 * |
|
21 * @note that this does not start an actual worker thread. The worker |
|
22 * is executed on the main thread, within a separate namespace object. |
|
23 */ |
|
24 function newWorker(custom_ns) { |
|
25 let worker_ns = { |
|
26 importScripts: function() { |
|
27 Array.slice(arguments).forEach(function(script) { |
|
28 if (!script.startsWith("resource:")) { |
|
29 script = "resource://gre/modules/" + script; |
|
30 } |
|
31 subscriptLoader.loadSubScript(script, this); |
|
32 }, this); |
|
33 }, |
|
34 |
|
35 postRILMessage: function(message) { |
|
36 }, |
|
37 |
|
38 postMessage: function(message) { |
|
39 }, |
|
40 |
|
41 // Define these variables inside the worker scope so ES5 strict mode |
|
42 // doesn't flip out. |
|
43 onmessage: undefined, |
|
44 onerror: undefined, |
|
45 |
|
46 DEBUG: true |
|
47 }; |
|
48 // The 'self' variable in a worker points to the worker's own namespace. |
|
49 worker_ns.self = worker_ns; |
|
50 |
|
51 // Copy the custom definitions over. |
|
52 for (let key in custom_ns) { |
|
53 worker_ns[key] = custom_ns[key]; |
|
54 } |
|
55 |
|
56 // fake require() for toolkit/components/workerloader/require.js |
|
57 let require = (function() { |
|
58 return function require(script) { |
|
59 worker_ns.module = {}; |
|
60 worker_ns.importScripts(script); |
|
61 return worker_ns; |
|
62 } |
|
63 })(); |
|
64 |
|
65 Object.freeze(require); |
|
66 Object.defineProperty(worker_ns, "require", { |
|
67 value: require, |
|
68 enumerable: true, |
|
69 configurable: false |
|
70 }); |
|
71 |
|
72 // Load the RIL worker itself. |
|
73 worker_ns.importScripts("ril_worker.js"); |
|
74 |
|
75 // Register at least one client. |
|
76 worker_ns.ContextPool.registerClient({ clientId: 0 }); |
|
77 |
|
78 return worker_ns; |
|
79 } |
|
80 |
|
81 /** |
|
82 * Create a parcel suitable for postRILMessage(). |
|
83 * |
|
84 * @param fakeParcelSize |
|
85 * Value to be written to parcel size field for testing |
|
86 * incorrect/incomplete parcel reading. Replaced with correct |
|
87 * one determined length of data if negative. |
|
88 * @param response |
|
89 * Response code of the incoming parcel. |
|
90 * @param request |
|
91 * Request code of the incoming parcel. |
|
92 * @param data |
|
93 * Extra data to be appended. |
|
94 * |
|
95 * @return an Uint8Array carrying all parcel data. |
|
96 */ |
|
97 function newIncomingParcel(fakeParcelSize, response, request, data) { |
|
98 const UINT32_SIZE = 4; |
|
99 const PARCEL_SIZE_SIZE = 4; |
|
100 |
|
101 let realParcelSize = data.length + 2 * UINT32_SIZE; |
|
102 let buffer = new ArrayBuffer(realParcelSize + PARCEL_SIZE_SIZE); |
|
103 let bytes = new Uint8Array(buffer); |
|
104 |
|
105 let writeIndex = 0; |
|
106 function writeUint8(value) { |
|
107 bytes[writeIndex] = value; |
|
108 ++writeIndex; |
|
109 } |
|
110 |
|
111 function writeInt32(value) { |
|
112 writeUint8(value & 0xff); |
|
113 writeUint8((value >> 8) & 0xff); |
|
114 writeUint8((value >> 16) & 0xff); |
|
115 writeUint8((value >> 24) & 0xff); |
|
116 } |
|
117 |
|
118 function writeParcelSize(value) { |
|
119 writeUint8((value >> 24) & 0xff); |
|
120 writeUint8((value >> 16) & 0xff); |
|
121 writeUint8((value >> 8) & 0xff); |
|
122 writeUint8(value & 0xff); |
|
123 } |
|
124 |
|
125 if (fakeParcelSize < 0) { |
|
126 fakeParcelSize = realParcelSize; |
|
127 } |
|
128 writeParcelSize(fakeParcelSize); |
|
129 |
|
130 writeInt32(response); |
|
131 writeInt32(request); |
|
132 |
|
133 // write parcel data |
|
134 for (let ii = 0; ii < data.length; ++ii) { |
|
135 writeUint8(data[ii]); |
|
136 } |
|
137 |
|
138 return bytes; |
|
139 } |
|
140 |
|
141 /** |
|
142 * |
|
143 */ |
|
144 let ril_ns; |
|
145 function newRadioInterface() { |
|
146 if (!ril_ns) { |
|
147 ril_ns = {}; |
|
148 subscriptLoader.loadSubScript("resource://gre/components/RadioInterfaceLayer.js", ril_ns); |
|
149 } |
|
150 |
|
151 return { |
|
152 __proto__: ril_ns.RadioInterface.prototype, |
|
153 }; |
|
154 } |
|
155 |
|
156 /** |
|
157 * Test whether specified function throws exception with expected |
|
158 * result. |
|
159 * |
|
160 * @param func |
|
161 * Function to be tested. |
|
162 * @param message |
|
163 * Message of expected exception. <code>null</code> for no throws. |
|
164 * @param stack |
|
165 * Optional stack object to be printed. <code>null</code> for |
|
166 * Components#stack#caller. |
|
167 */ |
|
168 function do_check_throws(func, message, stack) |
|
169 { |
|
170 if (!stack) |
|
171 stack = Components.stack.caller; |
|
172 |
|
173 try { |
|
174 func(); |
|
175 } catch (exc) { |
|
176 if (exc.message === message) { |
|
177 return; |
|
178 } |
|
179 do_throw("expecting exception '" + message |
|
180 + "', caught '" + exc.message + "'", stack); |
|
181 } |
|
182 |
|
183 if (message) { |
|
184 do_throw("expecting exception '" + message + "', none thrown", stack); |
|
185 } |
|
186 } |
|
187 |