mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-05 23:07:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
450
dom/base/nsFrameMessageManager.h
Normal file
450
dom/base/nsFrameMessageManager.h
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsFrameMessageManager_h__
|
||||
#define nsFrameMessageManager_h__
|
||||
|
||||
#include "nsIMessageManager.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/jsipc/CpowHolder.h"
|
||||
|
||||
class nsIFrameLoader;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class nsIContentParent;
|
||||
class nsIContentChild;
|
||||
class ClonedMessageData;
|
||||
class MessageManagerReporter;
|
||||
|
||||
namespace ipc {
|
||||
|
||||
enum MessageManagerFlags {
|
||||
MM_CHILD = 0,
|
||||
MM_CHROME = 1,
|
||||
MM_GLOBAL = 2,
|
||||
MM_PROCESSMANAGER = 4,
|
||||
MM_BROADCASTER = 8,
|
||||
MM_OWNSCALLBACK = 16
|
||||
};
|
||||
|
||||
class MessageManagerCallback
|
||||
{
|
||||
public:
|
||||
virtual ~MessageManagerCallback() {}
|
||||
|
||||
virtual bool DoLoadMessageManagerScript(const nsAString& aURL, bool aRunInGlobalScope)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual bool CheckPermission(const nsAString& aPermission)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool CheckManifestURL(const nsAString& aManifestURL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool CheckAppHasPermission(const nsAString& aPermission)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool CheckAppHasStatus(unsigned short aStatus)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool KillChild()
|
||||
{
|
||||
// By default, does nothing.
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual nsIMessageSender* GetProcessMessageManager() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData);
|
||||
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData);
|
||||
};
|
||||
|
||||
void UnpackClonedMessageDataForParent(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData);
|
||||
|
||||
void UnpackClonedMessageDataForChild(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData);
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
struct nsMessageListenerInfo
|
||||
{
|
||||
bool operator==(const nsMessageListenerInfo& aOther) const
|
||||
{
|
||||
return &aOther == this;
|
||||
}
|
||||
|
||||
// Exactly one of mStrongListener and mWeakListener must be non-null.
|
||||
nsCOMPtr<nsIMessageListener> mStrongListener;
|
||||
nsWeakPtr mWeakListener;
|
||||
bool mListenWhenClosed;
|
||||
};
|
||||
|
||||
|
||||
class MOZ_STACK_CLASS SameProcessCpowHolder : public mozilla::jsipc::CpowHolder
|
||||
{
|
||||
public:
|
||||
SameProcessCpowHolder(JS::RootingContext* aRootingCx, JS::Handle<JSObject*> aObj)
|
||||
: mObj(aRootingCx, aObj)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool ToObject(JSContext* aCx, JS::MutableHandle<JSObject*> aObjp)
|
||||
override;
|
||||
|
||||
private:
|
||||
JS::Rooted<JSObject*> mObj;
|
||||
};
|
||||
|
||||
class nsFrameMessageManager final : public nsIContentFrameMessageManager,
|
||||
public nsIMessageBroadcaster,
|
||||
public nsIFrameScriptLoader,
|
||||
public nsIGlobalProcessScriptLoader,
|
||||
public nsIProcessChecker
|
||||
{
|
||||
friend class mozilla::dom::MessageManagerReporter;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
public:
|
||||
nsFrameMessageManager(mozilla::dom::ipc::MessageManagerCallback* aCallback,
|
||||
nsFrameMessageManager* aParentManager,
|
||||
/* mozilla::dom::ipc::MessageManagerFlags */ uint32_t aFlags);
|
||||
|
||||
private:
|
||||
~nsFrameMessageManager();
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFrameMessageManager,
|
||||
nsIContentFrameMessageManager)
|
||||
NS_DECL_NSIMESSAGELISTENERMANAGER
|
||||
NS_DECL_NSIMESSAGESENDER
|
||||
NS_DECL_NSIMESSAGEBROADCASTER
|
||||
NS_DECL_NSISYNCMESSAGESENDER
|
||||
NS_DECL_NSIMESSAGEMANAGERGLOBAL
|
||||
NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
|
||||
NS_DECL_NSIFRAMESCRIPTLOADER
|
||||
NS_DECL_NSIPROCESSSCRIPTLOADER
|
||||
NS_DECL_NSIGLOBALPROCESSSCRIPTLOADER
|
||||
NS_DECL_NSIPROCESSCHECKER
|
||||
|
||||
static nsFrameMessageManager*
|
||||
NewProcessMessageManager(bool aIsRemote);
|
||||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync, StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal);
|
||||
|
||||
void AddChildManager(nsFrameMessageManager* aManager);
|
||||
void RemoveChildManager(nsFrameMessageManager* aManager)
|
||||
{
|
||||
mChildManagers.RemoveObject(aManager);
|
||||
}
|
||||
void Disconnect(bool aRemoveFromParent = true);
|
||||
void Close();
|
||||
|
||||
void InitWithCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback);
|
||||
void SetCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback);
|
||||
|
||||
mozilla::dom::ipc::MessageManagerCallback* GetCallback()
|
||||
{
|
||||
return mCallback;
|
||||
}
|
||||
|
||||
nsresult DispatchAsyncMessage(const nsAString& aMessageName,
|
||||
const JS::Value& aJSON,
|
||||
const JS::Value& aObjects,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const JS::Value& aTransfers,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc);
|
||||
|
||||
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
void RemoveFromParent();
|
||||
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
||||
void SetParentManager(nsFrameMessageManager* aParent)
|
||||
{
|
||||
NS_ASSERTION(!mParentManager, "We have parent manager already!");
|
||||
NS_ASSERTION(mChrome, "Should not set parent manager!");
|
||||
mParentManager = aParent;
|
||||
}
|
||||
bool IsGlobal() { return mGlobal; }
|
||||
bool IsBroadcaster() { return mIsBroadcaster; }
|
||||
|
||||
static nsFrameMessageManager* GetParentProcessManager()
|
||||
{
|
||||
return sParentProcessManager;
|
||||
}
|
||||
static nsFrameMessageManager* GetChildProcessManager()
|
||||
{
|
||||
return sChildProcessManager;
|
||||
}
|
||||
static void SetChildProcessManager(nsFrameMessageManager* aManager)
|
||||
{
|
||||
sChildProcessManager = aManager;
|
||||
}
|
||||
|
||||
void SetInitialProcessData(JS::HandleValue aInitialData);
|
||||
|
||||
void LoadPendingScripts();
|
||||
|
||||
private:
|
||||
nsresult SendMessage(const nsAString& aMessageName,
|
||||
JS::Handle<JS::Value> aJSON,
|
||||
JS::Handle<JS::Value> aObjects,
|
||||
nsIPrincipal* aPrincipal,
|
||||
JSContext* aCx,
|
||||
uint8_t aArgc,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
bool aIsSync);
|
||||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
bool aTargetClosed, const nsAString& aMessage,
|
||||
bool aIsSync, StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal);
|
||||
|
||||
NS_IMETHOD LoadScript(const nsAString& aURL,
|
||||
bool aAllowDelayedLoad,
|
||||
bool aRunInGlobalScope);
|
||||
NS_IMETHOD RemoveDelayedScript(const nsAString& aURL);
|
||||
NS_IMETHOD GetDelayedScripts(JSContext* aCx, JS::MutableHandle<JS::Value> aList);
|
||||
|
||||
protected:
|
||||
friend class MMListenerRemover;
|
||||
// We keep the message listeners as arrays in a hastable indexed by the
|
||||
// message name. That gives us fast lookups in ReceiveMessage().
|
||||
nsClassHashtable<nsStringHashKey,
|
||||
nsAutoTObserverArray<nsMessageListenerInfo, 1>> mListeners;
|
||||
nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
|
||||
bool mChrome; // true if we're in the chrome process
|
||||
bool mGlobal; // true if we're the global frame message manager
|
||||
bool mIsProcessManager; // true if the message manager belongs to the process realm
|
||||
bool mIsBroadcaster; // true if the message manager is a broadcaster
|
||||
bool mOwnsCallback;
|
||||
bool mHandlingMessage;
|
||||
bool mClosed; // true if we can no longer send messages
|
||||
bool mDisconnected;
|
||||
mozilla::dom::ipc::MessageManagerCallback* mCallback;
|
||||
nsAutoPtr<mozilla::dom::ipc::MessageManagerCallback> mOwnedCallback;
|
||||
RefPtr<nsFrameMessageManager> mParentManager;
|
||||
nsTArray<nsString> mPendingScripts;
|
||||
nsTArray<bool> mPendingScriptsGlobalStates;
|
||||
JS::Heap<JS::Value> mInitialProcessData;
|
||||
|
||||
void LoadPendingScripts(nsFrameMessageManager* aManager,
|
||||
nsFrameMessageManager* aChildMM);
|
||||
public:
|
||||
static nsFrameMessageManager* sParentProcessManager;
|
||||
static nsFrameMessageManager* sSameProcessParentManager;
|
||||
static nsTArray<nsCOMPtr<nsIRunnable> >* sPendingSameProcessAsyncMessages;
|
||||
private:
|
||||
static nsFrameMessageManager* sChildProcessManager;
|
||||
enum ProcessCheckerType {
|
||||
PROCESS_CHECKER_PERMISSION,
|
||||
PROCESS_CHECKER_MANIFEST_URL,
|
||||
ASSERT_APP_HAS_PERMISSION
|
||||
};
|
||||
nsresult AssertProcessInternal(ProcessCheckerType aType,
|
||||
const nsAString& aCapability,
|
||||
bool* aValid);
|
||||
};
|
||||
|
||||
/* A helper class for taking care of many details for async message sending
|
||||
within a single process. Intended to be used like so:
|
||||
|
||||
class MyAsyncMessage : public nsSameProcessAsyncMessageBase, public Runnable
|
||||
{
|
||||
NS_IMETHOD Run() override {
|
||||
ReceiveMessage(..., ...);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
RefPtr<nsSameProcessAsyncMessageBase> ev = new MyAsyncMessage();
|
||||
nsresult rv = ev->Init(...);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_DispatchToMainThread(ev);
|
||||
}
|
||||
*/
|
||||
class nsSameProcessAsyncMessageBase
|
||||
{
|
||||
public:
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
|
||||
nsSameProcessAsyncMessageBase(JS::RootingContext* aRootingCx,
|
||||
JS::Handle<JSObject*> aCpows);
|
||||
nsresult Init(const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
void ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
nsFrameMessageManager* aManager);
|
||||
private:
|
||||
nsSameProcessAsyncMessageBase(const nsSameProcessAsyncMessageBase&);
|
||||
|
||||
JS::RootingContext* mRootingCx;
|
||||
nsString mMessage;
|
||||
StructuredCloneData mData;
|
||||
JS::PersistentRooted<JSObject*> mCpows;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
#ifdef DEBUG
|
||||
bool mCalledInit;
|
||||
#endif
|
||||
};
|
||||
|
||||
class nsScriptCacheCleaner;
|
||||
|
||||
struct nsMessageManagerScriptHolder
|
||||
{
|
||||
nsMessageManagerScriptHolder(JSContext* aCx,
|
||||
JSScript* aScript,
|
||||
bool aRunInGlobalScope)
|
||||
: mScript(aCx, aScript), mRunInGlobalScope(aRunInGlobalScope)
|
||||
{ MOZ_COUNT_CTOR(nsMessageManagerScriptHolder); }
|
||||
|
||||
~nsMessageManagerScriptHolder()
|
||||
{ MOZ_COUNT_DTOR(nsMessageManagerScriptHolder); }
|
||||
|
||||
bool WillRunInGlobalScope() { return mRunInGlobalScope; }
|
||||
|
||||
JS::PersistentRooted<JSScript*> mScript;
|
||||
bool mRunInGlobalScope;
|
||||
};
|
||||
|
||||
class nsMessageManagerScriptExecutor
|
||||
{
|
||||
public:
|
||||
static void PurgeCache();
|
||||
static void Shutdown();
|
||||
already_AddRefed<nsIXPConnectJSObjectHolder> GetGlobal()
|
||||
{
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> ref = mGlobal;
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
void MarkScopesForCC();
|
||||
protected:
|
||||
friend class nsMessageManagerScriptCx;
|
||||
nsMessageManagerScriptExecutor() { MOZ_COUNT_CTOR(nsMessageManagerScriptExecutor); }
|
||||
~nsMessageManagerScriptExecutor() { MOZ_COUNT_DTOR(nsMessageManagerScriptExecutor); }
|
||||
|
||||
void DidCreateGlobal();
|
||||
void LoadScriptInternal(const nsAString& aURL, bool aRunInGlobalScope);
|
||||
void TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
bool aRunInGlobalScope,
|
||||
bool aShouldCache,
|
||||
JS::MutableHandle<JSScript*> aScriptp);
|
||||
void TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
bool aRunInGlobalScope);
|
||||
bool InitChildGlobalInternal(nsISupports* aScope, const nsACString& aID);
|
||||
void Trace(const TraceCallbacks& aCallbacks, void* aClosure);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
AutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;
|
||||
|
||||
static nsDataHashtable<nsStringHashKey, nsMessageManagerScriptHolder*>* sCachedScripts;
|
||||
static mozilla::StaticRefPtr<nsScriptCacheCleaner> sScriptCacheCleaner;
|
||||
};
|
||||
|
||||
class nsScriptCacheCleaner final : public nsIObserver
|
||||
{
|
||||
~nsScriptCacheCleaner() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsScriptCacheCleaner()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
|
||||
if (obsSvc) {
|
||||
obsSvc->AddObserver(this, "message-manager-flush-caches", false);
|
||||
obsSvc->AddObserver(this, "xpcom-shutdown", false);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData) override
|
||||
{
|
||||
if (strcmp("message-manager-flush-caches", aTopic) == 0) {
|
||||
nsMessageManagerScriptExecutor::PurgeCache();
|
||||
} else if (strcmp("xpcom-shutdown", aTopic) == 0) {
|
||||
nsMessageManagerScriptExecutor::Shutdown();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue