1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/service_worker/service_worker_version.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/command_line.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/stl_util.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string16.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_instance.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_registry.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_utils.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/service_worker/service_worker_messages.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/public/common/content_switches.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace content {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef ServiceWorkerVersion::StatusCallback StatusCallback;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef ServiceWorkerVersion::MessageCallback MessageCallback;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Default delay for scheduled stop.
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// (Note that if all references to the version is dropped the worker
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// is also stopped without delay)
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int64 kStopWorkerDelay = 30;  // 30 secs.
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Default delay for scheduled update.
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kUpdateDelaySeconds = 1;
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RunSoon(const base::Closure& callback) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!callback.is_null())
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, callback);
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename CallbackArray, typename Arg>
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid RunCallbacks(ServiceWorkerVersion* version,
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                  CallbackArray* callbacks_ptr,
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                  const Arg& arg) {
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CallbackArray callbacks;
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callbacks.swap(*callbacks_ptr);
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<ServiceWorkerVersion> protect(version);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (typename CallbackArray::const_iterator i = callbacks.begin();
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       i != callbacks.end(); ++i)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    (*i).Run(arg);
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutemplate <typename IDMAP, typename Method, typename Params>
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RunIDMapCallbacks(IDMAP* callbacks, Method method, const Params& params) {
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typename IDMAP::iterator iter(callbacks);
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  while (!iter.IsAtEnd()) {
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DispatchToMethod(iter.GetCurrentValue(), method, params);
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    iter.Advance();
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  callbacks->Clear();
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A callback adapter to start a |task| after StartWorker.
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RunTaskAfterStartWorker(
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::WeakPtr<ServiceWorkerVersion> version,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const StatusCallback& error_callback,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Closure& task,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ServiceWorkerStatusCode status) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (status != SERVICE_WORKER_OK) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!error_callback.is_null())
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      error_callback.Run(status);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (version->running_status() != ServiceWorkerVersion::RUNNING) {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // We've tried to start the worker (and it has succeeded), but
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // it looks it's not running yet.
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "The worker's not running after successful StartWorker";
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!error_callback.is_null())
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  task.Run();
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RunErrorFetchCallback(const ServiceWorkerVersion::FetchCallback& callback,
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           ServiceWorkerStatusCode status) {
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  callback.Run(status,
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu               SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu               ServiceWorkerResponse());
88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ServiceWorkerVersion::ServiceWorkerVersion(
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ServiceWorkerRegistration* registration,
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& script_url,
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    int64 version_id,
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::WeakPtr<ServiceWorkerContextCore> context)
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : version_id_(version_id),
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      registration_id_(kInvalidServiceWorkerVersionId),
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      script_url_(script_url),
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      status_(NEW),
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      context_(context),
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      script_cache_map_(this, context),
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_doomed_(false),
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      weak_factory_(this) {
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(context_);
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(registration);
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (registration) {
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    registration_id_ = registration->id();
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scope_ = registration->pattern();
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  context_->AddLiveVersion(this);
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  embedded_worker_ = context_->embedded_worker_registry()->CreateWorker();
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  embedded_worker_->AddListener(this);
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cache_listener_.reset(new ServiceWorkerCacheListener(this, context));
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  embedded_worker_->AddListener(cache_listener_.get());
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochServiceWorkerVersion::~ServiceWorkerVersion() {
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  embedded_worker_->RemoveListener(this);
120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (context_)
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    context_->RemoveLiveVersion(version_id_);
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // EmbeddedWorker's dtor sends StopWorker if it's still running.
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerVersion::SetStatus(Status status) {
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (status_ == status)
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Schedule to stop worker after registration successfully completed.
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (status_ == ACTIVATING && status == ACTIVATED && !HasControllee())
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ScheduleStopWorker();
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  status_ = status;
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<base::Closure> callbacks;
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callbacks.swap(status_change_callbacks_);
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::vector<base::Closure>::const_iterator i = callbacks.begin();
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i != callbacks.end(); ++i) {
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    (*i).Run();
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FOR_EACH_OBSERVER(Listener, listeners_, OnVersionStateChanged(this));
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerVersion::RegisterStatusChangeCallback(
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::Closure& callback) {
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  status_change_callbacks_.push_back(callback);
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerVersionInfo ServiceWorkerVersion::GetInfo() {
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return ServiceWorkerVersionInfo(
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      running_status(),
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      status(),
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      script_url(),
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      version_id(),
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      embedded_worker()->process_id(),
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      embedded_worker()->thread_id(),
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      embedded_worker()->worker_devtools_agent_route_id());
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StartWorker(false, callback);
1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerVersion::StartWorker(
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool pause_after_download,
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const StatusCallback& callback) {
1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  switch (running_status()) {
1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    case RUNNING:
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return;
1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    case STOPPING:
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return;
1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    case STOPPED:
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    case STARTING:
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      start_callbacks_.push_back(callback);
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (running_status() == STOPPED) {
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        embedded_worker_->Start(
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            version_id_,
1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            scope_,
1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            script_url_,
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            pause_after_download,
1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            base::Bind(&ServiceWorkerVersion::RunStartWorkerCallbacksOnError,
1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       weak_factory_.GetWeakPtr()));
1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      }
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) {
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (running_status() == STOPPED) {
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (stop_callbacks_.empty()) {
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ServiceWorkerStatusCode status = embedded_worker_->Stop();
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (status != SERVICE_WORKER_OK) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RunSoon(base::Bind(callback, status));
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stop_callbacks_.push_back(callback);
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerVersion::ScheduleUpdate() {
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (update_timer_.IsRunning()) {
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    update_timer_.Reset();
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  update_timer_.Start(
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE, base::TimeDelta::FromSeconds(kUpdateDelaySeconds),
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&ServiceWorkerVersion::StartUpdate,
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 weak_factory_.GetWeakPtr()));
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerVersion::DeferScheduledUpdate() {
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (update_timer_.IsRunning())
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    update_timer_.Reset();
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerVersion::StartUpdate() {
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  update_timer_.Stop();
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!context_)
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ServiceWorkerRegistration* registration =
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      context_->GetLiveRegistration(registration_id_);
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!registration || !registration->GetNewestVersion())
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  context_->UpdateServiceWorker(registration);
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerVersion::SendMessage(
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const IPC::Message& message, const StatusCallback& callback) {
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (running_status() != RUNNING) {
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Schedule calling this method after starting the worker.
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StartWorker(base::Bind(&RunTaskAfterStartWorker,
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           weak_factory_.GetWeakPtr(), callback,
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           base::Bind(&self::SendMessage,
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      weak_factory_.GetWeakPtr(),
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      message, callback)));
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ServiceWorkerStatusCode status = embedded_worker_->SendMessage(message);
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunSoon(base::Bind(callback, status));
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerVersion::DispatchInstallEvent(
251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    int active_version_id,
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const StatusCallback& callback) {
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(INSTALLING, status()) << status();
2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (running_status() != RUNNING) {
2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Schedule calling this method after starting the worker.
2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    StartWorker(
2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(&RunTaskAfterStartWorker,
2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   weak_factory_.GetWeakPtr(),
2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   callback,
2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Bind(&self::DispatchInstallEventAfterStartWorker,
2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              weak_factory_.GetWeakPtr(),
2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              active_version_id,
2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              callback)));
2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DispatchInstallEventAfterStartWorker(active_version_id, callback);
2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerVersion::DispatchActivateEvent(
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const StatusCallback& callback) {
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(ACTIVATING, status()) << status();
2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (running_status() != RUNNING) {
2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Schedule calling this method after starting the worker.
2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    StartWorker(
2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(&RunTaskAfterStartWorker,
2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   weak_factory_.GetWeakPtr(),
2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   callback,
2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Bind(&self::DispatchActivateEventAfterStartWorker,
2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              weak_factory_.GetWeakPtr(),
2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              callback)));
2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DispatchActivateEventAfterStartWorker(callback);
2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerVersion::DispatchFetchEvent(
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ServiceWorkerFetchRequest& request,
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Closure& prepare_callback,
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const FetchCallback& fetch_callback) {
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(ACTIVATED, status()) << status();
2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (running_status() != RUNNING) {
2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Schedule calling this method after starting the worker.
2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    StartWorker(base::Bind(&RunTaskAfterStartWorker,
2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           weak_factory_.GetWeakPtr(),
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           base::Bind(&RunErrorFetchCallback, fetch_callback),
2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           base::Bind(&self::DispatchFetchEvent,
3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      weak_factory_.GetWeakPtr(),
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      request,
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      prepare_callback,
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      fetch_callback)));
3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prepare_callback.Run();
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int request_id = fetch_callbacks_.Add(new FetchCallback(fetch_callback));
3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ServiceWorkerMsg_FetchEvent(request_id, request));
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (status != SERVICE_WORKER_OK) {
3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    fetch_callbacks_.Remove(request_id);
3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(base::Bind(&RunErrorFetchCallback,
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       fetch_callback,
3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       SERVICE_WORKER_ERROR_FAILED));
3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
320e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ServiceWorkerVersion::DispatchSyncEvent(const StatusCallback& callback) {
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(ACTIVATED, status()) << status();
322a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
323a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!CommandLine::ForCurrentProcess()->HasSwitch(
324a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          switches::kEnableServiceWorkerSync)) {
325a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    callback.Run(SERVICE_WORKER_ERROR_ABORT);
326a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
327a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
328a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (running_status() != RUNNING) {
3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Schedule calling this method after starting the worker.
3315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    StartWorker(base::Bind(&RunTaskAfterStartWorker,
3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           weak_factory_.GetWeakPtr(), callback,
3335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           base::Bind(&self::DispatchSyncEvent,
3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      weak_factory_.GetWeakPtr(),
3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      callback)));
3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
3375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int request_id = sync_callbacks_.Add(new StatusCallback(callback));
3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ServiceWorkerMsg_SyncEvent(request_id));
3425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (status != SERVICE_WORKER_OK) {
3435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    sync_callbacks_.Remove(request_id);
3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(base::Bind(callback, status));
3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
346e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
347e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback& callback,
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             const std::string& data) {
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(ACTIVATED, status()) << status();
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          switches::kEnableExperimentalWebPlatformFeatures)) {
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    callback.Run(SERVICE_WORKER_ERROR_ABORT);
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (running_status() != RUNNING) {
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Schedule calling this method after starting the worker.
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    StartWorker(base::Bind(&RunTaskAfterStartWorker,
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           weak_factory_.GetWeakPtr(), callback,
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           base::Bind(&self::DispatchPushEvent,
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      weak_factory_.GetWeakPtr(),
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      callback, data)));
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int request_id = push_callbacks_.Add(new StatusCallback(callback));
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ServiceWorkerMsg_PushEvent(request_id, data));
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (status != SERVICE_WORKER_OK) {
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    push_callbacks_.Remove(request_id);
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RunSoon(base::Bind(callback, status));
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerVersion::AddControllee(
378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerProviderHost* provider_host) {
3790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(!ContainsKey(controllee_map_, provider_host));
3800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int controllee_id = controllee_by_id_.Add(provider_host);
3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  controllee_map_[provider_host] = controllee_id;
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (stop_worker_timer_.IsRunning())
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    stop_worker_timer_.Stop();
384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerVersion::RemoveControllee(
387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ServiceWorkerProviderHost* provider_host) {
3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ControlleeMap::iterator found = controllee_map_.find(provider_host);
3890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(found != controllee_map_.end());
3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  controllee_by_id_.Remove(found->second);
3910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  controllee_map_.erase(found);
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (HasControllee())
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(Listener, listeners_, OnNoControllees(this));
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (is_doomed_) {
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DoomInternal();
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleStopWorker();
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
402a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerVersion::AddListener(Listener* listener) {
403a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  listeners_.AddObserver(listener);
404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
405a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
406a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ServiceWorkerVersion::RemoveListener(Listener* listener) {
407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  listeners_.RemoveObserver(listener);
408a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
409a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerVersion::Doom() {
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (is_doomed_)
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  is_doomed_ = true;
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!HasControllee())
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DoomInternal();
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerVersion::OnStarted() {
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(RUNNING, running_status());
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (status() == ACTIVATED && !HasControllee())
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ScheduleStopWorker();
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Fire all start callbacks.
423c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK);
4240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this));
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerVersion::OnStopped() {
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(STOPPED, running_status());
429c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<ServiceWorkerVersion> protect(this);
430c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Fire all stop callbacks.
432c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RunCallbacks(this, &stop_callbacks_, SERVICE_WORKER_OK);
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Let all start callbacks fail.
435c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RunCallbacks(
436c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      this, &start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED);
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Let all message callbacks fail (this will also fire and clear all
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // callbacks for events).
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(kinuko): Consider if we want to add queue+resend mechanism here.
4415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunIDMapCallbacks(&activate_callbacks_,
4425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    &StatusCallback::Run,
4435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    MakeTuple(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED));
4445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunIDMapCallbacks(&install_callbacks_,
4455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    &StatusCallback::Run,
4465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    MakeTuple(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED));
4475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunIDMapCallbacks(&fetch_callbacks_,
4485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    &FetchCallback::Run,
4495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    MakeTuple(SERVICE_WORKER_ERROR_FAILED,
4505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
4515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              ServiceWorkerResponse()));
4525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunIDMapCallbacks(&sync_callbacks_,
4535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    &StatusCallback::Run,
4545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    MakeTuple(SERVICE_WORKER_ERROR_FAILED));
455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RunIDMapCallbacks(&push_callbacks_,
456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    &StatusCallback::Run,
457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    MakeTuple(SERVICE_WORKER_ERROR_FAILED));
4585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this));
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerVersion::OnReportException(
4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::string16& error_message,
4640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int line_number,
4650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int column_number,
4660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& source_url) {
4670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(
4680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      Listener,
4690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      listeners_,
4700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      OnErrorReported(
4710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          this, error_message, line_number, column_number, source_url));
4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerVersion::OnReportConsoleMessage(int source_identifier,
4750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                  int message_level,
4760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                  const base::string16& message,
4770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                  int line_number,
4780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                  const GURL& source_url) {
4790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(Listener,
4800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    listeners_,
4810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    OnReportConsoleMessage(this,
4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           source_identifier,
4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           message_level,
4840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           message,
4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           line_number,
4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                           source_url));
4870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
4900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool handled = true;
4910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  IPC_BEGIN_MESSAGE_MAP(ServiceWorkerVersion, message)
4920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientDocuments,
4930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                        OnGetClientDocuments)
4945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ActivateEventFinished,
4955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        OnActivateEventFinished)
4965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_InstallEventFinished,
4975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        OnInstallEventFinished)
4985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FetchEventFinished,
4995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        OnFetchEventFinished)
5005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished,
5015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                        OnSyncEventFinished)
502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished,
503f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        OnPushEventFinished)
504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument,
505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                        OnPostMessageToDocument)
5060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    IPC_MESSAGE_UNHANDLED(handled = false)
5070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  IPC_END_MESSAGE_MAP()
5080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return handled;
5090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::RunStartWorkerCallbacksOnError(
5125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ServiceWorkerStatusCode status) {
5135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (status != SERVICE_WORKER_OK)
5145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunCallbacks(this, &start_callbacks_, status);
5155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
5165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::DispatchInstallEventAfterStartWorker(
5185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int active_version_id,
5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const StatusCallback& callback) {
5205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK_EQ(RUNNING, running_status())
5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      << "Worker stopped too soon after it was started.";
522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int request_id = install_callbacks_.Add(new StatusCallback(callback));
5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ServiceWorkerStatusCode status = embedded_worker_->SendMessage(
5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ServiceWorkerMsg_InstallEvent(request_id, active_version_id));
5265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (status != SERVICE_WORKER_OK) {
5275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    install_callbacks_.Remove(request_id);
5285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(base::Bind(callback, status));
5295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
5315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::DispatchActivateEventAfterStartWorker(
5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const StatusCallback& callback) {
5345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK_EQ(RUNNING, running_status())
5355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      << "Worker stopped too soon after it was started.";
536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int request_id = activate_callbacks_.Add(new StatusCallback(callback));
5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ServiceWorkerStatusCode status =
5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id));
5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (status != SERVICE_WORKER_OK) {
5415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    activate_callbacks_.Remove(request_id);
5425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(base::Bind(callback, status));
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerVersion::OnGetClientDocuments(int request_id) {
5470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<int> client_ids;
5480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ControlleeByIDMap::iterator it(&controllee_by_id_);
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnGetClientDocuments");
5510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  while (!it.IsAtEnd()) {
5520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    client_ids.push_back(it.GetCurrentKey());
5530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    it.Advance();
5540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Don't bother if it's no longer running.
5560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (running_status() == RUNNING) {
5570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    embedded_worker_->SendMessage(
5580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        ServiceWorkerMsg_DidGetClientDocuments(request_id, client_ids));
5590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::OnActivateEventFinished(
5635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int request_id,
5645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    blink::WebServiceWorkerEventResult result) {
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(ACTIVATING == status() ||
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         REDUNDANT == status()) << status();
5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnActivateEventFinished");
569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  StatusCallback* callback = activate_callbacks_.Lookup(request_id);
5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!callback) {
5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NOTREACHED() << "Got unexpected message: " << request_id;
5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ServiceWorkerStatusCode rv = SERVICE_WORKER_OK;
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result == blink::WebServiceWorkerEventResultRejected ||
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      status() != ACTIVATING) {
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    rv = SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED;
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<ServiceWorkerVersion> protect(this);
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  callback->Run(rv);
5835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  activate_callbacks_.Remove(request_id);
5845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
5855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::OnInstallEventFinished(
5875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int request_id,
5885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    blink::WebServiceWorkerEventResult result) {
589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(INSTALLING, status()) << status();
5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnInstallEventFinished");
592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  StatusCallback* callback = install_callbacks_.Lookup(request_id);
5945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!callback) {
5955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NOTREACHED() << "Got unexpected message: " << request_id;
5965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
5975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
5985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
5995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (result == blink::WebServiceWorkerEventResultRejected)
6005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    status = SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED;
6015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<ServiceWorkerVersion> protect(this);
6035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  callback->Run(status);
6045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  install_callbacks_.Remove(request_id);
6055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
6065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::OnFetchEventFinished(
6085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int request_id,
6095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ServiceWorkerFetchEventResult result,
6105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const ServiceWorkerResponse& response) {
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("ServiceWorker",
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnFetchEventFinished",
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Request id", request_id);
6145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  FetchCallback* callback = fetch_callbacks_.Lookup(request_id);
6155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!callback) {
6165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NOTREACHED() << "Got unexpected message: " << request_id;
6175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
6185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
6195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<ServiceWorkerVersion> protect(this);
6215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  callback->Run(SERVICE_WORKER_OK, result, response);
6225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  fetch_callbacks_.Remove(request_id);
6235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
6245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerVersion::OnSyncEventFinished(
6265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int request_id) {
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("ServiceWorker",
6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnSyncEventFinished",
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Request id", request_id);
6305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  StatusCallback* callback = sync_callbacks_.Lookup(request_id);
6315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!callback) {
6325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NOTREACHED() << "Got unexpected message: " << request_id;
6335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
6345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
6355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<ServiceWorkerVersion> protect(this);
6375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  callback->Run(SERVICE_WORKER_OK);
6385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  sync_callbacks_.Remove(request_id);
6395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
6405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
641f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ServiceWorkerVersion::OnPushEventFinished(
642f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int request_id) {
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("ServiceWorker",
6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnPushEventFinished",
6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Request id", request_id);
646f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  StatusCallback* callback = push_callbacks_.Lookup(request_id);
647f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!callback) {
648f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    NOTREACHED() << "Got unexpected message: " << request_id;
649f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
651f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
652f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<ServiceWorkerVersion> protect(this);
653f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  callback->Run(SERVICE_WORKER_OK);
654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  push_callbacks_.Remove(request_id);
655f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
657010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerVersion::OnPostMessageToDocument(
658010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int client_id,
659010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const base::string16& message,
660010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::vector<int>& sent_message_port_ids) {
6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("ServiceWorker",
6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerVersion::OnPostMessageToDocument",
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "Client id", client_id);
664010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ServiceWorkerProviderHost* provider_host =
665010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      controllee_by_id_.Lookup(client_id);
666010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!provider_host) {
667010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // The client may already have been closed, just ignore.
668010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
669010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
670010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  provider_host->PostMessage(message, sent_message_port_ids);
671010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
672010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerVersion::ScheduleStopWorker() {
674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (running_status() != RUNNING)
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (stop_worker_timer_.IsRunning()) {
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    stop_worker_timer_.Reset();
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  stop_worker_timer_.Start(
681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay),
682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerVersion::StopWorker,
683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)));
685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
687116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerVersion::DoomInternal() {
688116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!HasControllee());
689116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SetStatus(REDUNDANT);
690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
691116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!context_)
692116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
693116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
694116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  script_cache_map_.GetResources(&resources);
695116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  context_->storage()->PurgeResources(resources);
696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
697116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace content
699