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

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: Minor. 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));
83 return; 70 return appcaches_cleared_event_.get();
84 } 71 }
85 clear_local_state_on_exit_ = clear_local_state; 72 // Only one appcache deletion should be in progress at any given time.
73 DCHECK(waiting_for_clear_appcaches_ == false);
74 waiting_for_clear_appcaches_ = true;
75 appcaches_cleared_callback_ = callback;
76 appcaches_cleared_event_->Reset();
77
78 // Keep the ChromeAppCacheService instance alive until the deletion has
79 // finished.
80 AddRef();
81
82 appcache_info_ = new appcache::AppCacheInfoCollection;
83 GetAllAppCacheInfo(
84 appcache_info_, &appcache_got_info_callback_);
85 // Continues in OnGotAppCacheInfo.
86
87 return appcaches_cleared_event_.get();
86 } 88 }
87 89
88 bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) { 90 bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
90 // We don't prompt for read access. 92 // We don't prompt for read access.
91 return content::GetContentClient()->browser()->AllowAppCache( 93 return content::GetContentClient()->browser()->AllowAppCache(
92 manifest_url, *resource_context_); 94 manifest_url, *resource_context_);
93 } 95 }
94 96
95 int ChromeAppCacheService::CanCreateAppCache( 97 int ChromeAppCacheService::CanCreateAppCache(
96 const GURL& manifest_url, net::CompletionCallback* callback) { 98 const GURL& manifest_url, net::CompletionCallback* callback) {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
98 return content::GetContentClient()->browser()->AllowAppCache( 100 return content::GetContentClient()->browser()->AllowAppCache(
99 manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED; 101 manifest_url, *resource_context_) ? net::OK : net::ERR_ACCESS_DENIED;
100 } 102 }
101 103
102 void ChromeAppCacheService::Observe(int type, 104 void ChromeAppCacheService::Observe(int type,
103 const NotificationSource& source, 105 const NotificationSource& source,
104 const NotificationDetails& details) { 106 const NotificationDetails& details) {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
106 DCHECK(type == content::NOTIFICATION_PURGE_MEMORY); 108 DCHECK(type == content::NOTIFICATION_PURGE_MEMORY);
107 PurgeMemory(); 109 PurgeMemory();
108 } 110 }
109 111
112 void ChromeAppCacheService::OnGotAppCacheInfo(int rv) {
113 typedef std::map<GURL, appcache::AppCacheInfoVector> InfoByOrigin;
114
115 appcaches_to_be_deleted_count_ = 0;
116 for (InfoByOrigin::const_iterator origin =
117 appcache_info_->infos_by_origin.begin();
118 origin != appcache_info_->infos_by_origin.end(); ++origin) {
119
120 if (special_storage_policy_->IsStorageProtected(origin->first))
121 continue;
122
123 appcache::AppCacheInfoVector::const_iterator info;
124 for (info = origin->second.begin(); info != origin->second.end(); ++info) {
125 ++appcaches_to_be_deleted_count_;
126 DeleteAppCacheGroup(info->manifest_url, &appcache_deleted_callback_);
127 }
128 }
129
130 if (appcaches_to_be_deleted_count_ == 0)
131 OnClearedAppCache();
132 // Else continues in OnAppCacheDeleted.
133 }
134
135 void ChromeAppCacheService::OnAppCacheDeleted(int rv) {
136 --appcaches_to_be_deleted_count_;
137 if (appcaches_to_be_deleted_count_ == 0)
138 OnClearedAppCache();
139 }
140
141 void ChromeAppCacheService::OnClearedAppCache() {
142 appcaches_cleared_event_->Signal();
143 if (appcaches_cleared_callback_) {
144 appcaches_cleared_callback_->Run(0);
145 }
146 waiting_for_clear_appcaches_ = false;
147 Release();
148 }
149
110 // ---------------------------------------------------------------------------- 150 // ----------------------------------------------------------------------------
111 151
112 static BrowserThread::ID ToBrowserThreadID(int id) { 152 static BrowserThread::ID ToBrowserThreadID(int id) {
113 DCHECK(has_initialized_thread_ids); 153 DCHECK(has_initialized_thread_ids);
114 DCHECK(id == BrowserThread::DB || id == BrowserThread::IO); 154 DCHECK(id == BrowserThread::DB || id == BrowserThread::IO);
115 return static_cast<BrowserThread::ID>(id); 155 return static_cast<BrowserThread::ID>(id);
116 } 156 }
117 157
118 namespace appcache { 158 namespace appcache {
119 159
120 // An impl of AppCacheThread we need to provide to the appcache lib. 160 // An impl of AppCacheThread we need to provide to the appcache lib.
121 161
122 bool AppCacheThread::PostTask( 162 bool AppCacheThread::PostTask(
123 int id, 163 int id,
124 const tracked_objects::Location& from_here, 164 const tracked_objects::Location& from_here,
125 Task* task) { 165 Task* task) {
126 return BrowserThread::PostTask(ToBrowserThreadID(id), from_here, task); 166 return BrowserThread::PostTask(ToBrowserThreadID(id), from_here, task);
127 } 167 }
128 168
129 bool AppCacheThread::CurrentlyOn(int id) { 169 bool AppCacheThread::CurrentlyOn(int id) {
130 return BrowserThread::CurrentlyOn(ToBrowserThreadID(id)); 170 return BrowserThread::CurrentlyOn(ToBrowserThreadID(id));
131 } 171 }
132 172
133 } // namespace appcache 173 } // namespace appcache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698