OLD | NEW |
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/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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 // is written out and followed by n tab closed sequences (as previoulsy | 74 // is written out and followed by n tab closed sequences (as previoulsy |
75 // described). | 75 // described). |
76 // . When the user restores an entry a command of type kCommandRestoredEntry | 76 // . When the user restores an entry a command of type kCommandRestoredEntry |
77 // is written. | 77 // is written. |
78 static const SessionCommand::id_type kCommandUpdateTabNavigation = 1; | 78 static const SessionCommand::id_type kCommandUpdateTabNavigation = 1; |
79 static const SessionCommand::id_type kCommandRestoredEntry = 2; | 79 static const SessionCommand::id_type kCommandRestoredEntry = 2; |
80 static const SessionCommand::id_type kCommandWindow = 3; | 80 static const SessionCommand::id_type kCommandWindow = 3; |
81 static const SessionCommand::id_type kCommandSelectedNavigationInTab = 4; | 81 static const SessionCommand::id_type kCommandSelectedNavigationInTab = 4; |
82 static const SessionCommand::id_type kCommandPinnedState = 5; | 82 static const SessionCommand::id_type kCommandPinnedState = 5; |
83 static const SessionCommand::id_type kCommandSetExtensionAppID = 6; | 83 static const SessionCommand::id_type kCommandSetExtensionAppID = 6; |
| 84 static const SessionCommand::id_type kCommandSetWindowAppName = 7; |
84 | 85 |
85 // Number of entries (not commands) before we clobber the file and write | 86 // Number of entries (not commands) before we clobber the file and write |
86 // everything. | 87 // everything. |
87 static const int kEntriesPerReset = 40; | 88 static const int kEntriesPerReset = 40; |
88 | 89 |
89 namespace { | 90 namespace { |
90 | 91 |
91 // Payload structures. | 92 // Payload structures. |
92 | 93 |
93 typedef int32 RestoredEntryPayload; | 94 typedef int32 RestoredEntryPayload; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 234 |
234 AddEntry(local_tab.release(), true, true); | 235 AddEntry(local_tab.release(), true, true); |
235 } | 236 } |
236 | 237 |
237 void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* delegate) { | 238 void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* delegate) { |
238 closing_delegates_.insert(delegate); | 239 closing_delegates_.insert(delegate); |
239 | 240 |
240 scoped_ptr<Window> window(new Window()); | 241 scoped_ptr<Window> window(new Window()); |
241 window->selected_tab_index = delegate->GetSelectedIndex(); | 242 window->selected_tab_index = delegate->GetSelectedIndex(); |
242 window->timestamp = TimeNow(); | 243 window->timestamp = TimeNow(); |
| 244 window->app_name = delegate->GetAppName(); |
| 245 |
243 // Don't use std::vector::resize() because it will push copies of an empty tab | 246 // 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. | 247 // into the vector, which will give all tabs in a window the same ID. |
245 for (int i = 0; i < delegate->GetTabCount(); ++i) { | 248 for (int i = 0; i < delegate->GetTabCount(); ++i) { |
246 window->tabs.push_back(Tab()); | 249 window->tabs.push_back(Tab()); |
247 } | 250 } |
248 size_t entry_index = 0; | 251 size_t entry_index = 0; |
249 for (int tab_index = 0; tab_index < delegate->GetTabCount(); ++tab_index) { | 252 for (int tab_index = 0; tab_index < delegate->GetTabCount(); ++tab_index) { |
250 PopulateTab(&(window->tabs[entry_index]), | 253 PopulateTab(&(window->tabs[entry_index]), |
251 tab_index, | 254 tab_index, |
252 delegate, | 255 delegate, |
253 &delegate->GetWebContentsAt(tab_index)->GetController()); | 256 &delegate->GetWebContentsAt(tab_index)->GetController()); |
254 if (window->tabs[entry_index].navigations.empty()) { | 257 if (window->tabs[entry_index].navigations.empty()) { |
255 window->tabs.erase(window->tabs.begin() + entry_index); | 258 window->tabs.erase(window->tabs.begin() + entry_index); |
256 } else { | 259 } else { |
257 window->tabs[entry_index].browser_id = delegate->GetSessionID().id(); | 260 window->tabs[entry_index].browser_id = delegate->GetSessionID().id(); |
258 entry_index++; | 261 entry_index++; |
259 } | 262 } |
260 } | 263 } |
261 if (window->tabs.size() == 1) { | 264 if (window->tabs.size() == 1 && window->app_name.empty()) { |
262 // Short-circuit creating a Window if only 1 tab was present. This fixes | 265 // Short-circuit creating a Window if only 1 tab was present. This fixes |
263 // http://crbug.com/56744. Copy the Tab because it's owned by an object on | 266 // http://crbug.com/56744. Copy the Tab because it's owned by an object on |
264 // the stack. | 267 // the stack. |
265 AddEntry(new Tab(window->tabs[0]), true, true); | 268 AddEntry(new Tab(window->tabs[0]), true, true); |
266 } else if (!window->tabs.empty()) { | 269 } else if (!window->tabs.empty()) { |
267 window->selected_tab_index = | 270 window->selected_tab_index = |
268 std::min(static_cast<int>(window->tabs.size() - 1), | 271 std::min(static_cast<int>(window->tabs.size() - 1), |
269 window->selected_tab_index); | 272 window->selected_tab_index); |
270 AddEntry(window.release(), true, true); | 273 AddEntry(window.release(), true, true); |
271 } | 274 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 delegate = RestoreTab(*tab, delegate, disposition); | 345 delegate = RestoreTab(*tab, delegate, disposition); |
343 delegate->ShowBrowserWindow(); | 346 delegate->ShowBrowserWindow(); |
344 } else if (entry->type == WINDOW) { | 347 } else if (entry->type == WINDOW) { |
345 TabRestoreServiceDelegate* current_delegate = delegate; | 348 TabRestoreServiceDelegate* current_delegate = delegate; |
346 Window* window = static_cast<Window*>(entry); | 349 Window* window = static_cast<Window*>(entry); |
347 | 350 |
348 // When restoring a window, either the entire window can be restored, or a | 351 // 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 | 352 // single tab within it. If the entry's ID matches the one to restore, then |
350 // the entire window will be restored. | 353 // the entire window will be restored. |
351 if (!restoring_tab_in_window) { | 354 if (!restoring_tab_in_window) { |
352 delegate = TabRestoreServiceDelegate::Create(profile()); | 355 delegate = TabRestoreServiceDelegate::Create(profile(), window->app_name); |
353 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { | 356 for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { |
354 const Tab& tab = window->tabs[tab_i]; | 357 const Tab& tab = window->tabs[tab_i]; |
355 WebContents* restored_tab = | 358 WebContents* restored_tab = |
356 delegate->AddRestoredTab(tab.navigations, delegate->GetTabCount(), | 359 delegate->AddRestoredTab(tab.navigations, delegate->GetTabCount(), |
357 tab.current_navigation_index, | 360 tab.current_navigation_index, |
358 tab.extension_app_id, | 361 tab.extension_app_id, |
359 static_cast<int>(tab_i) == | 362 static_cast<int>(tab_i) == |
360 window->selected_tab_index, | 363 window->selected_tab_index, |
361 tab.pinned, tab.from_last_session, | 364 tab.pinned, tab.from_last_session, |
362 tab.session_storage_namespace); | 365 tab.session_storage_namespace); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 } | 608 } |
606 if (valid_tab_count == 0) | 609 if (valid_tab_count == 0) |
607 return; // No tabs to persist. | 610 return; // No tabs to persist. |
608 | 611 |
609 ScheduleCommand( | 612 ScheduleCommand( |
610 CreateWindowCommand(window.id, | 613 CreateWindowCommand(window.id, |
611 std::min(real_selected_tab, valid_tab_count - 1), | 614 std::min(real_selected_tab, valid_tab_count - 1), |
612 valid_tab_count, | 615 valid_tab_count, |
613 window.timestamp)); | 616 window.timestamp)); |
614 | 617 |
| 618 if (!window.app_name.empty()) { |
| 619 ScheduleCommand( |
| 620 CreateSetWindowAppNameCommand(kCommandSetWindowAppName, |
| 621 window.id, |
| 622 window.app_name)); |
| 623 } |
| 624 |
615 for (size_t i = 0; i < window.tabs.size(); ++i) { | 625 for (size_t i = 0; i < window.tabs.size(); ++i) { |
616 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); | 626 int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]); |
617 if (selected_index != -1) | 627 if (selected_index != -1) |
618 ScheduleCommandsForTab(window.tabs[i], selected_index); | 628 ScheduleCommandsForTab(window.tabs[i], selected_index); |
619 } | 629 } |
620 } | 630 } |
621 | 631 |
622 void TabRestoreService::ScheduleCommandsForTab(const Tab& tab, | 632 void TabRestoreService::ScheduleCommandsForTab(const Tab& tab, |
623 int selected_index) { | 633 int selected_index) { |
624 const std::vector<TabNavigation>& navigations = tab.navigations; | 634 const std::vector<TabNavigation>& navigations = tab.navigations; |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 if (!current_tab) { | 889 if (!current_tab) { |
880 // Should be in a tab when we get this. | 890 // Should be in a tab when we get this. |
881 return; | 891 return; |
882 } | 892 } |
883 // NOTE: payload doesn't matter. kCommandPinnedState is only written if | 893 // NOTE: payload doesn't matter. kCommandPinnedState is only written if |
884 // tab is pinned. | 894 // tab is pinned. |
885 current_tab->pinned = true; | 895 current_tab->pinned = true; |
886 break; | 896 break; |
887 } | 897 } |
888 | 898 |
| 899 case kCommandSetWindowAppName: { |
| 900 if (!current_window) { |
| 901 // We should have created a window already. |
| 902 NOTREACHED(); |
| 903 return; |
| 904 } |
| 905 |
| 906 SessionID::id_type window_id; |
| 907 std::string app_name; |
| 908 if (!RestoreSetWindowAppNameCommand(command, &window_id, &app_name)) |
| 909 return; |
| 910 |
| 911 current_window->app_name.swap(app_name); |
| 912 break; |
| 913 } |
| 914 |
889 case kCommandSetExtensionAppID: { | 915 case kCommandSetExtensionAppID: { |
890 if (!current_tab) { | 916 if (!current_tab) { |
891 // Should be in a tab when we get this. | 917 // Should be in a tab when we get this. |
892 return; | 918 return; |
893 } | 919 } |
894 SessionID::id_type tab_id; | 920 SessionID::id_type tab_id; |
895 std::string extension_app_id; | 921 std::string extension_app_id; |
896 if (!RestoreSetTabExtensionAppIDCommand(command, &tab_id, | 922 if (!RestoreSetTabExtensionAppIDCommand(command, &tab_id, |
897 &extension_app_id)) { | 923 &extension_app_id)) { |
898 return; | 924 return; |
(...skipping 30 matching lines...) Expand all Loading... |
929 delegate = TabRestoreServiceDelegate::FindDelegateWithID(tab.browser_id); | 955 delegate = TabRestoreServiceDelegate::FindDelegateWithID(tab.browser_id); |
930 | 956 |
931 int tab_index = -1; | 957 int tab_index = -1; |
932 | 958 |
933 // |delegate| will be NULL in cases where one isn't already available (eg, | 959 // |delegate| will be NULL in cases where one isn't already available (eg, |
934 // when invoked on Mac OS X with no windows open). In this case, create a | 960 // when invoked on Mac OS X with no windows open). In this case, create a |
935 // new browser into which we restore the tabs. | 961 // new browser into which we restore the tabs. |
936 if (delegate && disposition != NEW_WINDOW) { | 962 if (delegate && disposition != NEW_WINDOW) { |
937 tab_index = tab.tabstrip_index; | 963 tab_index = tab.tabstrip_index; |
938 } else { | 964 } else { |
939 delegate = TabRestoreServiceDelegate::Create(profile()); | 965 delegate = TabRestoreServiceDelegate::Create(profile(), std::string()); |
940 if (tab.has_browser()) | 966 if (tab.has_browser()) |
941 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); | 967 UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); |
942 } | 968 } |
943 | 969 |
944 // Place the tab at the end if the tab index is no longer valid or | 970 // Place the tab at the end if the tab index is no longer valid or |
945 // we were passed a specific disposition. | 971 // we were passed a specific disposition. |
946 if (tab_index < 0 || tab_index > delegate->GetTabCount() || | 972 if (tab_index < 0 || tab_index > delegate->GetTabCount() || |
947 disposition != UNKNOWN) { | 973 disposition != UNKNOWN) { |
948 tab_index = delegate->GetTabCount(); | 974 tab_index = delegate->GetTabCount(); |
949 } | 975 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 // the front, not the end and we just added the entries to the end). | 1195 // the front, not the end and we just added the entries to the end). |
1170 entries_to_write_ = staging_entries_.size(); | 1196 entries_to_write_ = staging_entries_.size(); |
1171 | 1197 |
1172 PruneEntries(); | 1198 PruneEntries(); |
1173 NotifyTabsChanged(); | 1199 NotifyTabsChanged(); |
1174 } | 1200 } |
1175 | 1201 |
1176 Time TabRestoreService::TimeNow() const { | 1202 Time TabRestoreService::TimeNow() const { |
1177 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); | 1203 return time_factory_ ? time_factory_->TimeNow() : Time::Now(); |
1178 } | 1204 } |
OLD | NEW |