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 |