1 // Copyright 2013 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 "webkit/browser/quota/mock_storage_client.h" 6 7 #include "base/basictypes.h" 8 #include "base/bind.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/singleton.h" 11 #include "base/message_loop/message_loop_proxy.h" 12 #include "base/stl_util.h" 13 #include "net/base/net_util.h" 14 #include "webkit/browser/quota/quota_manager.h" 15 16 namespace quota { 17 18 using std::make_pair; 19 20 MockStorageClient::MockStorageClient( 21 QuotaManagerProxy* quota_manager_proxy, 22 const MockOriginData* mock_data, QuotaClient::ID id, size_t mock_data_size) 23 : quota_manager_proxy_(quota_manager_proxy), 24 id_(id), 25 mock_time_counter_(0), 26 weak_factory_(this) { 27 Populate(mock_data, mock_data_size); 28 } 29 30 void MockStorageClient::Populate( 31 const MockOriginData* mock_data, 32 size_t mock_data_size) { 33 for (size_t i = 0; i < mock_data_size; ++i) { 34 origin_data_[make_pair(GURL(mock_data[i].origin), mock_data[i].type)] = 35 mock_data[i].usage; 36 } 37 } 38 39 MockStorageClient::~MockStorageClient() {} 40 41 void MockStorageClient::AddOriginAndNotify( 42 const GURL& origin_url, StorageType type, int64 size) { 43 DCHECK(origin_data_.find(make_pair(origin_url, type)) == origin_data_.end()); 44 DCHECK_GE(size, 0); 45 origin_data_[make_pair(origin_url, type)] = size; 46 quota_manager_proxy_->quota_manager()->NotifyStorageModifiedInternal( 47 id(), origin_url, type, size, IncrementMockTime()); 48 } 49 50 void MockStorageClient::ModifyOriginAndNotify( 51 const GURL& origin_url, StorageType type, int64 delta) { 52 OriginDataMap::iterator find = origin_data_.find(make_pair(origin_url, type)); 53 DCHECK(find != origin_data_.end()); 54 find->second += delta; 55 DCHECK_GE(find->second, 0); 56 57 // TODO(tzik): Check quota to prevent usage exceed 58 quota_manager_proxy_->quota_manager()->NotifyStorageModifiedInternal( 59 id(), origin_url, type, delta, IncrementMockTime()); 60 } 61 62 void MockStorageClient::TouchAllOriginsAndNotify() { 63 for (OriginDataMap::const_iterator itr = origin_data_.begin(); 64 itr != origin_data_.end(); 65 ++itr) { 66 quota_manager_proxy_->quota_manager()->NotifyStorageModifiedInternal( 67 id(), itr->first.first, itr->first.second, 0, IncrementMockTime()); 68 } 69 } 70 71 void MockStorageClient::AddOriginToErrorSet( 72 const GURL& origin_url, StorageType type) { 73 error_origins_.insert(make_pair(origin_url, type)); 74 } 75 76 base::Time MockStorageClient::IncrementMockTime() { 77 ++mock_time_counter_; 78 return base::Time::FromDoubleT(mock_time_counter_ * 10.0); 79 } 80 81 QuotaClient::ID MockStorageClient::id() const { 82 return id_; 83 } 84 85 void MockStorageClient::OnQuotaManagerDestroyed() { 86 delete this; 87 } 88 89 void MockStorageClient::GetOriginUsage(const GURL& origin_url, 90 StorageType type, 91 const GetUsageCallback& callback) { 92 base::MessageLoopProxy::current()->PostTask( 93 FROM_HERE, 94 base::Bind(&MockStorageClient::RunGetOriginUsage, 95 weak_factory_.GetWeakPtr(), origin_url, type, callback)); 96 } 97 98 void MockStorageClient::GetOriginsForType( 99 StorageType type, const GetOriginsCallback& callback) { 100 base::MessageLoopProxy::current()->PostTask( 101 FROM_HERE, 102 base::Bind(&MockStorageClient::RunGetOriginsForType, 103 weak_factory_.GetWeakPtr(), type, callback)); 104 } 105 106 void MockStorageClient::GetOriginsForHost( 107 StorageType type, const std::string& host, 108 const GetOriginsCallback& callback) { 109 base::MessageLoopProxy::current()->PostTask( 110 FROM_HERE, 111 base::Bind(&MockStorageClient::RunGetOriginsForHost, 112 weak_factory_.GetWeakPtr(), type, host, callback)); 113 } 114 115 void MockStorageClient::DeleteOriginData( 116 const GURL& origin, StorageType type, 117 const DeletionCallback& callback) { 118 base::MessageLoopProxy::current()->PostTask( 119 FROM_HERE, 120 base::Bind(&MockStorageClient::RunDeleteOriginData, 121 weak_factory_.GetWeakPtr(), origin, type, callback)); 122 } 123 124 bool MockStorageClient::DoesSupport(quota::StorageType type) const { 125 return true; 126 } 127 128 void MockStorageClient::RunGetOriginUsage( 129 const GURL& origin_url, StorageType type, 130 const GetUsageCallback& callback) { 131 OriginDataMap::iterator find = origin_data_.find(make_pair(origin_url, type)); 132 if (find == origin_data_.end()) { 133 callback.Run(0); 134 } else { 135 callback.Run(find->second); 136 } 137 } 138 139 void MockStorageClient::RunGetOriginsForType( 140 StorageType type, const GetOriginsCallback& callback) { 141 std::set<GURL> origins; 142 for (OriginDataMap::iterator iter = origin_data_.begin(); 143 iter != origin_data_.end(); ++iter) { 144 if (type == iter->first.second) 145 origins.insert(iter->first.first); 146 } 147 callback.Run(origins); 148 } 149 150 void MockStorageClient::RunGetOriginsForHost( 151 StorageType type, const std::string& host, 152 const GetOriginsCallback& callback) { 153 std::set<GURL> origins; 154 for (OriginDataMap::iterator iter = origin_data_.begin(); 155 iter != origin_data_.end(); ++iter) { 156 std::string host_or_spec = net::GetHostOrSpecFromURL(iter->first.first); 157 if (type == iter->first.second && host == host_or_spec) 158 origins.insert(iter->first.first); 159 } 160 callback.Run(origins); 161 } 162 163 void MockStorageClient::RunDeleteOriginData( 164 const GURL& origin_url, 165 StorageType type, 166 const DeletionCallback& callback) { 167 ErrorOriginSet::iterator itr_error = 168 error_origins_.find(make_pair(origin_url, type)); 169 if (itr_error != error_origins_.end()) { 170 callback.Run(kQuotaErrorInvalidModification); 171 return; 172 } 173 174 OriginDataMap::iterator itr = 175 origin_data_.find(make_pair(origin_url, type)); 176 if (itr != origin_data_.end()) { 177 int64 delta = itr->second; 178 quota_manager_proxy_-> 179 NotifyStorageModified(id(), origin_url, type, -delta); 180 origin_data_.erase(itr); 181 } 182 183 callback.Run(kQuotaStatusOk); 184 } 185 186 } // namespace quota 187