mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Bug 1570115 - Add do_QueryActor to query JS-implemented interfaces. r=kmag
This allows querying an actor for interfaces implemented in JS. Differential Revision: https://phabricator.services.mozilla.com/D44050 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
29e0543f01
commit
3a3968887a
@ -10,6 +10,8 @@
|
||||
#include "mozilla/dom/PWindowGlobal.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "js/Promise.h"
|
||||
#include "xpcprivate.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -31,6 +33,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(JSWindowActor)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingQueries)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWrappedJS)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(JSWindowActor)
|
||||
@ -71,6 +74,26 @@ void JSWindowActor::InvokeCallback(CallbackFunction callback) {
|
||||
}
|
||||
}
|
||||
|
||||
nsresult JSWindowActor::QueryInterfaceActor(const nsIID& aIID, void** aPtr) {
|
||||
if (!mWrappedJS) {
|
||||
AutoEntryScript aes(GetParentObject(), "JSWindowActor query interface");
|
||||
JSContext* cx = aes.cx();
|
||||
|
||||
JS::Rooted<JSObject*> self(cx, GetWrapper());
|
||||
JSAutoRealm ar(cx, self);
|
||||
|
||||
RefPtr<nsXPCWrappedJS> wrappedJS;
|
||||
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(
|
||||
cx, self, NS_GET_IID(nsISupports), getter_AddRefs(wrappedJS));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mWrappedJS = do_QueryInterface(wrappedJS);
|
||||
MOZ_ASSERT(mWrappedJS);
|
||||
}
|
||||
|
||||
return mWrappedJS->QueryInterface(aIID, aPtr);
|
||||
}
|
||||
|
||||
void JSWindowActor::RejectPendingQueries() {
|
||||
// Take our queries out, in case somehow rejecting promises can trigger
|
||||
// additions or removals.
|
||||
|
@ -13,8 +13,10 @@
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
class nsQueryActor;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -77,6 +79,10 @@ class JSWindowActor : public nsISupports, public nsWrapperCache {
|
||||
void InvokeCallback(CallbackFunction willDestroy);
|
||||
|
||||
private:
|
||||
friend class ::nsQueryActor; // for QueryInterfaceActor
|
||||
|
||||
nsresult QueryInterfaceActor(const nsIID& aIID, void** aPtr);
|
||||
|
||||
void ReceiveMessageOrQuery(JSContext* aCx,
|
||||
const JSWindowActorMessageMeta& aMetadata,
|
||||
JS::Handle<JS::Value> aData, ErrorResult& aRv);
|
||||
@ -112,6 +118,7 @@ class JSWindowActor : public nsISupports, public nsWrapperCache {
|
||||
uint64_t mQueryId;
|
||||
};
|
||||
|
||||
nsCOMPtr<nsISupports> mWrappedJS;
|
||||
nsString mName;
|
||||
nsRefPtrHashtable<nsUint64HashKey, Promise> mPendingQueries;
|
||||
uint64_t mNextQueryId;
|
||||
|
@ -78,6 +78,10 @@ EXPORTS.mozilla += [
|
||||
'ProcessPriorityManager.h',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsQueryActor.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'BrowserBridgeChild.cpp',
|
||||
'BrowserBridgeHost.cpp',
|
||||
|
49
dom/ipc/nsQueryActor.h
Normal file
49
dom/ipc/nsQueryActor.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* 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 nsQueryActor_h
|
||||
#define nsQueryActor_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/JSWindowActorChild.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
|
||||
class MOZ_STACK_CLASS nsQueryActor final : public nsCOMPtr_helper {
|
||||
public:
|
||||
nsQueryActor(const nsDependentString aActorName, nsPIDOMWindowOuter* aWindow)
|
||||
: mActorName(aActorName), mWindow(aWindow) {}
|
||||
|
||||
virtual nsresult NS_FASTCALL operator()(const nsIID& aIID,
|
||||
void** aResult) const override {
|
||||
if (NS_WARN_IF(!mWindow) || NS_WARN_IF(!mWindow->GetCurrentInnerWindow())) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
RefPtr<mozilla::dom::WindowGlobalChild> wgc(
|
||||
mWindow->GetCurrentInnerWindow()->GetWindowGlobalChild());
|
||||
if (!wgc) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
RefPtr<mozilla::dom::JSWindowActorChild> actor =
|
||||
wgc->GetActor(mActorName, mozilla::IgnoreErrors());
|
||||
if (!actor) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
return actor->QueryInterfaceActor(aIID, aResult);
|
||||
}
|
||||
|
||||
private:
|
||||
const nsDependentString mActorName;
|
||||
nsPIDOMWindowOuter* mWindow;
|
||||
};
|
||||
|
||||
inline nsQueryActor do_QueryActor(const char16_t* aActorName,
|
||||
nsPIDOMWindowOuter* aWindow) {
|
||||
return nsQueryActor(nsDependentString(aActorName), aWindow);
|
||||
}
|
||||
|
||||
#endif // defined nsQueryActor_h
|
Loading…
Reference in New Issue
Block a user