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_local_storage_helper.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "chrome/browser/browsing_data/browsing_data_helper.h"
10#include "chrome/browser/profiles/profile.h"
11#include "content/public/browser/browser_thread.h"
12#include "content/public/browser/local_storage_usage_info.h"
13#include "content/public/browser/storage_partition.h"
14
15using content::BrowserContext;
16using content::BrowserThread;
17using content::DOMStorageContext;
18
19BrowsingDataLocalStorageHelper::LocalStorageInfo::LocalStorageInfo(
20    const GURL& origin_url, int64 size, base::Time last_modified)
21    : origin_url(origin_url), size(size), last_modified(last_modified) {}
22
23BrowsingDataLocalStorageHelper::LocalStorageInfo::~LocalStorageInfo() {}
24
25BrowsingDataLocalStorageHelper::BrowsingDataLocalStorageHelper(
26    Profile* profile)
27    : dom_storage_context_(
28          BrowserContext::GetDefaultStoragePartition(profile)->
29              GetDOMStorageContext()),
30      is_fetching_(false) {
31  DCHECK(dom_storage_context_);
32}
33
34BrowsingDataLocalStorageHelper::~BrowsingDataLocalStorageHelper() {
35}
36
37void BrowsingDataLocalStorageHelper::StartFetching(
38    const base::Callback<void(const std::list<LocalStorageInfo>&)>& callback) {
39  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40  DCHECK(!is_fetching_);
41  DCHECK_EQ(false, callback.is_null());
42
43  is_fetching_ = true;
44  completion_callback_ = callback;
45  dom_storage_context_->GetLocalStorageUsage(
46      base::Bind(
47          &BrowsingDataLocalStorageHelper::GetUsageInfoCallback, this));
48}
49
50void BrowsingDataLocalStorageHelper::DeleteOrigin(const GURL& origin) {
51  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52  dom_storage_context_->DeleteLocalStorage(origin);
53}
54
55void BrowsingDataLocalStorageHelper::GetUsageInfoCallback(
56    const std::vector<content::LocalStorageUsageInfo>& infos) {
57  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
58
59  for (size_t i = 0; i < infos.size(); ++i) {
60    // Non-websafe state is not considered browsing data.
61    const content::LocalStorageUsageInfo& info = infos[i];
62    if (BrowsingDataHelper::HasWebScheme(info.origin)) {
63      local_storage_info_.push_back(
64          LocalStorageInfo(info.origin, info.data_size, info.last_modified));
65    }
66  }
67
68  BrowserThread::PostTask(
69      BrowserThread::UI, FROM_HERE,
70      base::Bind(&BrowsingDataLocalStorageHelper::CallCompletionCallback,
71                 this));
72}
73
74void BrowsingDataLocalStorageHelper::CallCompletionCallback() {
75  DCHECK(is_fetching_);
76  completion_callback_.Run(local_storage_info_);
77  completion_callback_.Reset();
78  is_fetching_ = false;
79}
80
81//---------------------------------------------------------
82
83CannedBrowsingDataLocalStorageHelper::CannedBrowsingDataLocalStorageHelper(
84    Profile* profile)
85    : BrowsingDataLocalStorageHelper(profile),
86      profile_(profile) {
87}
88
89CannedBrowsingDataLocalStorageHelper*
90CannedBrowsingDataLocalStorageHelper::Clone() {
91  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92  CannedBrowsingDataLocalStorageHelper* clone =
93      new CannedBrowsingDataLocalStorageHelper(profile_);
94
95  clone->pending_local_storage_info_ = pending_local_storage_info_;
96  return clone;
97}
98
99void CannedBrowsingDataLocalStorageHelper::AddLocalStorage(
100    const GURL& origin) {
101  if (BrowsingDataHelper::HasWebScheme(origin))
102    pending_local_storage_info_.insert(origin);
103}
104
105void CannedBrowsingDataLocalStorageHelper::Reset() {
106  pending_local_storage_info_.clear();
107}
108
109bool CannedBrowsingDataLocalStorageHelper::empty() const {
110  return pending_local_storage_info_.empty();
111}
112
113size_t CannedBrowsingDataLocalStorageHelper::GetLocalStorageCount() const {
114  return pending_local_storage_info_.size();
115}
116
117const std::set<GURL>&
118CannedBrowsingDataLocalStorageHelper::GetLocalStorageInfo() const {
119  return pending_local_storage_info_;
120}
121
122void CannedBrowsingDataLocalStorageHelper::StartFetching(
123    const base::Callback<void(const std::list<LocalStorageInfo>&)>& callback) {
124  DCHECK(!is_fetching_);
125  DCHECK_EQ(false, callback.is_null());
126
127  is_fetching_ = true;
128  completion_callback_ = callback;
129
130  // We post a task to emulate async fetching behavior.
131  base::MessageLoop::current()->PostTask(
132      FROM_HERE,
133      base::Bind(&CannedBrowsingDataLocalStorageHelper::ConvertPendingInfo,
134                 this));
135}
136
137CannedBrowsingDataLocalStorageHelper::~CannedBrowsingDataLocalStorageHelper() {}
138
139void CannedBrowsingDataLocalStorageHelper::ConvertPendingInfo() {
140  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
141  local_storage_info_.clear();
142  for (std::set<GURL>::iterator iter = pending_local_storage_info_.begin();
143       iter != pending_local_storage_info_.end(); ++iter) {
144    local_storage_info_.push_back(
145        LocalStorageInfo(*iter, 0,  base::Time()));
146  }
147  base::MessageLoop::current()->PostTask(
148      FROM_HERE,
149      base::Bind(&CannedBrowsingDataLocalStorageHelper::CallCompletionCallback,
150                 this));
151}
152