Index: chrome/browser/sessions/session_service.cc |
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc |
index 1c570ac88b87ac2ecf5d90cc2b44e9e4dd8996a0..9b335fd7fe1e96120c66ec0166a0eedcf2f6f474 100644 |
--- a/chrome/browser/sessions/session_service.cc |
+++ b/chrome/browser/sessions/session_service.cc |
@@ -9,13 +9,16 @@ |
#include <set> |
#include <vector> |
+#include "base/command_line.h" |
#include "base/file_util.h" |
+#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_vector.h" |
#include "base/message_loop.h" |
#include "base/metrics/histogram.h" |
#include "base/pickle.h" |
#include "base/threading/thread.h" |
#include "chrome/browser/extensions/extension_tab_helper.h" |
+#include "chrome/browser/net/chrome_cookie_notification_details.h" |
#include "chrome/browser/prefs/session_startup_pref.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/sessions/restore_tab_helper.h" |
@@ -29,12 +32,16 @@ |
#include "chrome/browser/ui/browser_window.h" |
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
#include "chrome/common/chrome_notification_types.h" |
+#include "chrome/common/chrome_switches.h" |
#include "chrome/common/extensions/extension.h" |
#include "content/browser/tab_contents/navigation_details.h" |
#include "content/browser/tab_contents/navigation_entry.h" |
#include "content/browser/tab_contents/tab_contents.h" |
+#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/notification_details.h" |
+#include "net/url_request/url_request_context.h" |
+#include "net/url_request/url_request_context_getter.h" |
#if defined(OS_MACOSX) |
#include "chrome/browser/app_controller_cppsafe_mac.h" |
@@ -62,6 +69,7 @@ static const SessionCommand::id_type |
static const SessionCommand::id_type kCommandSetPinnedState = 12; |
static const SessionCommand::id_type kCommandSetExtensionAppID = 13; |
static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; |
+static const SessionCommand::id_type kCommandSessionCookieCreated = 15; |
// Every kWritesPerReset commands triggers recreating the file. |
static const int kWritesPerReset = 250; |
@@ -137,6 +145,19 @@ struct PinnedStatePayload { |
bool pinned_state; |
}; |
+struct CookieListHolder : public base::RefCountedThreadSafe<CookieListHolder> { |
+ net::CookieList cookie_list; |
+}; |
+ |
+void RestoreCookies( |
+ net::URLRequestContextGetter* url_request_context_getter, |
+ CookieListHolder* cookie_list_holder) { |
+ net::CookieMonster* cookie_monster = |
+ url_request_context_getter->GetURLRequestContext()->cookie_store()-> |
+ GetCookieMonster(); |
+ cookie_monster->InitializeFrom(cookie_list_holder->cookie_list); |
+} |
+ |
} // namespace |
// SessionService ------------------------------------------------------------- |
@@ -465,6 +486,29 @@ void SessionService::Save() { |
} |
} |
+void SessionService::StoreSessionCookie( |
+ const net::CookieMonster::CanonicalCookie* cookie, |
+ bool removed) { |
+ if (!removed) { |
+ Pickle saved_cookie; |
+ saved_cookie.WriteString(cookie->Source()); |
+ saved_cookie.WriteString(cookie->Name()); |
+ saved_cookie.WriteString(cookie->Value()); |
+ saved_cookie.WriteString(cookie->Domain()); |
+ saved_cookie.WriteString(cookie->Path()); |
+ saved_cookie.WriteString(cookie->MACKey()); |
+ saved_cookie.WriteString(cookie->MACAlgorithm()); |
+ saved_cookie.WriteInt64(cookie->CreationDate().ToInternalValue()); |
+ saved_cookie.WriteInt64(cookie->ExpiryDate().ToInternalValue()); |
+ saved_cookie.WriteBool(cookie->IsSecure()); |
+ saved_cookie.WriteBool(cookie->IsHttpOnly()); |
+ saved_cookie.WriteBool(cookie->IsPersistent()); |
+ SessionCommand* command = new SessionCommand(kCommandSessionCookieCreated, |
+ saved_cookie); |
+ ScheduleCommand(command); |
+ } |
+} |
+ |
void SessionService::Init() { |
// Register for the notifications we're interested in. |
registrar_.Add(this, content::NOTIFICATION_TAB_PARENTED, |
@@ -482,6 +526,9 @@ void SessionService::Init() { |
registrar_.Add( |
this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, |
content::NotificationService::AllSources()); |
+ registrar_.Add( |
+ this, chrome::NOTIFICATION_COOKIE_CHANGED, |
+ content::Source<Profile>(profile())); |
} |
bool SessionService::ShouldNewWindowStartSession() { |
@@ -650,6 +697,18 @@ void SessionService::Observe(int type, |
break; |
} |
+ case chrome::NOTIFICATION_COOKIE_CHANGED: { |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableRestoreSessionCookies)) { |
+ ChromeCookieDetails* cookie_details = |
+ content::Details<ChromeCookieDetails>(details).ptr(); |
+ if (!cookie_details->cookie->IsPersistent()) { |
+ StoreSessionCookie(cookie_details->cookie, cookie_details->removed); |
+ } |
+ } |
+ break; |
+ } |
+ |
default: |
NOTREACHED(); |
} |
@@ -949,6 +1008,11 @@ bool SessionService::CreateTabsAndWindows( |
// If the file is corrupt (command with wrong size, or unknown command), we |
// still return true and attempt to restore what we we can. |
+ // Session cookies are collected here and restored all at once. |
+ scoped_refptr<CookieListHolder> cookie_list_holder = new CookieListHolder; |
+ bool restore_session_cookies = CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableRestoreSessionCookies); |
+ |
for (std::vector<SessionCommand*>::const_iterator i = data.begin(); |
i != data.end(); ++i) { |
const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
@@ -1122,10 +1186,50 @@ bool SessionService::CreateTabsAndWindows( |
break; |
} |
+ case kCommandSessionCookieCreated: { |
jochen (gone - plz use gerrit)
2011/11/15 10:42:14
does this restore the cookies even if you just re-
marja
2011/11/17 12:54:46
Done.
|
+ if (restore_session_cookies) { |
+ scoped_ptr<Pickle> pickle(command->PayloadAsPickle()); |
+ std::string source, name, value, domain, path, mac_key, mac_algorithm; |
+ int64 creation_date_internal, expiry_date_internal; |
+ bool secure, http_only, persistent; |
+ void* iter = NULL; |
+ pickle->ReadString(&iter, &source); |
+ pickle->ReadString(&iter, &name); |
+ pickle->ReadString(&iter, &value); |
+ pickle->ReadString(&iter, &domain); |
+ pickle->ReadString(&iter, &path); |
+ pickle->ReadString(&iter, &mac_key); |
+ pickle->ReadString(&iter, &mac_algorithm); |
+ pickle->ReadInt64(&iter, &creation_date_internal); |
+ pickle->ReadInt64(&iter, &expiry_date_internal); |
+ pickle->ReadBool(&iter, &secure); |
+ pickle->ReadBool(&iter, &http_only); |
+ pickle->ReadBool(&iter, &persistent); |
+ scoped_ptr<net::CookieMonster::CanonicalCookie> cc( |
+ net::CookieMonster::CanonicalCookie::Create( |
+ GURL(source), name, value, domain, path, mac_key, |
+ mac_algorithm, |
+ base::Time::FromInternalValue(creation_date_internal), |
+ base::Time::FromInternalValue(expiry_date_internal), |
+ secure, http_only, persistent)); |
+ cookie_list_holder->cookie_list.push_back(*cc); |
+ break; |
+ } |
+ } |
+ |
default: |
return true; |
} |
} |
+ |
+ if (cookie_list_holder->cookie_list.size() > 0) { |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, FROM_HERE, |
+ NewRunnableFunction(&RestoreCookies, |
+ make_scoped_refptr(profile()->GetRequestContext()), |
+ cookie_list_holder)); |
+ } |
+ |
return true; |
} |