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; | |
sky
2011/08/19 16:59:54
Should this be _DEFAULT?
dhollowa
2011/08/19 17:58:53
No, the DEFAULT state is an indeterminate state, u
| |
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_DEFAULT; | |
974 switch (payload.show_state) { | |
sky
2011/08/19 16:59:54
How about defining a min/max value and making sure
dhollowa
2011/08/19 17:58:53
Done.
| |
975 case 1: | |
976 show_state = ui::SHOW_STATE_NORMAL; | |
977 break; | |
978 case 2: | |
979 show_state = ui::SHOW_STATE_MINIMIZED; | |
980 break; | |
981 case 3: | |
982 show_state = ui::SHOW_STATE_MAXIMIZED; | |
983 break; | |
984 default: | |
985 show_state = ui::SHOW_STATE_NORMAL; | |
986 NOTREACHED(); | |
987 break; | |
988 } | |
989 GetWindow(payload.window_id, windows)->show_state = show_state; | |
990 break; | |
991 } | |
992 | |
952 case kCommandSetTabIndexInWindow: { | 993 case kCommandSetTabIndexInWindow: { |
953 TabIndexInWindowPayload payload; | 994 TabIndexInWindowPayload payload; |
954 if (!command->GetPayload(&payload, sizeof(payload))) | 995 if (!command->GetPayload(&payload, sizeof(payload))) |
955 return true; | 996 return true; |
956 GetTab(payload.id, tabs)->tab_visual_index = payload.index; | 997 GetTab(payload.id, tabs)->tab_visual_index = payload.index; |
957 break; | 998 break; |
958 } | 999 } |
959 | 1000 |
960 case kCommandTabClosed: | 1001 case kCommandTabClosed: |
961 case kCommandWindowClosed: { | 1002 case kCommandWindowClosed: { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 } | 1171 } |
1131 | 1172 |
1132 void SessionService::BuildCommandsForBrowser( | 1173 void SessionService::BuildCommandsForBrowser( |
1133 Browser* browser, | 1174 Browser* browser, |
1134 std::vector<SessionCommand*>* commands, | 1175 std::vector<SessionCommand*>* commands, |
1135 IdToRange* tab_to_available_range, | 1176 IdToRange* tab_to_available_range, |
1136 std::set<SessionID::id_type>* windows_to_track) { | 1177 std::set<SessionID::id_type>* windows_to_track) { |
1137 DCHECK(browser && commands); | 1178 DCHECK(browser && commands); |
1138 DCHECK(browser->session_id().id()); | 1179 DCHECK(browser->session_id().id()); |
1139 | 1180 |
1181 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT; | |
sky
2011/08/19 16:59:54
nit: make this normal and remove last else clause.
dhollowa
2011/08/19 17:58:53
Done.
| |
1182 if (browser->window()->IsMaximized()) | |
1183 show_state = ui::SHOW_STATE_MAXIMIZED; | |
1184 else if (browser->window()->IsMinimized()) | |
1185 show_state = ui::SHOW_STATE_MINIMIZED; | |
1186 else | |
1187 show_state = ui::SHOW_STATE_NORMAL; | |
1188 | |
1140 commands->push_back( | 1189 commands->push_back( |
1141 CreateSetWindowBoundsCommand(browser->session_id(), | 1190 CreateSetWindowBoundsCommand(browser->session_id(), |
1142 browser->window()->GetRestoredBounds(), | 1191 browser->window()->GetRestoredBounds(), |
1143 browser->window()->IsMaximized())); | 1192 show_state)); |
1144 | 1193 |
1145 commands->push_back(CreateSetWindowTypeCommand( | 1194 commands->push_back(CreateSetWindowTypeCommand( |
1146 browser->session_id(), WindowTypeForBrowserType(browser->type()))); | 1195 browser->session_id(), WindowTypeForBrowserType(browser->type()))); |
1147 | 1196 |
1148 bool added_to_windows_to_track = false; | 1197 bool added_to_windows_to_track = false; |
1149 for (int i = 0; i < browser->tab_count(); ++i) { | 1198 for (int i = 0; i < browser->tab_count(); ++i) { |
1150 TabContentsWrapper* tab = browser->GetTabContentsWrapperAt(i); | 1199 TabContentsWrapper* tab = browser->GetTabContentsWrapperAt(i); |
1151 DCHECK(tab); | 1200 DCHECK(tab); |
1152 if (tab->profile() == profile() || profile() == NULL) { | 1201 if (tab->profile() == profile() || profile() == NULL) { |
1153 BuildCommandsForTab(browser->session_id(), tab, i, | 1202 BuildCommandsForTab(browser->session_id(), tab, i, |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1476 50); | 1525 50); |
1477 if (use_long_period) { | 1526 if (use_long_period) { |
1478 std::string long_name_("SessionRestore.SaveLongPeriod"); | 1527 std::string long_name_("SessionRestore.SaveLongPeriod"); |
1479 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, | 1528 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, |
1480 delta, | 1529 delta, |
1481 save_delay_in_mins_, | 1530 save_delay_in_mins_, |
1482 save_delay_in_hrs_, | 1531 save_delay_in_hrs_, |
1483 50); | 1532 50); |
1484 } | 1533 } |
1485 } | 1534 } |
OLD | NEW |