- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / browsing_data / browsing_data_quota_helper_impl.cc
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 "chrome/browser/browsing_data/browsing_data_quota_helper_impl.h"
6
7 #include <map>
8 #include <set>
9
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "chrome/browser/browsing_data/browsing_data_helper.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/storage_partition.h"
18 #include "webkit/browser/quota/quota_manager.h"
19
20 using content::BrowserThread;
21 using content::BrowserContext;
22
23 // static
24 BrowsingDataQuotaHelper* BrowsingDataQuotaHelper::Create(Profile* profile) {
25   return new BrowsingDataQuotaHelperImpl(
26       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(),
27       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
28       BrowserContext::GetDefaultStoragePartition(profile)->GetQuotaManager());
29 }
30
31 void BrowsingDataQuotaHelperImpl::StartFetching(
32     const FetchResultCallback& callback) {
33   DCHECK_EQ(false, callback.is_null());
34   DCHECK(callback_.is_null());
35   DCHECK(!is_fetching_);
36   callback_ = callback;
37   quota_info_.clear();
38   is_fetching_ = true;
39
40   FetchQuotaInfo();
41 }
42
43 void BrowsingDataQuotaHelperImpl::RevokeHostQuota(const std::string& host) {
44   if (!io_thread_->BelongsToCurrentThread()) {
45     io_thread_->PostTask(
46         FROM_HERE,
47         base::Bind(&BrowsingDataQuotaHelperImpl::RevokeHostQuota, this, host));
48     return;
49   }
50
51   quota_manager_->SetPersistentHostQuota(
52       host, 0,
53       base::Bind(&BrowsingDataQuotaHelperImpl::DidRevokeHostQuota,
54                  weak_factory_.GetWeakPtr()));
55 }
56
57 BrowsingDataQuotaHelperImpl::BrowsingDataQuotaHelperImpl(
58     base::MessageLoopProxy* ui_thread,
59     base::MessageLoopProxy* io_thread,
60     quota::QuotaManager* quota_manager)
61     : BrowsingDataQuotaHelper(io_thread),
62       quota_manager_(quota_manager),
63       is_fetching_(false),
64       ui_thread_(ui_thread),
65       io_thread_(io_thread),
66       weak_factory_(this) {
67   DCHECK(quota_manager);
68 }
69
70 BrowsingDataQuotaHelperImpl::~BrowsingDataQuotaHelperImpl() {}
71
72 void BrowsingDataQuotaHelperImpl::FetchQuotaInfo() {
73   if (!io_thread_->BelongsToCurrentThread()) {
74     io_thread_->PostTask(
75         FROM_HERE,
76         base::Bind(&BrowsingDataQuotaHelperImpl::FetchQuotaInfo, this));
77     return;
78   }
79
80   quota_manager_->GetOriginsModifiedSince(
81       quota::kStorageTypeTemporary,
82       base::Time(),
83       base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
84                  weak_factory_.GetWeakPtr()));
85 }
86
87 void BrowsingDataQuotaHelperImpl::GotOrigins(
88     const std::set<GURL>& origins, quota::StorageType type) {
89   for (std::set<GURL>::const_iterator itr = origins.begin();
90        itr != origins.end();
91        ++itr)
92     if (BrowsingDataHelper::HasWebScheme(*itr))
93       pending_hosts_.insert(std::make_pair(itr->host(), type));
94
95   DCHECK(type == quota::kStorageTypeTemporary ||
96          type == quota::kStorageTypePersistent ||
97          type == quota::kStorageTypeSyncable);
98
99   // Calling GetOriginsModifiedSince() for all types by chaining callbacks.
100   if (type == quota::kStorageTypeTemporary) {
101     quota_manager_->GetOriginsModifiedSince(
102         quota::kStorageTypePersistent,
103         base::Time(),
104         base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
105                    weak_factory_.GetWeakPtr()));
106   } else if (type == quota::kStorageTypePersistent) {
107     quota_manager_->GetOriginsModifiedSince(
108         quota::kStorageTypeSyncable,
109         base::Time(),
110         base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
111                    weak_factory_.GetWeakPtr()));
112   } else {
113     DCHECK(type == quota::kStorageTypeSyncable);
114     ProcessPendingHosts();
115   }
116 }
117
118 void BrowsingDataQuotaHelperImpl::ProcessPendingHosts() {
119   if (pending_hosts_.empty()) {
120     OnComplete();
121     return;
122   }
123
124   PendingHosts::iterator itr = pending_hosts_.begin();
125   std::string host = itr->first;
126   quota::StorageType type = itr->second;
127   pending_hosts_.erase(itr);
128   GetHostUsage(host, type);
129 }
130
131 void BrowsingDataQuotaHelperImpl::GetHostUsage(const std::string& host,
132                                                quota::StorageType type) {
133   DCHECK(quota_manager_.get());
134   quota_manager_->GetHostUsage(
135       host, type,
136       base::Bind(&BrowsingDataQuotaHelperImpl::GotHostUsage,
137                  weak_factory_.GetWeakPtr(), host, type));
138 }
139
140 void BrowsingDataQuotaHelperImpl::GotHostUsage(const std::string& host,
141                                                quota::StorageType type,
142                                                int64 usage) {
143   switch (type) {
144     case quota::kStorageTypeTemporary:
145       quota_info_[host].temporary_usage = usage;
146       break;
147     case quota::kStorageTypePersistent:
148       quota_info_[host].persistent_usage = usage;
149       break;
150     case quota::kStorageTypeSyncable:
151       quota_info_[host].syncable_usage = usage;
152       break;
153     default:
154       NOTREACHED();
155   }
156   ProcessPendingHosts();
157 }
158
159 void BrowsingDataQuotaHelperImpl::OnComplete() {
160   if (!ui_thread_->BelongsToCurrentThread()) {
161     ui_thread_->PostTask(
162         FROM_HERE,
163         base::Bind(&BrowsingDataQuotaHelperImpl::OnComplete, this));
164     return;
165   }
166
167   is_fetching_ = false;
168
169   QuotaInfoArray result;
170
171   for (std::map<std::string, QuotaInfo>::iterator itr = quota_info_.begin();
172        itr != quota_info_.end();
173        ++itr) {
174     QuotaInfo* info = &itr->second;
175     // Skip unused entries
176     if (info->temporary_usage <= 0 &&
177         info->persistent_usage <= 0 &&
178         info->syncable_usage <= 0)
179       continue;
180
181     info->host = itr->first;
182     result.push_back(*info);
183   }
184
185   callback_.Run(result);
186   callback_.Reset();
187 }
188
189 void BrowsingDataQuotaHelperImpl::DidRevokeHostQuota(
190     quota::QuotaStatusCode status_unused,
191     int64 quota_unused) {
192 }