18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/command_line.h"
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/ref_counted.h"
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/browser_shutdown.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/prefs/session_startup_pref.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/profiles/profile_io_data.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/browser_context.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/dom_storage_context.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/local_storage_usage_info.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/storage_partition.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/cookies/cookie_monster.h"
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/cookies/cookie_store.h"
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/cookies/cookie_util.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/url_request/url_request_context.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/special_storage_policy.h"
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void CookieDeleted(bool success) {
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(success);
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class SessionDataDeleter
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : public base::RefCountedThreadSafe<SessionDataDeleter> {
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public:
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SessionDataDeleter(storage::SpecialStoragePolicy* storage_policy,
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                     bool delete_only_by_session_only_policy);
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void Run(content::StoragePartition* storage_partition,
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)           ProfileIOData* profile_io_data);
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private:
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  friend class base::RefCountedThreadSafe<SessionDataDeleter>;
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ~SessionDataDeleter();
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Deletes the local storage described by |usages| for origins which are
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // session-only.
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void ClearSessionOnlyLocalStorage(
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      content::StoragePartition* storage_partition,
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::vector<content::LocalStorageUsageInfo>& usages);
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Deletes all cookies that are session only if
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // |delete_only_by_session_only_policy_| is false. Once completed or skipped,
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // this arranges for DeleteSessionOnlyOriginCookies to be called with a list
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // of all remaining cookies.
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void DeleteSessionCookiesOnIOThread(ProfileIOData* profile_io_data);
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Called when all session-only cookies have been deleted.
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void DeleteSessionCookiesDone(int num_deleted);
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Deletes the cookies in |cookies| that are for origins which are
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // session-only.
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void DeleteSessionOnlyOriginCookies(const net::CookieList& cookies);
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<net::CookieMonster> cookie_monster_;
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const bool delete_only_by_session_only_policy_;
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SessionDataDeleter);
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SessionDataDeleter::SessionDataDeleter(
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::SpecialStoragePolicy* storage_policy,
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool delete_only_by_session_only_policy)
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : storage_policy_(storage_policy),
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      delete_only_by_session_only_policy_(delete_only_by_session_only_policy) {
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SessionDataDeleter::Run(content::StoragePartition* storage_partition,
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                             ProfileIOData* profile_io_data) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (storage_policy_.get() && storage_policy_->HasSessionOnlyOrigins()) {
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    storage_partition->GetDOMStorageContext()->GetLocalStorageUsage(
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   this,
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   storage_partition));
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  content::BrowserThread::PostTask(
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      content::BrowserThread::IO,
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      FROM_HERE,
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread,
878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 this,
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 profile_io_data));
898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SessionDataDeleter::~SessionDataDeleter() {}
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SessionDataDeleter::ClearSessionOnlyLocalStorage(
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    content::StoragePartition* storage_partition,
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::vector<content::LocalStorageUsageInfo>& usages) {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(storage_policy_.get());
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(storage_policy_->HasSessionOnlyOrigins());
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < usages.size(); ++i) {
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const content::LocalStorageUsageInfo& usage = usages[i];
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!storage_policy_->IsStorageSessionOnly(usage.origin))
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      continue;
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    storage_partition->GetDOMStorageContext()->DeleteLocalStorage(usage.origin);
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SessionDataDeleter::DeleteSessionCookiesOnIOThread(
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ProfileIOData* profile_io_data) {
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  net::URLRequestContext* request_context =
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      profile_io_data->GetMainRequestContext();
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cookie_monster_ = request_context->cookie_store()->GetCookieMonster();
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (delete_only_by_session_only_policy_) {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cookie_monster_->GetAllCookiesAsync(
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cookie_monster_->DeleteSessionCookiesAsync(
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this));
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted) {
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cookie_monster_->GetAllCookiesAsync(
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SessionDataDeleter::DeleteSessionOnlyOriginCookies(
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const net::CookieList& cookies) {
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!storage_policy_.get() || !storage_policy_->HasSessionOnlyOrigins())
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (net::CookieList::const_iterator it = cookies.begin();
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       it != cookies.end();
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       ++it) {
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GURL url =
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        net::cookie_util::CookieOriginToURL(it->Domain(), it->IsSecure());
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!storage_policy_->IsStorageSessionOnly(url))
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      continue;
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cookie_monster_->DeleteCanonicalCookieAsync(*it, base::Bind(CookieDeleted));
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DeleteSessionOnlyData(Profile* profile) {
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (browser_shutdown::IsTryingToQuit())
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_ANDROID)
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SessionStartupPref::Type startup_pref_type =
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      SessionStartupPref::GetDefaultStartupType();
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SessionStartupPref::Type startup_pref_type =
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      StartupBrowserCreator::GetSessionStartupPref(
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          *CommandLine::ForCurrentProcess(), profile).type;
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<SessionDataDeleter> deleter(
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new SessionDataDeleter(profile->GetSpecialStoragePolicy(),
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                             startup_pref_type == SessionStartupPref::LAST));
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  deleter->Run(
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      Profile::GetDefaultStoragePartition(profile),
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ProfileIOData::FromResourceContext(profile->GetResourceContext()));
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
165