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.
6 #include "base/command_line.h"
7 #include "chrome/browser/browser_shutdown.h"
8 #include "chrome/browser/net/chrome_url_request_context.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 "webkit/browser/quota/special_storage_policy.h"
24 void CookieDeleted(bool success
) {
28 class SessionDataDeleter
29 : public base::RefCountedThreadSafe
<SessionDataDeleter
> {
31 SessionDataDeleter(quota::SpecialStoragePolicy
* storage_policy
,
32 bool delete_only_by_session_only_policy
);
34 void Run(content::StoragePartition
* storage_partition
,
35 ProfileIOData
* profile_io_data
);
38 friend class base::RefCountedThreadSafe
<SessionDataDeleter
>;
39 ~SessionDataDeleter();
41 // Deletes the local storage described by |usages| for origins which are
43 void ClearSessionOnlyLocalStorage(
44 content::StoragePartition
* storage_partition
,
45 const std::vector
<content::LocalStorageUsageInfo
>& usages
);
47 // Deletes all cookies that are session only if
48 // |delete_only_by_session_only_policy_| is false. Once completed or skipped,
49 // this arranges for DeleteSessionOnlyOriginCookies to be called with a list
50 // of all remaining cookies.
51 void DeleteSessionCookiesOnIOThread(ProfileIOData
* profile_io_data
);
53 // Called when all session-only cookies have been deleted.
54 void DeleteSessionCookiesDone(int num_deleted
);
56 // Deletes the cookies in |cookies| that are for origins which are
58 void DeleteSessionOnlyOriginCookies(const net::CookieList
& cookies
);
60 base::WeakPtr
<ChromeURLRequestContext
> request_context_
;
61 scoped_refptr
<quota::SpecialStoragePolicy
> storage_policy_
;
62 const bool delete_only_by_session_only_policy_
;
64 DISALLOW_COPY_AND_ASSIGN(SessionDataDeleter
);
67 SessionDataDeleter::SessionDataDeleter(
68 quota::SpecialStoragePolicy
* storage_policy
,
69 bool delete_only_by_session_only_policy
)
70 : storage_policy_(storage_policy
),
71 delete_only_by_session_only_policy_(delete_only_by_session_only_policy
) {}
73 void SessionDataDeleter::Run(content::StoragePartition
* storage_partition
,
74 ProfileIOData
* profile_io_data
) {
75 storage_partition
->GetDOMStorageContext()->GetLocalStorageUsage(
76 base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage
,
79 content::BrowserThread::PostTask(
80 content::BrowserThread::IO
,
82 base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread
,
87 SessionDataDeleter::~SessionDataDeleter() {}
89 void SessionDataDeleter::ClearSessionOnlyLocalStorage(
90 content::StoragePartition
* storage_partition
,
91 const std::vector
<content::LocalStorageUsageInfo
>& usages
) {
92 for (std::vector
<content::LocalStorageUsageInfo
>::const_iterator it
=
96 if (storage_policy_
->IsStorageSessionOnly(it
->origin
))
97 storage_partition
->GetDOMStorageContext()->DeleteLocalStorage(it
->origin
);
101 void SessionDataDeleter::DeleteSessionCookiesOnIOThread(
102 ProfileIOData
* profile_io_data
) {
103 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
104 ChromeURLRequestContext
* request_context
=
105 profile_io_data
->GetMainRequestContext();
106 request_context_
= request_context
->GetWeakPtr();
107 net::CookieMonster
* cookie_monster
=
108 request_context_
->cookie_store()->GetCookieMonster();
109 if (delete_only_by_session_only_policy_
) {
110 cookie_monster
->GetAllCookiesAsync(
111 base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies
, this));
113 cookie_monster
->DeleteSessionCookiesAsync(
114 base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone
, this));
118 void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted
) {
119 ChromeURLRequestContext
* request_context
= request_context_
.get();
120 if (!request_context
)
123 request_context
->cookie_store()->GetCookieMonster()->GetAllCookiesAsync(
124 base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies
, this));
127 void SessionDataDeleter::DeleteSessionOnlyOriginCookies(
128 const net::CookieList
& cookies
) {
129 ChromeURLRequestContext
* request_context
= request_context_
.get();
130 if (!request_context
)
133 net::CookieMonster
* cookie_monster
=
134 request_context
->cookie_store()->GetCookieMonster();
135 for (net::CookieList::const_iterator it
= cookies
.begin();
138 if (storage_policy_
->IsStorageSessionOnly(
139 net::cookie_util::CookieOriginToURL(it
->Domain(),
141 cookie_monster
->DeleteCanonicalCookieAsync(*it
,
142 base::Bind(CookieDeleted
));
149 void DeleteSessionOnlyData(Profile
* profile
) {
150 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
151 if (browser_shutdown::IsTryingToQuit())
154 #if defined(OS_ANDROID)
155 SessionStartupPref::Type startup_pref_type
=
156 SessionStartupPref::GetDefaultStartupType();
158 SessionStartupPref::Type startup_pref_type
=
159 StartupBrowserCreator::GetSessionStartupPref(
160 *CommandLine::ForCurrentProcess(), profile
).type
;
163 scoped_refptr
<SessionDataDeleter
> deleter(
164 new SessionDataDeleter(profile
->GetSpecialStoragePolicy(),
165 startup_pref_type
== SessionStartupPref::LAST
));
167 Profile::GetDefaultStoragePartition(profile
),
168 ProfileIOData::FromResourceContext(profile
->GetResourceContext()));