• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CookieDeleted(bool success)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 
SessionDataDeleter(quota::SpecialStoragePolicy * storage_policy,bool delete_only_by_session_only_policy)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 
Run(content::StoragePartition * storage_partition,ProfileIOData * profile_io_data)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 
~SessionDataDeleter()87 SessionDataDeleter::~SessionDataDeleter() {}
88 
ClearSessionOnlyLocalStorage(content::StoragePartition * storage_partition,const std::vector<content::LocalStorageUsageInfo> & usages)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 
DeleteSessionCookiesOnIOThread(ProfileIOData * profile_io_data)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 
DeleteSessionCookiesDone(int num_deleted)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 
DeleteSessionOnlyOriginCookies(const net::CookieList & cookies)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 
DeleteSessionOnlyData(Profile * profile)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