Prevent chrome://net-internals/#export from flickering
[chromium-blink-merge.git] / chrome / browser / sessions / session_data_deleter.cc
blob2d6134d7bfb00369d62ad3bd80af21243a811188
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.
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/memory/ref_counted.h"
8 #include "chrome/browser/browser_shutdown.h"
9 #include "chrome/browser/prefs/session_startup_pref.h"
10 #include "chrome/browser/profiles/profile_io_data.h"
11 #include "chrome/browser/ui/startup/startup_browser_creator.h"
12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/dom_storage_context.h"
15 #include "content/public/browser/local_storage_usage_info.h"
16 #include "content/public/browser/storage_partition.h"
17 #include "net/cookies/cookie_monster.h"
18 #include "net/cookies/cookie_store.h"
19 #include "net/cookies/cookie_util.h"
20 #include "net/url_request/url_request_context.h"
21 #include "storage/browser/quota/special_storage_policy.h"
23 namespace {
25 void CookieDeleted(bool success) {
26 DCHECK(success);
29 class SessionDataDeleter
30 : public base::RefCountedThreadSafe<SessionDataDeleter> {
31 public:
32 SessionDataDeleter(storage::SpecialStoragePolicy* storage_policy,
33 bool delete_only_by_session_only_policy);
35 void Run(content::StoragePartition* storage_partition,
36 ProfileIOData* profile_io_data);
38 private:
39 friend class base::RefCountedThreadSafe<SessionDataDeleter>;
40 ~SessionDataDeleter();
42 // Deletes the local storage described by |usages| for origins which are
43 // session-only.
44 void ClearSessionOnlyLocalStorage(
45 content::StoragePartition* storage_partition,
46 const std::vector<content::LocalStorageUsageInfo>& usages);
48 // Deletes all cookies that are session only if
49 // |delete_only_by_session_only_policy_| is false. Once completed or skipped,
50 // this arranges for DeleteSessionOnlyOriginCookies to be called with a list
51 // of all remaining cookies.
52 void DeleteSessionCookiesOnIOThread(ProfileIOData* profile_io_data);
54 // Called when all session-only cookies have been deleted.
55 void DeleteSessionCookiesDone(int num_deleted);
57 // Deletes the cookies in |cookies| that are for origins which are
58 // session-only.
59 void DeleteSessionOnlyOriginCookies(const net::CookieList& cookies);
61 scoped_refptr<net::CookieMonster> cookie_monster_;
62 scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
63 const bool delete_only_by_session_only_policy_;
65 DISALLOW_COPY_AND_ASSIGN(SessionDataDeleter);
68 SessionDataDeleter::SessionDataDeleter(
69 storage::SpecialStoragePolicy* storage_policy,
70 bool delete_only_by_session_only_policy)
71 : storage_policy_(storage_policy),
72 delete_only_by_session_only_policy_(delete_only_by_session_only_policy) {
75 void SessionDataDeleter::Run(content::StoragePartition* storage_partition,
76 ProfileIOData* profile_io_data) {
77 if (storage_policy_.get() && storage_policy_->HasSessionOnlyOrigins()) {
78 storage_partition->GetDOMStorageContext()->GetLocalStorageUsage(
79 base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage,
80 this,
81 storage_partition));
83 content::BrowserThread::PostTask(
84 content::BrowserThread::IO,
85 FROM_HERE,
86 base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread,
87 this,
88 profile_io_data));
91 SessionDataDeleter::~SessionDataDeleter() {}
93 void SessionDataDeleter::ClearSessionOnlyLocalStorage(
94 content::StoragePartition* storage_partition,
95 const std::vector<content::LocalStorageUsageInfo>& usages) {
96 DCHECK(storage_policy_.get());
97 DCHECK(storage_policy_->HasSessionOnlyOrigins());
98 for (size_t i = 0; i < usages.size(); ++i) {
99 const content::LocalStorageUsageInfo& usage = usages[i];
100 if (!storage_policy_->IsStorageSessionOnly(usage.origin))
101 continue;
102 storage_partition->GetDOMStorageContext()->DeleteLocalStorage(usage.origin);
106 void SessionDataDeleter::DeleteSessionCookiesOnIOThread(
107 ProfileIOData* profile_io_data) {
108 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
109 net::URLRequestContext* request_context =
110 profile_io_data->GetMainRequestContext();
111 cookie_monster_ = request_context->cookie_store()->GetCookieMonster();
112 if (delete_only_by_session_only_policy_) {
113 cookie_monster_->GetAllCookiesAsync(
114 base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
115 } else {
116 cookie_monster_->DeleteSessionCookiesAsync(
117 base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this));
121 void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted) {
122 cookie_monster_->GetAllCookiesAsync(
123 base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
126 void SessionDataDeleter::DeleteSessionOnlyOriginCookies(
127 const net::CookieList& cookies) {
128 if (!storage_policy_.get() || !storage_policy_->HasSessionOnlyOrigins())
129 return;
131 for (net::CookieList::const_iterator it = cookies.begin();
132 it != cookies.end();
133 ++it) {
134 GURL url =
135 net::cookie_util::CookieOriginToURL(it->Domain(), it->IsSecure());
136 if (!storage_policy_->IsStorageSessionOnly(url))
137 continue;
138 cookie_monster_->DeleteCanonicalCookieAsync(*it, base::Bind(CookieDeleted));
142 } // namespace
144 void DeleteSessionOnlyData(Profile* profile) {
145 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
146 if (browser_shutdown::IsTryingToQuit())
147 return;
149 // TODO: Remove Athena special casing once the AthenaSessionRestore is in
150 // place.
151 #if defined(OS_ANDROID)
152 SessionStartupPref::Type startup_pref_type =
153 SessionStartupPref::GetDefaultStartupType();
154 #else
155 SessionStartupPref::Type startup_pref_type =
156 StartupBrowserCreator::GetSessionStartupPref(
157 *base::CommandLine::ForCurrentProcess(), profile).type;
158 #endif
160 scoped_refptr<SessionDataDeleter> deleter(
161 new SessionDataDeleter(profile->GetSpecialStoragePolicy(),
162 startup_pref_type == SessionStartupPref::LAST));
163 deleter->Run(
164 Profile::GetDefaultStoragePartition(profile),
165 ProfileIOData::FromResourceContext(profile->GetResourceContext()));