| 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/session_service.h" | 5 #include "chrome/browser/sessions/session_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "content/common/notification_service.h" | 37 #include "content/common/notification_service.h" |
| 38 | 38 |
| 39 #if defined(OS_MACOSX) | 39 #if defined(OS_MACOSX) |
| 40 #include "chrome/browser/app_controller_cppsafe_mac.h" | 40 #include "chrome/browser/app_controller_cppsafe_mac.h" |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 using base::Time; | 43 using base::Time; |
| 44 | 44 |
| 45 // Identifier for commands written to file. | 45 // Identifier for commands written to file. |
| 46 static const SessionCommand::id_type kCommandSetTabWindow = 0; | 46 static const SessionCommand::id_type kCommandSetTabWindow = 0; |
| 47 // kCommandSetWindowBounds is no longer used (it's superseded by | 47 // OBSOLETE Superseded by kCommandSetWindowBounds3. |
| 48 // kCommandSetWindowBounds2). I leave it here to document what it was. | |
| 49 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; | 48 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; |
| 50 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; | 49 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; |
| 51 static const SessionCommand::id_type kCommandTabClosed = 3; | 50 static const SessionCommand::id_type kCommandTabClosed = 3; |
| 52 static const SessionCommand::id_type kCommandWindowClosed = 4; | 51 static const SessionCommand::id_type kCommandWindowClosed = 4; |
| 53 static const SessionCommand::id_type | 52 static const SessionCommand::id_type |
| 54 kCommandTabNavigationPathPrunedFromBack = 5; | 53 kCommandTabNavigationPathPrunedFromBack = 5; |
| 55 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6; | 54 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6; |
| 56 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; | 55 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; |
| 57 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; | 56 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; |
| 58 static const SessionCommand::id_type kCommandSetWindowType = 9; | 57 static const SessionCommand::id_type kCommandSetWindowType = 9; |
| 59 static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | 58 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. |
| 59 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
| 60 static const SessionCommand::id_type | 60 static const SessionCommand::id_type |
| 61 kCommandTabNavigationPathPrunedFromFront = 11; | 61 kCommandTabNavigationPathPrunedFromFront = 11; |
| 62 static const SessionCommand::id_type kCommandSetPinnedState = 12; | 62 static const SessionCommand::id_type kCommandSetPinnedState = 12; |
| 63 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; | 63 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; |
| 64 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; |
| 64 | 65 |
| 65 // Every kWritesPerReset commands triggers recreating the file. | 66 // Every kWritesPerReset commands triggers recreating the file. |
| 66 static const int kWritesPerReset = 250; | 67 static const int kWritesPerReset = 250; |
| 67 | 68 |
| 68 namespace { | 69 namespace { |
| 69 | 70 |
| 70 // The callback from GetLastSession is internally routed to SessionService | 71 // The callback from GetLastSession is internally routed to SessionService |
| 71 // first and then the caller. This is done so that the SessionWindows can be | 72 // first and then the caller. This is done so that the SessionWindows can be |
| 72 // recreated from the SessionCommands and the SessionWindows passed to the | 73 // recreated from the SessionCommands and the SessionWindows passed to the |
| 73 // caller. The following class is used for this. | 74 // caller. The following class is used for this. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 98 | 99 |
| 99 struct WindowBoundsPayload2 { | 100 struct WindowBoundsPayload2 { |
| 100 SessionID::id_type window_id; | 101 SessionID::id_type window_id; |
| 101 int32 x; | 102 int32 x; |
| 102 int32 y; | 103 int32 y; |
| 103 int32 w; | 104 int32 w; |
| 104 int32 h; | 105 int32 h; |
| 105 bool is_maximized; | 106 bool is_maximized; |
| 106 }; | 107 }; |
| 107 | 108 |
| 109 struct WindowBoundsPayload3 { |
| 110 SessionID::id_type window_id; |
| 111 int32 x; |
| 112 int32 y; |
| 113 int32 w; |
| 114 int32 h; |
| 115 int32 show_state; |
| 116 }; |
| 117 |
| 108 struct IDAndIndexPayload { | 118 struct IDAndIndexPayload { |
| 109 SessionID::id_type id; | 119 SessionID::id_type id; |
| 110 int32 index; | 120 int32 index; |
| 111 }; | 121 }; |
| 112 | 122 |
| 113 typedef IDAndIndexPayload TabIndexInWindowPayload; | 123 typedef IDAndIndexPayload TabIndexInWindowPayload; |
| 114 | 124 |
| 115 typedef IDAndIndexPayload TabNavigationPathPrunedFromBackPayload; | 125 typedef IDAndIndexPayload TabNavigationPathPrunedFromBackPayload; |
| 116 | 126 |
| 117 typedef IDAndIndexPayload SelectedNavigationIndexPayload; | 127 typedef IDAndIndexPayload SelectedNavigationIndexPayload; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 void SessionService::SetTabWindow(const SessionID& window_id, | 191 void SessionService::SetTabWindow(const SessionID& window_id, |
| 182 const SessionID& tab_id) { | 192 const SessionID& tab_id) { |
| 183 if (!ShouldTrackChangesToWindow(window_id)) | 193 if (!ShouldTrackChangesToWindow(window_id)) |
| 184 return; | 194 return; |
| 185 | 195 |
| 186 ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id)); | 196 ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id)); |
| 187 } | 197 } |
| 188 | 198 |
| 189 void SessionService::SetWindowBounds(const SessionID& window_id, | 199 void SessionService::SetWindowBounds(const SessionID& window_id, |
| 190 const gfx::Rect& bounds, | 200 const gfx::Rect& bounds, |
| 191 bool is_maximized) { | 201 ui::WindowShowState show_state) { |
| 192 if (!ShouldTrackChangesToWindow(window_id)) | 202 if (!ShouldTrackChangesToWindow(window_id)) |
| 193 return; | 203 return; |
| 194 | 204 |
| 195 ScheduleCommand(CreateSetWindowBoundsCommand(window_id, bounds, | 205 ScheduleCommand(CreateSetWindowBoundsCommand(window_id, bounds, show_state)); |
| 196 is_maximized)); | |
| 197 } | 206 } |
| 198 | 207 |
| 199 void SessionService::SetTabIndexInWindow(const SessionID& window_id, | 208 void SessionService::SetTabIndexInWindow(const SessionID& window_id, |
| 200 const SessionID& tab_id, | 209 const SessionID& tab_id, |
| 201 int new_index) { | 210 int new_index) { |
| 202 if (!ShouldTrackChangesToWindow(window_id)) | 211 if (!ShouldTrackChangesToWindow(window_id)) |
| 203 return; | 212 return; |
| 204 | 213 |
| 205 ScheduleCommand(CreateSetTabIndexInWindowCommand(tab_id, new_index)); | 214 ScheduleCommand(CreateSetTabIndexInWindowCommand(tab_id, new_index)); |
| 206 } | 215 } |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 SessionID::id_type payload[] = { window_id.id(), tab_id.id() }; | 669 SessionID::id_type payload[] = { window_id.id(), tab_id.id() }; |
| 661 SessionCommand* command = | 670 SessionCommand* command = |
| 662 new SessionCommand(kCommandSetTabWindow, sizeof(payload)); | 671 new SessionCommand(kCommandSetTabWindow, sizeof(payload)); |
| 663 memcpy(command->contents(), payload, sizeof(payload)); | 672 memcpy(command->contents(), payload, sizeof(payload)); |
| 664 return command; | 673 return command; |
| 665 } | 674 } |
| 666 | 675 |
| 667 SessionCommand* SessionService::CreateSetWindowBoundsCommand( | 676 SessionCommand* SessionService::CreateSetWindowBoundsCommand( |
| 668 const SessionID& window_id, | 677 const SessionID& window_id, |
| 669 const gfx::Rect& bounds, | 678 const gfx::Rect& bounds, |
| 670 bool is_maximized) { | 679 ui::WindowShowState show_state) { |
| 671 WindowBoundsPayload2 payload = { 0 }; | 680 WindowBoundsPayload3 payload = { 0 }; |
| 672 payload.window_id = window_id.id(); | 681 payload.window_id = window_id.id(); |
| 673 payload.x = bounds.x(); | 682 payload.x = bounds.x(); |
| 674 payload.y = bounds.y(); | 683 payload.y = bounds.y(); |
| 675 payload.w = bounds.width(); | 684 payload.w = bounds.width(); |
| 676 payload.h = bounds.height(); | 685 payload.h = bounds.height(); |
| 677 payload.is_maximized = is_maximized; | 686 payload.show_state = show_state; |
| 678 SessionCommand* command = new SessionCommand(kCommandSetWindowBounds2, | 687 SessionCommand* command = new SessionCommand(kCommandSetWindowBounds3, |
| 679 sizeof(payload)); | 688 sizeof(payload)); |
| 680 memcpy(command->contents(), &payload, sizeof(payload)); | 689 memcpy(command->contents(), &payload, sizeof(payload)); |
| 681 return command; | 690 return command; |
| 682 } | 691 } |
| 683 | 692 |
| 684 SessionCommand* SessionService::CreateSetTabIndexInWindowCommand( | 693 SessionCommand* SessionService::CreateSetTabIndexInWindowCommand( |
| 685 const SessionID& tab_id, | 694 const SessionID& tab_id, |
| 686 int new_index) { | 695 int new_index) { |
| 687 TabIndexInWindowPayload payload = { 0 }; | 696 TabIndexInWindowPayload payload = { 0 }; |
| 688 payload.id = tab_id.id(); | 697 payload.id = tab_id.id(); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 | 927 |
| 919 bool SessionService::CreateTabsAndWindows( | 928 bool SessionService::CreateTabsAndWindows( |
| 920 const std::vector<SessionCommand*>& data, | 929 const std::vector<SessionCommand*>& data, |
| 921 std::map<int, SessionTab*>* tabs, | 930 std::map<int, SessionTab*>* tabs, |
| 922 std::map<int, SessionWindow*>* windows) { | 931 std::map<int, SessionWindow*>* windows) { |
| 923 // If the file is corrupt (command with wrong size, or unknown command), we | 932 // If the file is corrupt (command with wrong size, or unknown command), we |
| 924 // still return true and attempt to restore what we we can. | 933 // still return true and attempt to restore what we we can. |
| 925 | 934 |
| 926 for (std::vector<SessionCommand*>::const_iterator i = data.begin(); | 935 for (std::vector<SessionCommand*>::const_iterator i = data.begin(); |
| 927 i != data.end(); ++i) { | 936 i != data.end(); ++i) { |
| 937 const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
| 928 const SessionCommand* command = *i; | 938 const SessionCommand* command = *i; |
| 929 | 939 |
| 930 switch (command->id()) { | 940 switch (command->id()) { |
| 931 case kCommandSetTabWindow: { | 941 case kCommandSetTabWindow: { |
| 932 SessionID::id_type payload[2]; | 942 SessionID::id_type payload[2]; |
| 933 if (!command->GetPayload(payload, sizeof(payload))) | 943 if (!command->GetPayload(payload, sizeof(payload))) |
| 934 return true; | 944 return true; |
| 935 GetTab(payload[1], tabs)->window_id.set_id(payload[0]); | 945 GetTab(payload[1], tabs)->window_id.set_id(payload[0]); |
| 936 break; | 946 break; |
| 937 } | 947 } |
| 938 | 948 |
| 949 // This is here for forward migration only. New data is saved with |
| 950 // |kCommandSetWindowBounds3|. |
| 939 case kCommandSetWindowBounds2: { | 951 case kCommandSetWindowBounds2: { |
| 940 WindowBoundsPayload2 payload; | 952 WindowBoundsPayload2 payload; |
| 941 if (!command->GetPayload(&payload, sizeof(payload))) | 953 if (!command->GetPayload(&payload, sizeof(payload))) |
| 942 return true; | 954 return true; |
| 943 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, | 955 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, |
| 944 payload.y, | 956 payload.y, |
| 945 payload.w, | 957 payload.w, |
| 946 payload.h); | 958 payload.h); |
| 947 GetWindow(payload.window_id, windows)->is_maximized = | 959 GetWindow(payload.window_id, windows)->show_state = |
| 948 payload.is_maximized; | 960 payload.is_maximized ? |
| 961 ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL; |
| 949 break; | 962 break; |
| 950 } | 963 } |
| 951 | 964 |
| 965 case kCommandSetWindowBounds3: { |
| 966 WindowBoundsPayload3 payload; |
| 967 if (!command->GetPayload(&payload, sizeof(payload))) |
| 968 return true; |
| 969 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, |
| 970 payload.y, |
| 971 payload.w, |
| 972 payload.h); |
| 973 ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL; |
| 974 if (payload.show_state > ui::SHOW_STATE_DEFAULT && |
| 975 payload.show_state < ui::SHOW_STATE_MAX) { |
| 976 show_state = static_cast<ui::WindowShowState>(payload.show_state); |
| 977 } else { |
| 978 NOTREACHED(); |
| 979 } |
| 980 GetWindow(payload.window_id, windows)->show_state = show_state; |
| 981 break; |
| 982 } |
| 983 |
| 952 case kCommandSetTabIndexInWindow: { | 984 case kCommandSetTabIndexInWindow: { |
| 953 TabIndexInWindowPayload payload; | 985 TabIndexInWindowPayload payload; |
| 954 if (!command->GetPayload(&payload, sizeof(payload))) | 986 if (!command->GetPayload(&payload, sizeof(payload))) |
| 955 return true; | 987 return true; |
| 956 GetTab(payload.id, tabs)->tab_visual_index = payload.index; | 988 GetTab(payload.id, tabs)->tab_visual_index = payload.index; |
| 957 break; | 989 break; |
| 958 } | 990 } |
| 959 | 991 |
| 960 case kCommandTabClosed: | 992 case kCommandTabClosed: |
| 961 case kCommandWindowClosed: { | 993 case kCommandWindowClosed: { |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 } | 1162 } |
| 1131 | 1163 |
| 1132 void SessionService::BuildCommandsForBrowser( | 1164 void SessionService::BuildCommandsForBrowser( |
| 1133 Browser* browser, | 1165 Browser* browser, |
| 1134 std::vector<SessionCommand*>* commands, | 1166 std::vector<SessionCommand*>* commands, |
| 1135 IdToRange* tab_to_available_range, | 1167 IdToRange* tab_to_available_range, |
| 1136 std::set<SessionID::id_type>* windows_to_track) { | 1168 std::set<SessionID::id_type>* windows_to_track) { |
| 1137 DCHECK(browser && commands); | 1169 DCHECK(browser && commands); |
| 1138 DCHECK(browser->session_id().id()); | 1170 DCHECK(browser->session_id().id()); |
| 1139 | 1171 |
| 1172 ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL; |
| 1173 if (browser->window()->IsMaximized()) |
| 1174 show_state = ui::SHOW_STATE_MAXIMIZED; |
| 1175 else if (browser->window()->IsMinimized()) |
| 1176 show_state = ui::SHOW_STATE_MINIMIZED; |
| 1177 |
| 1140 commands->push_back( | 1178 commands->push_back( |
| 1141 CreateSetWindowBoundsCommand(browser->session_id(), | 1179 CreateSetWindowBoundsCommand(browser->session_id(), |
| 1142 browser->window()->GetRestoredBounds(), | 1180 browser->window()->GetRestoredBounds(), |
| 1143 browser->window()->IsMaximized())); | 1181 show_state)); |
| 1144 | 1182 |
| 1145 commands->push_back(CreateSetWindowTypeCommand( | 1183 commands->push_back(CreateSetWindowTypeCommand( |
| 1146 browser->session_id(), WindowTypeForBrowserType(browser->type()))); | 1184 browser->session_id(), WindowTypeForBrowserType(browser->type()))); |
| 1147 | 1185 |
| 1148 bool added_to_windows_to_track = false; | 1186 bool added_to_windows_to_track = false; |
| 1149 for (int i = 0; i < browser->tab_count(); ++i) { | 1187 for (int i = 0; i < browser->tab_count(); ++i) { |
| 1150 TabContentsWrapper* tab = browser->GetTabContentsWrapperAt(i); | 1188 TabContentsWrapper* tab = browser->GetTabContentsWrapperAt(i); |
| 1151 DCHECK(tab); | 1189 DCHECK(tab); |
| 1152 if (tab->profile() == profile() || profile() == NULL) { | 1190 if (tab->profile() == profile() || profile() == NULL) { |
| 1153 BuildCommandsForTab(browser->session_id(), tab, i, | 1191 BuildCommandsForTab(browser->session_id(), tab, i, |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 50); | 1514 50); |
| 1477 if (use_long_period) { | 1515 if (use_long_period) { |
| 1478 std::string long_name_("SessionRestore.SaveLongPeriod"); | 1516 std::string long_name_("SessionRestore.SaveLongPeriod"); |
| 1479 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, | 1517 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, |
| 1480 delta, | 1518 delta, |
| 1481 save_delay_in_mins_, | 1519 save_delay_in_mins_, |
| 1482 save_delay_in_hrs_, | 1520 save_delay_in_hrs_, |
| 1483 50); | 1521 50); |
| 1484 } | 1522 } |
| 1485 } | 1523 } |
| OLD | NEW |