| 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/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> |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 #include "content/public/browser/notification_details.h" | 40 #include "content/public/browser/notification_details.h" |
| 41 #include "content/public/browser/notification_service.h" | 41 #include "content/public/browser/notification_service.h" |
| 42 #include "content/public/browser/session_storage_namespace.h" | 42 #include "content/public/browser/session_storage_namespace.h" |
| 43 #include "content/public/browser/web_contents.h" | 43 #include "content/public/browser/web_contents.h" |
| 44 | 44 |
| 45 #if defined(OS_MACOSX) | 45 #if defined(OS_MACOSX) |
| 46 #include "chrome/browser/app_controller_mac.h" | 46 #include "chrome/browser/app_controller_mac.h" |
| 47 #endif | 47 #endif |
| 48 | 48 |
| 49 using base::Time; | 49 using base::Time; |
| 50 using components::SerializedNavigationEntry; |
| 50 using content::NavigationEntry; | 51 using content::NavigationEntry; |
| 51 using content::WebContents; | 52 using content::WebContents; |
| 52 | 53 |
| 53 // Identifier for commands written to file. | 54 // Identifier for commands written to file. |
| 54 static const SessionCommand::id_type kCommandSetTabWindow = 0; | 55 static const SessionCommand::id_type kCommandSetTabWindow = 0; |
| 55 // OBSOLETE Superseded by kCommandSetWindowBounds3. | 56 // OBSOLETE Superseded by kCommandSetWindowBounds3. |
| 56 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; | 57 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; |
| 57 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; | 58 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; |
| 58 // Original kCommandTabClosed/kCommandWindowClosed. See comment in | 59 // Original kCommandTabClosed/kCommandWindowClosed. See comment in |
| 59 // MigrateClosedPayload for details on why they were replaced. | 60 // MigrateClosedPayload for details on why they were replaced. |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 SessionCommand* command = | 408 SessionCommand* command = |
| 408 new SessionCommand(kCommandTabNavigationPathPrunedFromFront, | 409 new SessionCommand(kCommandTabNavigationPathPrunedFromFront, |
| 409 sizeof(payload)); | 410 sizeof(payload)); |
| 410 memcpy(command->contents(), &payload, sizeof(payload)); | 411 memcpy(command->contents(), &payload, sizeof(payload)); |
| 411 ScheduleCommand(command); | 412 ScheduleCommand(command); |
| 412 } | 413 } |
| 413 | 414 |
| 414 void SessionService::UpdateTabNavigation( | 415 void SessionService::UpdateTabNavigation( |
| 415 const SessionID& window_id, | 416 const SessionID& window_id, |
| 416 const SessionID& tab_id, | 417 const SessionID& tab_id, |
| 417 const TabNavigation& navigation) { | 418 const SerializedNavigationEntry& navigation) { |
| 418 if (!ShouldTrackEntry(navigation.virtual_url()) || | 419 if (!ShouldTrackEntry(navigation.virtual_url()) || |
| 419 !ShouldTrackChangesToWindow(window_id)) { | 420 !ShouldTrackChangesToWindow(window_id)) { |
| 420 return; | 421 return; |
| 421 } | 422 } |
| 422 | 423 |
| 423 if (tab_to_available_range_.find(tab_id.id()) != | 424 if (tab_to_available_range_.find(tab_id.id()) != |
| 424 tab_to_available_range_.end()) { | 425 tab_to_available_range_.end()) { |
| 425 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 426 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
| 426 range.first = std::min(navigation.index(), range.first); | 427 range.first = std::min(navigation.index(), range.first); |
| 427 range.second = std::max(navigation.index(), range.second); | 428 range.second = std::max(navigation.index(), range.second); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 615 |
| 615 case content::NOTIFICATION_NAV_ENTRY_CHANGED: { | 616 case content::NOTIFICATION_NAV_ENTRY_CHANGED: { |
| 616 WebContents* web_contents = | 617 WebContents* web_contents = |
| 617 content::Source<content::NavigationController>(source).ptr()-> | 618 content::Source<content::NavigationController>(source).ptr()-> |
| 618 GetWebContents(); | 619 GetWebContents(); |
| 619 SessionTabHelper* session_tab_helper = | 620 SessionTabHelper* session_tab_helper = |
| 620 SessionTabHelper::FromWebContents(web_contents); | 621 SessionTabHelper::FromWebContents(web_contents); |
| 621 if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) | 622 if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) |
| 622 return; | 623 return; |
| 623 content::Details<content::EntryChangedDetails> changed(details); | 624 content::Details<content::EntryChangedDetails> changed(details); |
| 624 const TabNavigation navigation = | 625 const SerializedNavigationEntry navigation = |
| 625 TabNavigation::FromNavigationEntry( | 626 SerializedNavigationEntry::FromNavigationEntry( |
| 626 changed->index, *changed->changed_entry); | 627 changed->index, *changed->changed_entry); |
| 627 UpdateTabNavigation(session_tab_helper->window_id(), | 628 UpdateTabNavigation(session_tab_helper->window_id(), |
| 628 session_tab_helper->session_id(), | 629 session_tab_helper->session_id(), |
| 629 navigation); | 630 navigation); |
| 630 break; | 631 break; |
| 631 } | 632 } |
| 632 | 633 |
| 633 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { | 634 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { |
| 634 WebContents* web_contents = | 635 WebContents* web_contents = |
| 635 content::Source<content::NavigationController>(source).ptr()-> | 636 content::Source<content::NavigationController>(source).ptr()-> |
| 636 GetWebContents(); | 637 GetWebContents(); |
| 637 SessionTabHelper* session_tab_helper = | 638 SessionTabHelper* session_tab_helper = |
| 638 SessionTabHelper::FromWebContents(web_contents); | 639 SessionTabHelper::FromWebContents(web_contents); |
| 639 if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) | 640 if (!session_tab_helper || web_contents->GetBrowserContext() != profile()) |
| 640 return; | 641 return; |
| 641 int current_entry_index = | 642 int current_entry_index = |
| 642 web_contents->GetController().GetCurrentEntryIndex(); | 643 web_contents->GetController().GetCurrentEntryIndex(); |
| 643 SetSelectedNavigationIndex( | 644 SetSelectedNavigationIndex( |
| 644 session_tab_helper->window_id(), | 645 session_tab_helper->window_id(), |
| 645 session_tab_helper->session_id(), | 646 session_tab_helper->session_id(), |
| 646 current_entry_index); | 647 current_entry_index); |
| 647 const TabNavigation navigation = | 648 const SerializedNavigationEntry navigation = |
| 648 TabNavigation::FromNavigationEntry( | 649 SerializedNavigationEntry::FromNavigationEntry( |
| 649 current_entry_index, | 650 current_entry_index, |
| 650 *web_contents->GetController().GetEntryAtIndex( | 651 *web_contents->GetController().GetEntryAtIndex( |
| 651 current_entry_index)); | 652 current_entry_index)); |
| 652 UpdateTabNavigation( | 653 UpdateTabNavigation( |
| 653 session_tab_helper->window_id(), | 654 session_tab_helper->window_id(), |
| 654 session_tab_helper->session_id(), | 655 session_tab_helper->session_id(), |
| 655 navigation); | 656 navigation); |
| 656 content::Details<content::LoadCommittedDetails> changed(details); | 657 content::Details<content::LoadCommittedDetails> changed(details); |
| 657 if (changed->type == content::NAVIGATION_TYPE_NEW_PAGE || | 658 if (changed->type == content::NAVIGATION_TYPE_NEW_PAGE || |
| 658 changed->type == content::NAVIGATION_TYPE_EXISTING_PAGE) { | 659 changed->type == content::NAVIGATION_TYPE_EXISTING_PAGE) { |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 std::map<int, SessionTab*>::iterator i = tabs->find(tab_id); | 902 std::map<int, SessionTab*>::iterator i = tabs->find(tab_id); |
| 902 if (i == tabs->end()) { | 903 if (i == tabs->end()) { |
| 903 SessionTab* tab = new SessionTab(); | 904 SessionTab* tab = new SessionTab(); |
| 904 tab->tab_id.set_id(tab_id); | 905 tab->tab_id.set_id(tab_id); |
| 905 (*tabs)[tab_id] = tab; | 906 (*tabs)[tab_id] = tab; |
| 906 return tab; | 907 return tab; |
| 907 } | 908 } |
| 908 return i->second; | 909 return i->second; |
| 909 } | 910 } |
| 910 | 911 |
| 911 std::vector<TabNavigation>::iterator | 912 std::vector<SerializedNavigationEntry>::iterator |
| 912 SessionService::FindClosestNavigationWithIndex( | 913 SessionService::FindClosestNavigationWithIndex( |
| 913 std::vector<TabNavigation>* navigations, | 914 std::vector<SerializedNavigationEntry>* navigations, |
| 914 int index) { | 915 int index) { |
| 915 DCHECK(navigations); | 916 DCHECK(navigations); |
| 916 for (std::vector<TabNavigation>::iterator i = navigations->begin(); | 917 for (std::vector<SerializedNavigationEntry>::iterator |
| 917 i != navigations->end(); ++i) { | 918 i = navigations->begin(); i != navigations->end(); ++i) { |
| 918 if (i->index() >= index) | 919 if (i->index() >= index) |
| 919 return i; | 920 return i; |
| 920 } | 921 } |
| 921 return navigations->end(); | 922 return navigations->end(); |
| 922 } | 923 } |
| 923 | 924 |
| 924 // Function used in sorting windows. Sorting is done based on window id. As | 925 // Function used in sorting windows. Sorting is done based on window id. As |
| 925 // window ids increment for each new window, this effectively sorts by creation | 926 // window ids increment for each new window, this effectively sorts by creation |
| 926 // time. | 927 // time. |
| 927 static bool WindowOrderSortFunction(const SessionWindow* w1, | 928 static bool WindowOrderSortFunction(const SessionWindow* w1, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size(); | 974 VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size(); |
| 974 std::map<int, SessionTab*>::iterator i = tabs->begin(); | 975 std::map<int, SessionTab*>::iterator i = tabs->begin(); |
| 975 while (i != tabs->end()) { | 976 while (i != tabs->end()) { |
| 976 SessionTab* tab = i->second; | 977 SessionTab* tab = i->second; |
| 977 if (tab->window_id.id() && !tab->navigations.empty()) { | 978 if (tab->window_id.id() && !tab->navigations.empty()) { |
| 978 SessionWindow* window = GetWindow(tab->window_id.id(), windows); | 979 SessionWindow* window = GetWindow(tab->window_id.id(), windows); |
| 979 window->tabs.push_back(tab); | 980 window->tabs.push_back(tab); |
| 980 tabs->erase(i++); | 981 tabs->erase(i++); |
| 981 | 982 |
| 982 // See note in SessionTab as to why we do this. | 983 // See note in SessionTab as to why we do this. |
| 983 std::vector<TabNavigation>::iterator j = | 984 std::vector<SerializedNavigationEntry>::iterator j = |
| 984 FindClosestNavigationWithIndex(&(tab->navigations), | 985 FindClosestNavigationWithIndex(&(tab->navigations), |
| 985 tab->current_navigation_index); | 986 tab->current_navigation_index); |
| 986 if (j == tab->navigations.end()) { | 987 if (j == tab->navigations.end()) { |
| 987 tab->current_navigation_index = | 988 tab->current_navigation_index = |
| 988 static_cast<int>(tab->navigations.size() - 1); | 989 static_cast<int>(tab->navigations.size() - 1); |
| 989 } else { | 990 } else { |
| 990 tab->current_navigation_index = | 991 tab->current_navigation_index = |
| 991 static_cast<int>(j - tab->navigations.begin()); | 992 static_cast<int>(j - tab->navigations.begin()); |
| 992 } | 993 } |
| 993 } else { | 994 } else { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 VLOG(1) << "Failed reading command " << command->id(); | 1120 VLOG(1) << "Failed reading command " << command->id(); |
| 1120 return true; | 1121 return true; |
| 1121 } | 1122 } |
| 1122 SessionTab* tab = GetTab(payload.id, tabs); | 1123 SessionTab* tab = GetTab(payload.id, tabs); |
| 1123 | 1124 |
| 1124 // Update the selected navigation index. | 1125 // Update the selected navigation index. |
| 1125 tab->current_navigation_index = | 1126 tab->current_navigation_index = |
| 1126 std::max(-1, tab->current_navigation_index - payload.index); | 1127 std::max(-1, tab->current_navigation_index - payload.index); |
| 1127 | 1128 |
| 1128 // And update the index of existing navigations. | 1129 // And update the index of existing navigations. |
| 1129 for (std::vector<TabNavigation>::iterator i = tab->navigations.begin(); | 1130 for (std::vector<SerializedNavigationEntry>::iterator |
| 1131 i = tab->navigations.begin(); |
| 1130 i != tab->navigations.end();) { | 1132 i != tab->navigations.end();) { |
| 1131 i->set_index(i->index() - payload.index); | 1133 i->set_index(i->index() - payload.index); |
| 1132 if (i->index() < 0) | 1134 if (i->index() < 0) |
| 1133 i = tab->navigations.erase(i); | 1135 i = tab->navigations.erase(i); |
| 1134 else | 1136 else |
| 1135 ++i; | 1137 ++i; |
| 1136 } | 1138 } |
| 1137 break; | 1139 break; |
| 1138 } | 1140 } |
| 1139 | 1141 |
| 1140 case kCommandUpdateTabNavigation: { | 1142 case kCommandUpdateTabNavigation: { |
| 1141 TabNavigation navigation; | 1143 SerializedNavigationEntry navigation; |
| 1142 SessionID::id_type tab_id; | 1144 SessionID::id_type tab_id; |
| 1143 if (!RestoreUpdateTabNavigationCommand( | 1145 if (!RestoreUpdateTabNavigationCommand( |
| 1144 *command, &navigation, &tab_id)) { | 1146 *command, &navigation, &tab_id)) { |
| 1145 VLOG(1) << "Failed reading command " << command->id(); | 1147 VLOG(1) << "Failed reading command " << command->id(); |
| 1146 return true; | 1148 return true; |
| 1147 } | 1149 } |
| 1148 SessionTab* tab = GetTab(tab_id, tabs); | 1150 SessionTab* tab = GetTab(tab_id, tabs); |
| 1149 std::vector<TabNavigation>::iterator i = | 1151 std::vector<SerializedNavigationEntry>::iterator i = |
| 1150 FindClosestNavigationWithIndex(&(tab->navigations), | 1152 FindClosestNavigationWithIndex(&(tab->navigations), |
| 1151 navigation.index()); | 1153 navigation.index()); |
| 1152 if (i != tab->navigations.end() && i->index() == navigation.index()) | 1154 if (i != tab->navigations.end() && i->index() == navigation.index()) |
| 1153 *i = navigation; | 1155 *i = navigation; |
| 1154 else | 1156 else |
| 1155 tab->navigations.insert(i, navigation); | 1157 tab->navigations.insert(i, navigation); |
| 1156 break; | 1158 break; |
| 1157 } | 1159 } |
| 1158 | 1160 |
| 1159 case kCommandSetSelectedNavigationIndex: { | 1161 case kCommandSetSelectedNavigationIndex: { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 CreateSetTabUserAgentOverrideCommand( | 1310 CreateSetTabUserAgentOverrideCommand( |
| 1309 kCommandSetTabUserAgentOverride, session_id.id(), ua_override)); | 1311 kCommandSetTabUserAgentOverride, session_id.id(), ua_override)); |
| 1310 } | 1312 } |
| 1311 | 1313 |
| 1312 for (int i = min_index; i < max_index; ++i) { | 1314 for (int i = min_index; i < max_index; ++i) { |
| 1313 const NavigationEntry* entry = (i == pending_index) ? | 1315 const NavigationEntry* entry = (i == pending_index) ? |
| 1314 tab->GetController().GetPendingEntry() : | 1316 tab->GetController().GetPendingEntry() : |
| 1315 tab->GetController().GetEntryAtIndex(i); | 1317 tab->GetController().GetEntryAtIndex(i); |
| 1316 DCHECK(entry); | 1318 DCHECK(entry); |
| 1317 if (ShouldTrackEntry(entry->GetVirtualURL())) { | 1319 if (ShouldTrackEntry(entry->GetVirtualURL())) { |
| 1318 const TabNavigation navigation = | 1320 const SerializedNavigationEntry navigation = |
| 1319 TabNavigation::FromNavigationEntry(i, *entry); | 1321 SerializedNavigationEntry::FromNavigationEntry(i, *entry); |
| 1320 commands->push_back( | 1322 commands->push_back( |
| 1321 CreateUpdateTabNavigationCommand( | 1323 CreateUpdateTabNavigationCommand( |
| 1322 kCommandUpdateTabNavigation, session_id.id(), navigation)); | 1324 kCommandUpdateTabNavigation, session_id.id(), navigation)); |
| 1323 } | 1325 } |
| 1324 } | 1326 } |
| 1325 commands->push_back( | 1327 commands->push_back( |
| 1326 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); | 1328 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); |
| 1327 | 1329 |
| 1328 if (index_in_window != -1) { | 1330 if (index_in_window != -1) { |
| 1329 commands->push_back( | 1331 commands->push_back( |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1759 contents->GetController().GetDefaultSessionStorageNamespace(); | 1761 contents->GetController().GetDefaultSessionStorageNamespace(); |
| 1760 session_storage_namespace->SetShouldPersist(false); | 1762 session_storage_namespace->SetShouldPersist(false); |
| 1761 SessionTabHelper* session_tab_helper = | 1763 SessionTabHelper* session_tab_helper = |
| 1762 SessionTabHelper::FromWebContents(contents); | 1764 SessionTabHelper::FromWebContents(contents); |
| 1763 TabClosed(session_tab_helper->window_id(), | 1765 TabClosed(session_tab_helper->window_id(), |
| 1764 session_tab_helper->session_id(), | 1766 session_tab_helper->session_id(), |
| 1765 contents->GetClosedByUserGesture()); | 1767 contents->GetClosedByUserGesture()); |
| 1766 RecordSessionUpdateHistogramData(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 1768 RecordSessionUpdateHistogramData(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| 1767 &last_updated_tab_closed_time_); | 1769 &last_updated_tab_closed_time_); |
| 1768 } | 1770 } |
| OLD | NEW |