Home | History | Annotate | Download | only in sessions
      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.
      4 
      5 #include "base/bind.h"
      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"
     21 
     22 namespace {
     23 
     24 void CookieDeleted(bool success) {
     25   DCHECK(success);
     26 }
     27 
     28 class SessionDataDeleter
     29     : public base::RefCountedThreadSafe<SessionDataDeleter> {
     30  public:
     31   SessionDataDeleter(quota::SpecialStoragePolicy* storage_policy,
     32                      bool delete_only_by_session_only_policy);
     33 
     34   void Run(content::StoragePartition* storage_partition,
     35            ProfileIOData* profile_io_data);
     36 
     37  private:
     38   friend class base::RefCountedThreadSafe<SessionDataDeleter>;
     39   ~SessionDataDeleter();
     40 
     41   // Deletes the local storage described by |usages| for origins which are
     42   // session-only.
     43   void ClearSessionOnlyLocalStorage(
     44       content::StoragePartition* storage_partition,
     45       const std::vector<content::LocalStorageUsageInfo>& usages);
     46 
     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);
     52 
     53   // Called when all session-only cookies have been deleted.
     54   void DeleteSessionCookiesDone(int num_deleted);
     55 
     56   // Deletes the cookies in |cookies| that are for origins which are
     57   // session-only.
     58   void DeleteSessionOnlyOriginCookies(const net::CookieList& cookies);
     59 
     60   base::WeakPtr<ChromeURLRequestContext> request_context_;
     61   scoped_refptr<quota::SpecialStoragePolicy> storage_policy_;
     62   const bool delete_only_by_session_only_policy_;
     63 
     64   DISALLOW_COPY_AND_ASSIGN(SessionDataDeleter);
     65 };
     66 
     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) {}
     72 
     73 void SessionDataDeleter::Run(content::StoragePartition* storage_partition,
     74                              ProfileIOData* profile_io_data) {
     75   storage_partition->GetDOMStorageContext()->GetLocalStorageUsage(
     76       base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage,
     77                  this,
     78                  storage_partition));
     79   content::BrowserThread::PostTask(
     80       content::BrowserThread::IO,
     81       FROM_HERE,
     82       base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread,
     83                  this,
     84                  profile_io_data));
     85 }
     86 
     87 SessionDataDeleter::~SessionDataDeleter() {}
     88 
     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 =
     93            usages.begin();
     94        it != usages.end();
     95        ++it) {
     96     if (storage_policy_->IsStorageSessionOnly(it->origin))
     97       storage_partition->GetDOMStorageContext()->DeleteLocalStorage(it->origin);
     98   }
     99 }
    100 
    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));
    112   } else {
    113     cookie_monster->DeleteSessionCookiesAsync(
    114         base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this));
    115   }
    116 }
    117 
    118 void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted) {
    119   ChromeURLRequestContext* request_context = request_context_.get();
    120   if (!request_context)
    121     return;
    122 
    123   request_context->cookie_store()->GetCookieMonster()->GetAllCookiesAsync(
    124       base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
    125 }
    126 
    127 void SessionDataDeleter::DeleteSessionOnlyOriginCookies(
    128     const net::CookieList& cookies) {
    129   ChromeURLRequestContext* request_context = request_context_.get();
    130   if (!request_context)
    131     return;
    132 
    133   net::CookieMonster* cookie_monster =
    134       request_context->cookie_store()->GetCookieMonster();
    135   for (net::CookieList::const_iterator it = cookies.begin();
    136        it != cookies.end();
    137        ++it) {
    138     if (storage_policy_->IsStorageSessionOnly(
    139             net::cookie_util::CookieOriginToURL(it->Domain(),
    140                                                 it->IsSecure()))) {
    141       cookie_monster->DeleteCanonicalCookieAsync(*it,
    142                                                  base::Bind(CookieDeleted));
    143     }
    144   }
    145 }
    146 
    147 }  // namespace
    148 
    149 void DeleteSessionOnlyData(Profile* profile) {
    150   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    151   if (browser_shutdown::IsTryingToQuit())
    152     return;
    153 
    154 #if defined(OS_ANDROID)
    155   SessionStartupPref::Type startup_pref_type =
    156       SessionStartupPref::GetDefaultStartupType();
    157 #else
    158   SessionStartupPref::Type startup_pref_type =
    159       StartupBrowserCreator::GetSessionStartupPref(
    160           *CommandLine::ForCurrentProcess(), profile).type;
    161 #endif
    162 
    163   scoped_refptr<SessionDataDeleter> deleter(
    164       new SessionDataDeleter(profile->GetSpecialStoragePolicy(),
    165                              startup_pref_type == SessionStartupPref::LAST));
    166   deleter->Run(
    167       Profile::GetDefaultStoragePartition(profile),
    168       ProfileIOData::FromResourceContext(profile->GetResourceContext()));
    169 }
    170