1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "storage/browser/database/database_quota_client.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/bind_helpers.h" 11 #include "base/location.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/message_loop/message_loop_proxy.h" 14 #include "base/task_runner_util.h" 15 #include "net/base/net_errors.h" 16 #include "net/base/net_util.h" 17 #include "storage/browser/database/database_tracker.h" 18 #include "storage/browser/database/database_util.h" 19 #include "storage/common/database/database_identifier.h" 20 21 using storage::QuotaClient; 22 23 namespace storage { 24 25 namespace { 26 27 int64 GetOriginUsageOnDBThread( 28 DatabaseTracker* db_tracker, 29 const GURL& origin_url) { 30 OriginInfo info; 31 if (db_tracker->GetOriginInfo(storage::GetIdentifierFromOrigin(origin_url), 32 &info)) 33 return info.TotalSize(); 34 return 0; 35 } 36 37 void GetOriginsOnDBThread( 38 DatabaseTracker* db_tracker, 39 std::set<GURL>* origins_ptr) { 40 std::vector<std::string> origin_identifiers; 41 if (db_tracker->GetAllOriginIdentifiers(&origin_identifiers)) { 42 for (std::vector<std::string>::const_iterator iter = 43 origin_identifiers.begin(); 44 iter != origin_identifiers.end(); ++iter) { 45 GURL origin = storage::GetOriginFromIdentifier(*iter); 46 origins_ptr->insert(origin); 47 } 48 } 49 } 50 51 void GetOriginsForHostOnDBThread( 52 DatabaseTracker* db_tracker, 53 std::set<GURL>* origins_ptr, 54 const std::string& host) { 55 std::vector<std::string> origin_identifiers; 56 if (db_tracker->GetAllOriginIdentifiers(&origin_identifiers)) { 57 for (std::vector<std::string>::const_iterator iter = 58 origin_identifiers.begin(); 59 iter != origin_identifiers.end(); ++iter) { 60 GURL origin = storage::GetOriginFromIdentifier(*iter); 61 if (host == net::GetHostOrSpecFromURL(origin)) 62 origins_ptr->insert(origin); 63 } 64 } 65 } 66 67 void DidGetOrigins( 68 const QuotaClient::GetOriginsCallback& callback, 69 std::set<GURL>* origins_ptr) { 70 callback.Run(*origins_ptr); 71 } 72 73 void DidDeleteOriginData( 74 base::SingleThreadTaskRunner* original_task_runner, 75 const QuotaClient::DeletionCallback& callback, 76 int result) { 77 if (result == net::ERR_IO_PENDING) { 78 // The callback will be invoked via 79 // DatabaseTracker::ScheduleDatabasesForDeletion. 80 return; 81 } 82 83 storage::QuotaStatusCode status; 84 if (result == net::OK) 85 status = storage::kQuotaStatusOk; 86 else 87 status = storage::kQuotaStatusUnknown; 88 89 if (original_task_runner->BelongsToCurrentThread()) 90 callback.Run(status); 91 else 92 original_task_runner->PostTask(FROM_HERE, base::Bind(callback, status)); 93 } 94 95 } // namespace 96 97 DatabaseQuotaClient::DatabaseQuotaClient( 98 base::MessageLoopProxy* db_tracker_thread, 99 DatabaseTracker* db_tracker) 100 : db_tracker_thread_(db_tracker_thread), db_tracker_(db_tracker) { 101 } 102 103 DatabaseQuotaClient::~DatabaseQuotaClient() { 104 if (db_tracker_thread_.get() && 105 !db_tracker_thread_->RunsTasksOnCurrentThread() && db_tracker_.get()) { 106 DatabaseTracker* tracker = db_tracker_.get(); 107 tracker->AddRef(); 108 db_tracker_ = NULL; 109 if (!db_tracker_thread_->ReleaseSoon(FROM_HERE, tracker)) 110 tracker->Release(); 111 } 112 } 113 114 QuotaClient::ID DatabaseQuotaClient::id() const { 115 return kDatabase; 116 } 117 118 void DatabaseQuotaClient::OnQuotaManagerDestroyed() { 119 delete this; 120 } 121 122 void DatabaseQuotaClient::GetOriginUsage(const GURL& origin_url, 123 storage::StorageType type, 124 const GetUsageCallback& callback) { 125 DCHECK(!callback.is_null()); 126 DCHECK(db_tracker_.get()); 127 128 // All databases are in the temp namespace for now. 129 if (type != storage::kStorageTypeTemporary) { 130 callback.Run(0); 131 return; 132 } 133 134 base::PostTaskAndReplyWithResult( 135 db_tracker_thread_.get(), 136 FROM_HERE, 137 base::Bind(&GetOriginUsageOnDBThread, db_tracker_, origin_url), 138 callback); 139 } 140 141 void DatabaseQuotaClient::GetOriginsForType( 142 storage::StorageType type, 143 const GetOriginsCallback& callback) { 144 DCHECK(!callback.is_null()); 145 DCHECK(db_tracker_.get()); 146 147 // All databases are in the temp namespace for now. 148 if (type != storage::kStorageTypeTemporary) { 149 callback.Run(std::set<GURL>()); 150 return; 151 } 152 153 std::set<GURL>* origins_ptr = new std::set<GURL>(); 154 db_tracker_thread_->PostTaskAndReply( 155 FROM_HERE, 156 base::Bind(&GetOriginsOnDBThread, 157 db_tracker_, 158 base::Unretained(origins_ptr)), 159 base::Bind(&DidGetOrigins, 160 callback, 161 base::Owned(origins_ptr))); 162 } 163 164 void DatabaseQuotaClient::GetOriginsForHost( 165 storage::StorageType type, 166 const std::string& host, 167 const GetOriginsCallback& callback) { 168 DCHECK(!callback.is_null()); 169 DCHECK(db_tracker_.get()); 170 171 // All databases are in the temp namespace for now. 172 if (type != storage::kStorageTypeTemporary) { 173 callback.Run(std::set<GURL>()); 174 return; 175 } 176 177 std::set<GURL>* origins_ptr = new std::set<GURL>(); 178 db_tracker_thread_->PostTaskAndReply( 179 FROM_HERE, 180 base::Bind(&GetOriginsForHostOnDBThread, 181 db_tracker_, 182 base::Unretained(origins_ptr), 183 host), 184 base::Bind(&DidGetOrigins, 185 callback, 186 base::Owned(origins_ptr))); 187 } 188 189 void DatabaseQuotaClient::DeleteOriginData(const GURL& origin, 190 storage::StorageType type, 191 const DeletionCallback& callback) { 192 DCHECK(!callback.is_null()); 193 DCHECK(db_tracker_.get()); 194 195 // All databases are in the temp namespace for now, so nothing to delete. 196 if (type != storage::kStorageTypeTemporary) { 197 callback.Run(storage::kQuotaStatusOk); 198 return; 199 } 200 201 base::Callback<void(int)> delete_callback = 202 base::Bind(&DidDeleteOriginData, 203 base::MessageLoopProxy::current(), 204 callback); 205 206 PostTaskAndReplyWithResult( 207 db_tracker_thread_.get(), 208 FROM_HERE, 209 base::Bind(&DatabaseTracker::DeleteDataForOrigin, 210 db_tracker_, 211 storage::GetIdentifierFromOrigin(origin), 212 delete_callback), 213 delete_callback); 214 } 215 216 bool DatabaseQuotaClient::DoesSupport(storage::StorageType type) const { 217 return type == storage::kStorageTypeTemporary; 218 } 219 220 } // namespace storage 221