Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: chrome/browser/sessions/session_service.cc

Issue 694813003: Changing SessionService to have a BaseSessionService, not being one. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed non ChromeOS builds Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sessions/session_service.h" 5 #include "chrome/browser/sessions/session_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/pickle.h" 17 #include "base/pickle.h"
18 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
19 #include "chrome/browser/background/background_mode_manager.h" 19 #include "chrome/browser/background/background_mode_manager.h"
20 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chrome_notification_types.h" 21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/defaults.h" 22 #include "chrome/browser/defaults.h"
23 #include "chrome/browser/extensions/tab_helper.h" 23 #include "chrome/browser/extensions/tab_helper.h"
24 #include "chrome/browser/prefs/session_startup_pref.h" 24 #include "chrome/browser/prefs/session_startup_pref.h"
25 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/profiles/profile_manager.h" 26 #include "chrome/browser/profiles/profile_manager.h"
27 #include "chrome/browser/sessions/base_session_service_delegate_impl.h" 27 #include "chrome/browser/sessions/base_session_service_delegate_impl.h"
28 #include "chrome/browser/sessions/session_backend.h"
29 #include "chrome/browser/sessions/session_command.h" 28 #include "chrome/browser/sessions/session_command.h"
30 #include "chrome/browser/sessions/session_data_deleter.h" 29 #include "chrome/browser/sessions/session_data_deleter.h"
31 #include "chrome/browser/sessions/session_restore.h" 30 #include "chrome/browser/sessions/session_restore.h"
32 #include "chrome/browser/sessions/session_service_utils.h" 31 #include "chrome/browser/sessions/session_service_utils.h"
33 #include "chrome/browser/sessions/session_tab_helper.h" 32 #include "chrome/browser/sessions/session_tab_helper.h"
34 #include "chrome/browser/sessions/session_types.h" 33 #include "chrome/browser/sessions/session_types.h"
35 #include "chrome/browser/ui/browser_iterator.h" 34 #include "chrome/browser/ui/browser_iterator.h"
36 #include "chrome/browser/ui/browser_list.h" 35 #include "chrome/browser/ui/browser_list.h"
37 #include "chrome/browser/ui/browser_tabstrip.h" 36 #include "chrome/browser/ui/browser_tabstrip.h"
38 #include "chrome/browser/ui/browser_window.h" 37 #include "chrome/browser/ui/browser_window.h"
(...skipping 19 matching lines...) Expand all
58 using content::WebContents; 57 using content::WebContents;
59 using sessions::ContentSerializedNavigationBuilder; 58 using sessions::ContentSerializedNavigationBuilder;
60 using sessions::SerializedNavigationEntry; 59 using sessions::SerializedNavigationEntry;
61 60
62 // Every kWritesPerReset commands triggers recreating the file. 61 // Every kWritesPerReset commands triggers recreating the file.
63 static const int kWritesPerReset = 250; 62 static const int kWritesPerReset = 250;
64 63
65 // SessionService ------------------------------------------------------------- 64 // SessionService -------------------------------------------------------------
66 65
67 SessionService::SessionService(Profile* profile) 66 SessionService::SessionService(Profile* profile)
68 : BaseSessionService( 67 : BaseSessionServiceDelegateImpl(true),
69 SESSION_RESTORE,
70 profile->GetPath(),
71 scoped_ptr<BaseSessionServiceDelegate>(
72 new BaseSessionServiceDelegateImpl(true))),
73 profile_(profile), 68 profile_(profile),
69 base_session_service_(
70 new BaseSessionService(BaseSessionService::SESSION_RESTORE,
71 profile->GetPath(),
72 this)),
74 has_open_trackable_browsers_(false), 73 has_open_trackable_browsers_(false),
75 move_on_new_browser_(false), 74 move_on_new_browser_(false),
76 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), 75 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)),
77 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), 76 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)),
78 save_delay_in_hrs_(base::TimeDelta::FromHours(8)), 77 save_delay_in_hrs_(base::TimeDelta::FromHours(8)),
79 force_browser_not_alive_with_no_windows_(false), 78 force_browser_not_alive_with_no_windows_(false),
80 weak_factory_(this) { 79 weak_factory_(this) {
81 // We should never be created when incognito. 80 // We should never be created when incognito.
82 DCHECK(!profile->IsOffTheRecord()); 81 DCHECK(!profile->IsOffTheRecord());
83 Init(); 82 Init();
84 } 83 }
85 84
86 SessionService::SessionService(const base::FilePath& save_path) 85 SessionService::SessionService(const base::FilePath& save_path)
87 : BaseSessionService( 86 : BaseSessionServiceDelegateImpl(false),
88 SESSION_RESTORE,
89 save_path,
90 scoped_ptr<BaseSessionServiceDelegate>(
91 new BaseSessionServiceDelegateImpl(false))),
92 profile_(NULL), 87 profile_(NULL),
88 base_session_service_(
89 new BaseSessionService(BaseSessionService::SESSION_RESTORE,
90 save_path,
91 this)),
93 has_open_trackable_browsers_(false), 92 has_open_trackable_browsers_(false),
94 move_on_new_browser_(false), 93 move_on_new_browser_(false),
95 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), 94 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)),
96 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), 95 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)),
97 save_delay_in_hrs_(base::TimeDelta::FromHours(8)), 96 save_delay_in_hrs_(base::TimeDelta::FromHours(8)),
98 force_browser_not_alive_with_no_windows_(false), 97 force_browser_not_alive_with_no_windows_(false),
99 weak_factory_(this) { 98 weak_factory_(this) {
100 Init(); 99 Init();
101 } 100 }
102 101
103 SessionService::~SessionService() { 102 SessionService::~SessionService() {
104 // The BrowserList should outlive the SessionService since it's static and 103 // The BrowserList should outlive the SessionService since it's static and
105 // the SessionService is a KeyedService. 104 // the SessionService is a KeyedService.
106 BrowserList::RemoveObserver(this); 105 BrowserList::RemoveObserver(this);
107 Save(); 106 base_session_service_->SaveNow();
108 } 107 }
109 108
110 bool SessionService::ShouldNewWindowStartSession() { 109 bool SessionService::ShouldNewWindowStartSession() {
111 // ChromeOS and OSX have different ideas of application lifetime than 110 // ChromeOS and OSX have different ideas of application lifetime than
112 // the other platforms. 111 // the other platforms.
113 // On ChromeOS opening a new window should never start a new session. 112 // On ChromeOS opening a new window should never start a new session.
114 #if defined(OS_CHROMEOS) 113 #if defined(OS_CHROMEOS)
115 if (!force_browser_not_alive_with_no_windows_) 114 if (!force_browser_not_alive_with_no_windows_)
116 return false; 115 return false;
117 #endif 116 #endif
(...skipping 17 matching lines...) Expand all
135 134
136 void SessionService::ResetFromCurrentBrowsers() { 135 void SessionService::ResetFromCurrentBrowsers() {
137 ScheduleResetCommands(); 136 ScheduleResetCommands();
138 } 137 }
139 138
140 void SessionService::MoveCurrentSessionToLastSession() { 139 void SessionService::MoveCurrentSessionToLastSession() {
141 pending_tab_close_ids_.clear(); 140 pending_tab_close_ids_.clear();
142 window_closing_ids_.clear(); 141 window_closing_ids_.clear();
143 pending_window_close_ids_.clear(); 142 pending_window_close_ids_.clear();
144 143
145 Save(); 144 base_session_service_->MoveCurrentSessionToLastSession();
145 }
146 146
147 RunTaskOnBackendThread( 147 void SessionService::DeleteLastSession() {
148 FROM_HERE, base::Bind(&SessionBackend::MoveCurrentSessionToLastSession, 148 base_session_service_->DeleteLastSession();
149 backend()));
150 } 149 }
151 150
152 void SessionService::SetTabWindow(const SessionID& window_id, 151 void SessionService::SetTabWindow(const SessionID& window_id,
153 const SessionID& tab_id) { 152 const SessionID& tab_id) {
154 if (!ShouldTrackChangesToWindow(window_id)) 153 if (!ShouldTrackChangesToWindow(window_id))
155 return; 154 return;
156 155
157 ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id).Pass()); 156 ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id).Pass());
158 } 157 }
159 158
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 422
424 void SessionService::TabRestored(WebContents* tab, bool pinned) { 423 void SessionService::TabRestored(WebContents* tab, bool pinned) {
425 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); 424 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab);
426 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) 425 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id()))
427 return; 426 return;
428 427
429 BuildCommandsForTab(session_tab_helper->window_id(), 428 BuildCommandsForTab(session_tab_helper->window_id(),
430 tab, 429 tab,
431 -1, 430 -1,
432 pinned, 431 pinned,
433 &pending_commands(), 432 &base_session_service_->pending_commands(),
434 NULL); 433 NULL);
435 StartSaveTimer(); 434 base_session_service_->StartSaveTimer();
436 } 435 }
437 436
438 void SessionService::SetSelectedNavigationIndex(const SessionID& window_id, 437 void SessionService::SetSelectedNavigationIndex(const SessionID& window_id,
439 const SessionID& tab_id, 438 const SessionID& tab_id,
440 int index) { 439 int index) {
441 if (!ShouldTrackChangesToWindow(window_id)) 440 if (!ShouldTrackChangesToWindow(window_id))
442 return; 441 return;
443 442
444 if (tab_to_available_range_.find(tab_id.id()) != 443 if (tab_to_available_range_.find(tab_id.id()) !=
445 tab_to_available_range_.end()) { 444 tab_to_available_range_.end()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 482
484 ScheduleCommand( 483 ScheduleCommand(
485 CreateSetTabExtensionAppIDCommand(tab_id, extension_app_id).Pass()); 484 CreateSetTabExtensionAppIDCommand(tab_id, extension_app_id).Pass());
486 } 485 }
487 486
488 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( 487 base::CancelableTaskTracker::TaskId SessionService::GetLastSession(
489 const SessionCallback& callback, 488 const SessionCallback& callback,
490 base::CancelableTaskTracker* tracker) { 489 base::CancelableTaskTracker* tracker) {
491 // OnGotSessionCommands maps the SessionCommands to browser state, then run 490 // OnGotSessionCommands maps the SessionCommands to browser state, then run
492 // the callback. 491 // the callback.
493 return ScheduleGetLastSessionCommands( 492 return base_session_service_->ScheduleGetLastSessionCommands(
494 base::Bind(&SessionService::OnGotSessionCommands, 493 base::Bind(&SessionService::OnGotSessionCommands,
495 weak_factory_.GetWeakPtr(), 494 weak_factory_.GetWeakPtr(),
496 callback), 495 callback),
497 tracker); 496 tracker);
498 } 497 }
499 498
500 void SessionService::Save() { 499 void SessionService::OnSavedCommands() {
501 bool had_commands = !pending_commands().empty(); 500 RecordSessionUpdateHistogramData(chrome::NOTIFICATION_SESSION_SERVICE_SAVED,
502 BaseSessionService::Save(); 501 &last_updated_save_time_);
503 if (had_commands) { 502 content::NotificationService::current()->Notify(
504 RecordSessionUpdateHistogramData(chrome::NOTIFICATION_SESSION_SERVICE_SAVED, 503 chrome::NOTIFICATION_SESSION_SERVICE_SAVED,
505 &last_updated_save_time_); 504 content::Source<Profile>(profile()),
506 content::NotificationService::current()->Notify( 505 content::NotificationService::NoDetails());
507 chrome::NOTIFICATION_SESSION_SERVICE_SAVED, 506 }
508 content::Source<Profile>(profile()), 507
509 content::NotificationService::NoDetails()); 508 BaseSessionService* SessionService::GetBaseSessionServiceForTest() {
510 } 509 return base_session_service_.get();
511 } 510 }
512 511
513 void SessionService::Init() { 512 void SessionService::Init() {
514 // Register for the notifications we're interested in. 513 // Register for the notifications we're interested in.
515 registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED, 514 registrar_.Add(this, content::NOTIFICATION_NAV_LIST_PRUNED,
516 content::NotificationService::AllSources()); 515 content::NotificationService::AllSources());
517 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, 516 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED,
518 content::NotificationService::AllSources()); 517 content::NotificationService::AllSources());
519 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 518 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
520 content::NotificationService::AllSources()); 519 content::NotificationService::AllSources());
(...skipping 25 matching lines...) Expand all
546 window->app_name.empty() ? TYPE_NORMAL : 545 window->app_name.empty() ? TYPE_NORMAL :
547 TYPE_APP)) { 546 TYPE_APP)) {
548 delete window; 547 delete window;
549 window_list->erase(i++); 548 window_list->erase(i++);
550 } else { 549 } else {
551 ++i; 550 ++i;
552 } 551 }
553 } 552 }
554 } 553 }
555 554
556 bool SessionService::processed_any_commands() {
557 return backend()->inited() || !pending_commands().empty();
558 }
559
560 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open, 555 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open,
561 Browser* browser) { 556 Browser* browser) {
562 if (ShouldNewWindowStartSession()) { 557 if (ShouldNewWindowStartSession()) {
563 // We're going from no tabbed browsers to a tabbed browser (and not in 558 // We're going from no tabbed browsers to a tabbed browser (and not in
564 // process startup), restore the last session. 559 // process startup), restore the last session.
565 if (move_on_new_browser_) { 560 if (move_on_new_browser_) {
566 // Make the current session the last. 561 // Make the current session the last.
567 MoveCurrentSessionToLastSession(); 562 MoveCurrentSessionToLastSession();
568 move_on_new_browser_ = false; 563 move_on_new_browser_ = false;
569 } 564 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 bool is_pinned, 705 bool is_pinned,
711 ScopedVector<SessionCommand>* commands, 706 ScopedVector<SessionCommand>* commands,
712 IdToRange* tab_to_available_range) { 707 IdToRange* tab_to_available_range) {
713 DCHECK(tab && commands && window_id.id()); 708 DCHECK(tab && commands && window_id.id());
714 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); 709 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab);
715 const SessionID& session_id(session_tab_helper->session_id()); 710 const SessionID& session_id(session_tab_helper->session_id());
716 commands->push_back( 711 commands->push_back(
717 CreateSetTabWindowCommand(window_id, session_id).release()); 712 CreateSetTabWindowCommand(window_id, session_id).release());
718 713
719 const int current_index = tab->GetController().GetCurrentEntryIndex(); 714 const int current_index = tab->GetController().GetCurrentEntryIndex();
720 const int min_index = std::max(0, 715 const int min_index =
721 current_index - max_persist_navigation_count); 716 std::max(current_index - BaseSessionService::max_persist_navigation_count,
717 0);
722 const int max_index = 718 const int max_index =
723 std::min(current_index + max_persist_navigation_count, 719 std::min(current_index + BaseSessionService::max_persist_navigation_count,
724 tab->GetController().GetEntryCount()); 720 tab->GetController().GetEntryCount());
725 const int pending_index = tab->GetController().GetPendingEntryIndex(); 721 const int pending_index = tab->GetController().GetPendingEntryIndex();
726 if (tab_to_available_range) { 722 if (tab_to_available_range) {
727 (*tab_to_available_range)[session_id.id()] = 723 (*tab_to_available_range)[session_id.id()] =
728 std::pair<int, int>(min_index, max_index); 724 std::pair<int, int>(min_index, max_index);
729 } 725 }
730 726
731 if (is_pinned) 727 if (is_pinned)
732 commands->push_back(CreatePinnedStateCommand(session_id, true).release()); 728 commands->push_back(CreatePinnedStateCommand(session_id, true).release());
733 729
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 // deleted, so we ignore it. 824 // deleted, so we ignore it.
829 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && 825 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() &&
830 browser->window()) { 826 browser->window()) {
831 BuildCommandsForBrowser(browser, commands, tab_to_available_range, 827 BuildCommandsForBrowser(browser, commands, tab_to_available_range,
832 windows_to_track); 828 windows_to_track);
833 } 829 }
834 } 830 }
835 } 831 }
836 832
837 void SessionService::ScheduleResetCommands() { 833 void SessionService::ScheduleResetCommands() {
838 set_pending_reset(true); 834 base_session_service_->set_pending_reset(true);
sky 2014/10/31 22:36:17 I think you should remove this and the next line a
Mr4D (OOO till 08-26) 2014/11/01 01:28:24 I see what you are getting at, but this isn't as e
839 pending_commands().clear(); 835 base_session_service_->pending_commands().clear();
840 tab_to_available_range_.clear(); 836 tab_to_available_range_.clear();
841 windows_tracking_.clear(); 837 windows_tracking_.clear();
842 BuildCommandsFromBrowsers(&pending_commands(), 838 BuildCommandsFromBrowsers(&base_session_service_->pending_commands(),
843 &tab_to_available_range_, 839 &tab_to_available_range_,
844 &windows_tracking_); 840 &windows_tracking_);
845 if (!windows_tracking_.empty()) { 841 if (!windows_tracking_.empty()) {
846 // We're lazily created on startup and won't get an initial batch of 842 // We're lazily created on startup and won't get an initial batch of
847 // SetWindowType messages. Set these here to make sure our state is correct. 843 // SetWindowType messages. Set these here to make sure our state is correct.
848 has_open_trackable_browsers_ = true; 844 has_open_trackable_browsers_ = true;
849 move_on_new_browser_ = true; 845 move_on_new_browser_ = true;
850 } 846 }
851 StartSaveTimer(); 847 base_session_service_->StartSaveTimer();
sky 2014/10/31 22:36:16 StartSaveTimer shouldn't be necessary with the cha
Mr4D (OOO till 08-26) 2014/11/01 01:28:24 Ditto.
852 } 848 }
853 849
854 void SessionService::ScheduleCommand(scoped_ptr<SessionCommand> command) { 850 void SessionService::ScheduleCommand(scoped_ptr<SessionCommand> command) {
855 DCHECK(command); 851 DCHECK(command);
856 if (ReplacePendingCommand(pending_commands(), &command)) 852 if (ReplacePendingCommand(base_session_service_->pending_commands(),
853 &command))
857 return; 854 return;
858 bool is_closing_command = IsClosingCommand(command.get()); 855 bool is_closing_command = IsClosingCommand(command.get());
859 BaseSessionService::ScheduleCommand(command.Pass()); 856 base_session_service_->ScheduleCommand(command.Pass());
860 // Don't schedule a reset on tab closed/window closed. Otherwise we may 857 // Don't schedule a reset on tab closed/window closed. Otherwise we may
861 // lose tabs/windows we want to restore from if we exit right after this. 858 // lose tabs/windows we want to restore from if we exit right after this.
862 if (!pending_reset() && pending_window_close_ids_.empty() && 859 if (!base_session_service_->pending_reset() &&
863 commands_since_reset() >= kWritesPerReset && is_closing_command) { 860 pending_window_close_ids_.empty() &&
861 base_session_service_->commands_since_reset() >= kWritesPerReset &&
862 !is_closing_command) {
864 ScheduleResetCommands(); 863 ScheduleResetCommands();
865 } 864 }
866 } 865 }
867 866
868 void SessionService::CommitPendingCloses() { 867 void SessionService::CommitPendingCloses() {
869 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); 868 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin();
870 i != pending_tab_close_ids_.end(); ++i) { 869 i != pending_tab_close_ids_.end(); ++i) {
871 ScheduleCommand(CreateTabClosedCommand(*i).Pass()); 870 ScheduleCommand(CreateTabClosedCommand(*i).Pass());
872 } 871 }
873 pending_tab_close_ids_.clear(); 872 pending_tab_close_ids_.clear();
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 return; 1084 return;
1086 } 1085 }
1087 1086
1088 // Check for any open windows for the current profile that we aren't tracking. 1087 // Check for any open windows for the current profile that we aren't tracking.
1089 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 1088 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1090 if ((*it)->profile() == profile()) 1089 if ((*it)->profile() == profile())
1091 return; 1090 return;
1092 } 1091 }
1093 DeleteSessionOnlyData(profile()); 1092 DeleteSessionOnlyData(profile());
1094 } 1093 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698