1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * the Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2010
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Ms2ger <ms2ger@gmail.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "ContentChild.h"
40 : #include "ContentParent.h"
41 : #include "nsFrameMessageManager.h"
42 : #include "nsContentUtils.h"
43 : #include "nsIXPConnect.h"
44 : #include "jsapi.h"
45 : #include "nsJSUtils.h"
46 : #include "nsJSPrincipals.h"
47 : #include "nsNetUtil.h"
48 : #include "nsScriptLoader.h"
49 : #include "nsIJSContextStack.h"
50 : #include "nsIXULRuntime.h"
51 : #include "nsIScriptError.h"
52 : #include "nsIConsoleService.h"
53 : #include "nsIProtocolHandler.h"
54 : #include "nsIScriptSecurityManager.h"
55 : #include "nsIJSRuntimeService.h"
56 : #include "xpcpublic.h"
57 :
58 : #ifdef ANDROID
59 : #include <android/log.h>
60 : #endif
61 :
62 : static bool
63 239 : IsChromeProcess()
64 : {
65 478 : nsCOMPtr<nsIXULRuntime> rt = do_GetService("@mozilla.org/xre/runtime;1");
66 239 : if (!rt)
67 0 : return true;
68 :
69 : PRUint32 type;
70 239 : rt->GetProcessType(&type);
71 239 : return type == nsIXULRuntime::PROCESS_TYPE_DEFAULT;
72 : }
73 :
74 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsFrameMessageManager)
75 :
76 85 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameMessageManager)
77 85 : PRUint32 count = tmp->mListeners.Length();
78 246 : for (PRUint32 i = 0; i < count; i++) {
79 161 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mListeners[i] mListener");
80 161 : cb.NoteXPCOMChild(tmp->mListeners[i].mListener.get());
81 : }
82 85 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildManagers)
83 85 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
84 :
85 25 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFrameMessageManager)
86 25 : tmp->mListeners.Clear();
87 25 : for (PRInt32 i = tmp->mChildManagers.Count(); i > 0; --i) {
88 0 : static_cast<nsFrameMessageManager*>(tmp->mChildManagers[i - 1])->
89 0 : Disconnect(false);
90 : }
91 25 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildManagers)
92 25 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
93 :
94 :
95 8013 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameMessageManager)
96 5474 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentFrameMessageManager)
97 4705 : NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIFrameMessageManager,
98 : (mChrome ?
99 : static_cast<nsIFrameMessageManager*>(
100 : static_cast<nsIChromeFrameMessageManager*>(this)) :
101 : static_cast<nsIFrameMessageManager*>(
102 : static_cast<nsIContentFrameMessageManager*>(this))))
103 : /* nsIContentFrameMessageManager is accessible only in TabChildGlobal. */
104 4672 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIContentFrameMessageManager,
105 : !mChrome && !mIsProcessManager)
106 : /* Message managers in child process support nsISyncMessageSender. */
107 4672 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISyncMessageSender, !mChrome)
108 : /* Message managers in chrome process support nsITreeItemFrameMessageManager. */
109 4672 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsITreeItemFrameMessageManager, mChrome)
110 : /* Process message manager doesn't support nsIChromeFrameMessageManager. */
111 4672 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIChromeFrameMessageManager,
112 : mChrome && !mIsProcessManager)
113 3209 : NS_INTERFACE_MAP_END
114 :
115 3342 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameMessageManager)
116 3592 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameMessageManager)
117 :
118 : NS_IMETHODIMP
119 497 : nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
120 : nsIFrameMessageListener* aListener)
121 : {
122 994 : nsCOMPtr<nsIAtom> message = do_GetAtom(aMessage);
123 497 : PRUint32 len = mListeners.Length();
124 865 : for (PRUint32 i = 0; i < len; ++i) {
125 368 : if (mListeners[i].mMessage == message &&
126 0 : mListeners[i].mListener == aListener) {
127 0 : return NS_OK;
128 : }
129 : }
130 497 : nsMessageListenerInfo* entry = mListeners.AppendElement();
131 497 : NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
132 497 : entry->mMessage = message;
133 497 : entry->mListener = aListener;
134 497 : return NS_OK;
135 : }
136 :
137 : NS_IMETHODIMP
138 0 : nsFrameMessageManager::RemoveMessageListener(const nsAString& aMessage,
139 : nsIFrameMessageListener* aListener)
140 : {
141 0 : nsCOMPtr<nsIAtom> message = do_GetAtom(aMessage);
142 0 : PRUint32 len = mListeners.Length();
143 0 : for (PRUint32 i = 0; i < len; ++i) {
144 0 : if (mListeners[i].mMessage == message &&
145 0 : mListeners[i].mListener == aListener) {
146 0 : mListeners.RemoveElementAt(i);
147 0 : return NS_OK;
148 : }
149 : }
150 0 : return NS_OK;
151 : }
152 :
153 : NS_IMETHODIMP
154 228 : nsFrameMessageManager::LoadFrameScript(const nsAString& aURL,
155 : bool aAllowDelayedLoad)
156 : {
157 228 : if (aAllowDelayedLoad) {
158 228 : if (IsGlobal() || IsWindowLevel()) {
159 : // Cache for future windows or frames
160 228 : mPendingScripts.AppendElement(aURL);
161 0 : } else if (!mCallbackData) {
162 : // We're frame message manager, which isn't connected yet.
163 0 : mPendingScripts.AppendElement(aURL);
164 0 : return NS_OK;
165 : }
166 : }
167 :
168 228 : if (mCallbackData) {
169 : #ifdef DEBUG_smaug
170 : printf("Will load %s \n", NS_ConvertUTF16toUTF8(aURL).get());
171 : #endif
172 0 : NS_ENSURE_TRUE(mLoadScriptCallback(mCallbackData, aURL), NS_ERROR_FAILURE);
173 : }
174 :
175 228 : for (PRInt32 i = 0; i < mChildManagers.Count(); ++i) {
176 : nsRefPtr<nsFrameMessageManager> mm =
177 0 : static_cast<nsFrameMessageManager*>(mChildManagers[i]);
178 0 : if (mm) {
179 : // Use false here, so that child managers don't cache the script, which
180 : // is already cached in the parent.
181 0 : mm->LoadFrameScript(aURL, false);
182 : }
183 : }
184 228 : return NS_OK;
185 : }
186 :
187 : NS_IMETHODIMP
188 0 : nsFrameMessageManager::RemoveDelayedFrameScript(const nsAString& aURL)
189 : {
190 0 : mPendingScripts.RemoveElement(aURL);
191 0 : return NS_OK;
192 : }
193 :
194 : static JSBool
195 530 : JSONCreator(const jschar* aBuf, uint32 aLen, void* aData)
196 : {
197 530 : nsAString* result = static_cast<nsAString*>(aData);
198 : result->Append(static_cast<const PRUnichar*>(aBuf),
199 530 : static_cast<PRUint32>(aLen));
200 530 : return true;
201 : }
202 :
203 : void
204 530 : nsFrameMessageManager::GetParamsForMessage(const jsval& aObject,
205 : JSContext* aCx,
206 : nsAString& aJSON)
207 : {
208 530 : aJSON.Truncate();
209 1060 : JSAutoRequest ar(aCx);
210 530 : jsval v = aObject;
211 530 : JS_Stringify(aCx, &v, nsnull, JSVAL_NULL, JSONCreator, &aJSON);
212 530 : }
213 :
214 : NS_IMETHODIMP
215 0 : nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
216 : const jsval& aObject,
217 : JSContext* aCx,
218 : PRUint8 aArgc,
219 : jsval* aRetval)
220 : {
221 0 : NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
222 0 : NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
223 0 : NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
224 0 : *aRetval = JSVAL_VOID;
225 0 : if (mSyncCallback) {
226 0 : NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
227 0 : nsString json;
228 0 : if (aArgc >= 2) {
229 0 : GetParamsForMessage(aObject, aCx, json);
230 : }
231 0 : InfallibleTArray<nsString> retval;
232 0 : if (mSyncCallback(mCallbackData, aMessageName, json, &retval)) {
233 0 : JSAutoRequest ar(aCx);
234 0 : PRUint32 len = retval.Length();
235 0 : JSObject* dataArray = JS_NewArrayObject(aCx, len, NULL);
236 0 : NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
237 :
238 0 : for (PRUint32 i = 0; i < len; ++i) {
239 0 : if (retval[i].IsEmpty()) {
240 0 : continue;
241 : }
242 :
243 0 : jsval ret = JSVAL_VOID;
244 0 : if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
245 0 : retval[i].Length(), &ret)) {
246 0 : return NS_ERROR_UNEXPECTED;
247 : }
248 0 : NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret), NS_ERROR_OUT_OF_MEMORY);
249 : }
250 :
251 0 : *aRetval = OBJECT_TO_JSVAL(dataArray);
252 : }
253 : }
254 0 : return NS_OK;
255 : }
256 :
257 : nsresult
258 530 : nsFrameMessageManager::SendAsyncMessageInternal(const nsAString& aMessage,
259 : const nsAString& aJSON)
260 : {
261 530 : if (mAsyncCallback) {
262 0 : NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
263 0 : mAsyncCallback(mCallbackData, aMessage, aJSON);
264 : }
265 530 : PRInt32 len = mChildManagers.Count();
266 530 : for (PRInt32 i = 0; i < len; ++i) {
267 0 : static_cast<nsFrameMessageManager*>(mChildManagers[i])->
268 0 : SendAsyncMessageInternal(aMessage, aJSON);
269 : }
270 530 : return NS_OK;
271 : }
272 :
273 : NS_IMETHODIMP
274 530 : nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
275 : const jsval& aObject,
276 : JSContext* aCx,
277 : PRUint8 aArgc)
278 : {
279 1060 : nsString json;
280 530 : if (aArgc >= 2) {
281 530 : GetParamsForMessage(aObject, aCx, json);
282 : }
283 530 : return SendAsyncMessageInternal(aMessageName, json);
284 : }
285 :
286 : NS_IMETHODIMP
287 0 : nsFrameMessageManager::Dump(const nsAString& aStr)
288 : {
289 : #ifdef ANDROID
290 : __android_log_print(ANDROID_LOG_INFO, "Gecko", NS_ConvertUTF16toUTF8(aStr).get());
291 : #endif
292 0 : fputs(NS_ConvertUTF16toUTF8(aStr).get(), stdout);
293 0 : fflush(stdout);
294 0 : return NS_OK;
295 : }
296 :
297 : NS_IMETHODIMP
298 0 : nsFrameMessageManager::PrivateNoteIntentionalCrash()
299 : {
300 0 : return NS_ERROR_NOT_IMPLEMENTED;
301 : }
302 :
303 : NS_IMETHODIMP
304 0 : nsFrameMessageManager::GetContent(nsIDOMWindow** aContent)
305 : {
306 0 : *aContent = nsnull;
307 0 : return NS_OK;
308 : }
309 :
310 : NS_IMETHODIMP
311 0 : nsFrameMessageManager::GetDocShell(nsIDocShell** aDocShell)
312 : {
313 0 : *aDocShell = nsnull;
314 0 : return NS_OK;
315 : }
316 :
317 : NS_IMETHODIMP
318 0 : nsFrameMessageManager::GetChildCount(PRUint32* aChildCount)
319 : {
320 0 : *aChildCount = static_cast<PRUint32>(mChildManagers.Count());
321 0 : return NS_OK;
322 : }
323 :
324 : NS_IMETHODIMP
325 0 : nsFrameMessageManager::GetChildAt(PRUint32 aIndex,
326 : nsITreeItemFrameMessageManager** aMM)
327 : {
328 0 : *aMM = nsnull;
329 : nsCOMPtr<nsITreeItemFrameMessageManager> mm =
330 0 : do_QueryInterface(mChildManagers.SafeObjectAt(static_cast<PRUint32>(aIndex)));
331 0 : mm.swap(*aMM);
332 0 : return NS_OK;
333 : }
334 :
335 : NS_IMETHODIMP
336 0 : nsFrameMessageManager::Btoa(const nsAString& aBinaryData,
337 : nsAString& aAsciiBase64String)
338 : {
339 0 : return NS_OK;
340 : }
341 :
342 : NS_IMETHODIMP
343 0 : nsFrameMessageManager::Atob(const nsAString& aAsciiString,
344 : nsAString& aBinaryData)
345 : {
346 0 : return NS_OK;
347 : }
348 :
349 : class MMListenerRemover
350 : {
351 : public:
352 0 : MMListenerRemover(nsFrameMessageManager* aMM)
353 : : mWasHandlingMessage(aMM->mHandlingMessage)
354 0 : , mMM(aMM)
355 : {
356 0 : mMM->mHandlingMessage = true;
357 0 : }
358 0 : ~MMListenerRemover()
359 0 : {
360 0 : if (!mWasHandlingMessage) {
361 0 : mMM->mHandlingMessage = false;
362 0 : if (mMM->mDisconnected) {
363 0 : mMM->mListeners.Clear();
364 : }
365 : }
366 0 : }
367 :
368 : bool mWasHandlingMessage;
369 : nsRefPtr<nsFrameMessageManager> mMM;
370 : };
371 :
372 : nsresult
373 0 : nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
374 : const nsAString& aMessage,
375 : bool aSync, const nsAString& aJSON,
376 : JSObject* aObjectsArray,
377 : InfallibleTArray<nsString>* aJSONRetVal,
378 : JSContext* aContext)
379 : {
380 0 : JSContext* ctx = mContext ? mContext : aContext;
381 0 : if (!ctx) {
382 0 : nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&ctx);
383 : }
384 0 : if (mListeners.Length()) {
385 0 : nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
386 0 : MMListenerRemover lr(this);
387 :
388 0 : for (PRUint32 i = 0; i < mListeners.Length(); ++i) {
389 0 : if (mListeners[i].mMessage == name) {
390 : nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS =
391 0 : do_QueryInterface(mListeners[i].mListener);
392 0 : if (!wrappedJS) {
393 0 : continue;
394 : }
395 0 : JSObject* object = nsnull;
396 0 : wrappedJS->GetJSObject(&object);
397 0 : if (!object) {
398 0 : continue;
399 : }
400 0 : nsCxPusher pusher;
401 0 : NS_ENSURE_STATE(pusher.Push(ctx, false));
402 :
403 0 : JSAutoRequest ar(ctx);
404 :
405 0 : JSAutoEnterCompartment ac;
406 0 : if (!ac.enter(ctx, object))
407 0 : return NS_ERROR_FAILURE;
408 :
409 : // The parameter for the listener function.
410 0 : JSObject* param = JS_NewObject(ctx, NULL, NULL, NULL);
411 0 : NS_ENSURE_TRUE(param, NS_ERROR_OUT_OF_MEMORY);
412 :
413 : jsval targetv;
414 : nsContentUtils::WrapNative(ctx,
415 : JS_GetGlobalForObject(ctx, object),
416 0 : aTarget, &targetv, nsnull, true);
417 :
418 : // To keep compatibility with e10s message manager,
419 : // define empty objects array.
420 0 : if (!aObjectsArray) {
421 : // Because we want JS messages to have always the same properties,
422 : // create array even if len == 0.
423 0 : aObjectsArray = JS_NewArrayObject(ctx, 0, NULL);
424 0 : if (!aObjectsArray) {
425 0 : return NS_ERROR_OUT_OF_MEMORY;
426 : }
427 : }
428 :
429 0 : JS::AutoValueRooter objectsv(ctx);
430 0 : objectsv.set(OBJECT_TO_JSVAL(aObjectsArray));
431 0 : if (!JS_WrapValue(ctx, objectsv.jsval_addr()))
432 0 : return NS_ERROR_UNEXPECTED;
433 :
434 0 : jsval json = JSVAL_NULL;
435 0 : if (!aJSON.IsEmpty()) {
436 0 : if (!JS_ParseJSON(ctx, static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
437 0 : aJSON.Length(), &json)) {
438 0 : json = JSVAL_NULL;
439 : }
440 : }
441 : JSString* jsMessage =
442 : JS_NewUCStringCopyN(ctx,
443 0 : static_cast<const jschar*>(PromiseFlatString(aMessage).get()),
444 0 : aMessage.Length());
445 0 : NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
446 0 : JS_DefineProperty(ctx, param, "target", targetv, NULL, NULL, JSPROP_ENUMERATE);
447 : JS_DefineProperty(ctx, param, "name",
448 0 : STRING_TO_JSVAL(jsMessage), NULL, NULL, JSPROP_ENUMERATE);
449 : JS_DefineProperty(ctx, param, "sync",
450 0 : BOOLEAN_TO_JSVAL(aSync), NULL, NULL, JSPROP_ENUMERATE);
451 0 : JS_DefineProperty(ctx, param, "json", json, NULL, NULL, JSPROP_ENUMERATE);
452 0 : JS_DefineProperty(ctx, param, "objects", objectsv.jsval_value(), NULL, NULL, JSPROP_ENUMERATE);
453 :
454 0 : jsval thisValue = JSVAL_VOID;
455 :
456 0 : jsval funval = JSVAL_VOID;
457 0 : if (JS_ObjectIsCallable(ctx, object)) {
458 : // If the listener is a JS function:
459 0 : funval = OBJECT_TO_JSVAL(object);
460 :
461 : // A small hack to get 'this' value right on content side where
462 : // messageManager is wrapped in TabChildGlobal.
463 0 : nsCOMPtr<nsISupports> defaultThisValue;
464 0 : if (mChrome) {
465 0 : defaultThisValue = do_QueryObject(this);
466 : } else {
467 0 : defaultThisValue = aTarget;
468 : }
469 : nsContentUtils::WrapNative(ctx,
470 : JS_GetGlobalForObject(ctx, object),
471 0 : defaultThisValue, &thisValue, nsnull, true);
472 : } else {
473 : // If the listener is a JS object which has receiveMessage function:
474 0 : NS_ENSURE_STATE(JS_GetProperty(ctx, object, "receiveMessage",
475 : &funval) &&
476 : JSVAL_IS_OBJECT(funval) &&
477 : !JSVAL_IS_NULL(funval));
478 0 : JSObject* funobject = JSVAL_TO_OBJECT(funval);
479 0 : NS_ENSURE_STATE(JS_ObjectIsCallable(ctx, funobject));
480 0 : thisValue = OBJECT_TO_JSVAL(object);
481 : }
482 :
483 0 : jsval rval = JSVAL_VOID;
484 :
485 0 : JS::AutoValueRooter argv(ctx);
486 0 : argv.set(OBJECT_TO_JSVAL(param));
487 :
488 : {
489 0 : JSAutoEnterCompartment tac;
490 :
491 0 : JSObject* thisObject = JSVAL_TO_OBJECT(thisValue);
492 :
493 0 : if (!tac.enter(ctx, thisObject) ||
494 0 : !JS_WrapValue(ctx, argv.jsval_addr()))
495 0 : return NS_ERROR_UNEXPECTED;
496 :
497 : JS_CallFunctionValue(ctx, thisObject,
498 0 : funval, 1, argv.jsval_addr(), &rval);
499 0 : if (aJSONRetVal) {
500 0 : nsString json;
501 0 : if (JS_Stringify(ctx, &rval, nsnull, JSVAL_NULL,
502 0 : JSONCreator, &json)) {
503 0 : aJSONRetVal->AppendElement(json);
504 : }
505 : }
506 : }
507 : }
508 : }
509 : }
510 0 : nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
511 : return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
512 : aSync, aJSON, aObjectsArray,
513 0 : aJSONRetVal, mContext) : NS_OK;
514 : }
515 :
516 : void
517 11 : nsFrameMessageManager::AddChildManager(nsFrameMessageManager* aManager,
518 : bool aLoadScripts)
519 : {
520 11 : mChildManagers.AppendObject(aManager);
521 11 : if (aLoadScripts) {
522 22 : nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = this;
523 22 : nsRefPtr<nsFrameMessageManager> kungfuDeathGrip2 = aManager;
524 : // We have parent manager if we're a window message manager.
525 : // In that case we want to load the pending scripts from global
526 : // message manager.
527 11 : if (mParentManager) {
528 0 : nsRefPtr<nsFrameMessageManager> globalMM = mParentManager;
529 0 : for (PRUint32 i = 0; i < globalMM->mPendingScripts.Length(); ++i) {
530 0 : aManager->LoadFrameScript(globalMM->mPendingScripts[i], false);
531 : }
532 : }
533 11 : for (PRUint32 i = 0; i < mPendingScripts.Length(); ++i) {
534 0 : aManager->LoadFrameScript(mPendingScripts[i], false);
535 : }
536 : }
537 11 : }
538 :
539 : void
540 0 : nsFrameMessageManager::SetCallbackData(void* aData, bool aLoadScripts)
541 : {
542 0 : if (aData && mCallbackData != aData) {
543 0 : mCallbackData = aData;
544 : // First load global scripts by adding this to parent manager.
545 0 : if (mParentManager) {
546 0 : mParentManager->AddChildManager(this, aLoadScripts);
547 : }
548 0 : if (aLoadScripts) {
549 0 : for (PRUint32 i = 0; i < mPendingScripts.Length(); ++i) {
550 0 : LoadFrameScript(mPendingScripts[i], false);
551 : }
552 : }
553 : }
554 0 : }
555 :
556 : void
557 0 : nsFrameMessageManager::RemoveFromParent()
558 : {
559 0 : if (mParentManager) {
560 0 : mParentManager->RemoveChildManager(this);
561 : }
562 0 : mParentManager = nsnull;
563 0 : mCallbackData = nsnull;
564 0 : mContext = nsnull;
565 0 : }
566 :
567 : void
568 11 : nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
569 : {
570 11 : if (mParentManager && aRemoveFromParent) {
571 0 : mParentManager->RemoveChildManager(this);
572 : }
573 11 : mDisconnected = true;
574 11 : mParentManager = nsnull;
575 11 : mCallbackData = nsnull;
576 11 : mContext = nsnull;
577 11 : if (!mHandlingMessage) {
578 11 : mListeners.Clear();
579 : }
580 11 : }
581 :
582 : nsresult
583 228 : NS_NewGlobalMessageManager(nsIChromeFrameMessageManager** aResult)
584 : {
585 228 : NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
586 : nsFrameMessageManager* mm = new nsFrameMessageManager(true,
587 : nsnull,
588 : nsnull,
589 : nsnull,
590 : nsnull,
591 : nsnull,
592 : nsnull,
593 228 : true);
594 228 : NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
595 228 : return CallQueryInterface(mm, aResult);
596 : }
597 :
598 : void
599 0 : ContentScriptErrorReporter(JSContext* aCx,
600 : const char* aMessage,
601 : JSErrorReport* aReport)
602 : {
603 : nsresult rv;
604 : nsCOMPtr<nsIScriptError> scriptError =
605 0 : do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
606 0 : if (NS_FAILED(rv)) {
607 : return;
608 : }
609 0 : nsAutoString message, filename, line;
610 : PRUint32 lineNumber, columnNumber, flags, errorNumber;
611 :
612 0 : if (aReport) {
613 0 : if (aReport->ucmessage) {
614 0 : message.Assign(reinterpret_cast<const PRUnichar*>(aReport->ucmessage));
615 : }
616 0 : filename.AssignWithConversion(aReport->filename);
617 0 : line.Assign(reinterpret_cast<const PRUnichar*>(aReport->uclinebuf));
618 0 : lineNumber = aReport->lineno;
619 0 : columnNumber = aReport->uctokenptr - aReport->uclinebuf;
620 0 : flags = aReport->flags;
621 0 : errorNumber = aReport->errorNumber;
622 : } else {
623 0 : lineNumber = columnNumber = errorNumber = 0;
624 0 : flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
625 : }
626 :
627 0 : if (message.IsEmpty()) {
628 0 : message.AssignWithConversion(aMessage);
629 : }
630 :
631 0 : rv = scriptError->Init(message.get(), filename.get(), line.get(),
632 : lineNumber, columnNumber, flags,
633 0 : "Message manager content script");
634 0 : if (NS_FAILED(rv)) {
635 : return;
636 : }
637 :
638 : nsCOMPtr<nsIConsoleService> consoleService =
639 0 : do_GetService(NS_CONSOLESERVICE_CONTRACTID);
640 0 : if (consoleService) {
641 0 : (void) consoleService->LogMessage(scriptError);
642 : }
643 :
644 : #ifdef DEBUG
645 : // Print it to stderr as well, for the benefit of those invoking
646 : // mozilla with -console.
647 0 : nsCAutoString error;
648 0 : error.Assign("JavaScript ");
649 0 : if (JSREPORT_IS_STRICT(flags)) {
650 0 : error.Append("strict ");
651 : }
652 0 : if (JSREPORT_IS_WARNING(flags)) {
653 0 : error.Append("warning: ");
654 : } else {
655 0 : error.Append("error: ");
656 : }
657 0 : error.Append(aReport->filename);
658 0 : error.Append(", line ");
659 0 : error.AppendInt(lineNumber, 10);
660 0 : error.Append(": ");
661 0 : if (aReport->ucmessage) {
662 : AppendUTF16toUTF8(reinterpret_cast<const PRUnichar*>(aReport->ucmessage),
663 0 : error);
664 : } else {
665 0 : error.Append(aMessage);
666 : }
667 :
668 0 : fprintf(stderr, "%s\n", error.get());
669 0 : fflush(stderr);
670 : #endif
671 : }
672 :
673 : nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>*
674 : nsFrameScriptExecutor::sCachedScripts = nsnull;
675 1464 : nsRefPtr<nsScriptCacheCleaner> nsFrameScriptExecutor::sScriptCacheCleaner;
676 :
677 : void
678 0 : nsFrameScriptExecutor::DidCreateCx()
679 : {
680 0 : NS_ASSERTION(mCx, "Should have mCx!");
681 0 : if (!sCachedScripts) {
682 : sCachedScripts =
683 0 : new nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>;
684 0 : sCachedScripts->Init();
685 :
686 0 : sScriptCacheCleaner = new nsScriptCacheCleaner();
687 : }
688 0 : }
689 :
690 : void
691 0 : nsFrameScriptExecutor::DestroyCx()
692 : {
693 0 : if (mCxStackRefCnt) {
694 0 : mDelayedCxDestroy = true;
695 0 : return;
696 : }
697 0 : mDelayedCxDestroy = false;
698 0 : if (mCx) {
699 0 : nsIXPConnect* xpc = nsContentUtils::XPConnect();
700 0 : if (xpc) {
701 0 : xpc->ReleaseJSContext(mCx, true);
702 : } else {
703 0 : JS_DestroyContext(mCx);
704 : }
705 : }
706 0 : mCx = nsnull;
707 0 : mGlobal = nsnull;
708 : }
709 :
710 : static PLDHashOperator
711 0 : CachedScriptUnrooter(const nsAString& aKey,
712 : nsFrameJSScriptExecutorHolder*& aData,
713 : void* aUserArg)
714 : {
715 0 : JSContext* cx = static_cast<JSContext*>(aUserArg);
716 0 : JS_RemoveScriptRoot(cx, &(aData->mScript));
717 0 : delete aData;
718 0 : return PL_DHASH_REMOVE;
719 : }
720 :
721 : // static
722 : void
723 1403 : nsFrameScriptExecutor::Shutdown()
724 : {
725 1403 : if (sCachedScripts) {
726 0 : JSContext* cx = nsnull;
727 0 : nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
728 0 : if (cx) {
729 : #ifdef DEBUG_smaug
730 : printf("Will clear cached frame manager scripts!\n");
731 : #endif
732 0 : JSAutoRequest ar(cx);
733 0 : NS_ASSERTION(sCachedScripts != nsnull, "Need cached scripts");
734 0 : sCachedScripts->Enumerate(CachedScriptUnrooter, cx);
735 : } else {
736 0 : NS_WARNING("No context available. Leaking cached scripts!\n");
737 : }
738 :
739 0 : delete sCachedScripts;
740 0 : sCachedScripts = nsnull;
741 :
742 0 : sScriptCacheCleaner = nsnull;
743 : }
744 1403 : }
745 :
746 : void
747 0 : nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
748 : {
749 0 : if (!mGlobal || !mCx || !sCachedScripts) {
750 0 : return;
751 : }
752 :
753 0 : nsFrameJSScriptExecutorHolder* holder = sCachedScripts->Get(aURL);
754 0 : if (holder) {
755 0 : nsContentUtils::ThreadJSContextStack()->Push(mCx);
756 : {
757 : // Need to scope JSAutoRequest to happen after Push but before Pop,
758 : // at least for now. See bug 584673.
759 0 : JSAutoRequest ar(mCx);
760 0 : JSObject* global = nsnull;
761 0 : mGlobal->GetJSObject(&global);
762 0 : if (global) {
763 0 : (void) JS_ExecuteScript(mCx, global, holder->mScript, nsnull);
764 : }
765 : }
766 : JSContext* unused;
767 0 : nsContentUtils::ThreadJSContextStack()->Pop(&unused);
768 0 : return;
769 : }
770 :
771 0 : nsCString url = NS_ConvertUTF16toUTF8(aURL);
772 0 : nsCOMPtr<nsIURI> uri;
773 0 : nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
774 0 : if (NS_FAILED(rv)) {
775 : return;
776 : }
777 :
778 : bool hasFlags;
779 : rv = NS_URIChainHasFlags(uri,
780 : nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
781 0 : &hasFlags);
782 0 : if (NS_FAILED(rv) || !hasFlags) {
783 0 : NS_WARNING("Will not load a frame script!");
784 : return;
785 : }
786 :
787 0 : nsCOMPtr<nsIChannel> channel;
788 0 : NS_NewChannel(getter_AddRefs(channel), uri);
789 0 : if (!channel) {
790 : return;
791 : }
792 :
793 0 : nsCOMPtr<nsIInputStream> input;
794 0 : channel->Open(getter_AddRefs(input));
795 0 : nsString dataString;
796 0 : PRUint32 avail = 0;
797 0 : if (input && NS_SUCCEEDED(input->Available(&avail)) && avail) {
798 0 : nsCString buffer;
799 0 : if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
800 : return;
801 : }
802 0 : nsScriptLoader::ConvertToUTF16(channel, (PRUint8*)buffer.get(), avail,
803 0 : EmptyString(), nsnull, dataString);
804 : }
805 :
806 0 : if (!dataString.IsEmpty()) {
807 0 : nsContentUtils::ThreadJSContextStack()->Push(mCx);
808 : {
809 : // Need to scope JSAutoRequest to happen after Push but before Pop,
810 : // at least for now. See bug 584673.
811 0 : JSAutoRequest ar(mCx);
812 0 : JSObject* global = nsnull;
813 0 : mGlobal->GetJSObject(&global);
814 0 : JSAutoEnterCompartment ac;
815 0 : if (global && ac.enter(mCx, global)) {
816 0 : uint32 oldopts = JS_GetOptions(mCx);
817 0 : JS_SetOptions(mCx, oldopts | JSOPTION_NO_SCRIPT_RVAL);
818 :
819 : JSScript* script =
820 : JS_CompileUCScriptForPrincipals(mCx, nsnull,
821 0 : nsJSPrincipals::get(mPrincipal),
822 : static_cast<const jschar*>(dataString.get()),
823 : dataString.Length(),
824 0 : url.get(), 1);
825 :
826 0 : JS_SetOptions(mCx, oldopts);
827 :
828 0 : if (script) {
829 0 : nsCAutoString scheme;
830 0 : uri->GetScheme(scheme);
831 : // We don't cache data: scripts!
832 0 : if (!scheme.EqualsLiteral("data")) {
833 : nsFrameJSScriptExecutorHolder* holder =
834 0 : new nsFrameJSScriptExecutorHolder(script);
835 : // Root the object also for caching.
836 : JS_AddNamedScriptRoot(mCx, &(holder->mScript),
837 0 : "Cached message manager script");
838 0 : sCachedScripts->Put(aURL, holder);
839 : }
840 0 : (void) JS_ExecuteScript(mCx, global, script, nsnull);
841 : }
842 : }
843 : }
844 : JSContext* unused;
845 0 : nsContentUtils::ThreadJSContextStack()->Pop(&unused);
846 : }
847 : }
848 :
849 : bool
850 0 : nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
851 : {
852 :
853 : nsCOMPtr<nsIJSRuntimeService> runtimeSvc =
854 0 : do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
855 0 : NS_ENSURE_TRUE(runtimeSvc, false);
856 :
857 0 : JSRuntime* rt = nsnull;
858 0 : runtimeSvc->GetRuntime(&rt);
859 0 : NS_ENSURE_TRUE(rt, false);
860 :
861 0 : JSContext* cx = JS_NewContext(rt, 8192);
862 0 : NS_ENSURE_TRUE(cx, false);
863 :
864 0 : mCx = cx;
865 :
866 0 : nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
867 :
868 0 : JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
869 0 : JS_SetVersion(cx, JSVERSION_LATEST);
870 0 : JS_SetErrorReporter(cx, ContentScriptErrorReporter);
871 :
872 0 : xpc_LocalizeContext(cx);
873 :
874 0 : JSAutoRequest ar(cx);
875 0 : nsIXPConnect* xpc = nsContentUtils::XPConnect();
876 : const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
877 0 : nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
878 :
879 :
880 0 : JS_SetContextPrivate(cx, aScope);
881 :
882 : nsresult rv =
883 : xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
884 0 : flags, getter_AddRefs(mGlobal));
885 0 : NS_ENSURE_SUCCESS(rv, false);
886 :
887 :
888 0 : JSObject* global = nsnull;
889 0 : rv = mGlobal->GetJSObject(&global);
890 0 : NS_ENSURE_SUCCESS(rv, false);
891 :
892 0 : JS_SetGlobalObject(cx, global);
893 0 : DidCreateCx();
894 0 : return true;
895 : }
896 :
897 : // static
898 : void
899 0 : nsFrameScriptExecutor::Traverse(nsFrameScriptExecutor *tmp,
900 : nsCycleCollectionTraversalCallback &cb)
901 : {
902 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGlobal)
903 0 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCx");
904 0 : nsContentUtils::XPConnect()->NoteJSContext(tmp->mCx, cb);
905 0 : }
906 :
907 0 : NS_IMPL_ISUPPORTS1(nsScriptCacheCleaner, nsIObserver)
908 :
909 : nsFrameMessageManager* nsFrameMessageManager::sChildProcessManager = nsnull;
910 : nsFrameMessageManager* nsFrameMessageManager::sParentProcessManager = nsnull;
911 : nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager = nsnull;
912 : nsTArray<nsCOMPtr<nsIRunnable> >* nsFrameMessageManager::sPendingSameProcessAsyncMessages = nsnull;
913 :
914 0 : bool SendAsyncMessageToChildProcess(void* aCallbackData,
915 : const nsAString& aMessage,
916 : const nsAString& aJSON)
917 : {
918 : mozilla::dom::ContentParent* cp =
919 0 : static_cast<mozilla::dom::ContentParent*>(aCallbackData);
920 0 : NS_WARN_IF_FALSE(cp, "No child process!");
921 0 : if (cp) {
922 0 : return cp->SendAsyncMessage(nsString(aMessage), nsString(aJSON));
923 : }
924 0 : return true;
925 : }
926 :
927 : class nsAsyncMessageToSameProcessChild : public nsRunnable
928 0 : {
929 : public:
930 0 : nsAsyncMessageToSameProcessChild(const nsAString& aMessage, const nsAString& aJSON)
931 0 : : mMessage(aMessage), mJSON(aJSON) {}
932 :
933 0 : NS_IMETHOD Run()
934 : {
935 0 : if (nsFrameMessageManager::sChildProcessManager) {
936 0 : nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
937 0 : ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
938 0 : false, mJSON, nsnull, nsnull);
939 : }
940 0 : return NS_OK;
941 : }
942 : nsString mMessage;
943 : nsString mJSON;
944 : };
945 :
946 0 : bool SendAsyncMessageToSameProcessChild(void* aCallbackData,
947 : const nsAString& aMessage,
948 : const nsAString& aJSON)
949 : {
950 : nsRefPtr<nsIRunnable> ev =
951 0 : new nsAsyncMessageToSameProcessChild(aMessage, aJSON);
952 0 : NS_DispatchToCurrentThread(ev);
953 0 : return true;
954 : }
955 :
956 0 : bool SendSyncMessageToParentProcess(void* aCallbackData,
957 : const nsAString& aMessage,
958 : const nsAString& aJSON,
959 : InfallibleTArray<nsString>* aJSONRetVal)
960 : {
961 : mozilla::dom::ContentChild* cc =
962 0 : mozilla::dom::ContentChild::GetSingleton();
963 0 : if (cc) {
964 : return
965 0 : cc->SendSyncMessage(nsString(aMessage), nsString(aJSON), aJSONRetVal);
966 : }
967 0 : return true;
968 : }
969 :
970 0 : bool SendSyncMessageToSameProcessParent(void* aCallbackData,
971 : const nsAString& aMessage,
972 : const nsAString& aJSON,
973 : InfallibleTArray<nsString>* aJSONRetVal)
974 : {
975 0 : nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
976 0 : if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
977 0 : asyncMessages.SwapElements(*nsFrameMessageManager::sPendingSameProcessAsyncMessages);
978 0 : PRUint32 len = asyncMessages.Length();
979 0 : for (PRUint32 i = 0; i < len; ++i) {
980 0 : nsCOMPtr<nsIRunnable> async = asyncMessages[i];
981 0 : async->Run();
982 : }
983 : }
984 0 : if (nsFrameMessageManager::sSameProcessParentManager) {
985 0 : nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
986 0 : ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
987 0 : true, aJSON, nsnull, aJSONRetVal);
988 : }
989 0 : return true;
990 : }
991 :
992 0 : bool SendAsyncMessageToParentProcess(void* aCallbackData,
993 : const nsAString& aMessage,
994 : const nsAString& aJSON)
995 : {
996 : mozilla::dom::ContentChild* cc =
997 0 : mozilla::dom::ContentChild::GetSingleton();
998 0 : if (cc) {
999 0 : return cc->SendAsyncMessage(nsString(aMessage), nsString(aJSON));
1000 : }
1001 0 : return true;
1002 : }
1003 :
1004 : class nsAsyncMessageToSameProcessParent : public nsRunnable
1005 0 : {
1006 : public:
1007 0 : nsAsyncMessageToSameProcessParent(const nsAString& aMessage, const nsAString& aJSON)
1008 0 : : mMessage(aMessage), mJSON(aJSON) {}
1009 :
1010 0 : NS_IMETHOD Run()
1011 : {
1012 0 : if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
1013 0 : nsFrameMessageManager::sPendingSameProcessAsyncMessages->RemoveElement(this);
1014 : }
1015 0 : if (nsFrameMessageManager::sSameProcessParentManager) {
1016 0 : nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
1017 0 : ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage, false,
1018 0 : mJSON, nsnull, nsnull);
1019 : }
1020 0 : return NS_OK;
1021 : }
1022 : nsString mMessage;
1023 : nsString mJSON;
1024 : };
1025 :
1026 0 : bool SendAsyncMessageToSameProcessParent(void* aCallbackData,
1027 : const nsAString& aMessage,
1028 : const nsAString& aJSON)
1029 : {
1030 0 : if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
1031 0 : nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
1032 : }
1033 : nsCOMPtr<nsIRunnable> ev =
1034 0 : new nsAsyncMessageToSameProcessParent(aMessage, aJSON);
1035 0 : nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
1036 0 : NS_DispatchToCurrentThread(ev);
1037 0 : return true;
1038 : }
1039 :
1040 : // This creates the global parent process message manager.
1041 : nsresult
1042 11 : NS_NewParentProcessMessageManager(nsIFrameMessageManager** aResult)
1043 : {
1044 11 : NS_ASSERTION(!nsFrameMessageManager::sParentProcessManager,
1045 : "Re-creating sParentProcessManager");
1046 11 : NS_ENSURE_TRUE(IsChromeProcess(), NS_ERROR_NOT_AVAILABLE);
1047 : nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(true,
1048 : nsnull,
1049 : nsnull,
1050 : nsnull,
1051 : nsnull,
1052 : nsnull,
1053 : nsnull,
1054 : false,
1055 22 : true);
1056 11 : NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
1057 11 : nsFrameMessageManager::sParentProcessManager = mm;
1058 11 : nsFrameMessageManager::NewProcessMessageManager(nsnull); // Create same process message manager.
1059 11 : return CallQueryInterface(mm, aResult);
1060 : }
1061 :
1062 : nsFrameMessageManager*
1063 11 : nsFrameMessageManager::NewProcessMessageManager(mozilla::dom::ContentParent* aProcess)
1064 : {
1065 11 : if (!nsFrameMessageManager::sParentProcessManager) {
1066 0 : nsCOMPtr<nsIFrameMessageManager> dummy;
1067 0 : NS_NewParentProcessMessageManager(getter_AddRefs(dummy));
1068 : }
1069 :
1070 : nsFrameMessageManager* mm = new nsFrameMessageManager(true,
1071 : nsnull,
1072 : aProcess ? SendAsyncMessageToChildProcess
1073 : : SendAsyncMessageToSameProcessChild,
1074 : nsnull,
1075 : aProcess ? static_cast<void*>(aProcess)
1076 : : static_cast<void*>(&nsFrameMessageManager::sChildProcessManager),
1077 : nsFrameMessageManager::sParentProcessManager,
1078 : nsnull,
1079 : false,
1080 11 : true);
1081 11 : if (!aProcess) {
1082 11 : sSameProcessParentManager = mm;
1083 : }
1084 11 : return mm;
1085 : }
1086 :
1087 : nsresult
1088 0 : NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
1089 : {
1090 0 : NS_ASSERTION(!nsFrameMessageManager::sChildProcessManager,
1091 : "Re-creating sChildProcessManager");
1092 0 : bool isChrome = IsChromeProcess();
1093 : nsFrameMessageManager* mm = new nsFrameMessageManager(false,
1094 : isChrome ? SendSyncMessageToSameProcessParent
1095 : : SendSyncMessageToParentProcess,
1096 : isChrome ? SendAsyncMessageToSameProcessParent
1097 : : SendAsyncMessageToParentProcess,
1098 : nsnull,
1099 : &nsFrameMessageManager::sChildProcessManager,
1100 : nsnull,
1101 : nsnull,
1102 : false,
1103 0 : true);
1104 0 : NS_ENSURE_TRUE(mm, NS_ERROR_OUT_OF_MEMORY);
1105 0 : nsFrameMessageManager::sChildProcessManager = mm;
1106 0 : return CallQueryInterface(mm, aResult);
1107 : }
1108 :
1109 : bool
1110 0 : nsFrameMessageManager::MarkForCC()
1111 : {
1112 0 : PRUint32 len = mListeners.Length();
1113 0 : for (PRUint32 i = 0; i < len; ++i) {
1114 : nsCOMPtr<nsIXPConnectWrappedJS> wjs =
1115 0 : do_QueryInterface(mListeners[i].mListener);
1116 0 : xpc_UnmarkGrayObject(wjs);
1117 : }
1118 0 : return true;
1119 4392 : }
|