Chromium Code Reviews| Index: chrome/browser/sessions/session_data_deleter.cc |
| diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d8f64c1bf703a4b670298f61dba5a76277e5dc19 |
| --- /dev/null |
| +++ b/chrome/browser/sessions/session_data_deleter.cc |
| @@ -0,0 +1,169 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/bind.h" |
| +#include "base/command_line.h" |
| +#include "chrome/browser/browser_shutdown.h" |
| +#include "chrome/browser/net/chrome_url_request_context.h" |
| +#include "chrome/browser/prefs/session_startup_pref.h" |
| +#include "chrome/browser/profiles/profile_io_data.h" |
| +#include "chrome/browser/ui/startup/startup_browser_creator.h" |
| +#include "content/public/browser/browser_context.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/dom_storage_context.h" |
| +#include "content/public/browser/local_storage_usage_info.h" |
| +#include "content/public/browser/storage_partition.h" |
| +#include "net/cookies/cookie_monster.h" |
| +#include "net/cookies/cookie_store.h" |
| +#include "net/cookies/cookie_util.h" |
| +#include "webkit/browser/quota/special_storage_policy.h" |
| + |
| +namespace { |
| + |
| +void CookieDeleted(bool success) { |
| + DCHECK(success); |
| +} |
| + |
| +class SessionDataDeleter |
| + : public base::RefCountedThreadSafe<SessionDataDeleter> { |
| + public: |
| + SessionDataDeleter(quota::SpecialStoragePolicy* storage_policy, |
| + bool delete_all_session_cookies); |
|
marja
2013/10/16 14:18:08
Naming of this variable is a bit unclear to me. Fr
Sam McNally
2013/10/16 23:30:59
Done.
|
| + |
| + void Run(content::StoragePartition* storage_partition, |
| + ProfileIOData* profile_io_data); |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe<SessionDataDeleter>; |
| + ~SessionDataDeleter(); |
| + |
| + // Deletes the local storage described by |usages| for origins which are |
| + // session-only. |
| + void ClearSessionOnlyLocalStorage( |
| + content::StoragePartition* storage_partition, |
| + const std::vector<content::LocalStorageUsageInfo>& usages); |
| + |
| + // Deletes all cookies that are session only if |delete_all_session_cookies_| |
| + // is true. Once completed or skipped, this arranges for |
| + // DeleteSessionOnlyOriginCookies to be called with a list of all remaining |
| + // cookies. |
| + void DeleteSessionCookiesOnIOThread(ProfileIOData* profile_io_data); |
| + |
| + // Called when all session-only cookies have been deleted. |
| + void DeleteSessionCookiesDone(int num_deleted); |
| + |
| + // Deletes the cookies in |cookies| that are for origins which are |
| + // session-only. |
| + void DeleteSessionOnlyOriginCookies(const net::CookieList& cookies); |
| + |
| + base::WeakPtr<ChromeURLRequestContext> request_context_; |
| + scoped_refptr<quota::SpecialStoragePolicy> storage_policy_; |
| + const bool delete_all_session_cookies_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SessionDataDeleter); |
| +}; |
| + |
| +SessionDataDeleter::SessionDataDeleter( |
| + quota::SpecialStoragePolicy* storage_policy, |
| + bool delete_all_session_cookies) |
| + : storage_policy_(storage_policy), |
| + delete_all_session_cookies_(delete_all_session_cookies) {} |
| + |
| +void SessionDataDeleter::Run(content::StoragePartition* storage_partition, |
| + ProfileIOData* profile_io_data) { |
| + storage_partition->GetDOMStorageContext()->GetLocalStorageUsage( |
| + base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage, |
| + this, |
| + storage_partition)); |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread, |
| + this, |
| + profile_io_data)); |
| +} |
| + |
| +SessionDataDeleter::~SessionDataDeleter() {} |
| + |
| +void SessionDataDeleter::ClearSessionOnlyLocalStorage( |
| + content::StoragePartition* storage_partition, |
| + const std::vector<content::LocalStorageUsageInfo>& usages) { |
| + for (std::vector<content::LocalStorageUsageInfo>::const_iterator it = |
| + usages.begin(); |
| + it != usages.end(); |
| + ++it) { |
| + if (storage_policy_->IsStorageSessionOnly(it->origin)) |
| + storage_partition->GetDOMStorageContext()->DeleteLocalStorage(it->origin); |
| + } |
| +} |
| + |
| +void SessionDataDeleter::DeleteSessionCookiesOnIOThread( |
| + ProfileIOData* profile_io_data) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| + ChromeURLRequestContext* request_context = |
| + profile_io_data->GetMainRequestContext(); |
| + request_context_ = request_context->GetWeakPtr(); |
| + net::CookieMonster* cookie_monster = |
| + request_context_->cookie_store()->GetCookieMonster(); |
| + if (delete_all_session_cookies_) { |
| + cookie_monster->DeleteSessionCookiesAsync( |
| + base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this)); |
|
marja
2013/10/16 14:18:08
Inside the if branch: Shouldn't we also delete "no
Sam McNally
2013/10/16 23:30:59
That's done later in DeleteSessionCookiesDone.
|
| + } else { |
| + cookie_monster->GetAllCookiesAsync( |
| + base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this)); |
| + } |
| +} |
| + |
| +void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted) { |
| + ChromeURLRequestContext* request_context = request_context_.get(); |
| + if (!request_context) |
| + return; |
| + |
| + request_context->cookie_store()->GetCookieMonster()->GetAllCookiesAsync( |
| + base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this)); |
| +} |
| + |
| +void SessionDataDeleter::DeleteSessionOnlyOriginCookies( |
| + const net::CookieList& cookies) { |
| + ChromeURLRequestContext* request_context = request_context_.get(); |
| + if (!request_context) |
| + return; |
| + |
| + net::CookieMonster* cookie_monster = |
| + request_context->cookie_store()->GetCookieMonster(); |
| + for (net::CookieList::const_iterator it = cookies.begin(); |
| + it != cookies.end(); |
| + ++it) { |
| + if (storage_policy_->IsStorageSessionOnly( |
| + net::cookie_util::CookieOriginToURL(it->Domain(), |
| + it->IsSecure()))) { |
| + cookie_monster->DeleteCanonicalCookieAsync(*it, |
| + base::Bind(CookieDeleted)); |
| + } |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +void DeleteSessionOnlyData(Profile* profile) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| + if (browser_shutdown::IsTryingToQuit()) |
| + return; |
| + |
| +#if defined(OS_ANDROID) |
| + SessionStartupPref::Type startup_pref_type = |
| + SessionStartupPref::GetDefaultStartupType(); |
| +#else |
| + SessionStartupPref::Type startup_pref_type = |
| + StartupBrowserCreator::GetSessionStartupPref( |
| + *CommandLine::ForCurrentProcess(), profile).type; |
| +#endif |
| + |
| + scoped_refptr<SessionDataDeleter> deleter( |
| + new SessionDataDeleter(profile->GetSpecialStoragePolicy(), |
| + startup_pref_type != SessionStartupPref::LAST)); |
| + deleter->Run( |
| + Profile::GetDefaultStoragePartition(profile), |
| + ProfileIOData::FromResourceContext(profile->GetResourceContext())); |
| +} |