service_worker_storage.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_storage.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_info.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h"
12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/browser/service_worker/service_worker_utils.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_version.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "webkit/browser/quota/quota_manager_proxy.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content {
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RunSoon(const tracked_objects::Location& from_here,
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu             const base::Closure& closure) {
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::MessageLoop::current()->PostTask(from_here, closure);
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CompleteFindNow(
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const scoped_refptr<ServiceWorkerRegistration>& registration,
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerStatusCode status,
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerStorage::FindRegistrationCallback& callback) {
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  callback.Run(status, registration);
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CompleteFindSoon(
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const tracked_objects::Location& from_here,
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const scoped_refptr<ServiceWorkerRegistration>& registration,
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerStatusCode status,
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerStorage::FindRegistrationCallback& callback) {
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunSoon(from_here, base::Bind(callback, status, registration));
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const base::FilePath::CharType kServiceWorkerDirectory[] =
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FILE_PATH_LITERAL("ServiceWorker");
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ServiceWorkerStorage::ServiceWorkerStorage(
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::FilePath& path,
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::WeakPtr<ServiceWorkerContextCore> context,
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    quota::QuotaManagerProxy* quota_manager_proxy)
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : last_registration_id_(0),
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      last_version_id_(0),
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      last_resource_id_(0),
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      simulated_lazy_initted_(false),
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      context_(context),
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      quota_manager_proxy_(quota_manager_proxy) {
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!path.empty())
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    path_ = path.Append(kServiceWorkerDirectory);
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ServiceWorkerStorage::~ServiceWorkerStorage() {
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ServiceWorkerStorage::FindRegistrationForPattern(
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& scope,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FindRegistrationCallback& callback) {
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  simulated_lazy_initted_ = true;
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> null_registration;
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!context_) {
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CompleteFindSoon(
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE, null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> installing_registration =
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FindInstallingRegistrationForPattern(scope);
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (installing_registration) {
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CompleteFindSoon(
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // See if there are any registrations for the origin.
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  OriginRegistrationsMap::const_iterator
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      found = stored_registrations_.find(scope.GetOrigin());
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == stored_registrations_.end()) {
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CompleteFindSoon(
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Find one with a matching scope.
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationsMap::const_iterator it = found->second.begin();
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != found->second.end(); ++it) {
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (scope == it->second.scope) {
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const ServiceWorkerDatabase::RegistrationData* data = &(it->second);
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      scoped_refptr<ServiceWorkerRegistration> registration =
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          context_->GetLiveRegistration(data->registration_id);
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (registration) {
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        return;
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      registration = CreateRegistration(data);
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CompleteFindSoon(
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ServiceWorkerStorage::FindRegistrationForDocument(
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const GURL& document_url,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FindRegistrationCallback& callback) {
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  simulated_lazy_initted_ = true;
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> null_registration;
1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!context_) {
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // See if there are any registrations for the origin.
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  OriginRegistrationsMap::const_iterator
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      found = stored_registrations_.find(document_url.GetOrigin());
1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == stored_registrations_.end()) {
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Look for something currently being installed.
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_refptr<ServiceWorkerRegistration> installing_registration =
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FindInstallingRegistrationForDocument(document_url);
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (installing_registration) {
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Return syncly to simulate this class having an in memory map of
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // origins with registrations.
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_NOT_FOUND,
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    callback);
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Find one with a pattern match.
1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationsMap::const_iterator it = found->second.begin();
1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != found->second.end(); ++it) {
1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // TODO(michaeln): if there are multiple matches the one with
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // the longest scope should win.
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (ServiceWorkerUtils::ScopeMatches(it->second.scope, document_url)) {
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const ServiceWorkerDatabase::RegistrationData* data = &(it->second);
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // If its in the live map, return syncly to simulate this class having
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // iterated over the values in that map instead of reading the db.
1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      scoped_refptr<ServiceWorkerRegistration> registration =
1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          context_->GetLiveRegistration(data->registration_id);
1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (registration) {
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        CompleteFindNow(registration, SERVICE_WORKER_OK, callback);
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        return;
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // If we have to create a new instance, return it asyncly to simulate
1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // having had to retreive the RegistrationData from the db.
1610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      registration = CreateRegistration(data);
1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
1630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Look for something currently being installed.
1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(michaeln): Should be mixed in with the stored registrations
1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // for this test.
1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> installing_registration =
1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FindInstallingRegistrationForDocument(document_url);
1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (installing_registration) {
1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CompleteFindSoon(
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Return asyncly to simulate having had to look in the db since this
1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // origin does have some registations.
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CompleteFindSoon(
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServiceWorkerStorage::FindRegistrationForId(
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    int64 registration_id,
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const FindRegistrationCallback& callback) {
1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  simulated_lazy_initted_ = true;
1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> null_registration;
1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!context_) {
1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> installing_registration =
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FindInstallingRegistrationForId(registration_id);
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (installing_registration) {
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegistrationPtrMap::const_iterator found =
2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      registrations_by_id_.find(registration_id);
2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == registrations_by_id_.end()) {
2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_NOT_FOUND,
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    callback);
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> registration =
2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      context_->GetLiveRegistration(registration_id);
2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (registration) {
2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(registration, SERVICE_WORKER_OK, callback);
2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  registration = CreateRegistration(found->second);
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::GetAllRegistrations(
2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GetAllRegistrationInfosCallback& callback) {
2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  simulated_lazy_initted_ = true;
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<ServiceWorkerRegistrationInfo> registrations;
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!context_) {
2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, registrations));
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Add all stored registrations.
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationPtrMap::const_iterator it = registrations_by_id_.begin();
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != registrations_by_id_.end(); ++it) {
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerRegistration* registration =
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        context_->GetLiveRegistration(it->first);
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (registration) {
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      registrations.push_back(registration->GetInfo());
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      continue;
233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerRegistrationInfo info;
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    info.pattern = it->second->scope;
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    info.script_url = it->second->script;
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    info.active_version.is_null = false;
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (it->second->is_active)
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      info.active_version.status = ServiceWorkerVersion::ACTIVE;
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    else
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      info.active_version.status = ServiceWorkerVersion::INSTALLED;
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    registrations.push_back(info);
2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Add unstored registrations that are being installed.
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationRefsById::const_iterator it =
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           installing_registrations_.begin();
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != installing_registrations_.end(); ++it) {
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (registrations_by_id_.find(it->first) == registrations_by_id_.end())
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      registrations.push_back(it->second->GetInfo());
251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunSoon(FROM_HERE, base::Bind(callback, registrations));
254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerStorage::StoreRegistration(
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ServiceWorkerRegistration* registration,
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerVersion* version,
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const StatusCallback& callback) {
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(registration);
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(version);
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(simulated_lazy_initted_);
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!context_) {
2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Keep a database struct in the storage map.
2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegistrationsMap& storage_map =
2700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      stored_registrations_[registration->script_url().GetOrigin()];
2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ServiceWorkerDatabase::RegistrationData& data =
2720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      storage_map[registration->id()];
2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.registration_id = registration->id();
2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.scope = registration->pattern();
2750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.script = registration->script_url();
2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.has_fetch_handler = true;
2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.version_id = version->version_id();
2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.last_update_check = base::Time::Now();
2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.is_active = false;  // initially stored in the waiting state
2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Keep a seperate map of ptrs keyed by id only.
2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  registrations_by_id_[registration->id()] = &storage_map[registration->id()];
2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_OK));
2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void ServiceWorkerStorage::UpdateToActiveState(
2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ServiceWorkerRegistration* registration,
2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const StatusCallback& callback) {
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(simulated_lazy_initted_);
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!context_) {
2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegistrationPtrMap::const_iterator
2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       found = registrations_by_id_.find(registration->id());
2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == registrations_by_id_.end()) {
2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND));
3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(!found->second->is_active);
3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  found->second->is_active = true;
3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_OK));
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerStorage::DeleteRegistration(
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 registration_id,
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const StatusCallback& callback) {
3100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(simulated_lazy_initted_);
3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegistrationPtrMap::iterator
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      found = registrations_by_id_.find(registration_id);
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == registrations_by_id_.end()) {
3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND));
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
3170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  GURL origin = found->second->script.GetOrigin();
3190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  stored_registrations_[origin].erase(registration_id);
3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (stored_registrations_[origin].empty())
3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    stored_registrations_.erase(origin);
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  registrations_by_id_.erase(found);
3240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_OK));
3260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(michaeln): Either its instance should also be
3270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // removed from liveregistrations map or the live object
3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // should marked as deleted in some way and not 'findable'
3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // thereafter.
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 ServiceWorkerStorage::NewRegistrationId() {
3330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(simulated_lazy_initted_);
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ++last_registration_id_;
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 ServiceWorkerStorage::NewVersionId() {
3380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(simulated_lazy_initted_);
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return ++last_version_id_;
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint64 ServiceWorkerStorage::NewResourceId() {
3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(simulated_lazy_initted_);
3440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return ++last_resource_id_;
3450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::NotifyInstallingRegistration(
3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ServiceWorkerRegistration* registration) {
3490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  installing_registrations_[registration->id()] = registration;
3500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::NotifyDoneInstallingRegistration(
3530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ServiceWorkerRegistration* registration) {
3540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  installing_registrations_.erase(registration->id());
3550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochscoped_refptr<ServiceWorkerRegistration>
3580529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::CreateRegistration(
3590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerDatabase::RegistrationData* data) {
3600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> registration(
3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new ServiceWorkerRegistration(
3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          data->scope, data->script, data->registration_id, context_));
3630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerVersion> version =
3650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      context_->GetLiveVersion(data->version_id);
3660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!version) {
3670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    version = new ServiceWorkerVersion(
3680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        registration, data->version_id, context_);
3690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    version->SetStatus(data->GetVersionStatus());
3700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (version->status() == ServiceWorkerVersion::ACTIVE)
3730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    registration->set_active_version(version);
3740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else if (version->status() == ServiceWorkerVersion::INSTALLED)
3750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    registration->set_pending_version(version);
3760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else
3770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    NOTREACHED();
3780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(michaeln): Hmmm, what if DeleteReg was invoked after
3790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the Find result we're returning here? NOTREACHED condition?
3800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return registration;
3820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3840529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration*
3850529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForDocument(
3860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& document_url) {
3870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(michaeln): if there are multiple matches the one with
3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the longest scope should win, and these should on equal footing
3890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // with the stored registrations in FindRegistrationForDocument().
3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationRefsById::const_iterator it =
3910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           installing_registrations_.begin();
3920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != installing_registrations_.end(); ++it) {
3930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (ServiceWorkerUtils::ScopeMatches(
3940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            it->second->pattern(), document_url)) {
3950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return it->second;
3960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
3970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return NULL;
3990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4010529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration*
4020529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForPattern(
4030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& scope) {
4040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationRefsById::const_iterator it =
4050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           installing_registrations_.begin();
4060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != installing_registrations_.end(); ++it) {
4070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (it->second->pattern() == scope)
4080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return it->second;
4090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return NULL;
4110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4130529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration*
4140529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForId(
4150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 registration_id) {
4160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegistrationRefsById::const_iterator found =
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      installing_registrations_.find(registration_id);
4180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == installing_registrations_.end())
4190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return NULL;
4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return found->second;
4210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace content
424