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_quota_manager.h"
6
7#include <set>
8#include <string>
9#include <vector>
10
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/message_loop/message_loop.h"
14#include "base/single_thread_task_runner.h"
15#include "url/gurl.h"
16
17namespace quota {
18
19MockQuotaManager::OriginInfo::OriginInfo(
20    const GURL& origin,
21    StorageType type,
22    int quota_client_mask,
23    base::Time modified)
24    : origin(origin),
25      type(type),
26      quota_client_mask(quota_client_mask),
27      modified(modified) {
28}
29
30MockQuotaManager::OriginInfo::~OriginInfo() {}
31
32MockQuotaManager::StorageInfo::StorageInfo() : usage(0), quota(kint64max) {}
33MockQuotaManager::StorageInfo::~StorageInfo() {}
34
35// MockQuotaManager ----------------------------------------------------------
36
37MockQuotaManager::MockQuotaManager(
38    bool is_incognito,
39    const base::FilePath& profile_path,
40    base::SingleThreadTaskRunner* io_thread,
41    base::SequencedTaskRunner* db_thread,
42    SpecialStoragePolicy* special_storage_policy)
43    : QuotaManager(is_incognito, profile_path, io_thread, db_thread,
44        special_storage_policy),
45      weak_factory_(this) {
46}
47
48void MockQuotaManager::GetUsageAndQuota(
49    const GURL& origin,
50    quota::StorageType type,
51    const GetUsageAndQuotaCallback& callback) {
52  StorageInfo& info = usage_and_quota_map_[std::make_pair(origin, type)];
53  callback.Run(quota::kQuotaStatusOk, info.usage, info.quota);
54}
55
56void MockQuotaManager::SetQuota(const GURL& origin, StorageType type,
57                                int64 quota) {
58  usage_and_quota_map_[std::make_pair(origin, type)].quota = quota;
59}
60
61bool MockQuotaManager::AddOrigin(
62    const GURL& origin,
63    StorageType type,
64    int quota_client_mask,
65    base::Time modified) {
66  origins_.push_back(OriginInfo(origin, type, quota_client_mask, modified));
67  return true;
68}
69
70bool MockQuotaManager::OriginHasData(
71    const GURL& origin,
72    StorageType type,
73    QuotaClient::ID quota_client) const {
74  for (std::vector<OriginInfo>::const_iterator current = origins_.begin();
75       current != origins_.end();
76       ++current) {
77    if (current->origin == origin &&
78        current->type == type &&
79        current->quota_client_mask & quota_client)
80      return true;
81  }
82  return false;
83}
84
85void MockQuotaManager::GetOriginsModifiedSince(
86    StorageType type,
87    base::Time modified_since,
88    const GetOriginsCallback& callback) {
89  std::set<GURL>* origins_to_return = new std::set<GURL>();
90  for (std::vector<OriginInfo>::const_iterator current = origins_.begin();
91       current != origins_.end();
92       ++current) {
93    if (current->type == type && current->modified >= modified_since)
94      origins_to_return->insert(current->origin);
95  }
96
97  base::MessageLoop::current()->PostTask(
98      FROM_HERE,
99      base::Bind(&MockQuotaManager::DidGetModifiedSince,
100                 weak_factory_.GetWeakPtr(),
101                 callback,
102                 base::Owned(origins_to_return),
103                 type));
104}
105
106void MockQuotaManager::DeleteOriginData(
107    const GURL& origin,
108    StorageType type,
109    int quota_client_mask,
110    const StatusCallback& callback) {
111  for (std::vector<OriginInfo>::iterator current = origins_.begin();
112       current != origins_.end();
113       ++current) {
114    if (current->origin == origin && current->type == type) {
115      // Modify the mask: if it's 0 after "deletion", remove the origin.
116      current->quota_client_mask &= ~quota_client_mask;
117      if (current->quota_client_mask == 0)
118        origins_.erase(current);
119      break;
120    }
121  }
122
123  base::MessageLoop::current()->PostTask(
124      FROM_HERE,
125      base::Bind(&MockQuotaManager::DidDeleteOriginData,
126                 weak_factory_.GetWeakPtr(),
127                 callback,
128                 kQuotaStatusOk));
129}
130
131MockQuotaManager::~MockQuotaManager() {}
132
133void MockQuotaManager::UpdateUsage(
134    const GURL& origin, StorageType type, int64 delta) {
135  usage_and_quota_map_[std::make_pair(origin, type)].usage += delta;
136}
137
138void MockQuotaManager::DidGetModifiedSince(
139    const GetOriginsCallback& callback,
140    std::set<GURL>* origins,
141    StorageType storage_type) {
142  callback.Run(*origins, storage_type);
143}
144
145void MockQuotaManager::DidDeleteOriginData(
146    const StatusCallback& callback,
147    QuotaStatusCode status) {
148  callback.Run(status);
149}
150
151// MockQuotaManagerProxy -----------------------------------------------------
152
153MockQuotaManagerProxy::MockQuotaManagerProxy(
154    MockQuotaManager* quota_manager,
155    base::SingleThreadTaskRunner* task_runner)
156    : QuotaManagerProxy(quota_manager, task_runner),
157      storage_accessed_count_(0),
158      storage_modified_count_(0),
159      last_notified_type_(kStorageTypeUnknown),
160      last_notified_delta_(0),
161      registered_client_(NULL) {}
162
163void MockQuotaManagerProxy::RegisterClient(QuotaClient* client) {
164  DCHECK(!registered_client_);
165  registered_client_ = client;
166}
167
168void MockQuotaManagerProxy::SimulateQuotaManagerDestroyed() {
169  if (registered_client_) {
170    // We cannot call this in the destructor as the client (indirectly)
171    // holds a refptr of the proxy.
172    registered_client_->OnQuotaManagerDestroyed();
173    registered_client_ = NULL;
174  }
175}
176
177void MockQuotaManagerProxy::NotifyStorageAccessed(
178    QuotaClient::ID client_id, const GURL& origin, StorageType type) {
179  ++storage_accessed_count_;
180  last_notified_origin_ = origin;
181  last_notified_type_ = type;
182}
183
184void MockQuotaManagerProxy::NotifyStorageModified(
185    QuotaClient::ID client_id, const GURL& origin,
186    StorageType type, int64 delta) {
187  ++storage_modified_count_;
188  last_notified_origin_ = origin;
189  last_notified_type_ = type;
190  last_notified_delta_ = delta;
191  if (mock_manager())
192    mock_manager()->UpdateUsage(origin, type, delta);
193}
194
195MockQuotaManagerProxy::~MockQuotaManagerProxy() {
196  DCHECK(!registered_client_);
197}
198
199}  // namespace quota
200