Chromium Code Reviews| 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; |
| } |