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

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: Test beautification. 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_interfaces.h"
12 #include "webkit/appcache/appcache_thread.h" 13 #include "webkit/appcache/appcache_thread.h"
13 #include "webkit/quota/quota_manager.h" 14 #include "webkit/quota/quota_manager.h"
14 15
15 static bool has_initialized_thread_ids; 16 static bool has_initialized_thread_ids;
16 17
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 // ---------------------------------------------------------------------------- 18 // ----------------------------------------------------------------------------
32 19
33 ChromeAppCacheService::ChromeAppCacheService( 20 ChromeAppCacheService::ChromeAppCacheService(
34 quota::QuotaManagerProxy* quota_manager_proxy) 21 quota::QuotaManagerProxy* quota_manager_proxy)
35 : AppCacheService(quota_manager_proxy), 22 : AppCacheService(quota_manager_proxy),
36 resource_context_(NULL), clear_local_state_on_exit_(false) { 23 resource_context_(NULL),
24 ALLOW_THIS_IN_INITIALIZER_LIST(appcache_got_info_callback_(
25 this, &ChromeAppCacheService::OnGotAppCacheInfo)),
26 ALLOW_THIS_IN_INITIALIZER_LIST(appcache_deleted_callback_(
27 this, &ChromeAppCacheService::OnAppCacheDeleted)),
28 appcaches_to_be_deleted_count_(0),
29 appcaches_cleared_event_(new base::WaitableEvent(true, false)),
30 appcaches_cleared_callback_(NULL),
31 waiting_for_clear_appcaches_(false) {
37 } 32 }
38 33
39 void ChromeAppCacheService::InitializeOnIOThread( 34 void ChromeAppCacheService::InitializeOnIOThread(
40 const FilePath& cache_path, 35 const FilePath& cache_path,
41 const content::ResourceContext* resource_context, 36 const content::ResourceContext* resource_context,
42 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy, 37 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy) {
43 bool clear_local_state_on_exit) {
44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
45 39
46 if (!has_initialized_thread_ids) { 40 if (!has_initialized_thread_ids) {
47 has_initialized_thread_ids = true; 41 has_initialized_thread_ids = true;
48 appcache::AppCacheThread::Init(BrowserThread::DB, BrowserThread::IO); 42 appcache::AppCacheThread::Init(BrowserThread::DB, BrowserThread::IO);
49 } 43 }
50 44
51 cache_path_ = cache_path; 45 cache_path_ = cache_path;
52 resource_context_ = resource_context; 46 resource_context_ = resource_context;
53 registrar_.Add( 47 registrar_.Add(
54 this, content::NOTIFICATION_PURGE_MEMORY, 48 this, content::NOTIFICATION_PURGE_MEMORY,
55 NotificationService::AllSources()); 49 NotificationService::AllSources());
56 SetClearLocalStateOnExit(clear_local_state_on_exit);
57 50
58 // Init our base class. 51 // Init our base class.
59 Initialize(cache_path_, 52 Initialize(cache_path_,
60 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); 53 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
61 set_appcache_policy(this); 54 set_appcache_policy(this);
62 set_special_storage_policy(special_storage_policy); 55 set_special_storage_policy(special_storage_policy);
63 } 56 }
64 57
65 ChromeAppCacheService::~ChromeAppCacheService() { 58 ChromeAppCacheService::~ChromeAppCacheService() {
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
67
68 if (clear_local_state_on_exit_ && !cache_path_.empty()) {
69 BrowserThread::PostTask(
70 BrowserThread::IO, FROM_HERE,
71 NewRunnableFunction(DeleteLocalStateOnIOThread, cache_path_));
72 }
73 } 59 }
74 60
75 void ChromeAppCacheService::SetClearLocalStateOnExit(bool clear_local_state) { 61 base::WaitableEvent* ChromeAppCacheService::ClearAppCache(
76 // TODO(michaeln): How is 'protected' status granted to apps in this case? 62 net::CompletionCallback* callback)
63 {
77 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 64 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
78 BrowserThread::PostTask( 65 BrowserThread::PostTask(
79 BrowserThread::IO, FROM_HERE, 66 BrowserThread::IO, FROM_HERE,
80 NewRunnableMethod(this, 67 NewRunnableMethod(this,
81 &ChromeAppCacheService::SetClearLocalStateOnExit, 68 &ChromeAppCacheService::ClearAppCache,
82 clear_local_state)); 69 callback));
70 return appcaches_cleared_event_.get();
71 }
72 // Only one appcache deletion (async or sync) should be in progress at any
73 // given time.
74 DCHECK(waiting_for_clear_appcaches_ == false);
75 waiting_for_clear_appcaches_ = true;
76 appcaches_cleared_callback_ = callback;
77 appcaches_cleared_event_->Reset();
78
79 // Keep the ChromeAppCacheService instance alive until the deletion has
80 // finished.
81 AddRef();
82
83 appcache_info_ = new appcache::AppCacheInfoCollection;
84 GetAllAppCacheInfo(
85 appcache_info_, &appcache_got_info_callback_);
86 // Continues in OnGotAppCacheInfo.
87
88 return appcaches_cleared_event_.get();
89 }
90
91 void ChromeAppCacheService::SyncClearAppCacheOnIOThread() {
92 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
93 BrowserThread::PostTask(
94 BrowserThread::IO, FROM_HERE,
95 NewRunnableMethod(this,
96 &ChromeAppCacheService::SyncClearAppCacheOnIOThread));
83 return; 97 return;
84 } 98 }
85 clear_local_state_on_exit_ = clear_local_state; 99
100 // Only one appcache deletion (async or sync) should be in progress at any
101 // given time.
102 DCHECK(waiting_for_clear_appcaches_ == false);
103 waiting_for_clear_appcaches_ = true;
104
105 appcache_info_ = new appcache::AppCacheInfoCollection;
106 SyncGetAllAppCacheInfo(appcache_info_);
107
108 typedef std::map<GURL, appcache::AppCacheInfoVector> InfoByOrigin;
109 for (InfoByOrigin::const_iterator origin =
110 appcache_info_->infos_by_origin.begin();
111 origin != appcache_info_->infos_by_origin.end(); ++origin) {
112 if (special_storage_policy_->IsStorageProtected(origin->first))
113 continue;
114 appcache::AppCacheInfoVector::const_iterator info;
115 for (info = origin->second.begin(); info != origin->second.end(); ++info) {
116 SyncDeleteAppCacheGroup(info->manifest_url);
117 }
118 }
119 waiting_for_clear_appcaches_ = false;
120 appcache_info_ = NULL;
86 } 121 }
87 122
88 bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) { 123 bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
90 // We don't prompt for read access. 125 // We don't prompt for read access.
91 return content::GetContentClient()->browser()->AllowAppCache( 126 return content::GetContentClient()->browser()->AllowAppCache(
92 manifest_url, *resource_context_); 127 manifest_url, *resource_context_);
93 } 128 }
94 129
95 int ChromeAppCacheService::CanCreateAppCache( 130 int ChromeAppCacheService::CanCreateAppCache(
96 const GURL& manifest_url, net::CompletionCallback* callback) { 131 const GURL& manifest_url, net::CompletionCallback* callback) {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
98 return content::GetContentClient()->browser()->AllowAppCache( 133 return content::GetContentClient()->browser()->AllowAppCache(
99 manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED; 134 manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED;
100 } 135 }
101 136
102 void ChromeAppCacheService::Observe(int type, 137 void ChromeAppCacheService::Observe(int type,
103 const NotificationSource& source, 138 const NotificationSource& source,
104 const NotificationDetails& details) { 139 const NotificationDetails& details) {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
106 DCHECK(type == content::NOTIFICATION_PURGE_MEMORY); 141 DCHECK(type == content::NOTIFICATION_PURGE_MEMORY);
107 PurgeMemory(); 142 PurgeMemory();
108 } 143 }
109 144
145 void ChromeAppCacheService::OnGotAppCacheInfo(int rv) {
146 typedef std::map<GURL, appcache::AppCacheInfoVector> InfoByOrigin;
147
148 appcaches_to_be_deleted_count_ = 0;
149 for (InfoByOrigin::const_iterator origin =
150 appcache_info_->infos_by_origin.begin();
151 origin != appcache_info_->infos_by_origin.end(); ++origin) {
152
153 if (special_storage_policy_->IsStorageProtected(origin->first))
154 continue;
155
156 appcache::AppCacheInfoVector::const_iterator info;
157 for (info = origin->second.begin(); info != origin->second.end(); ++info) {
158 ++appcaches_to_be_deleted_count_;
159 DeleteAppCacheGroup(info->manifest_url, &appcache_deleted_callback_);
160 }
161 }
162
163 if (appcaches_to_be_deleted_count_ == 0)
164 OnClearedAppCache();
165 // Else continues in OnAppCacheDeleted.
166 }
167
168 void ChromeAppCacheService::OnAppCacheDeleted(int rv) {
169 --appcaches_to_be_deleted_count_;
170 if (appcaches_to_be_deleted_count_ == 0)
171 OnClearedAppCache();
172 }
173
174 void ChromeAppCacheService::OnClearedAppCache() {
175 appcaches_cleared_event_->Signal();
176 if (appcaches_cleared_callback_) {
177 appcaches_cleared_callback_->Run(0);
178 }
179 waiting_for_clear_appcaches_ = false;
180 Release();
181 }
182
110 // ---------------------------------------------------------------------------- 183 // ----------------------------------------------------------------------------
111 184
112 static BrowserThread::ID ToBrowserThreadID(int id) { 185 static BrowserThread::ID ToBrowserThreadID(int id) {
113 DCHECK(has_initialized_thread_ids); 186 DCHECK(has_initialized_thread_ids);
114 DCHECK(id == BrowserThread::DB || id == BrowserThread::IO); 187 DCHECK(id == BrowserThread::DB || id == BrowserThread::IO);
115 return static_cast<BrowserThread::ID>(id); 188 return static_cast<BrowserThread::ID>(id);
116 } 189 }
117 190
118 namespace appcache { 191 namespace appcache {
119 192
120 // An impl of AppCacheThread we need to provide to the appcache lib. 193 // An impl of AppCacheThread we need to provide to the appcache lib.
121 194
122 bool AppCacheThread::PostTask( 195 bool AppCacheThread::PostTask(
123 int id, 196 int id,
124 const tracked_objects::Location& from_here, 197 const tracked_objects::Location& from_here,
125 Task* task) { 198 Task* task) {
126 return BrowserThread::PostTask(ToBrowserThreadID(id), from_here, task); 199 return BrowserThread::PostTask(ToBrowserThreadID(id), from_here, task);
127 } 200 }
128 201
129 bool AppCacheThread::CurrentlyOn(int id) { 202 bool AppCacheThread::CurrentlyOn(int id) {
130 return BrowserThread::CurrentlyOn(ToBrowserThreadID(id)); 203 return BrowserThread::CurrentlyOn(ToBrowserThreadID(id));
131 } 204 }
132 205
133 } // namespace appcache 206 } // namespace appcache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698