2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "web/ServiceWorkerGlobalScopeProxy.h"
34 #include "bindings/core/v8/WorkerScriptController.h"
35 #include "core/dom/CrossThreadTask.h"
36 #include "core/dom/Document.h"
37 #include "core/dom/ExecutionContext.h"
38 #include "core/dom/MessagePort.h"
39 #include "core/events/MessageEvent.h"
40 #include "core/inspector/ConsoleMessage.h"
41 #include "core/workers/WorkerGlobalScope.h"
42 #include "core/workers/WorkerThread.h"
43 #include "modules/background_sync/SyncEvent.h"
44 #include "modules/background_sync/SyncRegistration.h"
45 #include "modules/fetch/Headers.h"
46 #include "modules/geofencing/CircularGeofencingRegion.h"
47 #include "modules/geofencing/GeofencingEvent.h"
48 #include "modules/navigatorconnect/AcceptConnectionObserver.h"
49 #include "modules/navigatorconnect/CrossOriginServiceWorkerClient.h"
50 #include "modules/navigatorconnect/ServicePortCollection.h"
51 #include "modules/navigatorconnect/WorkerNavigatorServices.h"
52 #include "modules/notifications/Notification.h"
53 #include "modules/notifications/NotificationEvent.h"
54 #include "modules/notifications/NotificationEventInit.h"
55 #include "modules/push_messaging/PushEvent.h"
56 #include "modules/push_messaging/PushMessageData.h"
57 #include "modules/serviceworkers/ExtendableEvent.h"
58 #include "modules/serviceworkers/FetchEvent.h"
59 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h"
60 #include "modules/serviceworkers/WaitUntilObserver.h"
61 #include "platform/RuntimeEnabledFeatures.h"
62 #include "public/platform/WebCrossOriginServiceWorkerClient.h"
63 #include "public/platform/WebServiceWorkerEventResult.h"
64 #include "public/platform/WebServiceWorkerRequest.h"
65 #include "public/platform/modules/notifications/WebNotificationData.h"
66 #include "public/web/WebSerializedScriptValue.h"
67 #include "public/web/WebServiceWorkerContextClient.h"
68 #include "web/WebEmbeddedWorkerImpl.h"
69 #include "wtf/Assertions.h"
70 #include "wtf/Functional.h"
71 #include "wtf/PassOwnPtr.h"
75 PassOwnPtr
<ServiceWorkerGlobalScopeProxy
> ServiceWorkerGlobalScopeProxy::create(WebEmbeddedWorkerImpl
& embeddedWorker
, Document
& document
, WebServiceWorkerContextClient
& client
)
77 return adoptPtr(new ServiceWorkerGlobalScopeProxy(embeddedWorker
, document
, client
));
80 ServiceWorkerGlobalScopeProxy::~ServiceWorkerGlobalScopeProxy()
84 void ServiceWorkerGlobalScopeProxy::setRegistration(WebPassOwnPtr
<WebServiceWorkerRegistration::Handle
> handle
)
86 ASSERT(m_workerGlobalScope
);
87 m_workerGlobalScope
->setRegistration(handle
);
90 void ServiceWorkerGlobalScopeProxy::dispatchActivateEvent(int eventID
)
92 ASSERT(m_workerGlobalScope
);
93 WaitUntilObserver
* observer
= WaitUntilObserver::create(m_workerGlobalScope
, WaitUntilObserver::Activate
, eventID
);
94 RefPtrWillBeRawPtr
<Event
> event(ExtendableEvent::create(EventTypeNames::activate
, ExtendableEventInit(), observer
));
95 m_workerGlobalScope
->dispatchExtendableEvent(event
.release(), observer
);
98 void ServiceWorkerGlobalScopeProxy::dispatchFetchEvent(int eventID
, const WebServiceWorkerRequest
& webRequest
)
100 ASSERT(m_workerGlobalScope
);
101 RespondWithObserver
* observer
= RespondWithObserver::create(m_workerGlobalScope
, eventID
, webRequest
.url(), webRequest
.mode(), webRequest
.frameType(), webRequest
.requestContext());
102 bool defaultPrevented
= false;
103 Request
* request
= Request::create(m_workerGlobalScope
, webRequest
);
104 request
->headers()->setGuard(Headers::ImmutableGuard
);
105 FetchEventInit eventInit
;
106 eventInit
.setCancelable(true);
107 eventInit
.setRequest(request
);
108 eventInit
.setIsReload(webRequest
.isReload());
109 RefPtrWillBeRawPtr
<FetchEvent
> fetchEvent(FetchEvent::create(EventTypeNames::fetch
, eventInit
, observer
));
110 defaultPrevented
= !m_workerGlobalScope
->dispatchEvent(fetchEvent
.release());
111 observer
->didDispatchEvent(defaultPrevented
);
114 void ServiceWorkerGlobalScopeProxy::dispatchGeofencingEvent(int eventID
, WebGeofencingEventType eventType
, const WebString
& regionID
, const WebCircularGeofencingRegion
& region
)
116 ASSERT(m_workerGlobalScope
);
117 const AtomicString
& type
= eventType
== WebGeofencingEventTypeEnter
? EventTypeNames::geofenceenter
: EventTypeNames::geofenceleave
;
118 m_workerGlobalScope
->dispatchEvent(GeofencingEvent::create(type
, regionID
, CircularGeofencingRegion::create(regionID
, region
)));
121 void ServiceWorkerGlobalScopeProxy::dispatchInstallEvent(int eventID
)
123 ASSERT(m_workerGlobalScope
);
124 WaitUntilObserver
* observer
= WaitUntilObserver::create(m_workerGlobalScope
, WaitUntilObserver::Install
, eventID
);
125 RefPtrWillBeRawPtr
<Event
> event(ExtendableEvent::create(EventTypeNames::install
, ExtendableEventInit(), observer
));
126 m_workerGlobalScope
->dispatchExtendableEvent(event
.release(), observer
);
129 void ServiceWorkerGlobalScopeProxy::dispatchMessageEvent(const WebString
& message
, const WebMessagePortChannelArray
& webChannels
)
131 ASSERT(m_workerGlobalScope
);
133 MessagePortArray
* ports
= MessagePort::toMessagePortArray(m_workerGlobalScope
, webChannels
);
134 WebSerializedScriptValue value
= WebSerializedScriptValue::fromString(message
);
135 m_workerGlobalScope
->dispatchEvent(MessageEvent::create(ports
, value
));
138 void ServiceWorkerGlobalScopeProxy::dispatchNotificationClickEvent(int eventID
, int64_t notificationID
, const WebNotificationData
& data
, int actionIndex
)
140 ASSERT(m_workerGlobalScope
);
141 WaitUntilObserver
* observer
= WaitUntilObserver::create(m_workerGlobalScope
, WaitUntilObserver::NotificationClick
, eventID
);
142 NotificationEventInit eventInit
;
143 eventInit
.setNotification(Notification::create(m_workerGlobalScope
, notificationID
, data
));
144 if (0 <= actionIndex
&& actionIndex
< static_cast<int>(data
.actions
.size()))
145 eventInit
.setAction(data
.actions
[actionIndex
].action
);
146 RefPtrWillBeRawPtr
<Event
> event(NotificationEvent::create(EventTypeNames::notificationclick
, eventInit
, observer
));
147 m_workerGlobalScope
->dispatchExtendableEvent(event
.release(), observer
);
150 void ServiceWorkerGlobalScopeProxy::dispatchPushEvent(int eventID
, const WebString
& data
)
152 ASSERT(m_workerGlobalScope
);
153 WaitUntilObserver
* observer
= WaitUntilObserver::create(m_workerGlobalScope
, WaitUntilObserver::Push
, eventID
);
154 RefPtrWillBeRawPtr
<Event
> event(PushEvent::create(EventTypeNames::push
, PushMessageData::create(data
), observer
));
155 m_workerGlobalScope
->dispatchExtendableEvent(event
.release(), observer
);
158 void ServiceWorkerGlobalScopeProxy::dispatchServicePortConnectEvent(WebServicePortConnectEventCallbacks
* rawCallbacks
, const WebURL
& targetURL
, const WebString
& origin
, WebServicePortID portID
)
160 ASSERT(m_workerGlobalScope
);
161 OwnPtr
<WebServicePortConnectEventCallbacks
> callbacks
= adoptPtr(rawCallbacks
);
162 ServicePortCollection
* collection
= WorkerNavigatorServices::services(m_workerGlobalScope
, *m_workerGlobalScope
->navigator());
163 collection
->dispatchConnectEvent(callbacks
.release(), targetURL
, origin
, portID
);
166 void ServiceWorkerGlobalScopeProxy::dispatchSyncEvent(int eventID
, const WebSyncRegistration
& registration
)
168 ASSERT(m_workerGlobalScope
);
169 if (!RuntimeEnabledFeatures::backgroundSyncEnabled()) {
170 ServiceWorkerGlobalScopeClient::from(m_workerGlobalScope
)->didHandleSyncEvent(eventID
, WebServiceWorkerEventResultCompleted
);
173 WaitUntilObserver
* observer
= WaitUntilObserver::create(m_workerGlobalScope
, WaitUntilObserver::Sync
, eventID
);
174 RefPtrWillBeRawPtr
<Event
> event(SyncEvent::create(EventTypeNames::sync
, SyncRegistration::create(registration
, m_workerGlobalScope
->registration()), observer
));
175 m_workerGlobalScope
->dispatchExtendableEvent(event
.release(), observer
);
178 void ServiceWorkerGlobalScopeProxy::dispatchCrossOriginMessageEvent(const WebCrossOriginServiceWorkerClient
& webClient
, const WebString
& message
, const WebMessagePortChannelArray
& webChannels
)
180 ASSERT(m_workerGlobalScope
);
181 MessagePortArray
* ports
= MessagePort::toMessagePortArray(m_workerGlobalScope
, webChannels
);
182 WebSerializedScriptValue value
= WebSerializedScriptValue::fromString(message
);
183 // FIXME: Have proper source for this MessageEvent.
184 RefPtrWillBeRawPtr
<MessageEvent
> event
= MessageEvent::create(ports
, value
, webClient
.origin
.string());
185 event
->setType(EventTypeNames::crossoriginmessage
);
186 m_workerGlobalScope
->dispatchEvent(event
);
189 void ServiceWorkerGlobalScopeProxy::reportException(const String
& errorMessage
, int lineNumber
, int columnNumber
, const String
& sourceURL
, int)
191 m_client
.reportException(errorMessage
, lineNumber
, columnNumber
, sourceURL
);
194 void ServiceWorkerGlobalScopeProxy::reportConsoleMessage(PassRefPtrWillBeRawPtr
<ConsoleMessage
> consoleMessage
)
196 m_client
.reportConsoleMessage(consoleMessage
->source(), consoleMessage
->level(), consoleMessage
->message(), consoleMessage
->lineNumber(), consoleMessage
->url());
199 void ServiceWorkerGlobalScopeProxy::postMessageToPageInspector(const String
& message
)
201 m_document
.postInspectorTask(FROM_HERE
, createCrossThreadTask(&WebEmbeddedWorkerImpl::postMessageToPageInspector
, &m_embeddedWorker
, message
));
204 void ServiceWorkerGlobalScopeProxy::didEvaluateWorkerScript(bool success
)
206 m_client
.didEvaluateWorkerScript(success
);
209 void ServiceWorkerGlobalScopeProxy::didInitializeWorkerContext()
211 ASSERT(m_workerGlobalScope
);
212 ScriptState::Scope
scope(m_workerGlobalScope
->script()->scriptState());
213 m_client
.didInitializeWorkerContext(m_workerGlobalScope
->script()->context(), WebURL(m_documentURL
));
216 void ServiceWorkerGlobalScopeProxy::workerGlobalScopeStarted(WorkerGlobalScope
* workerGlobalScope
)
218 ASSERT(!m_workerGlobalScope
);
219 m_workerGlobalScope
= static_cast<ServiceWorkerGlobalScope
*>(workerGlobalScope
);
220 m_client
.workerContextStarted(this);
223 void ServiceWorkerGlobalScopeProxy::workerGlobalScopeClosed()
225 m_document
.postTask(FROM_HERE
, createCrossThreadTask(&WebEmbeddedWorkerImpl::terminateWorkerContext
, &m_embeddedWorker
));
228 void ServiceWorkerGlobalScopeProxy::willDestroyWorkerGlobalScope()
230 v8::HandleScope
handleScope(m_workerGlobalScope
->thread()->isolate());
231 m_client
.willDestroyWorkerContext(m_workerGlobalScope
->script()->context());
232 m_workerGlobalScope
= nullptr;
235 void ServiceWorkerGlobalScopeProxy::workerThreadTerminated()
237 m_client
.workerContextDestroyed();
240 ServiceWorkerGlobalScopeProxy::ServiceWorkerGlobalScopeProxy(WebEmbeddedWorkerImpl
& embeddedWorker
, Document
& document
, WebServiceWorkerContextClient
& client
)
241 : m_embeddedWorker(embeddedWorker
)
242 , m_document(document
)
243 , m_documentURL(document
.url().copy())
245 , m_workerGlobalScope(nullptr)