#include <vector>
#include "base/memory/weak_ptr.h"
-#include "content/browser/service_worker/service_worker_registration_status.h"
-#include "content/browser/service_worker/service_worker_storage.h"
-#include "content/browser/service_worker/service_worker_version.h"
+#include "content/browser/service_worker/service_worker_register_job_base.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+#include "url/gurl.h"
namespace content {
-class EmbeddedWorkerRegistry;
class ServiceWorkerJobCoordinator;
-
-// A ServiceWorkerRegisterJob lives only for the lifetime of a single
-// registration or unregistration.
-class ServiceWorkerRegisterJob {
+class ServiceWorkerStorage;
+
+// Handles the registration of a Service Worker.
+//
+// The registration flow includes most or all of the following,
+// depending on what is already registered:
+// - creating a ServiceWorkerRegistration instance if there isn't
+// already something registered
+// - creating a ServiceWorkerVersion for the new registration instance.
+// - starting a worker for the ServiceWorkerVersion
+// - telling the Version to evaluate the script
+// - firing the 'install' event at the ServiceWorkerVersion
+// - firing the 'activate' event at the ServiceWorkerVersion
+// - waiting for older ServiceWorkerVersions to deactivate
+// - designating the new version to be the 'active' version
+class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
public:
- enum RegistrationType {
- REGISTER,
- UNREGISTER,
- };
-
- typedef base::Callback<void(ServiceWorkerStatusCode status)>
- StatusCallback;
-
- typedef base::Callback<
- void(ServiceWorkerStatusCode status,
- const scoped_refptr<ServiceWorkerRegistration>& registration)>
+ typedef base::Callback<void(ServiceWorkerStatusCode status,
+ ServiceWorkerRegistration* registration,
+ ServiceWorkerVersion* version)>
RegistrationCallback;
- typedef StatusCallback UnregistrationCallback;
-
- // All type of jobs (Register and Unregister) complete through a
- // single call to this callback on the IO thread.
- ServiceWorkerRegisterJob(ServiceWorkerStorage* storage,
- EmbeddedWorkerRegistry* worker_registry,
- ServiceWorkerJobCoordinator* coordinator,
- const GURL& pattern,
- const GURL& script_url,
- RegistrationType type);
- ~ServiceWorkerRegisterJob();
+ CONTENT_EXPORT ServiceWorkerRegisterJob(
+ base::WeakPtr<ServiceWorkerContextCore> context,
+ const GURL& pattern,
+ const GURL& script_url);
+ virtual ~ServiceWorkerRegisterJob();
+
+ // Registers a callback to be called when the promise would resolve (whether
+ // successfully or not). Multiple callbacks may be registered. If |process_id|
+ // is not -1, it's added to the existing clients when deciding in which
+ // process to create the Service Worker instance. If there are no existing
+ // clients, a new RenderProcessHost will be created.
void AddCallback(const RegistrationCallback& callback, int process_id);
- void Start();
-
- bool Equals(ServiceWorkerRegisterJob* job);
+ // ServiceWorkerRegisterJobBase implementation:
+ virtual void Start() OVERRIDE;
+ virtual bool Equals(ServiceWorkerRegisterJobBase* job) OVERRIDE;
+ virtual RegistrationJobType GetType() OVERRIDE;
private:
- // The Registration flow includes most or all of the following,
- // depending on what is already registered:
- // - creating a ServiceWorkerRegistration instance if there isn't
- // already something registered
- // - creating a ServiceWorkerVersion for the new registration instance.
- // - starting a worker for the ServiceWorkerVersion
- // - telling the Version to evaluate the script
- // - firing the 'install' event at the ServiceWorkerVersion
- // - firing the 'activate' event at the ServiceWorkerVersion
- // - Waiting for older ServiceWorkerVersions to deactivate
- // - designating the new version to be the 'active' version
- // This method should be called once and only once per job.
- void StartRegister();
-
- // The Unregistration process is primarily cleanup, removing
- // everything that was created during the Registration process,
- // including the ServiceWorkerRegistration itself.
- // This method should be called once and only once per job.
- void StartUnregister();
-
- // These are all steps in the registration and unregistration pipeline.
- void RegisterPatternAndContinue(
- const StatusCallback& callback,
- ServiceWorkerStatusCode previous_status);
-
- void UnregisterPatternAndContinue(
- const StatusCallback& callback,
- ServiceWorkerStatusCode previous_status,
- const scoped_refptr<ServiceWorkerRegistration>& previous_registration);
-
- void StartWorkerAndContinue(
- const StatusCallback& callback,
- ServiceWorkerStatusCode previous_status);
-
- // This method is the last internal callback in the callback
- // chain, and ultimately call callback_.
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerRegisterJobAndProviderHostTest,
+ AssociatePendingVersionToDocuments);
+
+ enum Phase {
+ INITIAL,
+ START,
+ REGISTER,
+ UPDATE,
+ INSTALL,
+ STORE,
+ ACTIVATE,
+ COMPLETE
+ };
+
+ // Holds internal state of ServiceWorkerRegistrationJob, to compel use of the
+ // getter/setter functions.
+ struct Internal {
+ Internal();
+ ~Internal();
+ scoped_refptr<ServiceWorkerRegistration> registration;
+ scoped_refptr<ServiceWorkerVersion> pending_version;
+ };
+
+ void set_registration(ServiceWorkerRegistration* registration);
+ ServiceWorkerRegistration* registration();
+ void set_pending_version(ServiceWorkerVersion* version);
+ ServiceWorkerVersion* pending_version();
+
+ void SetPhase(Phase phase);
+
+ void HandleExistingRegistrationAndContinue(
+ ServiceWorkerStatusCode status,
+ const scoped_refptr<ServiceWorkerRegistration>& registration);
+ void RegisterAndContinue(ServiceWorkerStatusCode status);
+ void UpdateAndContinue(ServiceWorkerStatusCode status);
+ void OnStartWorkerFinished(ServiceWorkerStatusCode status);
+ void OnStoreRegistrationComplete(ServiceWorkerStatusCode status);
+ void InstallAndContinue();
+ void OnInstallFinished(ServiceWorkerStatusCode status);
+ void ActivateAndContinue();
+ void OnActivateFinished(ServiceWorkerStatusCode status);
void Complete(ServiceWorkerStatusCode status);
- // The ServiceWorkerStorage object should always outlive
- // this.
-
- // TODO(alecflett) When we support job cancelling, if we are keeping
- // this job alive for any reason, be sure to clear this variable,
- // because we may be cancelling while there are outstanding
- // callbacks that expect access to storage_.
- ServiceWorkerStorage* storage_;
- EmbeddedWorkerRegistry* worker_registry_;
- ServiceWorkerJobCoordinator* coordinator_;
- scoped_refptr<ServiceWorkerRegistration> registration_;
- scoped_refptr<ServiceWorkerVersion> pending_version_;
+ void ResolvePromise(ServiceWorkerStatusCode status,
+ ServiceWorkerRegistration* registration,
+ ServiceWorkerVersion* version);
+
+ CONTENT_EXPORT void AssociatePendingVersionToDocuments(
+ ServiceWorkerVersion* version);
+
+ // The ServiceWorkerContextCore object should always outlive this.
+ base::WeakPtr<ServiceWorkerContextCore> context_;
+
const GURL pattern_;
const GURL script_url_;
- const RegistrationType type_;
std::vector<RegistrationCallback> callbacks_;
std::vector<int> pending_process_ids_;
+ Phase phase_;
+ Internal internal_;
+ bool is_promise_resolved_;
+ ServiceWorkerStatusCode promise_resolved_status_;
+ scoped_refptr<ServiceWorkerRegistration> promise_resolved_registration_;
+ scoped_refptr<ServiceWorkerVersion> promise_resolved_version_;
base::WeakPtrFactory<ServiceWorkerRegisterJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegisterJob);
};
+
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_