Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_register_job.cc
index f293237..5f9d2f2 100644 (file)
@@ -15,12 +15,15 @@ namespace content {
 
 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
     ServiceWorkerStorage* storage,
+    EmbeddedWorkerRegistry* worker_registry,
     ServiceWorkerJobCoordinator* coordinator,
     const GURL& pattern,
     const GURL& script_url,
     RegistrationType type)
     : storage_(storage),
+      worker_registry_(worker_registry),
       coordinator_(coordinator),
+      pending_version_(NULL),
       pattern_(pattern),
       script_url_(script_url),
       type_(type),
@@ -28,9 +31,17 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
 
 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {}
 
-void ServiceWorkerRegisterJob::AddCallback(
-    const RegistrationCallback& callback) {
+void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback,
+                                           int process_id) {
+  // if we've created a pending version, associate source_provider it with
+  // that, otherwise queue it up
   callbacks_.push_back(callback);
+  DCHECK(process_id != -1);
+  if (pending_version_) {
+    pending_version_->AddProcessToWorker(process_id);
+  } else {
+    pending_process_ids_.push_back(process_id);
+  }
 }
 
 void ServiceWorkerRegisterJob::Start() {
@@ -49,13 +60,18 @@ bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJob* job) {
 void ServiceWorkerRegisterJob::StartRegister() {
   // Set up a chain of callbacks, in reverse order. Each of these
   // callbacks may be called asynchronously by the previous callback.
-  RegistrationCallback finish_registration(base::Bind(
+  StatusCallback finish_registration(base::Bind(
       &ServiceWorkerRegisterJob::RegisterComplete, weak_factory_.GetWeakPtr()));
 
+  RegistrationCallback start_worker(
+      base::Bind(&ServiceWorkerRegisterJob::StartWorkerAndContinue,
+                 weak_factory_.GetWeakPtr(),
+                 finish_registration));
+
   UnregistrationCallback register_new(
       base::Bind(&ServiceWorkerRegisterJob::RegisterPatternAndContinue,
                  weak_factory_.GetWeakPtr(),
-                 finish_registration));
+                 start_worker));
 
   ServiceWorkerStorage::FindRegistrationCallback unregister_old(
       base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue,
@@ -80,6 +96,35 @@ void ServiceWorkerRegisterJob::StartUnregister() {
   storage_->FindRegistrationForPattern(pattern_, unregister);
 }
 
+void ServiceWorkerRegisterJob::StartWorkerAndContinue(
+    const StatusCallback& callback,
+    ServiceWorkerStatusCode status,
+    const scoped_refptr<ServiceWorkerRegistration>& registration) {
+  if (registration->active_version()) {
+    // We have an active version, so we can complete immediately, even
+    // if the service worker isn't running.
+    callback.Run(registration, SERVICE_WORKER_OK);
+    return;
+  }
+
+  pending_version_ = new ServiceWorkerVersion(
+      registration, worker_registry_, registration->next_version_id());
+  for (std::vector<int>::const_iterator it = pending_process_ids_.begin();
+       it != pending_process_ids_.end();
+       ++it)
+    pending_version_->AddProcessToWorker(*it);
+
+  // The callback to watch "installation" actually fires as soon as
+  // the worker is up and running, just before the install event is
+  // dispatched. The job will continue to run even though the main
+  // callback has executed.
+  pending_version_->StartWorker(base::Bind(callback, registration));
+
+  // TODO(alecflett): Don't set the active version until just before
+  // the activate event is dispatched.
+  registration->set_active_version(pending_version_);
+}
+
 void ServiceWorkerRegisterJob::RegisterPatternAndContinue(
     const RegistrationCallback& callback,
     ServiceWorkerStatusCode previous_status) {
@@ -97,6 +142,7 @@ void ServiceWorkerRegisterJob::RegisterPatternAndContinue(
   // operation. Pass its resulting status through 'callback'.
   scoped_refptr<ServiceWorkerRegistration> registration =
       storage_->RegisterInternal(pattern_, script_url_);
+
   BrowserThread::PostTask(BrowserThread::IO,
                           FROM_HERE,
                           base::Bind(callback, SERVICE_WORKER_OK,
@@ -118,6 +164,9 @@ void ServiceWorkerRegisterJob::UnregisterPatternAndContinue(
     // 'callback'.
     storage_->UnregisterInternal(pattern_);
     DCHECK(previous_registration->is_shutdown());
+  } else {
+    // TODO(alecflett): We have an existing registration, we should
+    // schedule an update.
   }
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE, base::Bind(callback, previous_status));
@@ -132,10 +181,11 @@ void ServiceWorkerRegisterJob::RunCallbacks(
     it->Run(status, registration);
   }
 }
+
 void ServiceWorkerRegisterJob::RegisterComplete(
-    ServiceWorkerStatusCode status,
-    const scoped_refptr<ServiceWorkerRegistration>& registration) {
-  RunCallbacks(status, registration);
+    const scoped_refptr<ServiceWorkerRegistration>& registration,
+    ServiceWorkerStatusCode start_status) {
+  RunCallbacks(start_status, registration);
   coordinator_->FinishJob(pattern_, this);
 }