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" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/sequenced_task_runner.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/task_runner_util.h" 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/service_worker/service_worker_disk_cache.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/browser/service_worker/service_worker_histograms.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_info.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h" 18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/browser/service_worker/service_worker_utils.h" 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_version.h" 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/common/service_worker/service_worker_types.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/base/net_errors.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "webkit/browser/quota/quota_manager_proxy.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RunSoon(const tracked_objects::Location& from_here, 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::Closure& closure) { 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::MessageLoop::current()->PostTask(from_here, closure); 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CompleteFindNow( 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const scoped_refptr<ServiceWorkerRegistration>& registration, 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServiceWorkerStatusCode status, 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const ServiceWorkerStorage::FindRegistrationCallback& callback) { 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch callback.Run(status, registration); 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid CompleteFindSoon( 425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const tracked_objects::Location& from_here, 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const scoped_refptr<ServiceWorkerRegistration>& registration, 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServiceWorkerStatusCode status, 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const ServiceWorkerStorage::FindRegistrationCallback& callback) { 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu RunSoon(from_here, base::Bind(callback, status, registration)); 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const base::FilePath::CharType kServiceWorkerDirectory[] = 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FILE_PATH_LITERAL("Service Worker"); 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const base::FilePath::CharType kDatabaseName[] = 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FILE_PATH_LITERAL("Database"); 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const base::FilePath::CharType kDiskCacheName[] = 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FILE_PATH_LITERAL("Cache"); 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kMaxDiskCacheSize = 250 * 1024 * 1024; 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EmptyCompletionCallback(int) {} 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerStatusCode DatabaseStatusToStatusCode( 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (status) { 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ServiceWorkerDatabase::STATUS_OK: 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SERVICE_WORKER_OK; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND: 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SERVICE_WORKER_ERROR_NOT_FOUND; 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case ServiceWorkerDatabase::STATUS_ERROR_MAX: 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED(); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return SERVICE_WORKER_ERROR_FAILED; 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::InitialData::InitialData() 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : next_registration_id(kInvalidServiceWorkerRegistrationId), 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_version_id(kInvalidServiceWorkerVersionId), 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_resource_id(kInvalidServiceWorkerResourceId) { 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::InitialData::~InitialData() { 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ServiceWorkerStorage::ServiceWorkerStorage( 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::FilePath& path, 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::WeakPtr<ServiceWorkerContextCore> context, 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::SequencedTaskRunner* database_task_runner, 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoopProxy* disk_cache_thread, 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) quota::QuotaManagerProxy* quota_manager_proxy) 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : next_registration_id_(kInvalidServiceWorkerRegistrationId), 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_version_id_(kInvalidServiceWorkerVersionId), 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_resource_id_(kInvalidServiceWorkerResourceId), 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_(UNINITIALIZED), 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch context_(context), 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_task_runner_(database_task_runner), 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) disk_cache_thread_(disk_cache_thread), 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) quota_manager_proxy_(quota_manager_proxy), 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_purge_pending_(false), 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_(this) { 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!path.empty()) 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) path_ = path.Append(kServiceWorkerDirectory); 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_.reset(new ServiceWorkerDatabase(GetDatabasePath())); 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ServiceWorkerStorage::~ServiceWorkerStorage() { 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_task_runner_->DeleteSoon(FROM_HERE, database_.release()); 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindRegistrationForDocument( 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& document_url, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const FindRegistrationCallback& callback) { 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!document_url.has_ref()); 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!LazyInitialize(base::Bind( 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &ServiceWorkerStorage::FindRegistrationForDocument, 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), document_url, callback))) { 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ != INITIALIZING || !context_) { 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(), 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_ERROR_FAILED, callback); 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // See if there are any stored registrations for the origin. 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!ContainsKey(registered_origins_, document_url.GetOrigin())) { 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Look for something currently being installed. 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> installing_registration = 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FindInstallingRegistrationForDocument(document_url); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CompleteFindNow( 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration, 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration ? 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback); 1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind( 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &FindForDocumentInDB, 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_.get(), 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoopProxy::current(), 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) document_url, 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidFindRegistrationForDocument, 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), document_url, callback))); 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindRegistrationForPattern( 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& scope, 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const FindRegistrationCallback& callback) { 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!LazyInitialize(base::Bind( 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &ServiceWorkerStorage::FindRegistrationForPattern, 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), scope, callback))) { 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (state_ != INITIALIZING || !context_) { 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(), 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_ERROR_FAILED, callback); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // See if there are any stored registrations for the origin. 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!ContainsKey(registered_origins_, scope.GetOrigin())) { 1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Look for something currently being installed. 1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<ServiceWorkerRegistration> installing_registration = 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FindInstallingRegistrationForPattern(scope); 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CompleteFindSoon( 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, installing_registration, 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration ? 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback); 1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind( 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &FindForPatternInDB, 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_.get(), 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoopProxy::current(), 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scope, 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidFindRegistrationForPattern, 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), scope, callback))); 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ServiceWorkerStorage::FindRegistrationForId( 190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int64 registration_id, 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GURL& origin, 192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const FindRegistrationCallback& callback) { 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!LazyInitialize(base::Bind( 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &ServiceWorkerStorage::FindRegistrationForId, 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.GetWeakPtr(), registration_id, origin, callback))) { 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (state_ != INITIALIZING || !context_) { 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(), 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_ERROR_FAILED, callback); 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // See if there are any stored registrations for the origin. 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!ContainsKey(registered_origins_, origin)) { 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Look for something currently being installed. 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> installing_registration = 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FindInstallingRegistrationForId(registration_id); 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CompleteFindNow( 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration, 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration ? 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback); 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<ServiceWorkerRegistration> registration = 2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch context_->GetLiveRegistration(registration_id); 2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (registration) { 2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CompleteFindNow(registration, SERVICE_WORKER_OK, callback); 2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_task_runner_->PostTask( 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&FindForIdInDB, 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_.get(), 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoopProxy::current(), 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registration_id, origin, 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId, 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback))); 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::GetAllRegistrations( 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const GetAllRegistrationInfosCallback& callback) { 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!LazyInitialize(base::Bind( 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &ServiceWorkerStorage::GetAllRegistrations, 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback))) { 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ != INITIALIZING || !context_) { 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunSoon(FROM_HERE, base::Bind( 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback, std::vector<ServiceWorkerRegistrationInfo>())); 242effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RegistrationList* registrations = new RegistrationList; 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PostTaskAndReplyWithResult( 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_task_runner_, 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ServiceWorkerDatabase::GetAllRegistrations, 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(database_.get()), 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(registrations)), 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidGetAllRegistrations, 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.GetWeakPtr(), 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback, 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Owned(registrations))); 258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerStorage::StoreRegistration( 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerRegistration* registration, 2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServiceWorkerVersion* version, 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const StatusCallback& callback) { 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(registration); 2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(version); 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(state_ == INITIALIZED || state_ == DISABLED); 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ != INITIALIZED || !context_) { 2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerDatabase::RegistrationData data; 2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.registration_id = registration->id(); 2750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.scope = registration->pattern(); 2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.script = registration->script_url(); 2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.has_fetch_handler = true; 2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.version_id = version->version_id(); 2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.last_update_check = base::Time::Now(); 2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.is_active = false; // initially stored in the waiting state 2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ResourceList resources; 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) version->script_cache_map()->GetResources(&resources); 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&WriteRegistrationInDB, 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_.get(), 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoopProxy::current(), 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data, resources, 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidStoreRegistration, 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback))); 2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::UpdateToActiveState( 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerRegistration* registration, 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const StatusCallback& callback) { 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(registration); 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(state_ == INITIALIZED || state_ == DISABLED); 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ != INITIALIZED || !context_) { 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PostTaskAndReplyWithResult( 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_, 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerDatabase::UpdateVersionToActive, 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(database_.get()), 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registration->id(), 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registration->script_url().GetOrigin()), 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidUpdateToActiveState, 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback)); 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerStorage::DeleteRegistration( 3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int64 registration_id, 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GURL& origin, 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const StatusCallback& callback) { 323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(state_ == INITIALIZED || state_ == DISABLED); 324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ != INITIALIZED || !context_) { 325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_task_runner_->PostTask( 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&DeleteRegistrationFromDB, 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_.get(), 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoopProxy::current(), 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registration_id, origin, 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidDeleteRegistration, 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.GetWeakPtr(), origin, callback))); 3370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(michaeln): Either its instance should also be 3390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // removed from liveregistrations map or the live object 3400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // should marked as deleted in some way and not 'findable' 3410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // thereafter. 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_ptr<ServiceWorkerResponseReader> 345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::CreateResponseReader(int64 response_id) { 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return make_scoped_ptr( 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new ServiceWorkerResponseReader(response_id, disk_cache())); 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_ptr<ServiceWorkerResponseWriter> 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerStorage::CreateResponseWriter(int64 response_id) { 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return make_scoped_ptr( 353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new ServiceWorkerResponseWriter(response_id, disk_cache())); 354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::StoreUncommittedReponseId(int64 id) { 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_NE(kInvalidServiceWorkerResponseId, id); 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(base::IgnoreResult( 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &ServiceWorkerDatabase::WriteUncommittedResourceIds), 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(database_.get()), 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::set<int64>(&id, &id + 1))); 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DoomUncommittedResponse(int64 id) { 367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_NE(kInvalidServiceWorkerResponseId, id); 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(base::IgnoreResult( 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &ServiceWorkerDatabase::PurgeUncommittedResourceIds), 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(database_.get()), 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::set<int64>(&id, &id + 1))); 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StartPurgingResources(std::vector<int64>(1, id)); 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 ServiceWorkerStorage::NewRegistrationId() { 378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ == DISABLED) 379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return kInvalidServiceWorkerRegistrationId; 380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return next_registration_id_++; 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 ServiceWorkerStorage::NewVersionId() { 385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ == DISABLED) 386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return kInvalidServiceWorkerVersionId; 387010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return next_version_id_++; 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochint64 ServiceWorkerStorage::NewResourceId() { 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (state_ == DISABLED) 393010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return kInvalidServiceWorkerResourceId; 394010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZED, state_); 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return next_resource_id_++; 3960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 3970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::NotifyInstallingRegistration( 3990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServiceWorkerRegistration* registration) { 4000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch installing_registrations_[registration->id()] = registration; 4010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerStorage::NotifyDoneInstallingRegistration( 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerRegistration* registration, 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerVersion* version, 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerStatusCode status) { 4070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch installing_registrations_.erase(registration->id()); 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != SERVICE_WORKER_OK && version) { 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceList resources; 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) version->script_cache_map()->GetResources(&resources); 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::set<int64> ids; 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (size_t i = 0; i < resources.size(); ++i) 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ids.insert(resources[i].resource_id); 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(base::IgnoreResult( 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &ServiceWorkerDatabase::PurgeUncommittedResourceIds), 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(database_.get()), 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ids)); 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StartPurgingResources(resources); 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath ServiceWorkerStorage::GetDatabasePath() { 428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (path_.empty()) 429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::FilePath(); 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return path_.Append(kDatabaseName); 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath ServiceWorkerStorage::GetDiskCachePath() { 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (path_.empty()) 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return base::FilePath(); 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return path_.Append(kDiskCacheName); 4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 439010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { 440010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!context_) 441010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch (state_) { 444010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case INITIALIZED: 445010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 446010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case DISABLED: 447010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 448010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case INITIALIZING: 449010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pending_tasks_.push_back(callback); 450010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 451010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case UNINITIALIZED: 452010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pending_tasks_.push_back(callback); 453010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Fall-through. 454010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 455010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 456010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_ = INITIALIZING; 457010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_task_runner_->PostTask( 458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ReadInitialDataFromDB, 460010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) database_.get(), 461010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoopProxy::current(), 462010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ServiceWorkerStorage::DidReadInitialData, 463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_factory_.GetWeakPtr()))); 464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidReadInitialData( 468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) InitialData* data, 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 470010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(data); 471010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(INITIALIZING, state_); 472010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status == ServiceWorkerDatabase::STATUS_OK) { 474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_registration_id_ = data->next_registration_id; 475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_version_id_ = data->next_version_id; 476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) next_resource_id_ = data->next_resource_id; 477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registered_origins_.swap(data->origins); 478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_ = INITIALIZED; 479010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): If status==STATUS_ERROR_CORRUPTED, do corruption recovery 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // (http://crbug.com/371675). 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DLOG(WARNING) << "Failed to initialize: " << status; 483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_ = DISABLED; 484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); 487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != pending_tasks_.end(); ++it) { 488010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunSoon(FROM_HERE, *it); 489010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 490010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pending_tasks_.clear(); 491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidFindRegistrationForDocument( 494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& document_url, 495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const FindRegistrationCallback& callback, 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ServiceWorkerDatabase::RegistrationData& data, 497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceList& resources, 498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status == ServiceWorkerDatabase::STATUS_OK) { 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources)); 501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 502010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Look for something currently being installed. 506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> installing_registration = 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FindInstallingRegistrationForDocument(document_url); 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(installing_registration ? 509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, 510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration); 511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 512010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 513010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(DatabaseStatusToStatusCode(status), 516010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<ServiceWorkerRegistration>()); 517010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 518010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidFindRegistrationForPattern( 520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& scope, 521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const FindRegistrationCallback& callback, 522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ServiceWorkerDatabase::RegistrationData& data, 523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceList& resources, 524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status == ServiceWorkerDatabase::STATUS_OK) { 526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources)); 527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { 531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> installing_registration = 532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FindInstallingRegistrationForPattern(scope); 533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(installing_registration ? 534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, 535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installing_registration); 536010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(DatabaseStatusToStatusCode(status), 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<ServiceWorkerRegistration>()); 542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidFindRegistrationForId( 545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const FindRegistrationCallback& callback, 546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ServiceWorkerDatabase::RegistrationData& data, 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ResourceList& resources, 548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status == ServiceWorkerDatabase::STATUS_OK) { 550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(SERVICE_WORKER_OK, 551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetOrCreateRegistration(data, resources)); 552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(DatabaseStatusToStatusCode(status), 556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<ServiceWorkerRegistration>()); 557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidGetAllRegistrations( 560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GetAllRegistrationInfosCallback& callback, 561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RegistrationList* registrations, 562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(registrations); 564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(std::vector<ServiceWorkerRegistrationInfo>()); 567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Add all stored registrations. 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::set<int64> pushed_registrations; 572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<ServiceWorkerRegistrationInfo> infos; 573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (RegistrationList::const_iterator it = registrations->begin(); 574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != registrations->end(); ++it) { 57546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const bool inserted = 57646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pushed_registrations.insert(it->registration_id).second; 57746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(inserted); 57846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerRegistration* registration = 580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) context_->GetLiveRegistration(it->registration_id); 581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (registration) { 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) infos.push_back(registration->GetInfo()); 583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 584010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 58546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 586010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ServiceWorkerRegistrationInfo info; 587010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) info.pattern = it->scope; 588010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) info.script_url = it->script; 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) info.registration_id = it->registration_id; 59046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (ServiceWorkerVersion* version = 59146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) context_->GetLiveVersion(it->version_id)) { 59246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (it->is_active) 59346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) info.active_version = version->GetInfo(); 59446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) else 59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) info.waiting_version = version->GetInfo(); 596f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) infos.push_back(info); 597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) continue; 598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (it->is_active) { 60146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) info.active_version.is_null = false; 602f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.active_version.status = ServiceWorkerVersion::ACTIVE; 60346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) info.active_version.version_id = it->version_id; 604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.waiting_version.is_null = false; 606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.waiting_version.status = ServiceWorkerVersion::INSTALLED; 607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) info.waiting_version.version_id = it->version_id; 60846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 609010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) infos.push_back(info); 610010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 611010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 612010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Add unstored registrations that are being installed. 613010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (RegistrationRefsById::const_iterator it = 614010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) installing_registrations_.begin(); 615010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != installing_registrations_.end(); ++it) { 616010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pushed_registrations.insert(it->first).second) 617010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) infos.push_back(it->second->GetInfo()); 618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(infos); 621010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 622010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 623010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidStoreRegistration( 624010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const StatusCallback& callback, 625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& origin, 626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<int64>& newly_purgeable_resources, 627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(DatabaseStatusToStatusCode(status)); 631010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 632010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registered_origins_.insert(origin); 634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(SERVICE_WORKER_OK); 635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StartPurgingResources(newly_purgeable_resources); 636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DidUpdateToActiveState( 639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const StatusCallback& callback, 640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(DatabaseStatusToStatusCode(status)); 643010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 644010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 645010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ServiceWorkerStorage::DidDeleteRegistration( 646010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const GURL& origin, 647010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const StatusCallback& callback, 648010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool origin_is_deletable, 649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<int64>& newly_purgeable_resources, 650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status) { 651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Handle database error (http://crbug.com/371675). 653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(DatabaseStatusToStatusCode(status)); 654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 656010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (origin_is_deletable) 657010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registered_origins_.erase(origin); 658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(SERVICE_WORKER_OK); 659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StartPurgingResources(newly_purgeable_resources); 660010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 661010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 6620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochscoped_refptr<ServiceWorkerRegistration> 663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerStorage::GetOrCreateRegistration( 664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ServiceWorkerDatabase::RegistrationData& data, 665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceList& resources) { 666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> registration = 667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context_->GetLiveRegistration(data.registration_id); 668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (registration) 669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return registration; 6700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registration = new ServiceWorkerRegistration( 672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) data.scope, data.script, data.registration_id, context_); 6730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_refptr<ServiceWorkerVersion> version = 674010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) context_->GetLiveVersion(data.version_id); 6750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!version) { 676010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) version = new ServiceWorkerVersion(registration, data.version_id, context_); 677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) version->SetStatus(data.is_active ? 678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED); 679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) version->script_cache_map()->SetResources(resources); 6800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 6810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 6820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (version->status() == ServiceWorkerVersion::ACTIVE) 6830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch registration->set_active_version(version); 6840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else if (version->status() == ServiceWorkerVersion::INSTALLED) 685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registration->set_waiting_version(version); 6860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 6870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NOTREACHED(); 6880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(michaeln): Hmmm, what if DeleteReg was invoked after 6890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // the Find result we're returning here? NOTREACHED condition? 6900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return registration; 6910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 6920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 6930529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration* 6940529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForDocument( 6950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const GURL& document_url) { 69646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!document_url.has_ref()); 69746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 69846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LongestScopeMatcher matcher(document_url); 69946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ServiceWorkerRegistration* match = NULL; 70046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 70146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // TODO(nhiroki): This searches over installing registrations linearly and it 70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // couldn't be scalable. Maybe the regs should be partitioned by origin. 7030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (RegistrationRefsById::const_iterator it = 7040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch installing_registrations_.begin(); 7050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch it != installing_registrations_.end(); ++it) { 70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (matcher.MatchLongest(it->second->pattern())) 70746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) match = it->second; 7080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return match; 7100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 7110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 7120529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration* 7130529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForPattern( 7140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const GURL& scope) { 7150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (RegistrationRefsById::const_iterator it = 7160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch installing_registrations_.begin(); 7170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch it != installing_registrations_.end(); ++it) { 7180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (it->second->pattern() == scope) 7190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return it->second; 7200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 7210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 7220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 7230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 7240529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegistration* 7250529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerStorage::FindInstallingRegistrationForId( 7260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int64 registration_id) { 7270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RegistrationRefsById::const_iterator found = 7280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch installing_registrations_.find(registration_id); 7290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (found == installing_registrations_.end()) 7300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 7310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return found->second; 7320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 7330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { 735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (disk_cache_) 736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return disk_cache_.get(); 737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) disk_cache_.reset(new ServiceWorkerDiskCache); 739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath path = GetDiskCachePath(); 741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (path.empty()) { 742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int rv = disk_cache_->InitWithMemBackend( 743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kMaxMemDiskCacheSize, 744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&EmptyCompletionCallback)); 745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_EQ(net::OK, rv); 746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return disk_cache_.get(); 747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int rv = disk_cache_->InitWithDiskBackend( 750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) path, kMaxDiskCacheSize, false, 751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) disk_cache_thread_.get(), 752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized, 753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr())); 754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnDiskCacheInitialized(rv); 756cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 757010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return disk_cache_.get(); 758010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 759010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) { 761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rv != net::OK) { 762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Failed to open the serviceworker diskcache: " 763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << net::ErrorToString(rv); 764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(michaeln): DeleteAndStartOver() 765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) disk_cache_->Disable(); 766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state_ = DISABLED; 767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ServiceWorkerHistograms::CountInitDiskCacheResult(rv == net::OK); 769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::StartPurgingResources( 772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<int64>& ids) { 773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (size_t i = 0; i < ids.size(); ++i) 774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) purgeable_reource_ids_.push_back(ids[i]); 775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ContinuePurgingResources(); 776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::StartPurgingResources( 779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceList& resources) { 780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (size_t i = 0; i < resources.size(); ++i) 781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) purgeable_reource_ids_.push_back(resources[i].resource_id); 782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ContinuePurgingResources(); 783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::ContinuePurgingResources() { 786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (purgeable_reource_ids_.empty() || is_purge_pending_) 787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Do one at a time until we're done, use RunSoon to avoid recursion when 790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // DoomEntry returns immediately. 791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_purge_pending_ = true; 792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int64 id = purgeable_reource_ids_.front(); 793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) purgeable_reource_ids_.pop_front(); 794cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RunSoon(FROM_HERE, 795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ServiceWorkerStorage::PurgeResource, 796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), id)); 797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::PurgeResource(int64 id) { 800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(is_purge_pending_); 801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int rv = disk_cache()->DoomEntry( 802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) id, base::Bind(&ServiceWorkerStorage::OnResourcePurged, 803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_factory_.GetWeakPtr(), id)); 804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnResourcePurged(id, rv); 806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) { 809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(is_purge_pending_); 810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_purge_pending_ = false; 811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database_task_runner_->PostTask( 813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(base::IgnoreResult( 815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &ServiceWorkerDatabase::ClearPurgeableResourceIds), 816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(database_.get()), 817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::set<int64>(&id, &id + 1))); 818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ContinuePurgingResources(); 820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::ReadInitialDataFromDB( 823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase* database, 824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> original_task_runner, 825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const InitializeCallback& callback) { 826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(database); 827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<ServiceWorkerStorage::InitialData> data( 828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new ServiceWorkerStorage::InitialData()); 829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status = 831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database->GetNextAvailableIds(&data->next_registration_id, 832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &data->next_version_id, 833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &data->next_resource_id); 834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); 837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status = database->GetOriginsWithRegistrations(&data->origins); 841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); 843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::DeleteRegistrationFromDB( 846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase* database, 847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> original_task_runner, 848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int64 registration_id, 849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& origin, 850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const DeleteRegistrationCallback& callback) { 851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(database); 852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<int64> newly_purgeable_resources; 854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status = 855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database->DeleteRegistration(registration_id, origin, 856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &newly_purgeable_resources); 857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status)); 860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the 864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // unique origin list. 865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<ServiceWorkerDatabase::RegistrationData> registrations; 866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status = database->GetRegistrationsForOrigin(origin, ®istrations); 867cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 868cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 869cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status)); 870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 873cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool deletable = registrations.empty(); 874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(callback, deletable, 876cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) newly_purgeable_resources, status)); 877cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::WriteRegistrationInDB( 880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase* database, 881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> original_task_runner, 882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ServiceWorkerDatabase::RegistrationData& data, 883cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceList& resources, 884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const WriteRegistrationCallback& callback) { 885cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(database); 886cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<int64> newly_purgeable_resources; 887cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status = 888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database->WriteRegistration(data, resources, &newly_purgeable_resources); 889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 891cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, data.script.GetOrigin(), 892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) newly_purgeable_resources, status)); 893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindForDocumentInDB( 896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase* database, 897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> original_task_runner, 898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& document_url, 899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const FindInDBCallback& callback) { 900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL origin = document_url.GetOrigin(); 901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RegistrationList registrations; 902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status = 903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database->GetRegistrationsForOrigin(origin, ®istrations); 904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, 908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::RegistrationData(), 909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceList(), 910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status)); 911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::RegistrationData data; 915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceList resources; 916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND; 91746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 91846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Find one with a pattern match. 91946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LongestScopeMatcher matcher(document_url); 92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int64 match = kInvalidServiceWorkerRegistrationId; 92146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (size_t i = 0; i < registrations.size(); ++i) { 92246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (matcher.MatchLongest(registrations[i].scope)) 92346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) match = registrations[i].registration_id; 924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 92646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (match != kInvalidServiceWorkerRegistrationId) 92746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) status = database->ReadRegistration(match, origin, &data, &resources); 92846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, data, resources, status)); 932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindForPatternInDB( 935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase* database, 936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> original_task_runner, 937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& scope, 938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const FindInDBCallback& callback) { 939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL origin = scope.GetOrigin(); 940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<ServiceWorkerDatabase::RegistrationData> registrations; 941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status = 942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database->GetRegistrationsForOrigin(origin, ®istrations); 943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status != ServiceWorkerDatabase::STATUS_OK) { 944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, 947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::RegistrationData(), 948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceList(), 949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status)); 950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Find one with an exact matching scope. 954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::RegistrationData data; 955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceList resources; 956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND; 957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (RegistrationList::const_iterator it = registrations.begin(); 958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != registrations.end(); ++it) { 959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (scope != it->scope) 960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continue; 961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) status = database->ReadRegistration(it->registration_id, origin, 962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &data, &resources); 963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; // We're done looping. 964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, data, resources, status)); 969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerStorage::FindForIdInDB( 972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase* database, 973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> original_task_runner, 974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int64 registration_id, 975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& origin, 976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const FindInDBCallback& callback) { 977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::RegistrationData data; 978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ResourceList resources; 979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerDatabase::Status status = 980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) database->ReadRegistration(registration_id, origin, &data, &resources); 981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) original_task_runner->PostTask( 982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, base::Bind(callback, data, resources, status)); 983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 985a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace content 986