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

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

Issue 6660028: Decouple TabRestoreService from Browser (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 9 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/tab_restore_service.h" 5 #include "chrome/browser/sessions/tab_restore_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <map> 9 #include <map>
10 10
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/scoped_vector.h" 13 #include "base/scoped_vector.h"
14 #include "base/stl_util-inl.h" 14 #include "base/stl_util-inl.h"
15 #include "chrome/browser/browser_list.h"
16 #include "chrome/browser/browser_window.h" 15 #include "chrome/browser/browser_window.h"
17 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/sessions/session_service.h" 18 #include "chrome/browser/sessions/session_service.h"
20 #include "chrome/browser/sessions/session_command.h" 19 #include "chrome/browser/sessions/session_command.h"
21 #include "chrome/browser/sessions/session_types.h" 20 #include "chrome/browser/sessions/session_types.h"
22 #include "chrome/browser/sessions/tab_restore_service_observer.h" 21 #include "chrome/browser/sessions/tab_restore_service_observer.h"
23 #include "chrome/browser/tabs/tab_strip_model.h"
24 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
25 #include "chrome/common/extensions/extension_constants.h" 23 #include "chrome/common/extensions/extension_constants.h"
26 #include "content/browser/tab_contents/navigation_controller.h" 24 #include "content/browser/tab_contents/navigation_controller.h"
27 #include "content/browser/tab_contents/navigation_entry.h" 25 #include "content/browser/tab_contents/navigation_entry.h"
28 #include "content/browser/tab_contents/tab_contents.h" 26 #include "content/browser/tab_contents/tab_contents.h"
29 27
30 using base::Time; 28 using base::Time;
31 29
32 // TimeFactory----------------------------------------------------------------- 30 // TimeFactory-----------------------------------------------------------------
33 31
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // If the ID matches one of this window's tabs, remove it from the list. 143 // If the ID matches one of this window's tabs, remove it from the list.
146 if ((*j).id == id) { 144 if ((*j).id == id) {
147 window->tabs.erase(j); 145 window->tabs.erase(j);
148 return; 146 return;
149 } 147 }
150 } 148 }
151 } 149 }
152 } 150 }
153 } 151 }
154 152
155 void RecordAppLaunch(Browser* browser, const TabRestoreService::Tab& tab) { 153 void RecordAppLaunch(TabRestoreServiceDelegate* browser,
154 const TabRestoreService::Tab& tab) {
156 GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url(); 155 GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url();
157 Profile* profile = browser->profile(); 156 Profile* profile = browser->profile();
158 DCHECK(profile->GetExtensionService()); 157 DCHECK(profile->GetExtensionService());
159 if (!profile->GetExtensionService()->IsInstalledApp(url)) 158 if (!profile->GetExtensionService()->IsInstalledApp(url))
160 return; 159 return;
161 160
162 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram, 161 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
163 extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED, 162 extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED,
164 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); 163 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
165 } 164 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } 210 }
212 211
213 void TabRestoreService::RemoveObserver(TabRestoreServiceObserver* observer) { 212 void TabRestoreService::RemoveObserver(TabRestoreServiceObserver* observer) {
214 observer_list_.RemoveObserver(observer); 213 observer_list_.RemoveObserver(observer);
215 } 214 }
216 215
217 void TabRestoreService::CreateHistoricalTab(NavigationController* tab) { 216 void TabRestoreService::CreateHistoricalTab(NavigationController* tab) {
218 if (restoring_) 217 if (restoring_)
219 return; 218 return;
220 219
221 Browser* browser = Browser::GetBrowserForController(tab, NULL); 220 TabRestoreServiceDelegate* browser =
221 TabRestoreServiceDelegate::GetBrowserForController(tab, NULL);
222 if (closing_browsers_.find(browser) != closing_browsers_.end()) 222 if (closing_browsers_.find(browser) != closing_browsers_.end())
223 return; 223 return;
224 224
225 scoped_ptr<Tab> local_tab(new Tab()); 225 scoped_ptr<Tab> local_tab(new Tab());
226 PopulateTab(local_tab.get(), browser, tab); 226 PopulateTab(local_tab.get(), browser, tab);
227 if (local_tab->navigations.empty()) 227 if (local_tab->navigations.empty())
228 return; 228 return;
229 229
230 AddEntry(local_tab.release(), true, true); 230 AddEntry(local_tab.release(), true, true);
231 } 231 }
232 232
233 void TabRestoreService::BrowserClosing(Browser* browser) { 233 void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* browser) {
234 if (browser->type() != Browser::TYPE_NORMAL || 234 if (!browser->IsNormalBrowser() || browser->tab_count() == 0)
235 browser->tab_count() == 0)
236 return; 235 return;
237 236
238 closing_browsers_.insert(browser); 237 closing_browsers_.insert(browser);
239 238
240 scoped_ptr<Window> window(new Window()); 239 scoped_ptr<Window> window(new Window());
241 window->selected_tab_index = browser->selected_index(); 240 window->selected_tab_index = browser->selected_index();
242 window->timestamp = TimeNow(); 241 window->timestamp = TimeNow();
243 // Don't use std::vector::resize() because it will push copies of an empty tab 242 // Don't use std::vector::resize() because it will push copies of an empty tab
244 // into the vector, which will give all tabs in a window the same ID. 243 // into the vector, which will give all tabs in a window the same ID.
245 for (int i = 0; i < browser->tab_count(); ++i) { 244 for (int i = 0; i < browser->tab_count(); ++i) {
(...skipping 17 matching lines...) Expand all
263 // the stack. 262 // the stack.
264 AddEntry(new Tab(window->tabs[0]), true, true); 263 AddEntry(new Tab(window->tabs[0]), true, true);
265 } else if (!window->tabs.empty()) { 264 } else if (!window->tabs.empty()) {
266 window->selected_tab_index = 265 window->selected_tab_index =
267 std::min(static_cast<int>(window->tabs.size() - 1), 266 std::min(static_cast<int>(window->tabs.size() - 1),
268 window->selected_tab_index); 267 window->selected_tab_index);
269 AddEntry(window.release(), true, true); 268 AddEntry(window.release(), true, true);
270 } 269 }
271 } 270 }
272 271
273 void TabRestoreService::BrowserClosed(Browser* browser) { 272 void TabRestoreService::BrowserClosed(TabRestoreServiceDelegate* browser) {
274 closing_browsers_.erase(browser); 273 closing_browsers_.erase(browser);
275 } 274 }
276 275
277 void TabRestoreService::ClearEntries() { 276 void TabRestoreService::ClearEntries() {
278 // Mark all the tabs as closed so that we don't attempt to restore them. 277 // Mark all the tabs as closed so that we don't attempt to restore them.
279 for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) 278 for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i)
280 ScheduleCommand(CreateRestoredEntryCommand((*i)->id)); 279 ScheduleCommand(CreateRestoredEntryCommand((*i)->id));
281 280
282 entries_to_write_ = 0; 281 entries_to_write_ = 0;
283 282
284 // Schedule a pending reset so that we nuke the file on next write. 283 // Schedule a pending reset so that we nuke the file on next write.
285 set_pending_reset(true); 284 set_pending_reset(true);
286 285
287 // Schedule a command, otherwise if there are no pending commands Save does 286 // Schedule a command, otherwise if there are no pending commands Save does
288 // nothing. 287 // nothing.
289 ScheduleCommand(CreateRestoredEntryCommand(1)); 288 ScheduleCommand(CreateRestoredEntryCommand(1));
290 289
291 STLDeleteElements(&entries_); 290 STLDeleteElements(&entries_);
292 NotifyTabsChanged(); 291 NotifyTabsChanged();
293 } 292 }
294 293
295 const TabRestoreService::Entries& TabRestoreService::entries() const { 294 const TabRestoreService::Entries& TabRestoreService::entries() const {
296 return entries_; 295 return entries_;
297 } 296 }
298 297
299 void TabRestoreService::RestoreMostRecentEntry(Browser* browser) { 298 void TabRestoreService::RestoreMostRecentEntry(
299 TabRestoreServiceDelegate* browser) {
300 if (entries_.empty()) 300 if (entries_.empty())
301 return; 301 return;
302 302
303 RestoreEntryById(browser, entries_.front()->id, false); 303 RestoreEntryById(browser, entries_.front()->id, false);
304 } 304 }
305 305
306 void TabRestoreService::RestoreEntryById(Browser* browser, 306 void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* browser,
307 SessionID::id_type id, 307 SessionID::id_type id,
308 bool replace_existing_tab) { 308 bool replace_existing_tab) {
309 Entries::iterator i = GetEntryIteratorById(id); 309 Entries::iterator i = GetEntryIteratorById(id);
310 if (i == entries_.end()) { 310 if (i == entries_.end()) {
311 // Don't hoark here, we allow an invalid id. 311 // Don't hoark here, we allow an invalid id.
312 return; 312 return;
313 } 313 }
314 314
315 size_t index = 0; 315 size_t index = 0;
316 for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end(); 316 for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end();
(...skipping 16 matching lines...) Expand all
333 } 333 }
334 334
335 // |browser| will be NULL in cases where one isn't already available (eg, 335 // |browser| will be NULL in cases where one isn't already available (eg,
336 // when invoked on Mac OS X with no windows open). In this case, create a 336 // when invoked on Mac OS X with no windows open). In this case, create a
337 // new browser into which we restore the tabs. 337 // new browser into which we restore the tabs.
338 if (entry->type == TAB) { 338 if (entry->type == TAB) {
339 Tab* tab = static_cast<Tab*>(entry); 339 Tab* tab = static_cast<Tab*>(entry);
340 browser = RestoreTab(*tab, browser, replace_existing_tab); 340 browser = RestoreTab(*tab, browser, replace_existing_tab);
341 browser->window()->Show(); 341 browser->window()->Show();
342 } else if (entry->type == WINDOW) { 342 } else if (entry->type == WINDOW) {
343 Browser* current_browser = browser; 343 TabRestoreServiceDelegate* current_browser = browser;
344 Window* window = static_cast<Window*>(entry); 344 Window* window = static_cast<Window*>(entry);
345 345
346 // When restoring a window, either the entire window can be restored, or a 346 // When restoring a window, either the entire window can be restored, or a
347 // single tab within it. If the entry's ID matches the one to restore, then 347 // single tab within it. If the entry's ID matches the one to restore, then
348 // the entire window will be restored. 348 // the entire window will be restored.
349 if (!restoring_tab_in_window) { 349 if (!restoring_tab_in_window) {
350 browser = Browser::Create(profile()); 350 browser = TabRestoreServiceDelegate::Create(profile());
351 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { 351 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) {
352 const Tab& tab = window->tabs[tab_i]; 352 const Tab& tab = window->tabs[tab_i];
353 TabContents* restored_tab = 353 TabContents* restored_tab =
354 browser->AddRestoredTab(tab.navigations, browser->tab_count(), 354 browser->AddRestoredTab(tab.navigations, browser->tab_count(),
355 tab.current_navigation_index, 355 tab.current_navigation_index,
356 tab.extension_app_id, 356 tab.extension_app_id,
357 (static_cast<int>(tab_i) == 357 (static_cast<int>(tab_i) ==
358 window->selected_tab_index), 358 window->selected_tab_index),
359 tab.pinned, tab.from_last_session, 359 tab.pinned, tab.from_last_session,
360 tab.session_storage_namespace); 360 tab.session_storage_namespace);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 469 }
470 entries_written_++; 470 entries_written_++;
471 } 471 }
472 } 472 }
473 if (pending_reset()) 473 if (pending_reset())
474 entries_written_ = 0; 474 entries_written_ = 0;
475 BaseSessionService::Save(); 475 BaseSessionService::Save();
476 } 476 }
477 477
478 void TabRestoreService::PopulateTab(Tab* tab, 478 void TabRestoreService::PopulateTab(Tab* tab,
479 Browser* browser, 479 TabRestoreServiceDelegate* browser,
480 NavigationController* controller) { 480 NavigationController* controller) {
481 const int pending_index = controller->pending_entry_index(); 481 const int pending_index = controller->pending_entry_index();
482 int entry_count = controller->entry_count(); 482 int entry_count = controller->entry_count();
483 if (entry_count == 0 && pending_index == 0) 483 if (entry_count == 0 && pending_index == 0)
484 entry_count++; 484 entry_count++;
485 tab->navigations.resize(static_cast<int>(entry_count)); 485 tab->navigations.resize(static_cast<int>(entry_count));
486 for (int i = 0; i < entry_count; ++i) { 486 for (int i = 0; i < entry_count; ++i) {
487 NavigationEntry* entry = (i == pending_index) ? 487 NavigationEntry* entry = (i == pending_index) ?
488 controller->pending_entry() : controller->GetEntryAtIndex(i); 488 controller->pending_entry() : controller->GetEntryAtIndex(i);
489 tab->navigations[i].SetFromNavigationEntry(*entry); 489 tab->navigations[i].SetFromNavigationEntry(*entry);
490 } 490 }
491 tab->timestamp = TimeNow(); 491 tab->timestamp = TimeNow();
492 tab->current_navigation_index = controller->GetCurrentEntryIndex(); 492 tab->current_navigation_index = controller->GetCurrentEntryIndex();
493 if (tab->current_navigation_index == -1 && entry_count > 0) 493 if (tab->current_navigation_index == -1 && entry_count > 0)
494 tab->current_navigation_index = 0; 494 tab->current_navigation_index = 0;
495 495
496 const Extension* extension = controller->tab_contents()->extension_app(); 496 const Extension* extension = controller->tab_contents()->extension_app();
497 if (extension) 497 if (extension)
498 tab->extension_app_id = extension->id(); 498 tab->extension_app_id = extension->id();
499 499
500 tab->session_storage_namespace = controller->session_storage_namespace(); 500 tab->session_storage_namespace = controller->session_storage_namespace();
501 501
502 // Browser may be NULL during unit tests. 502 // Browser may be NULL during unit tests.
503 if (browser) { 503 if (browser) {
504 tab->browser_id = browser->session_id().id(); 504 tab->browser_id = browser->session_id().id();
505 tab->tabstrip_index = 505 tab->tabstrip_index = browser->GetIndexOfController(controller);
506 browser->tabstrip_model()->GetIndexOfController(controller); 506 tab->pinned = browser->IsTabPinned(tab->tabstrip_index);
507 tab->pinned = browser->tabstrip_model()->IsTabPinned(tab->tabstrip_index);
508 } 507 }
509 } 508 }
510 509
511 void TabRestoreService::NotifyTabsChanged() { 510 void TabRestoreService::NotifyTabsChanged() {
512 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, 511 FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_,
513 TabRestoreServiceChanged(this)); 512 TabRestoreServiceChanged(this));
514 } 513 }
515 514
516 void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) { 515 void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) {
517 if (to_front) 516 if (to_front)
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 } 871 }
873 } 872 }
874 873
875 // If there was corruption some of the entries won't be valid. Prune any 874 // If there was corruption some of the entries won't be valid. Prune any
876 // entries with no navigations. 875 // entries with no navigations.
877 ValidateAndDeleteEmptyEntries(&(entries.get())); 876 ValidateAndDeleteEmptyEntries(&(entries.get()));
878 877
879 loaded_entries->swap(entries.get()); 878 loaded_entries->swap(entries.get());
880 } 879 }
881 880
882 Browser* TabRestoreService::RestoreTab(const Tab& tab, 881 TabRestoreServiceDelegate* TabRestoreService::RestoreTab(const Tab& tab,
883 Browser* browser, 882 TabRestoreServiceDelegate* browser,
884 bool replace_existing_tab) { 883 bool replace_existing_tab) {
885 // |browser| will be NULL in cases where one isn't already available (eg, 884 // |browser| will be NULL in cases where one isn't already available (eg,
886 // when invoked on Mac OS X with no windows open). In this case, create a 885 // when invoked on Mac OS X with no windows open). In this case, create a
887 // new browser into which we restore the tabs. 886 // new browser into which we restore the tabs.
888 if (replace_existing_tab && browser) { 887 if (replace_existing_tab && browser) {
889 browser->ReplaceRestoredTab(tab.navigations, 888 browser->ReplaceRestoredTab(tab.navigations,
890 tab.current_navigation_index, 889 tab.current_navigation_index,
891 tab.from_last_session, 890 tab.from_last_session,
892 tab.extension_app_id, 891 tab.extension_app_id,
893 tab.session_storage_namespace); 892 tab.session_storage_namespace);
894 } else { 893 } else {
895 if (tab.has_browser()) 894 if (tab.has_browser())
896 browser = BrowserList::FindBrowserWithID(tab.browser_id); 895 browser = TabRestoreServiceDelegate::FindBrowserWithID(tab.browser_id);
897 896
898 int tab_index = -1; 897 int tab_index = -1;
899 if (browser) { 898 if (browser) {
900 tab_index = tab.tabstrip_index; 899 tab_index = tab.tabstrip_index;
901 } else { 900 } else {
902 browser = Browser::Create(profile()); 901 browser = TabRestoreServiceDelegate::Create(profile());
903 if (tab.has_browser()) { 902 if (tab.has_browser()) {
904 UpdateTabBrowserIDs(tab.browser_id, browser->session_id().id()); 903 UpdateTabBrowserIDs(tab.browser_id, browser->session_id().id());
905 } 904 }
906 } 905 }
907 906
908 if (tab_index < 0 || tab_index > browser->tab_count()) { 907 if (tab_index < 0 || tab_index > browser->tab_count()) {
909 tab_index = browser->tab_count(); 908 tab_index = browser->tab_count();
910 } 909 }
911 910
912 browser->AddRestoredTab(tab.navigations, 911 browser->AddRestoredTab(tab.navigations,
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 // correctly write out the entries when Save is invoked (Save starts from 1075 // correctly write out the entries when Save is invoked (Save starts from
1077 // the front, not the end and we just added the entries to the end). 1076 // the front, not the end and we just added the entries to the end).
1078 entries_to_write_ = staging_entries_.size(); 1077 entries_to_write_ = staging_entries_.size();
1079 1078
1080 PruneAndNotify(); 1079 PruneAndNotify();
1081 } 1080 }
1082 1081
1083 Time TabRestoreService::TimeNow() const { 1082 Time TabRestoreService::TimeNow() const {
1084 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); 1083 return time_factory_ ? time_factory_->TimeNow() : Time::Now();
1085 } 1084 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698