1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_ 6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_ 7 8 #include <vector> 9 10 #include "base/memory/weak_ptr.h" 11 #include "content/browser/service_worker/service_worker_register_job_base.h" 12 #include "content/browser/service_worker/service_worker_registration.h" 13 #include "content/common/service_worker/service_worker_status_code.h" 14 #include "url/gurl.h" 15 16 namespace content { 17 18 class ServiceWorkerJobCoordinator; 19 class ServiceWorkerStorage; 20 21 // Handles the registration of a Service Worker. 22 // 23 // The registration flow includes most or all of the following, 24 // depending on what is already registered: 25 // - creating a ServiceWorkerRegistration instance if there isn't 26 // already something registered 27 // - creating a ServiceWorkerVersion for the new registration instance. 28 // - starting a worker for the ServiceWorkerVersion 29 // - telling the Version to evaluate the script 30 // - firing the 'install' event at the ServiceWorkerVersion 31 // - firing the 'activate' event at the ServiceWorkerVersion 32 // - waiting for older ServiceWorkerVersions to deactivate 33 // - designating the new version to be the 'active' version 34 class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase { 35 public: 36 typedef base::Callback<void(ServiceWorkerStatusCode status, 37 ServiceWorkerRegistration* registration, 38 ServiceWorkerVersion* version)> 39 RegistrationCallback; 40 41 CONTENT_EXPORT ServiceWorkerRegisterJob( 42 base::WeakPtr<ServiceWorkerContextCore> context, 43 const GURL& pattern, 44 const GURL& script_url); 45 virtual ~ServiceWorkerRegisterJob(); 46 47 // Registers a callback to be called when the promise would resolve (whether 48 // successfully or not). Multiple callbacks may be registered. If |process_id| 49 // is not -1, it's added to the existing clients when deciding in which 50 // process to create the Service Worker instance. If there are no existing 51 // clients, a new RenderProcessHost will be created. 52 void AddCallback(const RegistrationCallback& callback, int process_id); 53 54 // ServiceWorkerRegisterJobBase implementation: 55 virtual void Start() OVERRIDE; 56 virtual void Abort() OVERRIDE; 57 virtual bool Equals(ServiceWorkerRegisterJobBase* job) OVERRIDE; 58 virtual RegistrationJobType GetType() OVERRIDE; 59 60 private: 61 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostWaitingVersionTest, 62 AssociateWaitingVersionToDocuments); 63 FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostWaitingVersionTest, 64 DisassociateWaitingVersionFromDocuments); 65 66 enum Phase { 67 INITIAL, 68 START, 69 REGISTER, 70 UPDATE, 71 INSTALL, 72 STORE, 73 ACTIVATE, 74 COMPLETE, 75 ABORT, 76 }; 77 78 // Holds internal state of ServiceWorkerRegistrationJob, to compel use of the 79 // getter/setter functions. 80 struct Internal { 81 Internal(); 82 ~Internal(); 83 scoped_refptr<ServiceWorkerRegistration> registration; 84 85 // Holds 'installing' or 'waiting' version depending on the phase. 86 scoped_refptr<ServiceWorkerVersion> pending_version; 87 }; 88 89 void set_registration(ServiceWorkerRegistration* registration); 90 ServiceWorkerRegistration* registration(); 91 void set_pending_version(ServiceWorkerVersion* version); 92 ServiceWorkerVersion* pending_version(); 93 94 void SetPhase(Phase phase); 95 96 void HandleExistingRegistrationAndContinue( 97 ServiceWorkerStatusCode status, 98 const scoped_refptr<ServiceWorkerRegistration>& registration); 99 void RegisterAndContinue(ServiceWorkerStatusCode status); 100 void UpdateAndContinue(ServiceWorkerStatusCode status); 101 void OnStartWorkerFinished(ServiceWorkerStatusCode status); 102 void OnStoreRegistrationComplete(ServiceWorkerStatusCode status); 103 void InstallAndContinue(); 104 void OnInstallFinished(ServiceWorkerStatusCode status); 105 void ActivateAndContinue(); 106 void OnActivateFinished(ServiceWorkerStatusCode status); 107 void Complete(ServiceWorkerStatusCode status); 108 void CompleteInternal(ServiceWorkerStatusCode status); 109 110 void ResolvePromise(ServiceWorkerStatusCode status, 111 ServiceWorkerRegistration* registration, 112 ServiceWorkerVersion* version); 113 114 // Associates a waiting version to documents matched with a scope of the 115 // version. 116 CONTENT_EXPORT static void AssociateWaitingVersionToDocuments( 117 base::WeakPtr<ServiceWorkerContextCore> context, 118 ServiceWorkerVersion* version); 119 120 // Disassociates a waiting version specified by |version_id| from documents. 121 CONTENT_EXPORT static void DisassociateWaitingVersionFromDocuments( 122 base::WeakPtr<ServiceWorkerContextCore> context, 123 int64 version_id); 124 125 // The ServiceWorkerContextCore object should always outlive this. 126 base::WeakPtr<ServiceWorkerContextCore> context_; 127 128 const GURL pattern_; 129 const GURL script_url_; 130 std::vector<RegistrationCallback> callbacks_; 131 std::vector<int> pending_process_ids_; 132 Phase phase_; 133 Internal internal_; 134 bool is_promise_resolved_; 135 ServiceWorkerStatusCode promise_resolved_status_; 136 scoped_refptr<ServiceWorkerRegistration> promise_resolved_registration_; 137 scoped_refptr<ServiceWorkerVersion> promise_resolved_version_; 138 base::WeakPtrFactory<ServiceWorkerRegisterJob> weak_factory_; 139 140 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegisterJob); 141 }; 142 143 } // namespace content 144 145 #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_ 146