Index: content/browser/service_worker/service_worker_version.h |
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h |
index 5856ed6c63c7f6a371bcb4424b377f375126d615..0e9e49b7f640477867cf06c8c95cc356e89f48e2 100644 |
--- a/content/browser/service_worker/service_worker_version.h |
+++ b/content/browser/service_worker/service_worker_version.h |
@@ -14,6 +14,7 @@ |
#include <vector> |
#include "base/callback.h" |
+#include "base/containers/scoped_ptr_hash_map.h" |
#include "base/gtest_prod_util.h" |
#include "base/id_map.h" |
#include "base/macros.h" |
@@ -23,10 +24,10 @@ |
#include "base/timer/timer.h" |
#include "content/browser/background_sync/background_sync_registration_handle.h" |
#include "content/browser/service_worker/embedded_worker_instance.h" |
+#include "content/browser/service_worker/service_worker_metrics.h" |
#include "content/browser/service_worker/service_worker_script_cache_map.h" |
#include "content/common/background_sync_service.mojom.h" |
#include "content/common/content_export.h" |
-#include "content/common/service_port_service.mojom.h" |
#include "content/common/service_worker/service_worker_status_code.h" |
#include "content/common/service_worker/service_worker_types.h" |
#include "content/public/common/service_registry.h" |
@@ -74,11 +75,6 @@ class CONTENT_EXPORT ServiceWorkerVersion |
typedef base::Callback<void(ServiceWorkerStatusCode, |
ServiceWorkerFetchEventResult, |
const ServiceWorkerResponse&)> FetchCallback; |
- typedef base::Callback<void(ServiceWorkerStatusCode, |
- bool /* accept_connction */, |
- const base::string16& /* name */, |
- const base::string16& /* data */)> |
- ServicePortConnectCallback; |
enum RunningStatus { |
STOPPED = EmbeddedWorkerInstance::STOPPED, |
@@ -178,6 +174,36 @@ class CONTENT_EXPORT ServiceWorkerVersion |
// Starts an update now. |
void StartUpdate(); |
+ // Starts the worker if it isn't already running, and calls |task| when the |
+ // worker is running, or |error_callback| if starting the worker failed. |
+ void RunAfterStartWorker(const StatusCallback& error_callback, |
+ const base::Closure& task); |
+ |
+ // Call this while the worker is running before dispatching an event to the |
+ // worker. This informs ServiceWorkerVersion about the event in progress. |
+ // Returns a request id, which should later be passed to FinishRequest when |
+ // the event finished. |
+ // The |error_callback| is called if either ServiceWorkerVersion decides the |
+ // event is taking too long, or if for some reason the worker stops or is |
+ // killed before the request finishes. |
+ int StartRequest(ServiceWorkerMetrics::EventType event_type, |
+ const StatusCallback& error_callback); |
+ |
+ // Informs ServiceWorkerVersion that an event has finished being dispatched. |
+ // Returns false if no pending requests with the provided id exist, for |
+ // example if the request has already timed out. |
+ bool FinishRequest(int request_id); |
+ |
+ // Connects to a specific mojo service exposed by the (running) service |
+ // worker. If a connection to a service for the same Interface already exists |
+ // this will return that existing connection. The |request_id| must be a value |
+ // previously returned by StartRequest. If the connection to the service |
+ // fails or closes before the request finished, the error callback associated |
+ // with |request_id| is called. |
+ // Only call GetMojoServiceForRequest once for a specific |request_id|. |
+ template <typename Interface> |
+ base::WeakPtr<Interface> GetMojoServiceForRequest(int request_id); |
+ |
// Sends a message event to the associated embedded worker. |
void DispatchMessageEvent( |
const base::string16& message, |
@@ -254,16 +280,6 @@ class CONTENT_EXPORT ServiceWorkerVersion |
const std::string& region_id, |
const blink::WebCircularGeofencingRegion& region); |
- // Sends a ServicePort connect event to the associated embedded worker and |
- // asynchronously calls |callback| with the response from the worker. |
- // |
- // This must be called when the status() is ACTIVATED. |
- void DispatchServicePortConnectEvent( |
- const ServicePortConnectCallback& callback, |
- const GURL& target_url, |
- const GURL& origin, |
- int port_id); |
- |
// Sends a cross origin message event to the associated embedded worker and |
// asynchronously calls |callback| when the message was sent (or failed to |
// sent). |
@@ -366,6 +382,7 @@ class CONTENT_EXPORT ServiceWorkerVersion |
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, |
StaleUpdate_DoNotDeferTimer); |
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWaitForeverInFetchTest, RequestTimeout); |
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestTimeout); |
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerFailToStartTest, Timeout); |
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionBrowserTest, |
TimeoutStartingWorker); |
@@ -382,7 +399,6 @@ class CONTENT_EXPORT ServiceWorkerVersion |
class Metrics; |
class PingController; |
- // Used for UMA; add new entries to the end, before NUM_REQUEST_TYPES. |
enum RequestType { |
REQUEST_ACTIVATE, |
REQUEST_INSTALL, |
@@ -391,16 +407,20 @@ class CONTENT_EXPORT ServiceWorkerVersion |
REQUEST_NOTIFICATION_CLICK, |
REQUEST_PUSH, |
REQUEST_GEOFENCING, |
- REQUEST_SERVICE_PORT_CONNECT, |
+ REQUEST_CUSTOM, |
NUM_REQUEST_TYPES |
}; |
struct RequestInfo { |
- RequestInfo(int id, RequestType type, const base::TimeTicks& expiration); |
+ RequestInfo(int id, |
+ RequestType type, |
+ ServiceWorkerMetrics::EventType event_type, |
+ const base::TimeTicks& expiration); |
~RequestInfo(); |
bool operator>(const RequestInfo& other) const; |
int id; |
RequestType type; |
+ ServiceWorkerMetrics::EventType event_type; |
base::TimeTicks expiration; |
}; |
@@ -411,6 +431,44 @@ class CONTENT_EXPORT ServiceWorkerVersion |
CallbackType callback; |
base::TimeTicks start_time; |
+ // Name of the mojo service this request is associated with. Used to call |
+ // the callback when a connection closes with outstanding requests. |
+ // Compared as pointer, so should only contain static strings. Typically |
+ // this would be Interface::Name_ for some mojo interface. |
+ const char* mojo_service = nullptr; |
+ }; |
+ |
+ // Base class to enable storing a list of mojo interface pointers for |
+ // arbitrary interfaces. The destructor is also responsible for calling the |
+ // error callbacks for any outstanding requests using this service. |
+ class CONTENT_EXPORT BaseMojoService { |
Ken Rockot(use gerrit already)
2016/01/07 20:36:48
nit: I find the name a little confusing since it's
Marijn Kruisselbrink
2016/01/07 21:33:06
renamed it to (Base)MojoServiceWrapper
|
+ public: |
+ BaseMojoService(ServiceWorkerVersion* worker, const char* service_name); |
+ virtual ~BaseMojoService(); |
+ |
+ private: |
+ ServiceWorkerVersion* worker_; |
+ const char* service_name_; |
+ }; |
Ken Rockot(use gerrit already)
2016/01/07 20:36:48
nit: DISALLOW_COPY_AND_ASSIGN
Marijn Kruisselbrink
2016/01/07 21:33:06
Done
|
+ |
+ // Wrapper around a mojo::InterfacePtr, which passes out WeakPtr's to the |
+ // interface. |
+ template <typename Interface> |
+ class MojoService : public BaseMojoService { |
+ public: |
+ MojoService(ServiceWorkerVersion* worker, |
+ mojo::InterfacePtr<Interface> interface) |
+ : BaseMojoService(worker, Interface::Name_), |
+ interface_(std::move(interface)), |
+ weak_ptr_factory_(interface_.get()) {} |
+ |
+ base::WeakPtr<Interface> GetWeakPtr() { |
+ return weak_ptr_factory_.GetWeakPtr(); |
+ } |
+ |
+ private: |
+ mojo::InterfacePtr<Interface> interface_; |
+ base::WeakPtrFactory<Interface> weak_ptr_factory_; |
}; |
typedef ServiceWorkerVersion self; |
@@ -481,10 +539,6 @@ class CONTENT_EXPORT ServiceWorkerVersion |
void OnPushEventFinished(int request_id, |
blink::WebServiceWorkerEventResult result); |
void OnGeofencingEventFinished(int request_id); |
- void OnServicePortConnectEventFinished(int request_id, |
- ServicePortConnectResult result, |
- const mojo::String& name, |
- const mojo::String& data); |
void OnOpenWindow(int request_id, GURL url); |
void OnOpenWindowFinished(int request_id, |
ServiceWorkerStatusCode status, |
@@ -555,13 +609,15 @@ class CONTENT_EXPORT ServiceWorkerVersion |
int AddRequest( |
const CallbackType& callback, |
IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, |
- RequestType request_type); |
+ RequestType request_type, |
+ ServiceWorkerMetrics::EventType event_type); |
template <typename CallbackType> |
int AddRequestWithExpiration( |
const CallbackType& callback, |
IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, |
RequestType request_type, |
+ ServiceWorkerMetrics::EventType event_type, |
base::TimeTicks expiration); |
bool MaybeTimeOutRequest(const RequestInfo& info); |
@@ -587,9 +643,11 @@ class CONTENT_EXPORT ServiceWorkerVersion |
// Called when a connection to a mojo event Dispatcher drops or fails. |
// Calls callbacks for any outstanding requests to the dispatcher as well |
// as cleans up the dispatcher. |
- void OnServicePortDispatcherConnectionError(); |
void OnBackgroundSyncDispatcherConnectionError(); |
+ // Called when the remote side of a connection to a mojo service is lost. |
+ void OnMojoConnectionError(const char* service_name); |
+ |
// Called at the beginning of each Dispatch*Event function: records |
// the time elapsed since idle (generally the time since the previous |
// event ended). |
@@ -617,12 +675,18 @@ class CONTENT_EXPORT ServiceWorkerVersion |
notification_click_requests_; |
IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> push_requests_; |
IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> geofencing_requests_; |
- IDMap<PendingRequest<ServicePortConnectCallback>, IDMapOwnPointer> |
- service_port_connect_requests_; |
+ IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> custom_requests_; |
- ServicePortDispatcherPtr service_port_dispatcher_; |
BackgroundSyncServiceClientPtr background_sync_dispatcher_; |
+ // Stores all open connections to mojo services. Maps the service name to |
+ // the actual interface pointer. When a connection is closed it is removed |
+ // from this map. |
+ // mojo_services_[Interface::Name_] is assumed to always contain a |
+ // MojoService<Interface> instance. |
+ base::ScopedPtrHashMap<const char*, scoped_ptr<BaseMojoService>> |
+ mojo_services_; |
+ |
std::set<const ServiceWorkerURLRequestJob*> streaming_url_request_jobs_; |
std::map<std::string, ServiceWorkerProviderHost*> controllee_map_; |
@@ -677,6 +741,31 @@ class CONTENT_EXPORT ServiceWorkerVersion |
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion); |
}; |
+template <typename Interface> |
+base::WeakPtr<Interface> ServiceWorkerVersion::GetMojoServiceForRequest( |
+ int request_id) { |
+ DCHECK_EQ(RUNNING, running_status()); |
+ PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id); |
+ DCHECK(request) << "Invalid request id"; |
+ DCHECK(!request->mojo_service) |
+ << "Request is already associated with a mojo service"; |
+ |
+ MojoService<Interface>* service = static_cast<MojoService<Interface>*>( |
+ mojo_services_.get(Interface::Name_)); |
+ if (!service) { |
+ mojo::InterfacePtr<Interface> interface; |
+ embedded_worker_->GetServiceRegistry()->ConnectToRemoteService( |
+ mojo::GetProxy(&interface)); |
+ interface.set_connection_error_handler( |
+ base::Bind(&ServiceWorkerVersion::OnMojoConnectionError, |
+ weak_factory_.GetWeakPtr(), Interface::Name_)); |
+ service = new MojoService<Interface>(this, std::move(interface)); |
+ mojo_services_.add(Interface::Name_, make_scoped_ptr(service)); |
+ } |
+ request->mojo_service = Interface::Name_; |
+ return service->GetWeakPtr(); |
+} |
+ |
} // namespace content |
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_ |