service_worker_register_job.h revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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/embedded_worker_instance.h"
12#include "content/browser/service_worker/service_worker_register_job_base.h"
13#include "content/browser/service_worker/service_worker_registration.h"
14#include "content/common/service_worker/service_worker_status_code.h"
15#include "url/gurl.h"
16
17namespace content {
18
19class ServiceWorkerJobCoordinator;
20class ServiceWorkerStorage;
21
22// Handles the initial registration of a Service Worker and the
23// subsequent update of existing registrations.
24//
25// The control flow includes most or all of the following,
26// depending on what is already registered:
27//  - creating a ServiceWorkerRegistration instance if there isn't
28//    already something registered
29//  - creating a ServiceWorkerVersion for the new version.
30//  - starting a worker for the ServiceWorkerVersion
31//  - firing the 'install' event at the ServiceWorkerVersion
32//  - firing the 'activate' event at the ServiceWorkerVersion
33//  - waiting for older ServiceWorkerVersions to deactivate
34//  - designating the new version to be the 'active' version
35//  - updating storage
36class ServiceWorkerRegisterJob
37    : public ServiceWorkerRegisterJobBase,
38      public EmbeddedWorkerInstance::Listener {
39 public:
40  typedef base::Callback<void(ServiceWorkerStatusCode status,
41                              ServiceWorkerRegistration* registration,
42                              ServiceWorkerVersion* version)>
43      RegistrationCallback;
44
45  // For registration jobs.
46  CONTENT_EXPORT ServiceWorkerRegisterJob(
47      base::WeakPtr<ServiceWorkerContextCore> context,
48      const GURL& pattern,
49      const GURL& script_url);
50
51  // For update jobs.
52  CONTENT_EXPORT ServiceWorkerRegisterJob(
53      base::WeakPtr<ServiceWorkerContextCore> context,
54      ServiceWorkerRegistration* registration);
55  virtual ~ServiceWorkerRegisterJob();
56
57  // Registers a callback to be called when the promise would resolve (whether
58  // successfully or not). Multiple callbacks may be registered. If |process_id|
59  // is not -1, it's added to the existing clients when deciding in which
60  // process to create the Service Worker instance.  If there are no existing
61  // clients, a new RenderProcessHost will be created.
62  void AddCallback(const RegistrationCallback& callback, int process_id);
63
64  // ServiceWorkerRegisterJobBase implementation:
65  virtual void Start() OVERRIDE;
66  virtual void Abort() OVERRIDE;
67  virtual bool Equals(ServiceWorkerRegisterJobBase* job) OVERRIDE;
68  virtual RegistrationJobType GetType() OVERRIDE;
69
70  // TODO(michaeln): Use the registration listerer's OnVersionAttributesChanged
71  // method to replace these methods, have the host listen for changes
72  // to their registration.
73  CONTENT_EXPORT static void AssociateInstallingVersionToDocuments(
74      base::WeakPtr<ServiceWorkerContextCore> context,
75      ServiceWorkerVersion* version);
76  static void AssociateWaitingVersionToDocuments(
77      base::WeakPtr<ServiceWorkerContextCore> context,
78      ServiceWorkerVersion* version);
79  static void AssociateActiveVersionToDocuments(
80      base::WeakPtr<ServiceWorkerContextCore> context,
81      ServiceWorkerVersion* version);
82  CONTENT_EXPORT static void DisassociateVersionFromDocuments(
83      base::WeakPtr<ServiceWorkerContextCore> context,
84      ServiceWorkerVersion* version);
85
86 private:
87  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostWaitingVersionTest,
88                           AssociateInstallingVersionToDocuments);
89  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostWaitingVersionTest,
90                           DisassociateVersionFromDocuments);
91
92  enum Phase {
93     INITIAL,
94     START,
95     REGISTER,
96     UPDATE,
97     INSTALL,
98     STORE,
99     COMPLETE,
100     ABORT,
101  };
102
103  // Holds internal state of ServiceWorkerRegistrationJob, to compel use of the
104  // getter/setter functions.
105  struct Internal {
106    Internal();
107    ~Internal();
108    scoped_refptr<ServiceWorkerRegistration> registration;
109
110    // Holds the version created by this job. It can be the 'installing',
111    // 'waiting', or 'active' version depending on the phase.
112    scoped_refptr<ServiceWorkerVersion> new_version;
113  };
114
115  void set_registration(ServiceWorkerRegistration* registration);
116  ServiceWorkerRegistration* registration();
117  void set_new_version(ServiceWorkerVersion* version);
118  ServiceWorkerVersion* new_version();
119
120  void SetPhase(Phase phase);
121
122  void ContinueWithRegistration(
123      ServiceWorkerStatusCode status,
124      const scoped_refptr<ServiceWorkerRegistration>& registration);
125  void ContinueWithUpdate(
126      ServiceWorkerStatusCode status,
127      const scoped_refptr<ServiceWorkerRegistration>& registration);
128  void RegisterAndContinue(ServiceWorkerStatusCode status);
129  void UpdateAndContinue();
130  void OnStartWorkerFinished(ServiceWorkerStatusCode status);
131  void OnStoreRegistrationComplete(ServiceWorkerStatusCode status);
132  void InstallAndContinue();
133  void OnInstallFinished(ServiceWorkerStatusCode status);
134  void ActivateAndContinue();
135  void OnActivateFinished(ServiceWorkerStatusCode status);
136  void Complete(ServiceWorkerStatusCode status);
137  void CompleteInternal(ServiceWorkerStatusCode status);
138  void ResolvePromise(ServiceWorkerStatusCode status,
139                      ServiceWorkerRegistration* registration,
140                      ServiceWorkerVersion* version);
141
142  // EmbeddedWorkerInstance::Listener override of OnPausedAfterDownload.
143  virtual void OnPausedAfterDownload() OVERRIDE;
144  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
145
146  void OnCompareScriptResourcesComplete(
147      ServiceWorkerVersion* current_version,
148      ServiceWorkerStatusCode status,
149      bool are_equal);
150
151  // The ServiceWorkerContextCore object should always outlive this.
152  base::WeakPtr<ServiceWorkerContextCore> context_;
153
154  RegistrationJobType job_type_;
155  const GURL pattern_;
156  const GURL script_url_;
157  std::vector<RegistrationCallback> callbacks_;
158  std::vector<int> pending_process_ids_;
159  Phase phase_;
160  Internal internal_;
161  bool is_promise_resolved_;
162  ServiceWorkerStatusCode promise_resolved_status_;
163  scoped_refptr<ServiceWorkerRegistration> promise_resolved_registration_;
164  scoped_refptr<ServiceWorkerVersion> promise_resolved_version_;
165  base::WeakPtrFactory<ServiceWorkerRegisterJob> weak_factory_;
166
167  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegisterJob);
168};
169
170}  // namespace content
171
172#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_
173