| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 | 295 |
| 296 const TabRestoreService::Entries& TabRestoreService::entries() const { | 296 const TabRestoreService::Entries& TabRestoreService::entries() const { |
| 297 return entries_; | 297 return entries_; |
| 298 } | 298 } |
| 299 | 299 |
| 300 void TabRestoreService::RestoreMostRecentEntry( | 300 void TabRestoreService::RestoreMostRecentEntry( |
| 301 TabRestoreServiceDelegate* delegate) { | 301 TabRestoreServiceDelegate* delegate) { |
| 302 if (entries_.empty()) | 302 if (entries_.empty()) |
| 303 return; | 303 return; |
| 304 | 304 |
| 305 RestoreEntryById(delegate, entries_.front()->id, false); | 305 RestoreEntryById(delegate, entries_.front()->id, UNKNOWN); |
| 306 } | 306 } |
| 307 | 307 |
| 308 void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate, | 308 void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate, |
| 309 SessionID::id_type id, | 309 SessionID::id_type id, |
| 310 bool replace_existing_tab) { | 310 WindowOpenDisposition disposition) { |
| 311 Entries::iterator i = GetEntryIteratorById(id); | 311 Entries::iterator i = GetEntryIteratorById(id); |
| 312 if (i == entries_.end()) { | 312 if (i == entries_.end()) { |
| 313 // Don't hoark here, we allow an invalid id. | 313 // Don't hoark here, we allow an invalid id. |
| 314 return; | 314 return; |
| 315 } | 315 } |
| 316 | 316 |
| 317 size_t index = 0; | 317 size_t index = 0; |
| 318 for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end(); | 318 for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end(); |
| 319 ++j, ++index) {} | 319 ++j, ++index) {} |
| 320 if (static_cast<int>(index) < entries_to_write_) | 320 if (static_cast<int>(index) < entries_to_write_) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 332 if (!restoring_tab_in_window) { | 332 if (!restoring_tab_in_window) { |
| 333 entries_.erase(i); | 333 entries_.erase(i); |
| 334 i = entries_.end(); | 334 i = entries_.end(); |
| 335 } | 335 } |
| 336 | 336 |
| 337 // |delegate| will be NULL in cases where one isn't already available (eg, | 337 // |delegate| will be NULL in cases where one isn't already available (eg, |
| 338 // when invoked on Mac OS X with no windows open). In this case, create a | 338 // when invoked on Mac OS X with no windows open). In this case, create a |
| 339 // new browser into which we restore the tabs. | 339 // new browser into which we restore the tabs. |
| 340 if (entry->type == TAB) { | 340 if (entry->type == TAB) { |
| 341 Tab* tab = static_cast<Tab*>(entry); | 341 Tab* tab = static_cast<Tab*>(entry); |
| 342 delegate = RestoreTab(*tab, delegate, replace_existing_tab); | 342 delegate = RestoreTab(*tab, delegate, disposition); |
| 343 delegate->ShowBrowserWindow(); | 343 delegate->ShowBrowserWindow(); |
| 344 } else if (entry->type == WINDOW) { | 344 } else if (entry->type == WINDOW) { |
| 345 TabRestoreServiceDelegate* current_delegate = delegate; | 345 TabRestoreServiceDelegate* current_delegate = delegate; |
| 346 Window* window = static_cast<Window*>(entry); | 346 Window* window = static_cast<Window*>(entry); |
| 347 | 347 |
| 348 // When restoring a window, either the entire window can be restored, or a | 348 // When restoring a window, either the entire window can be restored, or a |
| 349 // single tab within it. If the entry's ID matches the one to restore, then | 349 // single tab within it. If the entry's ID matches the one to restore, then |
| 350 // the entire window will be restored. | 350 // the entire window will be restored. |
| 351 if (!restoring_tab_in_window) { | 351 if (!restoring_tab_in_window) { |
| 352 delegate = TabRestoreServiceDelegate::Create(profile()); | 352 delegate = TabRestoreServiceDelegate::Create(profile()); |
| 353 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { | 353 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { |
| 354 const Tab& tab = window->tabs[tab_i]; | 354 const Tab& tab = window->tabs[tab_i]; |
| 355 TabContents* restored_tab = | 355 TabContents* restored_tab = |
| 356 delegate->AddRestoredTab(tab.navigations, delegate->GetTabCount(), | 356 delegate->AddRestoredTab(tab.navigations, delegate->GetTabCount(), |
| 357 tab.current_navigation_index, | 357 tab.current_navigation_index, |
| 358 tab.extension_app_id, | 358 tab.extension_app_id, |
| 359 (static_cast<int>(tab_i) == | 359 static_cast<int>(tab_i) == |
| 360 window->selected_tab_index), | 360 window->selected_tab_index, |
| 361 tab.pinned, tab.from_last_session, | 361 tab.pinned, tab.from_last_session, |
| 362 tab.session_storage_namespace); | 362 tab.session_storage_namespace); |
| 363 if (restored_tab) { | 363 if (restored_tab) { |
| 364 restored_tab->controller().LoadIfNecessary(); | 364 restored_tab->controller().LoadIfNecessary(); |
| 365 RecordAppLaunch(profile(), tab); | 365 RecordAppLaunch(profile(), tab); |
| 366 } | 366 } |
| 367 } | 367 } |
| 368 // All the window's tabs had the same former browser_id. | 368 // All the window's tabs had the same former browser_id. |
| 369 if (window->tabs[0].has_browser()) { | 369 if (window->tabs[0].has_browser()) { |
| 370 UpdateTabBrowserIDs(window->tabs[0].browser_id, | 370 UpdateTabBrowserIDs(window->tabs[0].browser_id, |
| 371 delegate->GetSessionID().id()); | 371 delegate->GetSessionID().id()); |
| 372 } | 372 } |
| 373 } else { | 373 } else { |
| 374 // Restore a single tab from the window. Find the tab that matches the ID | 374 // Restore a single tab from the window. Find the tab that matches the ID |
| 375 // in the window and restore it. | 375 // in the window and restore it. |
| 376 for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); | 376 for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); |
| 377 tab_i != window->tabs.end(); ++tab_i) { | 377 tab_i != window->tabs.end(); ++tab_i) { |
| 378 const Tab& tab = *tab_i; | 378 const Tab& tab = *tab_i; |
| 379 if (tab.id == id) { | 379 if (tab.id == id) { |
| 380 delegate = RestoreTab(tab, delegate, replace_existing_tab); | 380 delegate = RestoreTab(tab, delegate, disposition); |
| 381 window->tabs.erase(tab_i); | 381 window->tabs.erase(tab_i); |
| 382 // If restoring the tab leaves the window with nothing else, delete it | 382 // If restoring the tab leaves the window with nothing else, delete it |
| 383 // as well. | 383 // as well. |
| 384 if (!window->tabs.size()) { | 384 if (!window->tabs.size()) { |
| 385 entries_.erase(i); | 385 entries_.erase(i); |
| 386 delete entry; | 386 delete entry; |
| 387 } else { | 387 } else { |
| 388 // Update the browser ID of the rest of the tabs in the window so if | 388 // Update the browser ID of the rest of the tabs in the window so if |
| 389 // any one is restored, it goes into the same window as the tab | 389 // any one is restored, it goes into the same window as the tab |
| 390 // being restored now. | 390 // being restored now. |
| 391 UpdateTabBrowserIDs(tab.browser_id, | 391 UpdateTabBrowserIDs(tab.browser_id, |
| 392 delegate->GetSessionID().id()); | 392 delegate->GetSessionID().id()); |
| 393 for (std::vector<Tab>::iterator tab_j = window->tabs.begin(); | 393 for (std::vector<Tab>::iterator tab_j = window->tabs.begin(); |
| 394 tab_j != window->tabs.end(); ++tab_j) { | 394 tab_j != window->tabs.end(); ++tab_j) { |
| 395 (*tab_j).browser_id = delegate->GetSessionID().id(); | 395 (*tab_j).browser_id = delegate->GetSessionID().id(); |
| 396 } | 396 } |
| 397 } | 397 } |
| 398 break; | 398 break; |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 delegate->ShowBrowserWindow(); | 402 delegate->ShowBrowserWindow(); |
| 403 | 403 |
| 404 if (replace_existing_tab && current_delegate && | 404 if (disposition == CURRENT_TAB && current_delegate && |
| 405 current_delegate->GetSelectedTabContents()) { | 405 current_delegate->GetSelectedTabContents()) { |
| 406 current_delegate->CloseTab(); | 406 current_delegate->CloseTab(); |
| 407 } | 407 } |
| 408 } else { | 408 } else { |
| 409 NOTREACHED(); | 409 NOTREACHED(); |
| 410 } | 410 } |
| 411 | 411 |
| 412 if (!restoring_tab_in_window) { | 412 if (!restoring_tab_in_window) { |
| 413 delete entry; | 413 delete entry; |
| 414 } | 414 } |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 | 902 |
| 903 // If there was corruption some of the entries won't be valid. | 903 // If there was corruption some of the entries won't be valid. |
| 904 ValidateAndDeleteEmptyEntries(&(entries.get())); | 904 ValidateAndDeleteEmptyEntries(&(entries.get())); |
| 905 | 905 |
| 906 loaded_entries->swap(entries.get()); | 906 loaded_entries->swap(entries.get()); |
| 907 } | 907 } |
| 908 | 908 |
| 909 TabRestoreServiceDelegate* TabRestoreService::RestoreTab( | 909 TabRestoreServiceDelegate* TabRestoreService::RestoreTab( |
| 910 const Tab& tab, | 910 const Tab& tab, |
| 911 TabRestoreServiceDelegate* delegate, | 911 TabRestoreServiceDelegate* delegate, |
| 912 bool replace_existing_tab) { | 912 WindowOpenDisposition disposition) { |
| 913 // |browser| will be NULL in cases where one isn't already available (eg, | 913 if (disposition == CURRENT_TAB && delegate) { |
| 914 // when invoked on Mac OS X with no windows open). In this case, create a | |
| 915 // new browser into which we restore the tabs. | |
| 916 if (replace_existing_tab && delegate) { | |
| 917 delegate->ReplaceRestoredTab(tab.navigations, | 914 delegate->ReplaceRestoredTab(tab.navigations, |
| 918 tab.current_navigation_index, | 915 tab.current_navigation_index, |
| 919 tab.from_last_session, | 916 tab.from_last_session, |
| 920 tab.extension_app_id, | 917 tab.extension_app_id, |
| 921 tab.session_storage_namespace); | 918 tab.session_storage_namespace); |
| 922 } else { | 919 } else { |
| 923 if (tab.has_browser()) | 920 // We only respsect the tab's original browser if there's no disposition. |
| 921 if (disposition == UNKNOWN && tab.has_browser()) |
| 924 delegate = TabRestoreServiceDelegate::FindDelegateWithID(tab.browser_id); | 922 delegate = TabRestoreServiceDelegate::FindDelegateWithID(tab.browser_id); |
| 925 | 923 |
| 926 int tab_index = -1; | 924 int tab_index = -1; |
| 927 if (delegate) { | 925 |
| 926 // |delegate| will be NULL in cases where one isn't already available (eg, |
| 927 // when invoked on Mac OS X with no windows open). In this case, create a |
| 928 // new browser into which we restore the tabs. |
| 929 if (delegate && disposition != NEW_WINDOW) { |
| 928 tab_index = tab.tabstrip_index; | 930 tab_index = tab.tabstrip_index; |
| 929 } else { | 931 } else { |
| 930 delegate = TabRestoreServiceDelegate::Create(profile()); | 932 delegate = TabRestoreServiceDelegate::Create(profile()); |
| 931 if (tab.has_browser()) { | 933 if (tab.has_browser()) |
| 932 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); | 934 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); |
| 933 } | |
| 934 } | 935 } |
| 935 | 936 |
| 936 if (tab_index < 0 || tab_index > delegate->GetTabCount()) { | 937 // Place the tab at the end if the tab index is no longer valid or |
| 938 // we were passed a specific disposition. |
| 939 if (tab_index < 0 || tab_index > delegate->GetTabCount() || |
| 940 disposition != UNKNOWN) { |
| 937 tab_index = delegate->GetTabCount(); | 941 tab_index = delegate->GetTabCount(); |
| 938 } | 942 } |
| 939 | 943 |
| 940 delegate->AddRestoredTab(tab.navigations, | 944 delegate->AddRestoredTab(tab.navigations, |
| 941 tab_index, | 945 tab_index, |
| 942 tab.current_navigation_index, | 946 tab.current_navigation_index, |
| 943 tab.extension_app_id, | 947 tab.extension_app_id, |
| 944 true, tab.pinned, tab.from_last_session, | 948 disposition != NEW_BACKGROUND_TAB, |
| 949 tab.pinned, |
| 950 tab.from_last_session, |
| 945 tab.session_storage_namespace); | 951 tab.session_storage_namespace); |
| 946 } | 952 } |
| 947 RecordAppLaunch(profile(), tab); | 953 RecordAppLaunch(profile(), tab); |
| 948 return delegate; | 954 return delegate; |
| 949 } | 955 } |
| 950 | 956 |
| 951 | 957 |
| 952 bool TabRestoreService::ValidateTab(Tab* tab) { | 958 bool TabRestoreService::ValidateTab(Tab* tab) { |
| 953 if (tab->navigations.empty()) | 959 if (tab->navigations.empty()) |
| 954 return false; | 960 return false; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 // the front, not the end and we just added the entries to the end). | 1160 // the front, not the end and we just added the entries to the end). |
| 1155 entries_to_write_ = staging_entries_.size(); | 1161 entries_to_write_ = staging_entries_.size(); |
| 1156 | 1162 |
| 1157 PruneEntries(); | 1163 PruneEntries(); |
| 1158 NotifyTabsChanged(); | 1164 NotifyTabsChanged(); |
| 1159 } | 1165 } |
| 1160 | 1166 |
| 1161 Time TabRestoreService::TimeNow() const { | 1167 Time TabRestoreService::TimeNow() const { |
| 1162 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); | 1168 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); |
| 1163 } | 1169 } |
| OLD | NEW |