mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1113522 - ExtendableMessageEvent.source should be ServiceWorker-aware. r=dom-worker-reviewers,edenchuang
ServiceWorkers aren't exposed as clients, so when we are sending a postMessage from them, we need to capture their ServiceWorkerDescriptor and propagate that instead of the client state. Differential Revision: https://phabricator.services.mozilla.com/D213721
This commit is contained in:
parent
170e73042c
commit
6e5b348a26
@ -69,6 +69,21 @@ struct ClientInfoAndState
|
||||
IPCClientState state;
|
||||
};
|
||||
|
||||
// ExtendableMessageEvent.source can be one of a `ServiceWorker`, a
|
||||
// `WindowClient`, or a `Client`. We use the same `Client` binding for both
|
||||
// types of client (and they use the same underlying data source), but our
|
||||
// `ServiceWorker` binding needs different data.
|
||||
//
|
||||
// Note that ClientPostMessageArgs only needs to handle messages originating
|
||||
// from ServiceWorker instances because, until
|
||||
// https://github.com/w3c/ServiceWorker/issues/955 is addressed, the Clients API
|
||||
// is only exposed on ServiceWorkers, which means the source of such a message
|
||||
// will always be a ServiceWorker.
|
||||
union PostMessageSource {
|
||||
ClientInfoAndState;
|
||||
IPCServiceWorkerDescriptor;
|
||||
};
|
||||
|
||||
struct ClientSourceExecutionReadyArgs
|
||||
{
|
||||
nsCString url;
|
||||
@ -96,6 +111,7 @@ struct ClientNavigateArgs
|
||||
struct ClientPostMessageArgs
|
||||
{
|
||||
ClonedMessageData clonedData;
|
||||
// See PostMessageSource for why this can only be a ServiceWorker.
|
||||
IPCServiceWorkerDescriptor serviceWorker;
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@ protocol PServiceWorker
|
||||
parent:
|
||||
async Teardown();
|
||||
|
||||
async PostMessage(ClonedOrErrorMessageData aClonedData, ClientInfoAndState aSource);
|
||||
async PostMessage(ClonedOrErrorMessageData aClonedData, PostMessageSource aSource);
|
||||
|
||||
child:
|
||||
async __delete__();
|
||||
|
@ -252,9 +252,24 @@ void ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
return;
|
||||
}
|
||||
|
||||
mActor->SendPostMessage(
|
||||
clonedData,
|
||||
ClientInfoAndState(clientInfo.ref().ToIPC(), clientState.ref().ToIPC()));
|
||||
// If this global is a ServiceWorker, we need this global's
|
||||
// ServiceWorkerDescriptor. While we normally try and normalize things
|
||||
// through nsIGlobalObject, this is fairly one-off right now, so starting from
|
||||
// worker-specific logic.
|
||||
PostMessageSource source;
|
||||
if (WorkerPrivate* wp = GetCurrentThreadWorkerPrivate()) {
|
||||
if (wp->IsServiceWorker()) {
|
||||
source = wp->GetServiceWorkerDescriptor().ToIPC();
|
||||
} else {
|
||||
source = ClientInfoAndState(clientInfo.ref().ToIPC(),
|
||||
clientState.ref().ToIPC());
|
||||
}
|
||||
} else {
|
||||
source =
|
||||
ClientInfoAndState(clientInfo.ref().ToIPC(), clientState.ref().ToIPC());
|
||||
}
|
||||
|
||||
mActor->SendPostMessage(clonedData, source);
|
||||
}
|
||||
|
||||
void ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
|
@ -240,11 +240,8 @@ uint64_t ServiceWorkerInfo::GetNextID() const {
|
||||
}
|
||||
|
||||
void ServiceWorkerInfo::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState) {
|
||||
mServiceWorkerPrivate->SendMessageEvent(
|
||||
std::move(aData),
|
||||
ClientInfoAndState(aClientInfo.ToIPC(), aClientState.ToIPC()));
|
||||
const PostMessageSource& aSource) {
|
||||
mServiceWorkerPrivate->SendMessageEvent(std::move(aData), aSource);
|
||||
}
|
||||
|
||||
void ServiceWorkerInfo::UpdateInstalledTime() {
|
||||
|
@ -17,8 +17,7 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class ClientInfoAndState;
|
||||
class ClientState;
|
||||
class PostMessageSource;
|
||||
class ServiceWorkerCloneData;
|
||||
class ServiceWorkerPrivate;
|
||||
|
||||
@ -78,8 +77,7 @@ class ServiceWorkerInfo final : public nsIServiceWorkerInfo {
|
||||
NS_DECL_NSISERVICEWORKERINFO
|
||||
|
||||
void PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState);
|
||||
const PostMessageSource& aSource);
|
||||
|
||||
class ServiceWorkerPrivate* WorkerPrivate() const {
|
||||
MOZ_ASSERT(mServiceWorkerPrivate);
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "mozilla/dom/Response.h"
|
||||
#include "mozilla/dom/RootedDictionary.h"
|
||||
#include "mozilla/dom/SafeRefPtr.h"
|
||||
#include "mozilla/dom/ServiceWorker.h"
|
||||
#include "mozilla/dom/ServiceWorkerBinding.h"
|
||||
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
@ -1004,12 +1005,28 @@ class MessageEventOp final : public ExtendableEventOp {
|
||||
init.mPorts = std::move(ports);
|
||||
}
|
||||
|
||||
PostMessageSource& ipcSource =
|
||||
mArgs.get_ServiceWorkerMessageEventOpArgs().source();
|
||||
nsCString originSource;
|
||||
switch (ipcSource.type()) {
|
||||
case PostMessageSource::TClientInfoAndState:
|
||||
originSource = ipcSource.get_ClientInfoAndState().info().url();
|
||||
init.mSource.SetValue().SetAsClient() =
|
||||
new Client(sgo, ipcSource.get_ClientInfoAndState());
|
||||
break;
|
||||
case PostMessageSource::TIPCServiceWorkerDescriptor:
|
||||
originSource = ipcSource.get_IPCServiceWorkerDescriptor().scriptURL();
|
||||
init.mSource.SetValue().SetAsServiceWorker() = ServiceWorker::Create(
|
||||
sgo, ServiceWorkerDescriptor(
|
||||
ipcSource.get_IPCServiceWorkerDescriptor()));
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected source type");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> url;
|
||||
nsresult result = NS_NewURI(getter_AddRefs(url),
|
||||
mArgs.get_ServiceWorkerMessageEventOpArgs()
|
||||
.clientInfoAndState()
|
||||
.info()
|
||||
.url());
|
||||
nsresult result = NS_NewURI(getter_AddRefs(url), originSource);
|
||||
if (NS_WARN_IF(NS_FAILED(result))) {
|
||||
RejectAll(result);
|
||||
rv.SuppressException();
|
||||
@ -1033,9 +1050,6 @@ class MessageEventOp final : public ExtendableEventOp {
|
||||
|
||||
CopyUTF8toUTF16(origin, init.mOrigin);
|
||||
|
||||
init.mSource.SetValue().SetAsClient() = new Client(
|
||||
sgo, mArgs.get_ServiceWorkerMessageEventOpArgs().clientInfoAndState());
|
||||
|
||||
rv.SuppressException();
|
||||
RefPtr<EventTarget> target = aWorkerPrivate->GlobalScope();
|
||||
RefPtr<ExtendableMessageEvent> extendableEvent =
|
||||
|
@ -69,7 +69,7 @@ struct ServiceWorkerExtensionAPIEventOpArgs {
|
||||
};
|
||||
|
||||
struct ServiceWorkerMessageEventOpArgs {
|
||||
ClientInfoAndState clientInfoAndState;
|
||||
PostMessageSource source;
|
||||
ClonedOrErrorMessageData clonedData;
|
||||
};
|
||||
|
||||
|
@ -31,12 +31,11 @@ IPCResult ServiceWorkerParent::RecvTeardown() {
|
||||
|
||||
IPCResult ServiceWorkerParent::RecvPostMessage(
|
||||
const ClonedOrErrorMessageData& aClonedData,
|
||||
const ClientInfoAndState& aSource) {
|
||||
const PostMessageSource& aSource) {
|
||||
RefPtr<ServiceWorkerCloneData> data = new ServiceWorkerCloneData();
|
||||
data->CopyFromClonedMessageData(aClonedData);
|
||||
|
||||
mProxy->PostMessage(std::move(data), ClientInfo(aSource.info()),
|
||||
ClientState::FromIPC(aSource.state()));
|
||||
mProxy->PostMessage(std::move(data), aSource);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class ServiceWorkerParent final : public PServiceWorkerParent {
|
||||
|
||||
mozilla::ipc::IPCResult RecvPostMessage(
|
||||
const ClonedOrErrorMessageData& aClonedData,
|
||||
const ClientInfoAndState& aSource) override;
|
||||
const PostMessageSource& aSource) override;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerParent, override);
|
||||
|
@ -816,8 +816,7 @@ nsresult ServiceWorkerPrivate::CheckScriptEvaluation(
|
||||
}
|
||||
|
||||
nsresult ServiceWorkerPrivate::SendMessageEvent(
|
||||
RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfoAndState& aClientInfoAndState) {
|
||||
RefPtr<ServiceWorkerCloneData>&& aData, const PostMessageSource& aSource) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
@ -830,7 +829,7 @@ nsresult ServiceWorkerPrivate::SendMessageEvent(
|
||||
}
|
||||
|
||||
ServiceWorkerMessageEventOpArgs args;
|
||||
args.clientInfoAndState() = aClientInfoAndState;
|
||||
args.source() = aSource;
|
||||
if (!aData->BuildClonedMessageData(args.clonedData())) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class JSObjectHolder;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class ClientInfoAndState;
|
||||
class PostMessageSource;
|
||||
class RemoteWorkerControllerChild;
|
||||
class ServiceWorkerCloneData;
|
||||
class ServiceWorkerInfo;
|
||||
@ -83,7 +83,7 @@ class ServiceWorkerPrivate final : public RemoteWorkerObserver {
|
||||
explicit ServiceWorkerPrivate(ServiceWorkerInfo* aInfo);
|
||||
|
||||
nsresult SendMessageEvent(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfoAndState& aClientInfoAndState);
|
||||
const PostMessageSource& aSource);
|
||||
|
||||
// This is used to validate the worker script and continue the installation
|
||||
// process.
|
||||
|
@ -101,17 +101,15 @@ void ServiceWorkerProxy::RevokeActor(ServiceWorkerParent* aActor) {
|
||||
}
|
||||
|
||||
void ServiceWorkerProxy::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo,
|
||||
const ClientState& aClientState) {
|
||||
const PostMessageSource& aSource) {
|
||||
AssertIsOnBackgroundThread();
|
||||
RefPtr<ServiceWorkerProxy> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__,
|
||||
[self, data = std::move(aData), aClientInfo, aClientState]() mutable {
|
||||
__func__, [self, data = std::move(aData), aSource]() mutable {
|
||||
if (!self->mInfo) {
|
||||
return;
|
||||
}
|
||||
self->mInfo->PostMessage(std::move(data), aClientInfo, aClientState);
|
||||
self->mInfo->PostMessage(std::move(data), aSource);
|
||||
});
|
||||
MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r.forget()));
|
||||
}
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class ClientInfo;
|
||||
class ClientState;
|
||||
class PostMessageSource;
|
||||
class ServiceWorkerCloneData;
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerParent;
|
||||
@ -51,7 +50,7 @@ class ServiceWorkerProxy final {
|
||||
void RevokeActor(ServiceWorkerParent* aActor);
|
||||
|
||||
void PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfo& aClientInfo, const ClientState& aState);
|
||||
const PostMessageSource& aSource);
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ServiceWorkerProxy);
|
||||
};
|
||||
|
@ -1,13 +1,4 @@
|
||||
[extendable-message-event.https.html]
|
||||
expected: TIMEOUT
|
||||
[Post loopback extendable messages]
|
||||
expected:
|
||||
if os == "win": [TIMEOUT, NOTRUN]
|
||||
TIMEOUT
|
||||
|
||||
[Post extendable messages among service workers]
|
||||
expected: NOTRUN
|
||||
|
||||
[Post an extendable message from a nested client]
|
||||
expected:
|
||||
if os == "win": [PASS, NOTRUN, TIMEOUT]
|
||||
|
Loading…
Reference in New Issue
Block a user