#include "base/memory/scoped_ptr.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_types.h"
#include "url/gurl.h"
namespace content {
class ServiceWorkerRegistrationInfo;
class ServiceWorkerVersion;
-// This class manages all persistence of service workers:
-// - Registrations
-// - Mapping of caches to registrations / versions
-//
-// This is the place where we manage simultaneous
-// requests for the same registrations and caches, making sure that
-// two pages that are registering the same pattern at the same time
-// have their registrations coalesced rather than overwriting each
-// other.
-//
-// This class also manages the state of the upgrade process, which
-// includes managing which ServiceWorkerVersion is "active" vs "in
-// waiting".
+// This class represents a service worker registration. The
+// scope and script url are constant for the life of the persistent
+// registration. It's refcounted to facillitate multiple controllees
+// being associated with the same registration. The class roughly
+// corresponds to navigator.serviceWorker.registgration.
class CONTENT_EXPORT ServiceWorkerRegistration
- : NON_EXPORTED_BASE(public base::RefCounted<ServiceWorkerRegistration>) {
+ : NON_EXPORTED_BASE(public base::RefCounted<ServiceWorkerRegistration>),
+ public ServiceWorkerVersion::Listener {
public:
+ typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
+
+ class Listener {
+ public:
+ virtual void OnVersionAttributesChanged(
+ ServiceWorkerRegistration* registration,
+ ChangedVersionAttributesMask changed_mask,
+ const ServiceWorkerRegistrationInfo& info) = 0;
+ virtual void OnRegistrationFailed(
+ ServiceWorkerRegistration* registration) = 0;
+ };
+
ServiceWorkerRegistration(const GURL& pattern,
const GURL& script_url,
int64 registration_id,
const GURL& script_url() const { return script_url_; }
const GURL& pattern() const { return pattern_; }
+ bool is_deleted() const { return is_deleted_; }
+ void set_is_deleted(bool deleted) { is_deleted_ = deleted; }
+
+ bool is_uninstalling() const { return is_uninstalling_; }
+
ServiceWorkerVersion* active_version() const {
- DCHECK(!is_shutdown_);
return active_version_.get();
}
ServiceWorkerVersion* waiting_version() const {
- DCHECK(!is_shutdown_);
return waiting_version_.get();
}
- void set_active_version(ServiceWorkerVersion* version) {
- DCHECK(!is_shutdown_);
- active_version_ = version;
+ ServiceWorkerVersion* installing_version() const {
+ return installing_version_.get();
}
- void set_waiting_version(ServiceWorkerVersion* version) {
- DCHECK(!is_shutdown_);
- waiting_version_ = version;
- }
+ void AddListener(Listener* listener);
+ void RemoveListener(Listener* listener);
+ void NotifyRegistrationFailed();
ServiceWorkerRegistrationInfo GetInfo();
- // Returns the active version, if it is not null; otherwise, returns the
- // waiting version.
- ServiceWorkerVersion* GetNewestVersion();
-
- // The final synchronous switchover after all events have been
- // fired, and the old "active version" is being shut down.
- void ActivateWaitingVersion();
+ // Sets the corresposding version attribute and resets the position
+ // (if any) left vacant (ie. by a waiting version being promoted).
+ // Also notifies listeners via OnVersionAttributesChanged.
+ void SetActiveVersion(ServiceWorkerVersion* version);
+ void SetWaitingVersion(ServiceWorkerVersion* version);
+ void SetInstallingVersion(ServiceWorkerVersion* version);
+
+ // If version is the installing, waiting, active version of this
+ // registation, the method will reset that field to NULL, and notify
+ // listeners via OnVersionAttributesChanged.
+ void UnsetVersion(ServiceWorkerVersion* version);
+
+ // Triggers the [[Activate]] algorithm when the currently active version
+ // has no controllees. If there are no controllees at the time the method
+ // is called, activation is initiated immediately.
+ void ActivateWaitingVersionWhenReady();
+
+ // Triggers the [[ClearRegistration]] algorithm when the currently
+ // active version has no controllees. Deletes this registration
+ // from storage immediately.
+ void ClearWhenReady();
+
+ // Restores this registration in storage and cancels the pending
+ // [[ClearRegistration]] algorithm. If the algorithm was already triggered,
+ // does nothing.
+ void AbortPendingClear();
+
+ // The time of the most recent update check.
+ base::Time last_update_check() const { return last_update_check_; }
+ void set_last_update_check(base::Time last) { last_update_check_ = last; }
private:
- ~ServiceWorkerRegistration();
friend class base::RefCounted<ServiceWorkerRegistration>;
+ virtual ~ServiceWorkerRegistration();
+
+ void SetVersionInternal(
+ ServiceWorkerVersion* version,
+ scoped_refptr<ServiceWorkerVersion>* data_member,
+ int change_flag);
+ void UnsetVersionInternal(
+ ServiceWorkerVersion* version,
+ ChangedVersionAttributesMask* mask);
+
+ // ServiceWorkerVersion::Listener override.
+ virtual void OnNoControllees(ServiceWorkerVersion* version) OVERRIDE;
+
+ // This method corresponds to the [[Activate]] algorithm.
+ void ActivateWaitingVersion();
+ void OnActivateEventFinished(
+ ServiceWorkerVersion* activating_version,
+ ServiceWorkerStatusCode status);
+ void OnDeleteFinished(ServiceWorkerStatusCode status);
+
+ // This method corresponds to the [[ClearRegistration]] algorithm.
+ void Clear();
+ void OnStoreFinished(scoped_refptr<ServiceWorkerVersion> version,
+ ServiceWorkerStatusCode status);
+
const GURL pattern_;
const GURL script_url_;
const int64 registration_id_;
-
+ bool is_deleted_;
+ bool is_uninstalling_;
+ bool should_activate_when_ready_;
+ base::Time last_update_check_;
scoped_refptr<ServiceWorkerVersion> active_version_;
scoped_refptr<ServiceWorkerVersion> waiting_version_;
-
- bool is_shutdown_;
+ scoped_refptr<ServiceWorkerVersion> installing_version_;
+ ObserverList<Listener> listeners_;
base::WeakPtr<ServiceWorkerContextCore> context_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistration);
};
+
} // namespace content
+
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_H_