summaryrefslogtreecommitdiffstats
path: root/content/browser/service_worker/service_worker_register_job.h
blob: 0a0c198fcb1313626af87c491909f76e875f65c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTER_JOB_H_

#include <vector>

#include "base/memory/weak_ptr.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 ServiceWorkerJobCoordinator;
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:
  typedef base::Callback<void(ServiceWorkerStatusCode status,
                              ServiceWorkerRegistration* registration,
                              ServiceWorkerVersion* version)>
      RegistrationCallback;

  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);

  // ServiceWorkerRegisterJobBase implementation:
  virtual void Start() OVERRIDE;
  virtual bool Equals(ServiceWorkerRegisterJobBase* job) OVERRIDE;
  virtual RegistrationJobType GetType() OVERRIDE;

 private:
  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);

  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_;
  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_