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>
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/bind_helpers.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/hash.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/sequenced_task_runner.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/single_thread_task_runner.h"
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/task_runner_util.h"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/service_worker/service_worker_disk_cache.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_info.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/service_worker/service_worker_metrics.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h"
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/browser/service_worker/service_worker_utils.h"
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_version.h"
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/common/service_worker/service_worker_types.h"
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/completion_callback.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/io_buffer.h"
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/base/net_errors.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content {
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RunSoon(const tracked_objects::Location& from_here,
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu             const base::Closure& closure) {
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::MessageLoop::current()->PostTask(from_here, closure);
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CompleteFindNow(
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const scoped_refptr<ServiceWorkerRegistration>& registration,
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerStatusCode status,
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerStorage::FindRegistrationCallback& callback) {
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  callback.Run(status, registration);
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CompleteFindSoon(
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const tracked_objects::Location& from_here,
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const scoped_refptr<ServiceWorkerRegistration>& registration,
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerStatusCode status,
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ServiceWorkerStorage::FindRegistrationCallback& callback) {
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RunSoon(from_here, base::Bind(callback, status, registration));
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const base::FilePath::CharType kDatabaseName[] =
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FILE_PATH_LITERAL("Database");
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const base::FilePath::CharType kDiskCacheName[] =
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FILE_PATH_LITERAL("Cache");
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kMaxDiskCacheSize = 250 * 1024 * 1024;
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerStatusCode DatabaseStatusToStatusCode(
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (status) {
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case ServiceWorkerDatabase::STATUS_OK:
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return SERVICE_WORKER_OK;
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND:
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return SERVICE_WORKER_ERROR_NOT_FOUND;
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    case ServiceWorkerDatabase::STATUS_ERROR_MAX:
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      NOTREACHED();
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return SERVICE_WORKER_ERROR_FAILED;
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ResponseComparer : public base::RefCounted<ResponseComparer> {
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ResponseComparer(
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::WeakPtr<ServiceWorkerStorage> owner,
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_ptr<ServiceWorkerResponseReader> lhs,
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_ptr<ServiceWorkerResponseReader> rhs,
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const ServiceWorkerStorage::CompareCallback& callback)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : owner_(owner),
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        completion_callback_(callback),
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        lhs_reader_(lhs.release()),
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        rhs_reader_(rhs.release()),
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        completion_count_(0),
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        previous_result_(0) {
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void Start();
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  friend class base::RefCounted<ResponseComparer>;
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static const int kBufferSize = 16 * 1024;
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ~ResponseComparer() {}
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void ReadInfos();
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnReadInfoComplete(int result);
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void ReadSomeData();
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnReadDataComplete(int result);
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::WeakPtr<ServiceWorkerStorage> owner_;
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ServiceWorkerStorage::CompareCallback completion_callback_;
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ServiceWorkerResponseReader> lhs_reader_;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<HttpResponseInfoIOBuffer> lhs_info_;
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<net::IOBuffer> lhs_buffer_;
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ServiceWorkerResponseReader> rhs_reader_;
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<HttpResponseInfoIOBuffer> rhs_info_;
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<net::IOBuffer> rhs_buffer_;
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int completion_count_;
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int previous_result_;
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ResponseComparer);
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ResponseComparer::Start() {
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lhs_buffer_ = new net::IOBuffer(kBufferSize);
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lhs_info_ = new HttpResponseInfoIOBuffer();
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rhs_buffer_ = new net::IOBuffer(kBufferSize);
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rhs_info_ = new HttpResponseInfoIOBuffer();
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReadInfos();
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ResponseComparer::ReadInfos() {
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lhs_reader_->ReadInfo(
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      lhs_info_.get(), base::Bind(&ResponseComparer::OnReadInfoComplete, this));
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rhs_reader_->ReadInfo(
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      rhs_info_.get(), base::Bind(&ResponseComparer::OnReadInfoComplete, this));
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ResponseComparer::OnReadInfoComplete(int result) {
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (completion_callback_.is_null() || !owner_)
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result < 0) {
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, false);
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Reset();
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (++completion_count_ != 2)
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (lhs_info_->response_data_size != rhs_info_->response_data_size) {
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Run(SERVICE_WORKER_OK, false);
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReadSomeData();
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ResponseComparer::ReadSomeData() {
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  completion_count_ = 0;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lhs_reader_->ReadData(
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      lhs_buffer_.get(),
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kBufferSize,
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&ResponseComparer::OnReadDataComplete, this));
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rhs_reader_->ReadData(
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      rhs_buffer_.get(),
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kBufferSize,
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&ResponseComparer::OnReadDataComplete, this));
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ResponseComparer::OnReadDataComplete(int result) {
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (completion_callback_.is_null() || !owner_)
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result < 0) {
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Run(SERVICE_WORKER_ERROR_FAILED, false);
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Reset();
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (++completion_count_ != 2) {
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    previous_result_ = result;
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(michaeln): Probably shouldn't assume that the amounts read from
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // each reader will always be the same. This would wrongly signal false
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // in that case.
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result != previous_result_) {
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Run(SERVICE_WORKER_OK, false);
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result == 0) {
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Run(SERVICE_WORKER_OK, true);
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int compare_result =
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      memcmp(lhs_buffer_->data(), rhs_buffer_->data(), result);
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (compare_result != 0) {
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    completion_callback_.Run(SERVICE_WORKER_OK, false);
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReadSomeData();
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::InitialData::InitialData()
203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : next_registration_id(kInvalidServiceWorkerRegistrationId),
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      next_version_id(kInvalidServiceWorkerVersionId),
205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      next_resource_id(kInvalidServiceWorkerResourceId) {
206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::InitialData::~InitialData() {
209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ServiceWorkerStorage::
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DidDeleteRegistrationParams::DidDeleteRegistrationParams()
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : registration_id(kInvalidServiceWorkerRegistrationId) {
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ServiceWorkerStorage::
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DidDeleteRegistrationParams::~DidDeleteRegistrationParams() {
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
220116680a4aac90f2aa7413d9095a592090648e557Ben MurdochServiceWorkerStorage::~ServiceWorkerStorage() {
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  weak_factory_.InvalidateWeakPtrs();
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  database_task_runner_->DeleteSoon(FROM_HERE, database_.release());
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create(
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::FilePath& path,
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::WeakPtr<ServiceWorkerContextCore> context,
22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& database_task_runner,
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread,
23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::QuotaManagerProxy* quota_manager_proxy) {
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return make_scoped_ptr(new ServiceWorkerStorage(path,
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                  context,
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                  database_task_runner,
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                  disk_cache_thread,
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                  quota_manager_proxy));
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create(
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::WeakPtr<ServiceWorkerContextCore> context,
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerStorage* old_storage) {
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return make_scoped_ptr(
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new ServiceWorkerStorage(old_storage->path_,
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               context,
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               old_storage->database_task_runner_,
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               old_storage->disk_cache_thread_,
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               old_storage->quota_manager_proxy_.get()));
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindRegistrationForDocument(
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& document_url,
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FindRegistrationCallback& callback) {
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!document_url.has_ref());
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_BEGIN1(
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorker",
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorkerStorage::FindRegistrationForDocument",
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Hash(document_url.spec()),
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "URL", document_url.spec());
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!LazyInitialize(base::Bind(
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &ServiceWorkerStorage::FindRegistrationForDocument,
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          weak_factory_.GetWeakPtr(), document_url, callback))) {
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (state_ != INITIALIZING || !context_) {
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      SERVICE_WORKER_ERROR_FAILED, callback);
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
2700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // See if there are any stored registrations for the origin.
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!ContainsKey(registered_origins_, document_url.GetOrigin())) {
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Look for something currently being installed.
274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<ServiceWorkerRegistration> installing_registration =
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FindInstallingRegistrationForDocument(document_url);
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CompleteFindNow(installing_registration,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    installing_registration.get()
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        ? SERVICE_WORKER_OK
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        : SERVICE_WORKER_ERROR_NOT_FOUND,
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    callback);
2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  database_task_runner_->PostTask(
285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &FindForDocumentInDB,
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          database_.get(),
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::MessageLoopProxy::current(),
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          document_url,
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Bind(&ServiceWorkerStorage::DidFindRegistrationForDocument,
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     weak_factory_.GetWeakPtr(), document_url, callback)));
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindRegistrationForPattern(
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& scope,
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const FindRegistrationCallback& callback) {
298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!LazyInitialize(base::Bind(
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &ServiceWorkerStorage::FindRegistrationForPattern,
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          weak_factory_.GetWeakPtr(), scope, callback))) {
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (state_ != INITIALIZING || !context_) {
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(),
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       SERVICE_WORKER_ERROR_FAILED, callback);
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // See if there are any stored registrations for the origin.
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!ContainsKey(registered_origins_, scope.GetOrigin())) {
3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Look for something currently being installed.
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_refptr<ServiceWorkerRegistration> installing_registration =
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FindInstallingRegistrationForPattern(scope);
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CompleteFindSoon(FROM_HERE,
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     installing_registration,
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     installing_registration.get()
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         ? SERVICE_WORKER_OK
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         : SERVICE_WORKER_ERROR_NOT_FOUND,
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     callback);
3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  database_task_runner_->PostTask(
324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &FindForPatternInDB,
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          database_.get(),
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::MessageLoopProxy::current(),
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          scope,
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Bind(&ServiceWorkerStorage::DidFindRegistrationForPattern,
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     weak_factory_.GetWeakPtr(), scope, callback)));
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ServiceWorkerRegistration* ServiceWorkerStorage::GetUninstallingRegistration(
3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const GURL& scope) {
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (state_ != INITIALIZED || !context_)
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return NULL;
3386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (RegistrationRefsById::const_iterator it =
3396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           uninstalling_registrations_.begin();
3406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != uninstalling_registrations_.end();
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (it->second->pattern() == scope) {
3436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      DCHECK(it->second->is_uninstalling());
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return it->second.get();
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
3466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return NULL;
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServiceWorkerStorage::FindRegistrationForId(
351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    int64 registration_id,
352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GURL& origin,
353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const FindRegistrationCallback& callback) {
354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!LazyInitialize(base::Bind(
355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &ServiceWorkerStorage::FindRegistrationForId,
356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          weak_factory_.GetWeakPtr(), registration_id, origin, callback))) {
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (state_ != INITIALIZING || !context_) {
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                      SERVICE_WORKER_ERROR_FAILED, callback);
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
3610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
363010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
364010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // See if there are any stored registrations for the origin.
366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!ContainsKey(registered_origins_, origin)) {
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Look for something currently being installed.
368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_refptr<ServiceWorkerRegistration> installing_registration =
369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        FindInstallingRegistrationForId(registration_id);
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CompleteFindNow(installing_registration,
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    installing_registration.get()
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        ? SERVICE_WORKER_OK
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        : SERVICE_WORKER_ERROR_NOT_FOUND,
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    callback);
3750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerRegistration> registration =
3790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      context_->GetLiveRegistration(registration_id);
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (registration.get()) {
3810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CompleteFindNow(registration, SERVICE_WORKER_OK, callback);
3820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  database_task_runner_->PostTask(
386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FindForIdInDB,
388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 database_.get(),
389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::MessageLoopProxy::current(),
390010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 registration_id, origin,
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId,
392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            weak_factory_.GetWeakPtr(), callback)));
3930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::GetAllRegistrations(
3960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GetAllRegistrationInfosCallback& callback) {
397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!LazyInitialize(base::Bind(
398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &ServiceWorkerStorage::GetAllRegistrations,
399010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          weak_factory_.GetWeakPtr(), callback))) {
400010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (state_ != INITIALIZING || !context_) {
401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      RunSoon(FROM_HERE, base::Bind(
402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          callback, std::vector<ServiceWorkerRegistrationInfo>()));
403effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
405effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
406010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  RegistrationList* registrations = new RegistrationList;
409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  PostTaskAndReplyWithResult(
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      database_task_runner_.get(),
411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&ServiceWorkerDatabase::GetAllRegistrations,
413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Unretained(database_.get()),
414010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Unretained(registrations)),
415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&ServiceWorkerStorage::DidGetAllRegistrations,
416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 weak_factory_.GetWeakPtr(),
417010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 callback,
418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Owned(registrations)));
419effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
420effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerStorage::StoreRegistration(
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ServiceWorkerRegistration* registration,
4230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ServiceWorkerVersion* version,
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const StatusCallback& callback) {
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(registration);
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(version);
427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (IsDisabled() || !context_) {
4305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
434010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ServiceWorkerDatabase::RegistrationData data;
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.registration_id = registration->id();
4360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.scope = registration->pattern();
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  data.script = version->script_url();
4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.has_fetch_handler = true;
4390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  data.version_id = version->version_id();
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  data.last_update_check = registration->last_update_check();
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  data.is_active = (version == registration->active_version());
4420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ResourceList resources;
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version->script_cache_map()->GetResources(&resources);
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!has_checked_for_stale_resources_)
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DeleteStaleResources();
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  database_task_runner_->PostTask(
450010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&WriteRegistrationInDB,
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 database_.get(),
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::MessageLoopProxy::current(),
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 data, resources,
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Bind(&ServiceWorkerStorage::DidStoreRegistration,
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            weak_factory_.GetWeakPtr(),
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            callback)));
4586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registration->set_is_deleted(false);
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
462010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::UpdateToActiveState(
463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerRegistration* registration,
464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const StatusCallback& callback) {
465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(registration);
466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (IsDisabled() || !context_) {
4695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
4700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
4710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PostTaskAndReplyWithResult(
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      database_task_runner_.get(),
475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerDatabase::UpdateVersionToActive,
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(database_.get()),
478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 registration->id(),
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 registration->pattern().GetOrigin()),
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerStorage::DidUpdateToActiveState,
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 callback));
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerStorage::UpdateLastUpdateCheckTime(
4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ServiceWorkerRegistration* registration) {
4876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(registration);
4886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
4906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (IsDisabled() || !context_)
4916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return;
4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  database_task_runner_->PostTask(
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      FROM_HERE,
4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      base::Bind(
4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::IgnoreResult(&ServiceWorkerDatabase::UpdateLastCheckTime),
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::Unretained(database_.get()),
4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          registration->id(),
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          registration->pattern().GetOrigin(),
5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          registration->last_update_check()));
5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerStorage::DeleteRegistration(
5040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 registration_id,
505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GURL& origin,
506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const StatusCallback& callback) {
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (IsDisabled() || !context_) {
509010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
5120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!has_checked_for_stale_resources_)
514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DeleteStaleResources();
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DidDeleteRegistrationParams params;
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  params.registration_id = registration_id;
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  params.origin = origin;
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  params.callback = callback;
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  database_task_runner_->PostTask(
522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&DeleteRegistrationFromDB,
524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 database_.get(),
525010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::MessageLoopProxy::current(),
526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 registration_id, origin,
527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Bind(&ServiceWorkerStorage::DidDeleteRegistration,
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            weak_factory_.GetWeakPtr(), params)));
5290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The registration should no longer be findable.
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pending_deletions_.insert(registration_id);
5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ServiceWorkerRegistration* registration =
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      context_->GetLiveRegistration(registration_id);
5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (registration)
5356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    registration->set_is_deleted(true);
536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_ptr<ServiceWorkerResponseReader>
539010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::CreateResponseReader(int64 response_id) {
540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return make_scoped_ptr(
541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new ServiceWorkerResponseReader(response_id, disk_cache()));
542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_ptr<ServiceWorkerResponseWriter>
545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::CreateResponseWriter(int64 response_id) {
546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return make_scoped_ptr(
547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new ServiceWorkerResponseWriter(response_id, disk_cache()));
548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
550116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::StoreUncommittedResponseId(int64 id) {
551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(kInvalidServiceWorkerResponseId, id);
552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(INITIALIZED, state_);
553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!has_checked_for_stale_resources_)
555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DeleteStaleResources();
556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  database_task_runner_->PostTask(
558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE,
559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(base::IgnoreResult(
560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &ServiceWorkerDatabase::WriteUncommittedResourceIds),
561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Unretained(database_.get()),
562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          std::set<int64>(&id, &id + 1)));
563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DoomUncommittedResponse(int64 id) {
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(kInvalidServiceWorkerResponseId, id);
567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  database_task_runner_->PostTask(
568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE,
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(base::IgnoreResult(
570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &ServiceWorkerDatabase::PurgeUncommittedResourceIds),
571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Unretained(database_.get()),
572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          std::set<int64>(&id, &id + 1)));
573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StartPurgingResources(std::vector<int64>(1, id));
574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerStorage::CompareScriptResources(
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int64 lhs_id, int64 rhs_id,
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const CompareCallback& callback) {
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!callback.is_null());
5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<ResponseComparer> comparer =
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new ResponseComparer(weak_factory_.GetWeakPtr(),
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           CreateResponseReader(lhs_id),
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           CreateResponseReader(rhs_id),
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           callback);
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  comparer->Start();  // It deletes itself when done.
5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
588116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::DeleteAndStartOver(const StatusCallback& callback) {
589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Disable();
590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Delete the database on the database thread.
592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PostTaskAndReplyWithResult(
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      database_task_runner_.get(),
594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
595116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&ServiceWorkerDatabase::DestroyDatabase,
596116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(database_.get())),
597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&ServiceWorkerStorage::DidDeleteDatabase,
5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_factory_.GetWeakPtr(),
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 callback));
600116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
601116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 ServiceWorkerStorage::NewRegistrationId() {
603010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (state_ == DISABLED)
604010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return kInvalidServiceWorkerRegistrationId;
605010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
606010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return next_registration_id_++;
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 ServiceWorkerStorage::NewVersionId() {
610010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (state_ == DISABLED)
611010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return kInvalidServiceWorkerVersionId;
612010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
613010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return next_version_id_++;
614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint64 ServiceWorkerStorage::NewResourceId() {
617010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (state_ == DISABLED)
618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return kInvalidServiceWorkerResourceId;
619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return next_resource_id_++;
6210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::NotifyInstallingRegistration(
6240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ServiceWorkerRegistration* registration) {
6256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(installing_registrations_.find(registration->id()) ==
6266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         installing_registrations_.end());
6270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  installing_registrations_[registration->id()] = registration;
6280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::NotifyDoneInstallingRegistration(
631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ServiceWorkerRegistration* registration,
632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ServiceWorkerVersion* version,
633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ServiceWorkerStatusCode status) {
6340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  installing_registrations_.erase(registration->id());
635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != SERVICE_WORKER_OK && version) {
636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ResourceList resources;
637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version->script_cache_map()->GetResources(&resources);
638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::set<int64> ids;
640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (size_t i = 0; i < resources.size(); ++i)
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ids.insert(resources[i].resource_id);
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    database_task_runner_->PostTask(
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FROM_HERE,
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(base::IgnoreResult(
646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            &ServiceWorkerDatabase::PurgeUncommittedResourceIds),
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            base::Unretained(database_.get()),
648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            ids));
649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerStorage::NotifyUninstallingRegistration(
6536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ServiceWorkerRegistration* registration) {
6546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(uninstalling_registrations_.find(registration->id()) ==
6556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         uninstalling_registrations_.end());
6566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  uninstalling_registrations_[registration->id()] = registration;
6576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
6586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerStorage::NotifyDoneUninstallingRegistration(
6606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ServiceWorkerRegistration* registration) {
6616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  uninstalling_registrations_.erase(registration->id());
6626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
6636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
664116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::Disable() {
665116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  state_ = DISABLED;
666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (disk_cache_)
667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    disk_cache_->Disable();
668116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
669116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
670116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ServiceWorkerStorage::IsDisabled() const {
671116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return state_ == DISABLED;
672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
674116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::PurgeResources(const ResourceList& resources) {
675116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!has_checked_for_stale_resources_)
676116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DeleteStaleResources();
677116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartPurgingResources(resources);
678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
680116680a4aac90f2aa7413d9095a592090648e557Ben MurdochServiceWorkerStorage::ServiceWorkerStorage(
681116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::FilePath& path,
682116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::WeakPtr<ServiceWorkerContextCore> context,
68303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& database_task_runner,
68403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread,
68503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::QuotaManagerProxy* quota_manager_proxy)
686116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : next_registration_id_(kInvalidServiceWorkerRegistrationId),
687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      next_version_id_(kInvalidServiceWorkerVersionId),
688116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      next_resource_id_(kInvalidServiceWorkerResourceId),
689116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      state_(UNINITIALIZED),
690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      path_(path),
691116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      context_(context),
692116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      database_task_runner_(database_task_runner),
693116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      disk_cache_thread_(disk_cache_thread),
694116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      quota_manager_proxy_(quota_manager_proxy),
695116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_purge_pending_(false),
696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      has_checked_for_stale_resources_(false),
697116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      weak_factory_(this) {
698116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  database_.reset(new ServiceWorkerDatabase(GetDatabasePath()));
699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath ServiceWorkerStorage::GetDatabasePath() {
702cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (path_.empty())
703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return base::FilePath();
7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      .Append(kDatabaseName);
706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath ServiceWorkerStorage::GetDiskCachePath() {
709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (path_.empty())
710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return base::FilePath();
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      .Append(kDiskCacheName);
7130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
7140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
715010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
716010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!context_)
717010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
718010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
719010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  switch (state_) {
720010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case INITIALIZED:
721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return true;
722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case DISABLED:
723010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
724010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case INITIALIZING:
725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      pending_tasks_.push_back(callback);
726010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return false;
727010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case UNINITIALIZED:
728010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      pending_tasks_.push_back(callback);
729010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Fall-through.
730010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
731010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
732010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  state_ = INITIALIZING;
733010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  database_task_runner_->PostTask(
734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&ReadInitialDataFromDB,
736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 database_.get(),
737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::MessageLoopProxy::current(),
738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Bind(&ServiceWorkerStorage::DidReadInitialData,
739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            weak_factory_.GetWeakPtr())));
740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return false;
741010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
742010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
743010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidReadInitialData(
744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    InitialData* data,
745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(data);
747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(INITIALIZING, state_);
748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status == ServiceWorkerDatabase::STATUS_OK) {
750010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    next_registration_id_ = data->next_registration_id;
751010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    next_version_id_ = data->next_version_id;
752010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    next_resource_id_ = data->next_resource_id;
753010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    registered_origins_.swap(data->origins);
754010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_ = INITIALIZED;
755010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
756116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // TODO(nhiroki): Stringify |status| using StatusToString() defined in
757116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // service_worker_database.cc.
758116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DVLOG(2) << "Failed to initialize: " << status;
759116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleDeleteAndStartOver();
760010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
761010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
762010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin();
763010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       it != pending_tasks_.end(); ++it) {
764010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    RunSoon(FROM_HERE, *it);
765010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
766010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  pending_tasks_.clear();
767010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
768010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidFindRegistrationForDocument(
770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& document_url,
771010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const FindRegistrationCallback& callback,
772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ServiceWorkerDatabase::RegistrationData& data,
773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceList& resources,
774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status == ServiceWorkerDatabase::STATUS_OK) {
7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ReturnFoundRegistration(callback, data, resources);
7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_ASYNC_END1(
7781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "ServiceWorker",
7791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "ServiceWorkerStorage::FindRegistrationForDocument",
7801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Hash(document_url.spec()),
7811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "Status", "OK");
782010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
783010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
784010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Look for something currently being installed.
787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<ServiceWorkerRegistration> installing_registration =
788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FindInstallingRegistrationForDocument(document_url);
7891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callback.Run(installing_registration.get() ? SERVICE_WORKER_OK
7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               : SERVICE_WORKER_ERROR_NOT_FOUND,
7911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 installing_registration);
7921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_ASYNC_END1(
7931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "ServiceWorker",
7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "ServiceWorkerStorage::FindRegistrationForDocument",
7951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Hash(document_url.spec()),
7961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "Status", status);
797010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
798010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
799010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
800116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleDeleteAndStartOver();
801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  callback.Run(DatabaseStatusToStatusCode(status),
802010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)               scoped_refptr<ServiceWorkerRegistration>());
8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END1(
8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorker",
8051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ServiceWorkerStorage::FindRegistrationForDocument",
8061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Hash(document_url.spec()),
8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "Status", status);
808010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
809010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidFindRegistrationForPattern(
811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& scope,
812010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const FindRegistrationCallback& callback,
813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ServiceWorkerDatabase::RegistrationData& data,
814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceList& resources,
815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status == ServiceWorkerDatabase::STATUS_OK) {
8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ReturnFoundRegistration(callback, data, resources);
818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
819010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
820010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<ServiceWorkerRegistration> installing_registration =
823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FindInstallingRegistrationForPattern(scope);
8241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callback.Run(installing_registration.get() ? SERVICE_WORKER_OK
8251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               : SERVICE_WORKER_ERROR_NOT_FOUND,
8261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 installing_registration);
827010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
828010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
829010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
830116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleDeleteAndStartOver();
831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  callback.Run(DatabaseStatusToStatusCode(status),
832010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)               scoped_refptr<ServiceWorkerRegistration>());
833010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
834010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidFindRegistrationForId(
836010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const FindRegistrationCallback& callback,
837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ServiceWorkerDatabase::RegistrationData& data,
838010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const ResourceList& resources,
839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status == ServiceWorkerDatabase::STATUS_OK) {
8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ReturnFoundRegistration(callback, data, resources);
842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
844116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
846116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // TODO(nhiroki): Find a registration in |installing_registrations_|.
847116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(DatabaseStatusToStatusCode(status),
848116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 scoped_refptr<ServiceWorkerRegistration>());
849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
850116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleDeleteAndStartOver();
853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  callback.Run(DatabaseStatusToStatusCode(status),
854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               scoped_refptr<ServiceWorkerRegistration>());
855010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
856010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerStorage::ReturnFoundRegistration(
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const FindRegistrationCallback& callback,
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const ServiceWorkerDatabase::RegistrationData& data,
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const ResourceList& resources) {
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<ServiceWorkerRegistration> registration =
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetOrCreateRegistration(data, resources);
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (registration->is_deleted()) {
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // It's past the point of no return and no longer findable.
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, NULL);
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  callback.Run(SERVICE_WORKER_OK, registration);
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
871010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidGetAllRegistrations(
872010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GetAllRegistrationInfosCallback& callback,
873010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    RegistrationList* registrations,
874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
875010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(registrations);
876116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != ServiceWorkerDatabase::STATUS_OK &&
877116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status != ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
878116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleDeleteAndStartOver();
879010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    callback.Run(std::vector<ServiceWorkerRegistrationInfo>());
880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
882010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
883010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Add all stored registrations.
884010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::set<int64> pushed_registrations;
885010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::vector<ServiceWorkerRegistrationInfo> infos;
886010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (RegistrationList::const_iterator it = registrations->begin();
887010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       it != registrations->end(); ++it) {
88846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const bool inserted =
88946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        pushed_registrations.insert(it->registration_id).second;
89046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK(inserted);
89146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
892010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerRegistration* registration =
893010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        context_->GetLiveRegistration(it->registration_id);
894010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (registration) {
895010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      infos.push_back(registration->GetInfo());
896010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      continue;
897010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
89846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
899010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ServiceWorkerRegistrationInfo info;
900010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    info.pattern = it->scope;
901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    info.registration_id = it->registration_id;
90246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (ServiceWorkerVersion* version =
90346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            context_->GetLiveVersion(it->version_id)) {
90446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      if (it->is_active)
90546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        info.active_version = version->GetInfo();
90646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      else
90746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        info.waiting_version = version->GetInfo();
908f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      infos.push_back(info);
909f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      continue;
910f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
911f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
912f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (it->is_active) {
91346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      info.active_version.is_null = false;
914116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      info.active_version.status = ServiceWorkerVersion::ACTIVATED;
91546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      info.active_version.version_id = it->version_id;
916f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
917f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      info.waiting_version.is_null = false;
918f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      info.waiting_version.status = ServiceWorkerVersion::INSTALLED;
919f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      info.waiting_version.version_id = it->version_id;
92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
921010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    infos.push_back(info);
922010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
923010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
924010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Add unstored registrations that are being installed.
925010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (RegistrationRefsById::const_iterator it =
926010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           installing_registrations_.begin();
927010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       it != installing_registrations_.end(); ++it) {
928010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (pushed_registrations.insert(it->first).second)
929010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      infos.push_back(it->second->GetInfo());
930010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
931010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
932010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  callback.Run(infos);
933010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
934010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
935010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidStoreRegistration(
936010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const StatusCallback& callback,
937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& origin,
938116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int64 deleted_version_id,
939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::vector<int64>& newly_purgeable_resources,
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
942116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleDeleteAndStartOver();
943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback.Run(DatabaseStatusToStatusCode(status));
944010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
945010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
946010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  registered_origins_.insert(origin);
947010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  callback.Run(SERVICE_WORKER_OK);
948116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
949116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!context_ || !context_->GetLiveVersion(deleted_version_id))
950116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    StartPurgingResources(newly_purgeable_resources);
951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidUpdateToActiveState(
954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const StatusCallback& callback,
955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
956116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != ServiceWorkerDatabase::STATUS_OK &&
957116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status != ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
958116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleDeleteAndStartOver();
959116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  callback.Run(DatabaseStatusToStatusCode(status));
961010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
962010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
963010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidDeleteRegistration(
9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const DidDeleteRegistrationParams& params,
965010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool origin_is_deletable,
966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int64 version_id,
967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::vector<int64>& newly_purgeable_resources,
968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase::Status status) {
9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pending_deletions_.erase(params.registration_id);
970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
971116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleDeleteAndStartOver();
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    params.callback.Run(DatabaseStatusToStatusCode(status));
973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
975010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (origin_is_deletable)
9765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    registered_origins_.erase(params.origin);
9775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  params.callback.Run(SERVICE_WORKER_OK);
978116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
979116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!context_ || !context_->GetLiveVersion(version_id))
980116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    StartPurgingResources(newly_purgeable_resources);
981010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
982010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
9830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochscoped_refptr<ServiceWorkerRegistration>
984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerStorage::GetOrCreateRegistration(
985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ServiceWorkerDatabase::RegistrationData& data,
986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceList& resources) {
987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<ServiceWorkerRegistration> registration =
988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      context_->GetLiveRegistration(data.registration_id);
9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (registration.get())
990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return registration;
9910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registration = new ServiceWorkerRegistration(
9931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      data.scope, data.registration_id, context_);
9946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  registration->set_last_update_check(data.last_update_check);
9955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pending_deletions_.find(data.registration_id) !=
9965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      pending_deletions_.end()) {
9976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    registration->set_is_deleted(true);
9985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
9990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<ServiceWorkerVersion> version =
1000010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      context_->GetLiveVersion(data.version_id);
10011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!version.get()) {
10021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    version = new ServiceWorkerVersion(
10031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        registration.get(), data.script, data.version_id, context_);
1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version->SetStatus(data.is_active ?
1005116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ServiceWorkerVersion::ACTIVATED : ServiceWorkerVersion::INSTALLED);
1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version->script_cache_map()->SetResources(resources);
10070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
10080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1009116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (version->status() == ServiceWorkerVersion::ACTIVATED)
10101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetActiveVersion(version.get());
10110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else if (version->status() == ServiceWorkerVersion::INSTALLED)
10121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    registration->SetWaitingVersion(version.get());
10130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else
10140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    NOTREACHED();
10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return registration;
10170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
10180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
10190529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration*
10200529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForDocument(
10210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& document_url) {
102246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!document_url.has_ref());
102346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
102446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LongestScopeMatcher matcher(document_url);
102546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ServiceWorkerRegistration* match = NULL;
102646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
102746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(nhiroki): This searches over installing registrations linearly and it
102846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // couldn't be scalable. Maybe the regs should be partitioned by origin.
10290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationRefsById::const_iterator it =
10300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           installing_registrations_.begin();
10310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != installing_registrations_.end(); ++it) {
103246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (matcher.MatchLongest(it->second->pattern()))
10331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      match = it->second.get();
10340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
103546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return match;
10360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
10370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
10380529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration*
10390529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForPattern(
10400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& scope) {
10410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (RegistrationRefsById::const_iterator it =
10420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           installing_registrations_.begin();
10430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       it != installing_registrations_.end(); ++it) {
10440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (it->second->pattern() == scope)
10451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return it->second.get();
10460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
10470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return NULL;
10480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
10490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
10500529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration*
10510529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForId(
10520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 registration_id) {
10530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegistrationRefsById::const_iterator found =
10540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      installing_registrations_.find(registration_id);
10550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (found == installing_registrations_.end())
10560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return NULL;
10571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return found->second.get();
10580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
10590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1060010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
1061010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (disk_cache_)
1062010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return disk_cache_.get();
1063010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1064010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  disk_cache_.reset(new ServiceWorkerDiskCache);
1065cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::FilePath path = GetDiskCachePath();
1067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (path.empty()) {
10685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int rv = disk_cache_->InitWithMemBackend(kMaxMemDiskCacheSize,
10695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             net::CompletionCallback());
1070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(net::OK, rv);
1071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return disk_cache_.get();
1072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rv = disk_cache_->InitWithDiskBackend(
107503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      path,
107603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      kMaxDiskCacheSize,
107703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      false,
107803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      disk_cache_thread_,
1079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized,
1080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (rv != net::ERR_IO_PENDING)
1082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    OnDiskCacheInitialized(rv);
1083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1084010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return disk_cache_.get();
1085010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
1086010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) {
1088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (rv != net::OK) {
1089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(ERROR) << "Failed to open the serviceworker diskcache: "
1090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               << net::ErrorToString(rv);
1091116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleDeleteAndStartOver();
1092cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1093116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceWorkerMetrics::CountInitDiskCacheResult(rv == net::OK);
1094cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1096cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::StartPurgingResources(
1097cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::vector<int64>& ids) {
1098116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(has_checked_for_stale_resources_);
1099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < ids.size(); ++i)
1100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    purgeable_resource_ids_.push_back(ids[i]);
1101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ContinuePurgingResources();
1102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::StartPurgingResources(
1105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceList& resources) {
1106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(has_checked_for_stale_resources_);
1107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < resources.size(); ++i)
1108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    purgeable_resource_ids_.push_back(resources[i].resource_id);
1109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ContinuePurgingResources();
1110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::ContinuePurgingResources() {
1113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (purgeable_resource_ids_.empty() || is_purge_pending_)
1114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do one at a time until we're done, use RunSoon to avoid recursion when
1117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // DoomEntry returns immediately.
1118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  is_purge_pending_ = true;
1119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int64 id = purgeable_resource_ids_.front();
1120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  purgeable_resource_ids_.pop_front();
1121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RunSoon(FROM_HERE,
1122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Bind(&ServiceWorkerStorage::PurgeResource,
1123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     weak_factory_.GetWeakPtr(), id));
1124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::PurgeResource(int64 id) {
1127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(is_purge_pending_);
1128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int rv = disk_cache()->DoomEntry(
1129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      id, base::Bind(&ServiceWorkerStorage::OnResourcePurged,
1130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     weak_factory_.GetWeakPtr(), id));
1131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (rv != net::ERR_IO_PENDING)
1132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    OnResourcePurged(id, rv);
1133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) {
1136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(is_purge_pending_);
1137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  is_purge_pending_ = false;
1138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  database_task_runner_->PostTask(
1140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE,
1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(base::IgnoreResult(
1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &ServiceWorkerDatabase::ClearPurgeableResourceIds),
1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Unretained(database_.get()),
1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          std::set<int64>(&id, &id + 1)));
1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ContinuePurgingResources();
1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1149116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::DeleteStaleResources() {
1150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!has_checked_for_stale_resources_);
1151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  has_checked_for_stale_resources_ = true;
1152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  database_task_runner_->PostTask(
1153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
1154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&ServiceWorkerStorage::CollectStaleResourcesFromDB,
1155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 database_.get(),
1156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::MessageLoopProxy::current(),
1157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Bind(&ServiceWorkerStorage::DidCollectStaleResources,
1158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            weak_factory_.GetWeakPtr())));
1159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1161116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::DidCollectStaleResources(
1162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::vector<int64>& stale_resource_ids,
1163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerDatabase::Status status) {
1164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(ServiceWorkerDatabase::STATUS_OK, status);
1165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != ServiceWorkerDatabase::STATUS_OK)
1166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartPurgingResources(stale_resource_ids);
1168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1170116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::CollectStaleResourcesFromDB(
1171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerDatabase* database,
1172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GetResourcesCallback& callback) {
1174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::set<int64> ids;
1175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceWorkerDatabase::Status status =
1176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      database->GetUncommittedResourceIds(&ids);
1177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != ServiceWorkerDatabase::STATUS_OK) {
1178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    original_task_runner->PostTask(
1179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        FROM_HERE,
1180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(
1181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            callback, std::vector<int64>(ids.begin(), ids.end()), status));
1182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  status = database->PurgeUncommittedResourceIds(ids);
1186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != ServiceWorkerDatabase::STATUS_OK) {
1187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    original_task_runner->PostTask(
1188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        FROM_HERE,
1189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(
1190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            callback, std::vector<int64>(ids.begin(), ids.end()), status));
1191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ids.clear();
1195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  status = database->GetPurgeableResourceIds(&ids);
1196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  original_task_runner->PostTask(
1197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
1198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(callback, std::vector<int64>(ids.begin(), ids.end()), status));
1199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::ReadInitialDataFromDB(
1202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase* database,
1203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const InitializeCallback& callback) {
1205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(database);
1206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ServiceWorkerStorage::InitialData> data(
1207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new ServiceWorkerStorage::InitialData());
1208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::Status status =
1210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      database->GetNextAvailableIds(&data->next_registration_id,
1211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    &data->next_version_id,
1212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    &data->next_resource_id);
1213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
1214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    original_task_runner->PostTask(
1215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
1216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  status = database->GetOriginsWithRegistrations(&data->origins);
1220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  original_task_runner->PostTask(
1221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE, base::Bind(callback, base::Owned(data.release()), status));
1222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DeleteRegistrationFromDB(
1225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase* database,
1226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int64 registration_id,
1228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& origin,
1229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const DeleteRegistrationCallback& callback) {
1230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(database);
1231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int64 version_id = kInvalidServiceWorkerVersionId;
1233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<int64> newly_purgeable_resources;
1234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceWorkerDatabase::Status status = database->DeleteRegistration(
1235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      registration_id, origin, &version_id, &newly_purgeable_resources);
1236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
1237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    original_task_runner->PostTask(FROM_HERE,
1238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   base::Bind(callback,
1239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              false,
1240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              kInvalidServiceWorkerVersionId,
1241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              std::vector<int64>(),
1242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              status));
1243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the
1247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // unique origin list.
1248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
1249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  status = database->GetRegistrationsForOrigin(origin, &registrations);
1250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
1251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    original_task_runner->PostTask(FROM_HERE,
1252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   base::Bind(callback,
1253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              false,
1254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              kInvalidServiceWorkerVersionId,
1255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              std::vector<int64>(),
1256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                              status));
1257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool deletable = registrations.empty();
1261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  original_task_runner->PostTask(
1262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
1263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(
1264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          callback, deletable, version_id, newly_purgeable_resources, status));
1265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::WriteRegistrationInDB(
1268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase* database,
1269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ServiceWorkerDatabase::RegistrationData& data,
1271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceList& resources,
1272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const WriteRegistrationCallback& callback) {
1273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(database);
1274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int64 deleted_version_id = kInvalidServiceWorkerVersionId;
1275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<int64> newly_purgeable_resources;
1276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceWorkerDatabase::Status status = database->WriteRegistration(
1277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      data, resources, &deleted_version_id, &newly_purgeable_resources);
1278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  original_task_runner->PostTask(FROM_HERE,
1279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 base::Bind(callback,
1280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            data.script.GetOrigin(),
1281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            deleted_version_id,
1282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            newly_purgeable_resources,
1283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            status));
1284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindForDocumentInDB(
1287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase* database,
1288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& document_url,
1290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const FindInDBCallback& callback) {
1291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL origin = document_url.GetOrigin();
1292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RegistrationList registrations;
1293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::Status status =
1294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      database->GetRegistrationsForOrigin(origin, &registrations);
1295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
1296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    original_task_runner->PostTask(
1297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FROM_HERE,
1298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(callback,
1299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   ServiceWorkerDatabase::RegistrationData(),
1300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   ResourceList(),
1301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   status));
1302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::RegistrationData data;
1306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceList resources;
1307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND;
130846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
130946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Find one with a pattern match.
131046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LongestScopeMatcher matcher(document_url);
131146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int64 match = kInvalidServiceWorkerRegistrationId;
131246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (size_t i = 0; i < registrations.size(); ++i) {
131346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (matcher.MatchLongest(registrations[i].scope))
131446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      match = registrations[i].registration_id;
1315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
131746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (match != kInvalidServiceWorkerRegistrationId)
131846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    status = database->ReadRegistration(match, origin, &data, &resources);
131946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  original_task_runner->PostTask(
1321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE,
1322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(callback, data, resources, status));
1323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindForPatternInDB(
1326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase* database,
1327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& scope,
1329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const FindInDBCallback& callback) {
1330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL origin = scope.GetOrigin();
1331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
1332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::Status status =
1333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      database->GetRegistrationsForOrigin(origin, &registrations);
1334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status != ServiceWorkerDatabase::STATUS_OK) {
1335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    original_task_runner->PostTask(
1336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        FROM_HERE,
1337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(callback,
1338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   ServiceWorkerDatabase::RegistrationData(),
1339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   ResourceList(),
1340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   status));
1341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Find one with an exact matching scope.
1345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::RegistrationData data;
1346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceList resources;
1347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND;
1348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (RegistrationList::const_iterator it = registrations.begin();
1349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != registrations.end(); ++it) {
1350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (scope != it->scope)
1351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
1352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    status = database->ReadRegistration(it->registration_id, origin,
1353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        &data, &resources);
1354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    break;  // We're done looping.
1355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  original_task_runner->PostTask(
1358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE,
1359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(callback, data, resources, status));
1360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindForIdInDB(
1363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerDatabase* database,
1364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
1365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int64 registration_id,
1366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& origin,
1367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const FindInDBCallback& callback) {
1368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::RegistrationData data;
1369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceList resources;
1370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ServiceWorkerDatabase::Status status =
1371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      database->ReadRegistration(registration_id, origin, &data, &resources);
1372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  original_task_runner->PostTask(
1373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      FROM_HERE, base::Bind(callback, data, resources, status));
1374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(nhiroki): The corruption recovery should not be scheduled if the error
1377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// is transient and it can get healed soon (e.g. IO error). To do that, the
1378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// database should not disable itself when an error occurs and the storage
1379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// controls it instead.
1380116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::ScheduleDeleteAndStartOver() {
1381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (state_ == DISABLED) {
1382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Recovery process has already been scheduled.
1383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Disable();
1386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DVLOG(1) << "Schedule to delete the context and start over.";
1388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  context_->ScheduleDeleteAndStartOver();
1389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1391116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::DidDeleteDatabase(
1392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const StatusCallback& callback,
1393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerDatabase::Status status) {
1394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(DISABLED, state_);
1395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status != ServiceWorkerDatabase::STATUS_OK) {
1396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Give up the corruption recovery until the browser restarts.
1397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(ERROR) << "Failed to delete the database: " << status;
1398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(DatabaseStatusToStatusCode(status));
1399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DVLOG(1) << "Deleted ServiceWorkerDatabase successfully.";
1402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Delete the disk cache on the cache thread.
1404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(nhiroki): What if there is a bunch of files in the cache directory?
1405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Deleting the directory could take a long time and restart could be delayed.
1406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // We should probably rename the directory and delete it later.
1407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PostTaskAndReplyWithResult(
14081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      database_task_runner_.get(),
1409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
1410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&base::DeleteFile, GetDiskCachePath(), true),
1411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&ServiceWorkerStorage::DidDeleteDiskCache,
14121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_factory_.GetWeakPtr(),
14131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 callback));
1414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1416116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerStorage::DidDeleteDiskCache(
1417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const StatusCallback& callback, bool result) {
1418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(DISABLED, state_);
1419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!result) {
1420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Give up the corruption recovery until the browser restarts.
1421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(ERROR) << "Failed to delete the diskcache.";
1422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(SERVICE_WORKER_ERROR_FAILED);
1423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
1424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully.";
1426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(SERVICE_WORKER_OK);
1427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace content
1430