LCOV - code coverage report
Current view: directory - content/base/src - nsFrameMessageManager.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 524 106 20.2 %
Date: 2012-06-02 Functions: 63 20 31.7 %

       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 : }

Generated by: LCOV version 1.7