summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/background/background_mode_manager.cc2
-rw-r--r--chrome/browser/background/background_mode_manager.h6
-rw-r--r--chrome/browser/extensions/app_background_page_apitest.cc4
-rw-r--r--chrome/browser/sessions/better_session_restore_browsertest.cc187
-rw-r--r--chrome/browser/sessions/session_data_deleter.cc169
-rw-r--r--chrome/browser/sessions/session_data_deleter.h15
-rw-r--r--chrome/browser/sessions/session_service.cc12
-rw-r--r--chrome/browser/sessions/session_service_factory.cc3
8 files changed, 390 insertions, 8 deletions
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index 7fd24c0..b1ffcd1 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -262,7 +262,7 @@ void BackgroundModeManager::LaunchBackgroundApplication(
OpenApplication(AppLaunchParams(profile, extension, NEW_FOREGROUND_TAB));
}
-bool BackgroundModeManager::IsBackgroundModeActiveForTest() {
+bool BackgroundModeManager::IsBackgroundModeActive() {
return in_background_mode_;
}
diff --git a/chrome/browser/background/background_mode_manager.h b/chrome/browser/background/background_mode_manager.h
index 118d386..0494f5a 100644
--- a/chrome/browser/background/background_mode_manager.h
+++ b/chrome/browser/background/background_mode_manager.h
@@ -60,6 +60,9 @@ class BackgroundModeManager
static void LaunchBackgroundApplication(Profile* profile,
const extensions::Extension* extension);
+ // Returns true if background mode is active.
+ virtual bool IsBackgroundModeActive();
+
// For testing purposes.
int NumberOfBackgroundModeData();
@@ -246,9 +249,6 @@ class BackgroundModeManager
// (virtual to allow overriding in tests).
virtual bool IsBackgroundModePrefEnabled() const;
- // Returns true if background mode is active. Used only by tests.
- bool IsBackgroundModeActiveForTest();
-
// Turns off background mode if it's currently enabled.
void DisableBackgroundMode();
diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc
index f07952c..35165ec 100644
--- a/chrome/browser/extensions/app_background_page_apitest.cc
+++ b/chrome/browser/extensions/app_background_page_apitest.cc
@@ -69,7 +69,7 @@ class AppBackgroundPageApiTest : public ExtensionApiTest {
DLOG(WARNING) << "Skipping check - background mode disabled";
return true;
}
- if (manager->IsBackgroundModeActiveForTest() == expected_background_mode)
+ if (manager->IsBackgroundModeActive() == expected_background_mode)
return true;
// We are not currently in the expected state - wait for the state to
@@ -78,7 +78,7 @@ class AppBackgroundPageApiTest : public ExtensionApiTest {
chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED,
content::NotificationService::AllSources());
watcher.Wait();
- return manager->IsBackgroundModeActiveForTest() == expected_background_mode;
+ return manager->IsBackgroundModeActive() == expected_background_mode;
#endif
}
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc
index 11ea512..ad68c95 100644
--- a/chrome/browser/sessions/better_session_restore_browsertest.cc
+++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -9,16 +9,21 @@
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/cookie_settings.h"
+#include "chrome/browser/defaults.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_impl.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sessions/session_backend.h"
#include "chrome/browser/sessions/session_service_factory.h"
+#include "chrome/browser/sessions/session_service_test_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_iterator.h"
@@ -41,6 +46,10 @@
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_test_job.h"
+#if defined(OS_MACOSX)
+#include "base/mac/scoped_nsautorelease_pool.h"
+#endif
+
namespace {
Browser* FindOneOtherBrowserForProfile(Profile* profile,
@@ -97,6 +106,27 @@ net::URLRequestJob* URLRequestFakerForPostRequests(
true);
}
+class FakeBackgroundModeManager : public BackgroundModeManager {
+ public:
+ FakeBackgroundModeManager()
+ : BackgroundModeManager(
+ CommandLine::ForCurrentProcess(),
+ &g_browser_process->profile_manager()->GetProfileInfoCache()),
+ background_mode_active_(false) {}
+
+ void SetBackgroundModeActive(bool active) {
+ background_mode_active_ = active;
+ }
+
+ virtual bool IsBackgroundModeActive() OVERRIDE {
+ return background_mode_active_;
+ }
+
+ private:
+ bool background_mode_active_;
+
+};
+
} // namespace
class BetterSessionRestoreTest : public InProcessBrowserTest {
@@ -138,6 +168,15 @@ class BetterSessionRestoreTest : public InProcessBrowserTest {
}
protected:
+ virtual void SetUpOnMainThread() OVERRIDE {
+ SessionServiceTestHelper helper(
+ SessionServiceFactory::GetForProfile(browser()->profile()));
+ helper.SetForceBrowserNotAliveWithNoWindows(true);
+ helper.ReleaseService();
+ g_browser_process->set_background_mode_manager_for_test(
+ scoped_ptr<BackgroundModeManager>(new FakeBackgroundModeManager));
+ }
+
void StoreDataWithPage(const std::string& filename) {
StoreDataWithPage(browser(), filename);
}
@@ -184,7 +223,11 @@ class BetterSessionRestoreTest : public InProcessBrowserTest {
}
void CheckReloadedPageNotRestored() {
- CheckTitle(browser(), title_storing_);
+ CheckReloadedPageNotRestored(browser());
+ }
+
+ void CheckReloadedPageNotRestored(Browser* browser) {
+ CheckTitle(browser, title_storing_);
}
void CheckTitle(Browser* browser, const string16& expected_title) {
@@ -230,7 +273,12 @@ class BetterSessionRestoreTest : public InProcessBrowserTest {
}
void CheckFormRestored(bool text_present, bool password_present) {
- CheckReloadedPageRestored();
+ CheckFormRestored(browser(), text_present, password_present);
+ }
+
+ void CheckFormRestored(
+ Browser* browser, bool text_present, bool password_present) {
+ CheckReloadedPageRestored(browser);
if (text_present) {
EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-text") !=
std::string::npos);
@@ -255,6 +303,36 @@ class BetterSessionRestoreTest : public InProcessBrowserTest {
}
}
+ void CloseBrowserSynchronously(Browser* browser) {
+ content::WindowedNotificationObserver observer(
+ chrome::NOTIFICATION_BROWSER_CLOSED,
+ content::NotificationService::AllSources());
+ browser->window()->Close();
+#if defined(OS_MACOSX)
+ // BrowserWindowController depends on the auto release pool being recycled
+ // in the message loop to delete itself, which frees the Browser object
+ // which fires this event.
+ AutoreleasePool()->Recycle();
+#endif
+ observer.Wait();
+ }
+
+ virtual Browser* QuitBrowserAndRestore(Browser* browser) {
+ Profile* profile = browser->profile();
+
+ // Close the browser.
+ chrome::StartKeepAlive();
+ CloseBrowserSynchronously(browser);
+
+ // Create a new window, which should trigger session restore.
+ ui_test_utils::BrowserAddedObserver window_observer;
+ chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
+ Browser* new_browser = window_observer.WaitForSingleNewBrowser();
+ chrome::EndKeepAlive();
+
+ return new_browser;
+ }
+
std::string fake_server_address() {
return fake_server_address_;
}
@@ -263,6 +341,18 @@ class BetterSessionRestoreTest : public InProcessBrowserTest {
return test_path_;
}
+ void EnableBackgroundMode() {
+ static_cast<FakeBackgroundModeManager*>(
+ g_browser_process->background_mode_manager())->
+ SetBackgroundModeActive(true);
+ }
+
+ void DisableBackgroundMode() {
+ static_cast<FakeBackgroundModeManager*>(
+ g_browser_process->background_mode_manager())->
+ SetBackgroundModeActive(false);
+ }
+
private:
const std::string fake_server_address_;
const std::string test_path_;
@@ -284,6 +374,17 @@ class ContinueWhereILeftOffTest : public BetterSessionRestoreTest {
browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
}
+ protected:
+ virtual Browser* QuitBrowserAndRestore(Browser* browser) OVERRIDE {
+ content::WindowedNotificationObserver session_restore_observer(
+ chrome::NOTIFICATION_SESSION_RESTORE_DONE,
+ content::NotificationService::AllSources());
+ Browser* new_browser =
+ BetterSessionRestoreTest::QuitBrowserAndRestore(browser);
+ session_restore_observer.Wait();
+ return new_browser;
+ }
+
DISALLOW_COPY_AND_ASSIGN(ContinueWhereILeftOffTest);
};
@@ -360,6 +461,53 @@ IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PostWithPassword) {
CheckFormRestored(false, false);
}
+IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, SessionCookiesBrowserClose) {
+ // Set the startup preference to "continue where I left off" and visit a page
+ // which stores a session cookie.
+ StoreDataWithPage("session_cookies.html");
+ Browser* new_browser = QuitBrowserAndRestore(browser());
+ // The browsing session will be continued; just wait for the page to reload
+ // and check the stored data.
+ CheckReloadedPageRestored(new_browser);
+}
+
+IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
+ CookiesClearedOnBrowserClose) {
+ StoreDataWithPage("cookies.html");
+ // Normally cookies are restored.
+ Browser* new_browser = QuitBrowserAndRestore(browser());
+ CheckReloadedPageRestored(new_browser);
+ // ... but not if the content setting is set to clear on exit.
+ CookieSettings::Factory::GetForProfile(new_browser->profile())->
+ SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
+ // ... unless background mode is active.
+ EnableBackgroundMode();
+ new_browser = QuitBrowserAndRestore(new_browser);
+ CheckReloadedPageRestored(new_browser);
+
+ DisableBackgroundMode();
+ new_browser = QuitBrowserAndRestore(new_browser);
+ if (browser_defaults::kBrowserAliveWithNoWindows)
+ CheckReloadedPageRestored(new_browser);
+ else
+ CheckReloadedPageNotRestored(new_browser);
+}
+
+IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PostBrowserClose) {
+ PostFormWithPage("post.html", false);
+ Browser* new_browser = QuitBrowserAndRestore(browser());
+ CheckFormRestored(new_browser, true, false);
+}
+
+IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
+ PostWithPasswordBrowserClose) {
+ PostFormWithPage("post_with_password.html", true);
+ Browser* new_browser = QuitBrowserAndRestore(browser());
+ CheckReloadedPageRestored(new_browser);
+ // The form data contained passwords, so it's removed completely.
+ CheckFormRestored(new_browser, false, false);
+}
+
class RestartTest : public BetterSessionRestoreTest {
public:
RestartTest() { }
@@ -530,3 +678,38 @@ IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, CookiesClearedOnExit) {
web_contents->GetURL().spec());
StoreDataWithPage("local_storage.html");
}
+
+IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, SessionCookiesBrowserClose) {
+ StoreDataWithPage("session_cookies.html");
+ EnableBackgroundMode();
+ Browser* new_browser = QuitBrowserAndRestore(browser());
+ NavigateAndCheckStoredData(new_browser, "session_cookies.html");
+ DisableBackgroundMode();
+ new_browser = QuitBrowserAndRestore(new_browser);
+ if (browser_defaults::kBrowserAliveWithNoWindows)
+ NavigateAndCheckStoredData(new_browser, "session_cookies.html");
+ else
+ StoreDataWithPage(new_browser, "session_cookies.html");
+}
+
+IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, CookiesClearedOnBrowserClose) {
+ StoreDataWithPage("cookies.html");
+
+ // Normally cookies are restored.
+ Browser* new_browser = QuitBrowserAndRestore(browser());
+ NavigateAndCheckStoredData(new_browser, "cookies.html");
+
+ // ... but not if the content setting is set to clear on exit.
+ CookieSettings::Factory::GetForProfile(new_browser->profile())->
+ SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
+ // ... unless background mode is active.
+ EnableBackgroundMode();
+ new_browser = QuitBrowserAndRestore(new_browser);
+ NavigateAndCheckStoredData(new_browser, "cookies.html");
+ DisableBackgroundMode();
+ new_browser = QuitBrowserAndRestore(new_browser);
+ if (browser_defaults::kBrowserAliveWithNoWindows)
+ NavigateAndCheckStoredData(new_browser, "cookies.html");
+ else
+ StoreDataWithPage(new_browser, "cookies.html");
+}
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc
new file mode 100644
index 0000000..2378731
--- /dev/null
+++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -0,0 +1,169 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
+#include "chrome/browser/prefs/session_startup_pref.h"
+#include "chrome/browser/profiles/profile_io_data.h"
+#include "chrome/browser/ui/startup/startup_browser_creator.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/dom_storage_context.h"
+#include "content/public/browser/local_storage_usage_info.h"
+#include "content/public/browser/storage_partition.h"
+#include "net/cookies/cookie_monster.h"
+#include "net/cookies/cookie_store.h"
+#include "net/cookies/cookie_util.h"
+#include "webkit/browser/quota/special_storage_policy.h"
+
+namespace {
+
+void CookieDeleted(bool success) {
+ DCHECK(success);
+}
+
+class SessionDataDeleter
+ : public base::RefCountedThreadSafe<SessionDataDeleter> {
+ public:
+ SessionDataDeleter(quota::SpecialStoragePolicy* storage_policy,
+ bool delete_only_by_session_only_policy);
+
+ void Run(content::StoragePartition* storage_partition,
+ ProfileIOData* profile_io_data);
+
+ private:
+ friend class base::RefCountedThreadSafe<SessionDataDeleter>;
+ ~SessionDataDeleter();
+
+ // Deletes the local storage described by |usages| for origins which are
+ // session-only.
+ void ClearSessionOnlyLocalStorage(
+ content::StoragePartition* storage_partition,
+ const std::vector<content::LocalStorageUsageInfo>& usages);
+
+ // Deletes all cookies that are session only if
+ // |delete_only_by_session_only_policy_| is false. Once completed or skipped,
+ // this arranges for DeleteSessionOnlyOriginCookies to be called with a list
+ // of all remaining cookies.
+ void DeleteSessionCookiesOnIOThread(ProfileIOData* profile_io_data);
+
+ // Called when all session-only cookies have been deleted.
+ void DeleteSessionCookiesDone(int num_deleted);
+
+ // Deletes the cookies in |cookies| that are for origins which are
+ // session-only.
+ void DeleteSessionOnlyOriginCookies(const net::CookieList& cookies);
+
+ base::WeakPtr<ChromeURLRequestContext> request_context_;
+ scoped_refptr<quota::SpecialStoragePolicy> storage_policy_;
+ const bool delete_only_by_session_only_policy_;
+
+ DISALLOW_COPY_AND_ASSIGN(SessionDataDeleter);
+};
+
+SessionDataDeleter::SessionDataDeleter(
+ quota::SpecialStoragePolicy* storage_policy,
+ bool delete_only_by_session_only_policy)
+ : storage_policy_(storage_policy),
+ delete_only_by_session_only_policy_(delete_only_by_session_only_policy) {}
+
+void SessionDataDeleter::Run(content::StoragePartition* storage_partition,
+ ProfileIOData* profile_io_data) {
+ storage_partition->GetDOMStorageContext()->GetLocalStorageUsage(
+ base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage,
+ this,
+ storage_partition));
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&SessionDataDeleter::DeleteSessionCookiesOnIOThread,
+ this,
+ profile_io_data));
+}
+
+SessionDataDeleter::~SessionDataDeleter() {}
+
+void SessionDataDeleter::ClearSessionOnlyLocalStorage(
+ content::StoragePartition* storage_partition,
+ const std::vector<content::LocalStorageUsageInfo>& usages) {
+ for (std::vector<content::LocalStorageUsageInfo>::const_iterator it =
+ usages.begin();
+ it != usages.end();
+ ++it) {
+ if (storage_policy_->IsStorageSessionOnly(it->origin))
+ storage_partition->GetDOMStorageContext()->DeleteLocalStorage(it->origin);
+ }
+}
+
+void SessionDataDeleter::DeleteSessionCookiesOnIOThread(
+ ProfileIOData* profile_io_data) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ ChromeURLRequestContext* request_context =
+ profile_io_data->GetMainRequestContext();
+ request_context_ = request_context->GetWeakPtr();
+ net::CookieMonster* cookie_monster =
+ request_context_->cookie_store()->GetCookieMonster();
+ if (delete_only_by_session_only_policy_) {
+ cookie_monster->GetAllCookiesAsync(
+ base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
+ } else {
+ cookie_monster->DeleteSessionCookiesAsync(
+ base::Bind(&SessionDataDeleter::DeleteSessionCookiesDone, this));
+ }
+}
+
+void SessionDataDeleter::DeleteSessionCookiesDone(int num_deleted) {
+ ChromeURLRequestContext* request_context = request_context_.get();
+ if (!request_context)
+ return;
+
+ request_context->cookie_store()->GetCookieMonster()->GetAllCookiesAsync(
+ base::Bind(&SessionDataDeleter::DeleteSessionOnlyOriginCookies, this));
+}
+
+void SessionDataDeleter::DeleteSessionOnlyOriginCookies(
+ const net::CookieList& cookies) {
+ ChromeURLRequestContext* request_context = request_context_.get();
+ if (!request_context)
+ return;
+
+ net::CookieMonster* cookie_monster =
+ request_context->cookie_store()->GetCookieMonster();
+ for (net::CookieList::const_iterator it = cookies.begin();
+ it != cookies.end();
+ ++it) {
+ if (storage_policy_->IsStorageSessionOnly(
+ net::cookie_util::CookieOriginToURL(it->Domain(),
+ it->IsSecure()))) {
+ cookie_monster->DeleteCanonicalCookieAsync(*it,
+ base::Bind(CookieDeleted));
+ }
+ }
+}
+
+} // namespace
+
+void DeleteSessionOnlyData(Profile* profile) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (browser_shutdown::IsTryingToQuit())
+ return;
+
+#if defined(OS_ANDROID)
+ SessionStartupPref::Type startup_pref_type =
+ SessionStartupPref::GetDefaultStartupType();
+#else
+ SessionStartupPref::Type startup_pref_type =
+ StartupBrowserCreator::GetSessionStartupPref(
+ *CommandLine::ForCurrentProcess(), profile).type;
+#endif
+
+ scoped_refptr<SessionDataDeleter> deleter(
+ new SessionDataDeleter(profile->GetSpecialStoragePolicy(),
+ startup_pref_type == SessionStartupPref::LAST));
+ deleter->Run(
+ Profile::GetDefaultStoragePartition(profile),
+ ProfileIOData::FromResourceContext(profile->GetResourceContext()));
+}
diff --git a/chrome/browser/sessions/session_data_deleter.h b/chrome/browser/sessions/session_data_deleter.h
new file mode 100644
index 0000000..710cd7e
--- /dev/null
+++ b/chrome/browser/sessions/session_data_deleter.h
@@ -0,0 +1,15 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SESSIONS_SESSION_DATA_DELETER_H_
+#define CHROME_BROWSER_SESSIONS_SESSION_DATA_DELETER_H_
+
+class Profile;
+
+// Clears cookies and local storage for origins that are session-only and clears
+// session cookies unless the startup preference is to continue the previous
+// session.
+void DeleteSessionOnlyData(Profile* profile);
+
+#endif // CHROME_BROWSER_SESSIONS_SESSION_DATA_DELETER_H_
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 8af2138..0b7aca8 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -16,12 +16,16 @@
#include "base/metrics/histogram.h"
#include "base/pickle.h"
#include "base/threading/thread.h"
+#include "chrome/browser/background/background_mode_manager.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/defaults.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_backend.h"
#include "chrome/browser/sessions/session_command.h"
+#include "chrome/browser/sessions/session_data_deleter.h"
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/sessions/session_types.h"
@@ -338,6 +342,14 @@ void SessionService::WindowClosed(const SessionID& window_id) {
else
ScheduleCommand(CreateWindowClosedCommand(window_id.id()));
}
+ // Clear session data if the last window for a profile has been closed and
+ // closing the last window would normally close Chrome, unless background mode
+ // is active.
+ if (!has_open_trackable_browsers_ &&
+ !browser_defaults::kBrowserAliveWithNoWindows &&
+ !g_browser_process->background_mode_manager()->IsBackgroundModeActive()) {
+ DeleteSessionOnlyData(profile());
+ }
}
void SessionService::SetWindowType(const SessionID& window_id,
diff --git a/chrome/browser/sessions/session_service_factory.cc b/chrome/browser/sessions/session_service_factory.cc
index 05cf198..7e928f9 100644
--- a/chrome/browser/sessions/session_service_factory.cc
+++ b/chrome/browser/sessions/session_service_factory.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/sessions/session_service_factory.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/session_data_deleter.h"
#include "chrome/browser/sessions/session_service.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
@@ -33,6 +34,8 @@ SessionService* SessionServiceFactory::GetForProfileIfExisting(
// static
void SessionServiceFactory::ShutdownForProfile(Profile* profile) {
+ DeleteSessionOnlyData(profile);
+
// We're about to exit, force creation of the session service if it hasn't
// been created yet. We do this to ensure session state matches the point in
// time the user exited.