Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: content/browser/appcache/chrome_appcache_service.cc

Issue 7210006: AppCaches which belong to hosted apps are not protected from deletion (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixing the merge. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/appcache/chrome_appcache_service.h" 5 #include "content/browser/appcache/chrome_appcache_service.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "content/browser/content_browser_client.h" 9 #include "content/browser/content_browser_client.h"
10 #include "content/common/notification_service.h" 10 #include "content/common/notification_service.h"
11 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
12 #include "webkit/appcache/appcache_thread.h" 12 #include "webkit/appcache/appcache_thread.h"
13 #include "webkit/quota/quota_manager.h" 13 #include "webkit/quota/quota_manager.h"
14 14
15 static bool has_initialized_thread_ids; 15 static bool has_initialized_thread_ids;
16 16
17 namespace {
18
19 // Used to defer deleting of local storage until the destructor has finished.
20 void DeleteLocalStateOnIOThread(FilePath cache_path) {
21 // Post the actual deletion to the DB thread to ensure it happens after the
22 // database file has been closed.
23 BrowserThread::PostTask(
24 BrowserThread::DB, FROM_HERE,
25 NewRunnableFunction<bool(*)(const FilePath&, bool), FilePath, bool>(
26 &file_util::Delete, cache_path, true));
27 }
28
29 } // namespace
30
31 // ---------------------------------------------------------------------------- 17 // ----------------------------------------------------------------------------
32 18
33 ChromeAppCacheService::ChromeAppCacheService( 19 ChromeAppCacheService::ChromeAppCacheService(
34 quota::QuotaManagerProxy* quota_manager_proxy) 20 quota::QuotaManagerProxy* quota_manager_proxy)
35 : AppCacheService(quota_manager_proxy), 21 : AppCacheService(quota_manager_proxy),
36 resource_context_(NULL), clear_local_state_on_exit_(false) { 22 resource_context_(NULL), clear_appcache_helper_(NULL),
23 ALLOW_THIS_IN_INITIALIZER_LIST(appcache_got_info_callback_(
24 this, &ChromeAppCacheService::OnGotAppCacheInfo)),
25 ALLOW_THIS_IN_INITIALIZER_LIST(appcache_deleted_callback_(
26 this, &ChromeAppCacheService::OnAppCacheDeleted)),
27 appcaches_to_be_deleted_count_(0),
28 appcaches_cleared_event_(new base::WaitableEvent(true, false)) {
37 } 29 }
38 30
39 void ChromeAppCacheService::InitializeOnIOThread( 31 void ChromeAppCacheService::InitializeOnIOThread(
40 const FilePath& cache_path, 32 const FilePath& cache_path,
41 const content::ResourceContext* resource_context, 33 const content::ResourceContext* resource_context,
42 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy, 34 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy) {
43 bool clear_local_state_on_exit) {
44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
45 36
46 if (!has_initialized_thread_ids) { 37 if (!has_initialized_thread_ids) {
47 has_initialized_thread_ids = true; 38 has_initialized_thread_ids = true;
48 appcache::AppCacheThread::Init(BrowserThread::DB, BrowserThread::IO); 39 appcache::AppCacheThread::Init(BrowserThread::DB, BrowserThread::IO);
49 } 40 }
50 41
51 cache_path_ = cache_path; 42 cache_path_ = cache_path;
52 resource_context_ = resource_context; 43 resource_context_ = resource_context;
53 registrar_.Add( 44 registrar_.Add(
54 this, NotificationType::PURGE_MEMORY, NotificationService::AllSources()); 45 this, NotificationType::PURGE_MEMORY, NotificationService::AllSources());
55 SetClearLocalStateOnExit(clear_local_state_on_exit);
56 46
57 // Init our base class. 47 // Init our base class.
58 Initialize(cache_path_, 48 Initialize(cache_path_,
59 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); 49 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
60 set_appcache_policy(this); 50 set_appcache_policy(this);
61 set_special_storage_policy(special_storage_policy); 51 set_special_storage_policy(special_storage_policy);
62 } 52 }
63 53
64 ChromeAppCacheService::~ChromeAppCacheService() { 54 ChromeAppCacheService::~ChromeAppCacheService() {
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
66
67 if (clear_local_state_on_exit_ && !cache_path_.empty()) {
68 BrowserThread::PostTask(
69 BrowserThread::IO, FROM_HERE,
70 NewRunnableFunction(DeleteLocalStateOnIOThread, cache_path_));
71 }
72 } 55 }
73 56
74 void ChromeAppCacheService::SetClearLocalStateOnExit(bool clear_local_state) { 57 base::WaitableEvent* ChromeAppCacheService::ClearAppCache(
75 // TODO(michaeln): How is 'protected' status granted to apps in this case? 58 net::CompletionCallback* callback)
59 {
76 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 60 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
77 BrowserThread::PostTask( 61 BrowserThread::PostTask(
78 BrowserThread::IO, FROM_HERE, 62 BrowserThread::IO, FROM_HERE,
79 NewRunnableMethod(this, 63 NewRunnableMethod(this,
80 &ChromeAppCacheService::SetClearLocalStateOnExit, 64 &ChromeAppCacheService::ClearAppCache,
81 clear_local_state)); 65 callback));
82 return; 66 return appcaches_cleared_event_.get();
83 } 67 }
84 clear_local_state_on_exit_ = clear_local_state; 68
69 // FIXME: should we handle multiple simultaneous deletions better?
70 if (clear_appcache_helper_)
71 return appcaches_cleared_event_.get();
72
73 appcaches_cleared_event_->Reset();
74 // ClearAppCacheHelper keeps this ChromeAppCacheService alive until the
75 // deletion is done, even if other objects drop their references.
76 clear_appcache_helper_ = new ClearAppcacheHelper(this, callback);
jochen (gone - plz use gerrit) 2011/07/06 09:41:45 you could just this->Ref(); and Deref() later, no
marja(google) 2011/07/06 14:34:09 Done.
marja(google) 2011/07/13 11:06:59 Done.
77
78 appcache_info_ = new appcache::AppCacheInfoCollection;
79 GetAllAppCacheInfo(
80 appcache_info_, &appcache_got_info_callback_);
81 // continues in OnGotAppCacheInfo
82
83 return appcaches_cleared_event_.get();
84 }
85
86 void ChromeAppCacheService::OnGotAppCacheInfo(int rv) {
87 using appcache::AppCacheInfoVector;
88 typedef std::map<GURL, AppCacheInfoVector> InfoByOrigin;
89
90 appcaches_to_be_deleted_count_ = 0;
91 for (InfoByOrigin::const_iterator origin =
92 appcache_info_->infos_by_origin.begin();
93 origin != appcache_info_->infos_by_origin.end(); ++origin) {
94
95 if (special_storage_policy_->IsStorageProtected(origin->first))
96 continue;
97
98 ++appcaches_to_be_deleted_count_;
michaeln 2011/07/02 00:29:09 maybe origins_to_be_deleted_count_
marja(google) 2011/07/06 14:34:09 Done.
marja(google) 2011/07/13 11:06:59 I had changed this, but changed it back because of
99 DeleteAppCachesForOrigin(origin->first, &appcache_deleted_callback_);
michaeln 2011/07/02 00:29:09 maybe origin_deleted_callback_
marja(google) 2011/07/06 14:34:09 Done.
marja(google) 2011/07/13 11:06:59 Same here.
100 }
101
102 if (appcaches_to_be_deleted_count_ == 0)
103 clear_appcache_helper_->OnClearedAppCache();
104 // else continues in OnAppCacheDeleted
105 }
106
107 void ChromeAppCacheService::OnAppCacheDeleted(int rv) {
108 --appcaches_to_be_deleted_count_;
109 if (appcaches_to_be_deleted_count_ == 0)
110 clear_appcache_helper_->OnClearedAppCache();
85 } 111 }
86 112
87 bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) { 113 bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
89 // We don't prompt for read access. 115 // We don't prompt for read access.
90 return content::GetContentClient()->browser()->AllowAppCache( 116 return content::GetContentClient()->browser()->AllowAppCache(
91 manifest_url, *resource_context_); 117 manifest_url, *resource_context_);
92 } 118 }
93 119
94 int ChromeAppCacheService::CanCreateAppCache( 120 int ChromeAppCacheService::CanCreateAppCache(
95 const GURL& manifest_url, net::CompletionCallback* callback) { 121 const GURL& manifest_url, net::CompletionCallback* callback) {
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
97 return content::GetContentClient()->browser()->AllowAppCache( 123 return content::GetContentClient()->browser()->AllowAppCache(
98 manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED; 124 manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED;
99 } 125 }
100 126
101 void ChromeAppCacheService::Observe(NotificationType type, 127 void ChromeAppCacheService::Observe(NotificationType type,
102 const NotificationSource& source, 128 const NotificationSource& source,
103 const NotificationDetails& details) { 129 const NotificationDetails& details) {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
105 DCHECK(type == NotificationType::PURGE_MEMORY); 131 DCHECK(type == NotificationType::PURGE_MEMORY);
106 PurgeMemory(); 132 PurgeMemory();
107 } 133 }
108 134
109 // ---------------------------------------------------------------------------- 135 // ----------------------------------------------------------------------------
110 136
137 ChromeAppCacheService::ClearAppcacheHelper::ClearAppcacheHelper(
138 ChromeAppCacheService* parent, net::CompletionCallback* callback)
139 : parent_(parent), callback_(callback)
140 {
michaeln 2011/07/02 00:29:09 style: bracket belongs at the end of the previous
marja(google) 2011/07/06 14:34:09 Done.
141 }
142
143 ChromeAppCacheService::ClearAppcacheHelper::~ClearAppcacheHelper()
144 {
michaeln 2011/07/02 00:29:09 style: ditto
marja(google) 2011/07/06 14:34:09 Done.
145 }
146
147 void ChromeAppCacheService::ClearAppcacheHelper::OnClearedAppCache()
michaeln 2011/07/02 00:29:09 This class seems heavier weight than it needs to b
marja(google) 2011/07/06 14:34:09 Done.
148 {
149 parent_->appcaches_cleared_event_->Signal();
150 parent_->clear_appcache_helper_ = NULL;
151 if (callback_) {
152 callback_->Run(0);
153 }
154 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
155 }
156
157
158 // ----------------------------------------------------------------------------
159
111 static BrowserThread::ID ToBrowserThreadID(int id) { 160 static BrowserThread::ID ToBrowserThreadID(int id) {
112 DCHECK(has_initialized_thread_ids); 161 DCHECK(has_initialized_thread_ids);
113 DCHECK(id == BrowserThread::DB || id == BrowserThread::IO); 162 DCHECK(id == BrowserThread::DB || id == BrowserThread::IO);
114 return static_cast<BrowserThread::ID>(id); 163 return static_cast<BrowserThread::ID>(id);
115 } 164 }
116 165
117 namespace appcache { 166 namespace appcache {
118 167
119 // An impl of AppCacheThread we need to provide to the appcache lib. 168 // An impl of AppCacheThread we need to provide to the appcache lib.
120 169
121 bool AppCacheThread::PostTask( 170 bool AppCacheThread::PostTask(
122 int id, 171 int id,
123 const tracked_objects::Location& from_here, 172 const tracked_objects::Location& from_here,
124 Task* task) { 173 Task* task) {
125 return BrowserThread::PostTask(ToBrowserThreadID(id), from_here, task); 174 return BrowserThread::PostTask(ToBrowserThreadID(id), from_here, task);
126 } 175 }
127 176
128 bool AppCacheThread::CurrentlyOn(int id) { 177 bool AppCacheThread::CurrentlyOn(int id) {
129 return BrowserThread::CurrentlyOn(ToBrowserThreadID(id)); 178 return BrowserThread::CurrentlyOn(ToBrowserThreadID(id));
130 } 179 }
131 180
132 } // namespace appcache 181 } // namespace appcache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698