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 11 matching lines...) Expand all Loading... | |
22 #include "chrome/browser/defaults.h" | 22 #include "chrome/browser/defaults.h" |
23 #include "chrome/browser/extensions/tab_helper.h" | 23 #include "chrome/browser/extensions/tab_helper.h" |
24 #include "chrome/browser/prefs/session_startup_pref.h" | 24 #include "chrome/browser/prefs/session_startup_pref.h" |
25 #include "chrome/browser/profiles/profile.h" | 25 #include "chrome/browser/profiles/profile.h" |
26 #include "chrome/browser/profiles/profile_manager.h" | 26 #include "chrome/browser/profiles/profile_manager.h" |
27 #include "chrome/browser/sessions/base_session_service_delegate_impl.h" | 27 #include "chrome/browser/sessions/base_session_service_delegate_impl.h" |
28 #include "chrome/browser/sessions/session_backend.h" | 28 #include "chrome/browser/sessions/session_backend.h" |
29 #include "chrome/browser/sessions/session_command.h" | 29 #include "chrome/browser/sessions/session_command.h" |
30 #include "chrome/browser/sessions/session_data_deleter.h" | 30 #include "chrome/browser/sessions/session_data_deleter.h" |
31 #include "chrome/browser/sessions/session_restore.h" | 31 #include "chrome/browser/sessions/session_restore.h" |
32 #include "chrome/browser/sessions/session_service_utils.h" | |
32 #include "chrome/browser/sessions/session_tab_helper.h" | 33 #include "chrome/browser/sessions/session_tab_helper.h" |
33 #include "chrome/browser/sessions/session_types.h" | 34 #include "chrome/browser/sessions/session_types.h" |
34 #include "chrome/browser/ui/browser_iterator.h" | 35 #include "chrome/browser/ui/browser_iterator.h" |
35 #include "chrome/browser/ui/browser_list.h" | 36 #include "chrome/browser/ui/browser_list.h" |
36 #include "chrome/browser/ui/browser_tabstrip.h" | 37 #include "chrome/browser/ui/browser_tabstrip.h" |
37 #include "chrome/browser/ui/browser_window.h" | 38 #include "chrome/browser/ui/browser_window.h" |
38 #include "chrome/browser/ui/host_desktop.h" | 39 #include "chrome/browser/ui/host_desktop.h" |
39 #include "chrome/browser/ui/startup/startup_browser_creator.h" | 40 #include "chrome/browser/ui/startup/startup_browser_creator.h" |
40 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 41 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
41 #include "components/sessions/content/content_serialized_navigation_builder.h" | 42 #include "components/sessions/content/content_serialized_navigation_builder.h" |
42 #include "components/startup_metric_utils/startup_metric_utils.h" | 43 #include "components/startup_metric_utils/startup_metric_utils.h" |
43 #include "content/public/browser/navigation_details.h" | 44 #include "content/public/browser/navigation_details.h" |
44 #include "content/public/browser/navigation_entry.h" | 45 #include "content/public/browser/navigation_entry.h" |
45 #include "content/public/browser/notification_details.h" | 46 #include "content/public/browser/notification_details.h" |
46 #include "content/public/browser/notification_service.h" | 47 #include "content/public/browser/notification_service.h" |
47 #include "content/public/browser/session_storage_namespace.h" | 48 #include "content/public/browser/session_storage_namespace.h" |
48 #include "content/public/browser/web_contents.h" | 49 #include "content/public/browser/web_contents.h" |
49 #include "extensions/common/extension.h" | 50 #include "extensions/common/extension.h" |
50 | 51 |
51 #if defined(OS_MACOSX) | 52 #if defined(OS_MACOSX) |
52 #include "chrome/browser/app_controller_mac.h" | 53 #include "chrome/browser/app_controller_mac.h" |
53 #endif | 54 #endif |
54 | 55 |
55 using base::Time; | 56 using base::Time; |
56 using content::NavigationEntry; | 57 using content::NavigationEntry; |
57 using content::WebContents; | 58 using content::WebContents; |
58 using sessions::ContentSerializedNavigationBuilder; | 59 using sessions::ContentSerializedNavigationBuilder; |
59 using sessions::SerializedNavigationEntry; | 60 using sessions::SerializedNavigationEntry; |
60 | 61 |
61 // Identifier for commands written to file. | |
62 static const SessionCommand::id_type kCommandSetTabWindow = 0; | |
63 // OBSOLETE Superseded by kCommandSetWindowBounds3. | |
64 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; | |
65 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; | |
66 // OBSOLETE Superseded kCommandTabClosed/kCommandWindowClosed commands. | |
67 // static const SessionCommand::id_type kCommandTabClosedObsolete = 3; | |
68 // static const SessionCommand::id_type kCommandWindowClosedObsolete = 4; | |
69 static const SessionCommand::id_type | |
70 kCommandTabNavigationPathPrunedFromBack = 5; | |
71 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6; | |
72 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; | |
73 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; | |
74 static const SessionCommand::id_type kCommandSetWindowType = 9; | |
75 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. | |
76 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | |
77 static const SessionCommand::id_type | |
78 kCommandTabNavigationPathPrunedFromFront = 11; | |
79 static const SessionCommand::id_type kCommandSetPinnedState = 12; | |
80 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; | |
81 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; | |
82 static const SessionCommand::id_type kCommandSetWindowAppName = 15; | |
83 static const SessionCommand::id_type kCommandTabClosed = 16; | |
84 static const SessionCommand::id_type kCommandWindowClosed = 17; | |
85 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18; | |
86 static const SessionCommand::id_type kCommandSessionStorageAssociated = 19; | |
87 static const SessionCommand::id_type kCommandSetActiveWindow = 20; | |
88 | |
89 // Every kWritesPerReset commands triggers recreating the file. | 62 // Every kWritesPerReset commands triggers recreating the file. |
90 static const int kWritesPerReset = 250; | 63 static const int kWritesPerReset = 250; |
91 | 64 |
92 namespace { | |
93 | |
94 // Various payload structures. | |
95 struct ClosedPayload { | |
96 SessionID::id_type id; | |
97 int64 close_time; | |
98 }; | |
99 | |
100 struct WindowBoundsPayload2 { | |
101 SessionID::id_type window_id; | |
102 int32 x; | |
103 int32 y; | |
104 int32 w; | |
105 int32 h; | |
106 bool is_maximized; | |
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 | |
118 typedef SessionID::id_type ActiveWindowPayload; | |
119 | |
120 struct IDAndIndexPayload { | |
121 SessionID::id_type id; | |
122 int32 index; | |
123 }; | |
124 | |
125 typedef IDAndIndexPayload TabIndexInWindowPayload; | |
126 | |
127 typedef IDAndIndexPayload TabNavigationPathPrunedFromBackPayload; | |
128 | |
129 typedef IDAndIndexPayload SelectedNavigationIndexPayload; | |
130 | |
131 typedef IDAndIndexPayload SelectedTabInIndexPayload; | |
132 | |
133 typedef IDAndIndexPayload WindowTypePayload; | |
134 | |
135 typedef IDAndIndexPayload TabNavigationPathPrunedFromFrontPayload; | |
136 | |
137 struct PinnedStatePayload { | |
138 SessionID::id_type tab_id; | |
139 bool pinned_state; | |
140 }; | |
141 | |
142 // Persisted versions of ui::WindowShowState that are written to disk and can | |
143 // never change. | |
144 enum PersistedWindowShowState { | |
145 // SHOW_STATE_DEFAULT (0) never persisted. | |
146 PERSISTED_SHOW_STATE_NORMAL = 1, | |
147 PERSISTED_SHOW_STATE_MINIMIZED = 2, | |
148 PERSISTED_SHOW_STATE_MAXIMIZED = 3, | |
149 // SHOW_STATE_INACTIVE (4) never persisted. | |
150 PERSISTED_SHOW_STATE_FULLSCREEN = 5, | |
151 PERSISTED_SHOW_STATE_DETACHED_DEPRECATED = 6, | |
152 PERSISTED_SHOW_STATE_END = 6 | |
153 }; | |
154 | |
155 // Assert to ensure PersistedWindowShowState is updated if ui::WindowShowState | |
156 // is changed. | |
157 COMPILE_ASSERT(ui::SHOW_STATE_END == | |
158 static_cast<ui::WindowShowState>(PERSISTED_SHOW_STATE_END), | |
159 persisted_show_state_mismatch); | |
160 | |
161 // Returns the show state to store to disk based |state|. | |
162 PersistedWindowShowState ShowStateToPersistedShowState( | |
163 ui::WindowShowState state) { | |
164 switch (state) { | |
165 case ui::SHOW_STATE_NORMAL: | |
166 return PERSISTED_SHOW_STATE_NORMAL; | |
167 case ui::SHOW_STATE_MINIMIZED: | |
168 return PERSISTED_SHOW_STATE_MINIMIZED; | |
169 case ui::SHOW_STATE_MAXIMIZED: | |
170 return PERSISTED_SHOW_STATE_MAXIMIZED; | |
171 case ui::SHOW_STATE_FULLSCREEN: | |
172 return PERSISTED_SHOW_STATE_FULLSCREEN; | |
173 | |
174 case ui::SHOW_STATE_DEFAULT: | |
175 case ui::SHOW_STATE_INACTIVE: | |
176 return PERSISTED_SHOW_STATE_NORMAL; | |
177 | |
178 case ui::SHOW_STATE_END: | |
179 break; | |
180 } | |
181 NOTREACHED(); | |
182 return PERSISTED_SHOW_STATE_NORMAL; | |
183 } | |
184 | |
185 // Lints show state values when read back from persited disk. | |
186 ui::WindowShowState PersistedShowStateToShowState(int state) { | |
187 switch (state) { | |
188 case PERSISTED_SHOW_STATE_NORMAL: | |
189 return ui::SHOW_STATE_NORMAL; | |
190 case PERSISTED_SHOW_STATE_MINIMIZED: | |
191 return ui::SHOW_STATE_MINIMIZED; | |
192 case PERSISTED_SHOW_STATE_MAXIMIZED: | |
193 return ui::SHOW_STATE_MAXIMIZED; | |
194 case PERSISTED_SHOW_STATE_FULLSCREEN: | |
195 return ui::SHOW_STATE_FULLSCREEN; | |
196 case PERSISTED_SHOW_STATE_DETACHED_DEPRECATED: | |
197 return ui::SHOW_STATE_NORMAL; | |
198 } | |
199 NOTREACHED(); | |
200 return ui::SHOW_STATE_NORMAL; | |
201 } | |
202 | |
203 } // namespace | |
204 | |
205 // SessionService ------------------------------------------------------------- | 65 // SessionService ------------------------------------------------------------- |
206 | 66 |
207 SessionService::SessionService(Profile* profile) | 67 SessionService::SessionService(Profile* profile) |
208 : BaseSessionService( | 68 : BaseSessionService( |
209 SESSION_RESTORE, | 69 SESSION_RESTORE, |
210 profile->GetPath(), | 70 profile->GetPath(), |
211 scoped_ptr<BaseSessionServiceDelegate>( | 71 scoped_ptr<BaseSessionServiceDelegate>( |
212 new BaseSessionServiceDelegateImpl(true))), | 72 new BaseSessionServiceDelegateImpl(true))), |
213 profile_(profile), | 73 profile_(profile), |
214 has_open_trackable_browsers_(false), | 74 has_open_trackable_browsers_(false), |
(...skipping 30 matching lines...) Expand all Loading... | |
245 // the SessionService is a KeyedService. | 105 // the SessionService is a KeyedService. |
246 BrowserList::RemoveObserver(this); | 106 BrowserList::RemoveObserver(this); |
247 Save(); | 107 Save(); |
248 } | 108 } |
249 | 109 |
250 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { | 110 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { |
251 return RestoreIfNecessary(urls_to_open, NULL); | 111 return RestoreIfNecessary(urls_to_open, NULL); |
252 } | 112 } |
253 | 113 |
254 void SessionService::ResetFromCurrentBrowsers() { | 114 void SessionService::ResetFromCurrentBrowsers() { |
255 ScheduleReset(); | 115 ScheduleResetCommands(); |
256 } | 116 } |
257 | 117 |
258 void SessionService::MoveCurrentSessionToLastSession() { | 118 void SessionService::MoveCurrentSessionToLastSession() { |
259 pending_tab_close_ids_.clear(); | 119 pending_tab_close_ids_.clear(); |
260 window_closing_ids_.clear(); | 120 window_closing_ids_.clear(); |
261 pending_window_close_ids_.clear(); | 121 pending_window_close_ids_.clear(); |
262 | 122 |
263 Save(); | 123 Save(); |
264 | 124 |
265 RunTaskOnBackendThread( | 125 RunTaskOnBackendThread( |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 // tab closed. | 196 // tab closed. |
337 pending_tab_close_ids_.insert(tab_id.id()); | 197 pending_tab_close_ids_.insert(tab_id.id()); |
338 has_open_trackable_browsers_ = false; | 198 has_open_trackable_browsers_ = false; |
339 } | 199 } |
340 } | 200 } |
341 | 201 |
342 void SessionService::WindowOpened(Browser* browser) { | 202 void SessionService::WindowOpened(Browser* browser) { |
343 if (!ShouldTrackBrowser(browser)) | 203 if (!ShouldTrackBrowser(browser)) |
344 return; | 204 return; |
345 | 205 |
346 AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL; | |
347 RestoreIfNecessary(std::vector<GURL>(), browser); | 206 RestoreIfNecessary(std::vector<GURL>(), browser); |
348 SetWindowType(browser->session_id(), browser->type(), app_type); | 207 SetWindowType(browser->session_id(), |
208 browser->type(), | |
209 browser->is_app() ? TYPE_APP : TYPE_NORMAL); | |
349 SetWindowAppName(browser->session_id(), browser->app_name()); | 210 SetWindowAppName(browser->session_id(), browser->app_name()); |
350 } | 211 } |
351 | 212 |
352 void SessionService::WindowClosing(const SessionID& window_id) { | 213 void SessionService::WindowClosing(const SessionID& window_id) { |
353 if (!ShouldTrackChangesToWindow(window_id)) | 214 if (!ShouldTrackChangesToWindow(window_id)) |
354 return; | 215 return; |
355 | 216 |
356 // The window is about to close. If there are other tabbed browsers with the | 217 // The window is about to close. If there are other tabbed browsers with the |
357 // same original profile commit the close immediately. | 218 // same original profile commit the close immediately. |
358 // | 219 // |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 pending_window_close_ids_.insert(window_id.id()); | 273 pending_window_close_ids_.insert(window_id.id()); |
413 else | 274 else |
414 ScheduleCommand(CreateWindowClosedCommand(window_id.id())); | 275 ScheduleCommand(CreateWindowClosedCommand(window_id.id())); |
415 } | 276 } |
416 MaybeDeleteSessionOnlyData(); | 277 MaybeDeleteSessionOnlyData(); |
417 } | 278 } |
418 | 279 |
419 void SessionService::SetWindowType(const SessionID& window_id, | 280 void SessionService::SetWindowType(const SessionID& window_id, |
420 Browser::Type type, | 281 Browser::Type type, |
421 AppType app_type) { | 282 AppType app_type) { |
422 if (!should_track_changes_for_browser_type(type, app_type)) | 283 SessionWindow::WindowType window_type = WindowTypeForBrowserType(type); |
284 if (!ShouldRestoreWindowOfType(window_type, app_type)) | |
423 return; | 285 return; |
424 | 286 |
425 windows_tracking_.insert(window_id.id()); | 287 windows_tracking_.insert(window_id.id()); |
426 | 288 |
427 // The user created a new tabbed browser with our profile. Commit any | 289 // The user created a new tabbed browser with our profile. Commit any |
428 // pending closes. | 290 // pending closes. |
429 CommitPendingCloses(); | 291 CommitPendingCloses(); |
430 | 292 |
431 has_open_trackable_browsers_ = true; | 293 has_open_trackable_browsers_ = true; |
432 move_on_new_browser_ = true; | 294 move_on_new_browser_ = true; |
433 | 295 |
434 ScheduleCommand( | 296 ScheduleCommand(CreateSetWindowTypeCommand(window_id, window_type)); |
435 CreateSetWindowTypeCommand(window_id, WindowTypeForBrowserType(type))); | |
436 } | 297 } |
437 | 298 |
438 void SessionService::SetWindowAppName( | 299 void SessionService::SetWindowAppName( |
439 const SessionID& window_id, | 300 const SessionID& window_id, |
440 const std::string& app_name) { | 301 const std::string& app_name) { |
441 if (!ShouldTrackChangesToWindow(window_id)) | 302 if (!ShouldTrackChangesToWindow(window_id)) |
442 return; | 303 return; |
443 | 304 |
444 ScheduleCommand(CreateSetTabExtensionAppIDCommand( | 305 ScheduleCommand(CreateSetWindowAppNameCommand(window_id, app_name)); |
445 kCommandSetWindowAppName, | |
446 window_id.id(), | |
447 app_name)); | |
448 } | 306 } |
449 | 307 |
450 void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id, | 308 void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id, |
451 const SessionID& tab_id, | 309 const SessionID& tab_id, |
452 int count) { | 310 int count) { |
453 if (!ShouldTrackChangesToWindow(window_id)) | 311 if (!ShouldTrackChangesToWindow(window_id)) |
454 return; | 312 return; |
455 | 313 |
456 TabNavigationPathPrunedFromBackPayload payload = { 0 }; | 314 ScheduleCommand(CreateTabNavigationPathPrunedFromBackCommand(tab_id, count)); |
457 payload.id = tab_id.id(); | |
458 payload.index = count; | |
459 SessionCommand* command = | |
460 new SessionCommand(kCommandTabNavigationPathPrunedFromBack, | |
461 sizeof(payload)); | |
462 memcpy(command->contents(), &payload, sizeof(payload)); | |
463 ScheduleCommand(command); | |
464 } | 315 } |
465 | 316 |
466 void SessionService::TabNavigationPathPrunedFromFront( | 317 void SessionService::TabNavigationPathPrunedFromFront( |
467 const SessionID& window_id, | 318 const SessionID& window_id, |
468 const SessionID& tab_id, | 319 const SessionID& tab_id, |
469 int count) { | 320 int count) { |
470 if (!ShouldTrackChangesToWindow(window_id)) | 321 if (!ShouldTrackChangesToWindow(window_id)) |
471 return; | 322 return; |
472 | 323 |
473 // Update the range of indices. | 324 // Update the range of indices. |
474 if (tab_to_available_range_.find(tab_id.id()) != | 325 if (tab_to_available_range_.find(tab_id.id()) != |
475 tab_to_available_range_.end()) { | 326 tab_to_available_range_.end()) { |
476 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 327 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
477 range.first = std::max(0, range.first - count); | 328 range.first = std::max(0, range.first - count); |
478 range.second = std::max(0, range.second - count); | 329 range.second = std::max(0, range.second - count); |
479 } | 330 } |
480 | 331 |
481 TabNavigationPathPrunedFromFrontPayload payload = { 0 }; | 332 ScheduleCommand(CreateTabNavigationPathPrunedFromFrontCommand(tab_id, count)); |
482 payload.id = tab_id.id(); | |
483 payload.index = count; | |
484 SessionCommand* command = | |
485 new SessionCommand(kCommandTabNavigationPathPrunedFromFront, | |
486 sizeof(payload)); | |
487 memcpy(command->contents(), &payload, sizeof(payload)); | |
488 ScheduleCommand(command); | |
489 } | 333 } |
490 | 334 |
491 void SessionService::UpdateTabNavigation( | 335 void SessionService::UpdateTabNavigation( |
492 const SessionID& window_id, | 336 const SessionID& window_id, |
493 const SessionID& tab_id, | 337 const SessionID& tab_id, |
494 const SerializedNavigationEntry& navigation) { | 338 const SerializedNavigationEntry& navigation) { |
495 if (!ShouldTrackEntry(navigation.virtual_url()) || | 339 if (!ShouldTrackEntry(navigation.virtual_url()) || |
496 !ShouldTrackChangesToWindow(window_id)) { | 340 !ShouldTrackChangesToWindow(window_id)) { |
497 return; | 341 return; |
498 } | 342 } |
499 | 343 |
500 if (tab_to_available_range_.find(tab_id.id()) != | 344 if (tab_to_available_range_.find(tab_id.id()) != |
501 tab_to_available_range_.end()) { | 345 tab_to_available_range_.end()) { |
502 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 346 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
503 range.first = std::min(navigation.index(), range.first); | 347 range.first = std::min(navigation.index(), range.first); |
504 range.second = std::max(navigation.index(), range.second); | 348 range.second = std::max(navigation.index(), range.second); |
505 } | 349 } |
506 ScheduleCommand(CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, | 350 ScheduleCommand(CreateUpdateTabNavigationCommand(tab_id, navigation)); |
507 tab_id.id(), navigation)); | |
508 } | 351 } |
509 | 352 |
510 void SessionService::TabRestored(WebContents* tab, bool pinned) { | 353 void SessionService::TabRestored(WebContents* tab, bool pinned) { |
511 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); | 354 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); |
512 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) | 355 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) |
513 return; | 356 return; |
514 | 357 |
515 BuildCommandsForTab(session_tab_helper->window_id(), tab, -1, | 358 BuildCommandsForTab(session_tab_helper->window_id(), tab, -1, |
516 pinned, &pending_commands(), NULL); | 359 pinned, &pending_commands(), NULL); |
517 StartSaveTimer(); | 360 StartSaveTimer(); |
(...skipping 16 matching lines...) Expand all Loading... | |
534 } | 377 } |
535 } | 378 } |
536 ScheduleCommand(CreateSetSelectedNavigationIndexCommand(tab_id, index)); | 379 ScheduleCommand(CreateSetSelectedNavigationIndexCommand(tab_id, index)); |
537 } | 380 } |
538 | 381 |
539 void SessionService::SetSelectedTabInWindow(const SessionID& window_id, | 382 void SessionService::SetSelectedTabInWindow(const SessionID& window_id, |
540 int index) { | 383 int index) { |
541 if (!ShouldTrackChangesToWindow(window_id)) | 384 if (!ShouldTrackChangesToWindow(window_id)) |
542 return; | 385 return; |
543 | 386 |
544 ScheduleCommand(CreateSetSelectedTabInWindow(window_id, index)); | 387 ScheduleCommand(CreateSetSelectedTabInWindowCommand(window_id, index)); |
545 } | 388 } |
546 | 389 |
547 void SessionService::SetTabUserAgentOverride( | 390 void SessionService::SetTabUserAgentOverride( |
548 const SessionID& window_id, | 391 const SessionID& window_id, |
549 const SessionID& tab_id, | 392 const SessionID& tab_id, |
550 const std::string& user_agent_override) { | 393 const std::string& user_agent_override) { |
551 if (!ShouldTrackChangesToWindow(window_id)) | 394 if (!ShouldTrackChangesToWindow(window_id)) |
552 return; | 395 return; |
553 | 396 |
554 ScheduleCommand(CreateSetTabUserAgentOverrideCommand( | 397 ScheduleCommand(CreateSetTabUserAgentOverrideCommand(tab_id, |
555 kCommandSetTabUserAgentOverride, tab_id.id(), user_agent_override)); | 398 user_agent_override)); |
399 } | |
400 | |
401 void SessionService::SetTabExtensionAppID( | |
402 const SessionID& window_id, | |
403 const SessionID& tab_id, | |
404 const std::string& extension_app_id) { | |
405 if (!ShouldTrackChangesToWindow(window_id)) | |
406 return; | |
407 | |
408 ScheduleCommand(CreateSetTabExtensionAppIDCommand(tab_id, extension_app_id)); | |
556 } | 409 } |
557 | 410 |
558 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( | 411 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( |
559 const SessionCallback& callback, | 412 const SessionCallback& callback, |
560 base::CancelableTaskTracker* tracker) { | 413 base::CancelableTaskTracker* tracker) { |
561 // OnGotSessionCommands maps the SessionCommands to browser state, then run | 414 // OnGotSessionCommands maps the SessionCommands to browser state, then run |
562 // the callback. | 415 // the callback. |
563 return ScheduleGetLastSessionCommands( | 416 return ScheduleGetLastSessionCommands( |
564 base::Bind(&SessionService::OnGotSessionCommands, | 417 base::Bind(&SessionService::OnGotSessionCommands, |
565 weak_factory_.GetWeakPtr(), callback), | 418 weak_factory_.GetWeakPtr(), callback), |
(...skipping 21 matching lines...) Expand all Loading... | |
587 content::NotificationService::AllSources()); | 440 content::NotificationService::AllSources()); |
588 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 441 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
589 content::NotificationService::AllSources()); | 442 content::NotificationService::AllSources()); |
590 registrar_.Add( | 443 registrar_.Add( |
591 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, | 444 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, |
592 content::NotificationService::AllSources()); | 445 content::NotificationService::AllSources()); |
593 | 446 |
594 BrowserList::AddObserver(this); | 447 BrowserList::AddObserver(this); |
595 } | 448 } |
596 | 449 |
450 bool SessionService::ShouldRestoreWindowOfType( | |
451 SessionWindow::WindowType window_type, | |
452 AppType app_type) const { | |
453 #if defined(OS_CHROMEOS) | |
454 // Restore app popups for ChromeOS alone. | |
455 if (window_type == SessionWindow::TYPE_POPUP && app_type == TYPE_APP) | |
456 return true; | |
457 #endif | |
458 | |
459 return window_type == SessionWindow::TYPE_TABBED; | |
460 } | |
461 | |
462 void SessionService::RemoveUnusedRestoreWindows( | |
463 std::vector<SessionWindow*>* window_list) { | |
464 std::vector<SessionWindow*>::iterator i = window_list->begin(); | |
465 while (i != window_list->end()) { | |
sky
2014/10/29 23:58:03
You never increment i if it should be restored.
Mr4D (OOO till 08-26)
2014/10/30 00:04:25
Done.
| |
466 SessionWindow* window = *i; | |
467 if (!ShouldRestoreWindowOfType(window->type, | |
468 window->app_name.empty() ? TYPE_NORMAL : | |
469 TYPE_APP)) { | |
470 delete (*i); | |
471 window_list->erase(i); | |
472 i = window_list->begin(); | |
sky
2014/10/29 23:58:03
See line 1013 old for how to do this in an efficie
Mr4D (OOO till 08-26)
2014/10/30 00:04:25
Done.
| |
473 } | |
474 } | |
475 } | |
476 | |
597 bool SessionService::processed_any_commands() { | 477 bool SessionService::processed_any_commands() { |
598 return backend()->inited() || !pending_commands().empty(); | 478 return backend()->inited() || !pending_commands().empty(); |
599 } | 479 } |
600 | 480 |
601 bool SessionService::ShouldNewWindowStartSession() { | 481 bool SessionService::ShouldNewWindowStartSession() { |
602 // ChromeOS and OSX have different ideas of application lifetime than | 482 // ChromeOS and OSX have different ideas of application lifetime than |
603 // the other platforms. | 483 // the other platforms. |
604 // On ChromeOS opening a new window should never start a new session. | 484 // On ChromeOS opening a new window should never start a new session. |
605 #if defined(OS_CHROMEOS) | 485 #if defined(OS_CHROMEOS) |
606 if (!force_browser_not_alive_with_no_windows_) | 486 if (!force_browser_not_alive_with_no_windows_) |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
745 default: | 625 default: |
746 NOTREACHED(); | 626 NOTREACHED(); |
747 } | 627 } |
748 } | 628 } |
749 | 629 |
750 void SessionService::OnBrowserSetLastActive(Browser* browser) { | 630 void SessionService::OnBrowserSetLastActive(Browser* browser) { |
751 if (ShouldTrackBrowser(browser)) | 631 if (ShouldTrackBrowser(browser)) |
752 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); | 632 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); |
753 } | 633 } |
754 | 634 |
755 void SessionService::SetTabExtensionAppID( | |
756 const SessionID& window_id, | |
757 const SessionID& tab_id, | |
758 const std::string& extension_app_id) { | |
759 if (!ShouldTrackChangesToWindow(window_id)) | |
760 return; | |
761 | |
762 ScheduleCommand(CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID, | |
763 tab_id.id(), extension_app_id)); | |
764 } | |
765 | |
766 SessionCommand* SessionService::CreateSetSelectedTabInWindow( | |
767 const SessionID& window_id, | |
768 int index) { | |
769 SelectedTabInIndexPayload payload = { 0 }; | |
770 payload.id = window_id.id(); | |
771 payload.index = index; | |
772 SessionCommand* command = new SessionCommand(kCommandSetSelectedTabInIndex, | |
773 sizeof(payload)); | |
774 memcpy(command->contents(), &payload, sizeof(payload)); | |
775 return command; | |
776 } | |
777 | |
778 SessionCommand* SessionService::CreateSetTabWindowCommand( | |
779 const SessionID& window_id, | |
780 const SessionID& tab_id) { | |
781 SessionID::id_type payload[] = { window_id.id(), tab_id.id() }; | |
782 SessionCommand* command = | |
783 new SessionCommand(kCommandSetTabWindow, sizeof(payload)); | |
784 memcpy(command->contents(), payload, sizeof(payload)); | |
785 return command; | |
786 } | |
787 | |
788 SessionCommand* SessionService::CreateSetWindowBoundsCommand( | |
789 const SessionID& window_id, | |
790 const gfx::Rect& bounds, | |
791 ui::WindowShowState show_state) { | |
792 WindowBoundsPayload3 payload = { 0 }; | |
793 payload.window_id = window_id.id(); | |
794 payload.x = bounds.x(); | |
795 payload.y = bounds.y(); | |
796 payload.w = bounds.width(); | |
797 payload.h = bounds.height(); | |
798 payload.show_state = ShowStateToPersistedShowState(show_state); | |
799 SessionCommand* command = new SessionCommand(kCommandSetWindowBounds3, | |
800 sizeof(payload)); | |
801 memcpy(command->contents(), &payload, sizeof(payload)); | |
802 return command; | |
803 } | |
804 | |
805 SessionCommand* SessionService::CreateSetTabIndexInWindowCommand( | |
806 const SessionID& tab_id, | |
807 int new_index) { | |
808 TabIndexInWindowPayload payload = { 0 }; | |
809 payload.id = tab_id.id(); | |
810 payload.index = new_index; | |
811 SessionCommand* command = | |
812 new SessionCommand(kCommandSetTabIndexInWindow, sizeof(payload)); | |
813 memcpy(command->contents(), &payload, sizeof(payload)); | |
814 return command; | |
815 } | |
816 | |
817 SessionCommand* SessionService::CreateTabClosedCommand( | |
818 const SessionID::id_type tab_id) { | |
819 ClosedPayload payload; | |
820 // Because of what appears to be a compiler bug setting payload to {0} doesn't | |
821 // set the padding to 0, resulting in Purify reporting an UMR when we write | |
822 // the structure to disk. To avoid this we explicitly memset the struct. | |
823 memset(&payload, 0, sizeof(payload)); | |
824 payload.id = tab_id; | |
825 payload.close_time = Time::Now().ToInternalValue(); | |
826 SessionCommand* command = | |
827 new SessionCommand(kCommandTabClosed, sizeof(payload)); | |
828 memcpy(command->contents(), &payload, sizeof(payload)); | |
829 return command; | |
830 } | |
831 | |
832 SessionCommand* SessionService::CreateWindowClosedCommand( | |
833 const SessionID::id_type window_id) { | |
834 ClosedPayload payload; | |
835 // See comment in CreateTabClosedCommand as to why we do this. | |
836 memset(&payload, 0, sizeof(payload)); | |
837 payload.id = window_id; | |
838 payload.close_time = Time::Now().ToInternalValue(); | |
839 SessionCommand* command = | |
840 new SessionCommand(kCommandWindowClosed, sizeof(payload)); | |
841 memcpy(command->contents(), &payload, sizeof(payload)); | |
842 return command; | |
843 } | |
844 | |
845 SessionCommand* SessionService::CreateSetSelectedNavigationIndexCommand( | |
846 const SessionID& tab_id, | |
847 int index) { | |
848 SelectedNavigationIndexPayload payload = { 0 }; | |
849 payload.id = tab_id.id(); | |
850 payload.index = index; | |
851 SessionCommand* command = new SessionCommand( | |
852 kCommandSetSelectedNavigationIndex, sizeof(payload)); | |
853 memcpy(command->contents(), &payload, sizeof(payload)); | |
854 return command; | |
855 } | |
856 | |
857 SessionCommand* SessionService::CreateSetWindowTypeCommand( | |
858 const SessionID& window_id, | |
859 WindowType type) { | |
860 WindowTypePayload payload = { 0 }; | |
861 payload.id = window_id.id(); | |
862 payload.index = static_cast<int32>(type); | |
863 SessionCommand* command = new SessionCommand( | |
864 kCommandSetWindowType, sizeof(payload)); | |
865 memcpy(command->contents(), &payload, sizeof(payload)); | |
866 return command; | |
867 } | |
868 | |
869 SessionCommand* SessionService::CreatePinnedStateCommand( | |
870 const SessionID& tab_id, | |
871 bool is_pinned) { | |
872 PinnedStatePayload payload = { 0 }; | |
873 payload.tab_id = tab_id.id(); | |
874 payload.pinned_state = is_pinned; | |
875 SessionCommand* command = | |
876 new SessionCommand(kCommandSetPinnedState, sizeof(payload)); | |
877 memcpy(command->contents(), &payload, sizeof(payload)); | |
878 return command; | |
879 } | |
880 | |
881 SessionCommand* SessionService::CreateSessionStorageAssociatedCommand( | |
882 const SessionID& tab_id, | |
883 const std::string& session_storage_persistent_id) { | |
884 Pickle pickle; | |
885 pickle.WriteInt(tab_id.id()); | |
886 pickle.WriteString(session_storage_persistent_id); | |
887 return new SessionCommand(kCommandSessionStorageAssociated, pickle); | |
888 } | |
889 | |
890 SessionCommand* SessionService::CreateSetActiveWindowCommand( | |
891 const SessionID& window_id) { | |
892 ActiveWindowPayload payload = 0; | |
893 payload = window_id.id(); | |
894 SessionCommand* command = | |
895 new SessionCommand(kCommandSetActiveWindow, sizeof(payload)); | |
896 memcpy(command->contents(), &payload, sizeof(payload)); | |
897 return command; | |
898 } | |
899 | |
900 void SessionService::OnGotSessionCommands( | 635 void SessionService::OnGotSessionCommands( |
901 const SessionCallback& callback, | 636 const SessionCallback& callback, |
902 ScopedVector<SessionCommand> commands) { | 637 ScopedVector<SessionCommand> commands) { |
903 ScopedVector<SessionWindow> valid_windows; | 638 ScopedVector<SessionWindow> valid_windows; |
904 SessionID::id_type active_window_id = 0; | 639 SessionID::id_type active_window_id = 0; |
905 | 640 |
641 startup_metric_utils::ScopedSlowStartupUMA | |
642 scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows"); | |
643 | |
906 RestoreSessionFromCommands( | 644 RestoreSessionFromCommands( |
907 commands.get(), &valid_windows.get(), &active_window_id); | 645 commands.get(), &valid_windows.get(), &active_window_id); |
646 RemoveUnusedRestoreWindows(&valid_windows.get()); | |
647 | |
908 callback.Run(valid_windows.Pass(), active_window_id); | 648 callback.Run(valid_windows.Pass(), active_window_id); |
909 } | 649 } |
910 | 650 |
911 void SessionService::RestoreSessionFromCommands( | |
912 const std::vector<SessionCommand*>& commands, | |
913 std::vector<SessionWindow*>* valid_windows, | |
914 SessionID::id_type* active_window_id) { | |
915 std::map<int, SessionTab*> tabs; | |
916 std::map<int, SessionWindow*> windows; | |
917 | |
918 VLOG(1) << "RestoreSessionFromCommands " << commands.size(); | |
919 if (CreateTabsAndWindows(commands, &tabs, &windows, active_window_id)) { | |
920 AddTabsToWindows(&tabs, &windows); | |
921 SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows); | |
922 UpdateSelectedTabIndex(valid_windows); | |
923 } | |
924 STLDeleteValues(&tabs); | |
925 // Don't delete conents of windows, that is done by the caller as all | |
926 // valid windows are added to valid_windows. | |
927 } | |
928 | |
929 void SessionService::UpdateSelectedTabIndex( | |
930 std::vector<SessionWindow*>* windows) { | |
931 for (std::vector<SessionWindow*>::const_iterator i = windows->begin(); | |
932 i != windows->end(); ++i) { | |
933 // See note in SessionWindow as to why we do this. | |
934 int new_index = 0; | |
935 for (std::vector<SessionTab*>::const_iterator j = (*i)->tabs.begin(); | |
936 j != (*i)->tabs.end(); ++j) { | |
937 if ((*j)->tab_visual_index == (*i)->selected_tab_index) { | |
938 new_index = static_cast<int>(j - (*i)->tabs.begin()); | |
939 break; | |
940 } | |
941 } | |
942 (*i)->selected_tab_index = new_index; | |
943 } | |
944 } | |
945 | |
946 SessionWindow* SessionService::GetWindow( | |
947 SessionID::id_type window_id, | |
948 IdToSessionWindow* windows) { | |
949 std::map<int, SessionWindow*>::iterator i = windows->find(window_id); | |
950 if (i == windows->end()) { | |
951 SessionWindow* window = new SessionWindow(); | |
952 window->window_id.set_id(window_id); | |
953 (*windows)[window_id] = window; | |
954 return window; | |
955 } | |
956 return i->second; | |
957 } | |
958 | |
959 SessionTab* SessionService::GetTab( | |
960 SessionID::id_type tab_id, | |
961 IdToSessionTab* tabs) { | |
962 DCHECK(tabs); | |
963 std::map<int, SessionTab*>::iterator i = tabs->find(tab_id); | |
964 if (i == tabs->end()) { | |
965 SessionTab* tab = new SessionTab(); | |
966 tab->tab_id.set_id(tab_id); | |
967 (*tabs)[tab_id] = tab; | |
968 return tab; | |
969 } | |
970 return i->second; | |
971 } | |
972 | |
973 std::vector<SerializedNavigationEntry>::iterator | |
974 SessionService::FindClosestNavigationWithIndex( | |
975 std::vector<SerializedNavigationEntry>* navigations, | |
976 int index) { | |
977 DCHECK(navigations); | |
978 for (std::vector<SerializedNavigationEntry>::iterator | |
979 i = navigations->begin(); i != navigations->end(); ++i) { | |
980 if (i->index() >= index) | |
981 return i; | |
982 } | |
983 return navigations->end(); | |
984 } | |
985 | |
986 // Function used in sorting windows. Sorting is done based on window id. As | |
987 // window ids increment for each new window, this effectively sorts by creation | |
988 // time. | |
989 static bool WindowOrderSortFunction(const SessionWindow* w1, | |
990 const SessionWindow* w2) { | |
991 return w1->window_id.id() < w2->window_id.id(); | |
992 } | |
993 | |
994 // Compares the two tabs based on visual index. | |
995 static bool TabVisualIndexSortFunction(const SessionTab* t1, | |
996 const SessionTab* t2) { | |
997 const int delta = t1->tab_visual_index - t2->tab_visual_index; | |
998 return delta == 0 ? (t1->tab_id.id() < t2->tab_id.id()) : (delta < 0); | |
999 } | |
1000 | |
1001 void SessionService::SortTabsBasedOnVisualOrderAndPrune( | |
1002 std::map<int, SessionWindow*>* windows, | |
1003 std::vector<SessionWindow*>* valid_windows) { | |
1004 std::map<int, SessionWindow*>::iterator i = windows->begin(); | |
1005 while (i != windows->end()) { | |
1006 SessionWindow* window = i->second; | |
1007 AppType app_type = window->app_name.empty() ? TYPE_NORMAL : TYPE_APP; | |
1008 if (window->tabs.empty() || window->is_constrained || | |
1009 !should_track_changes_for_browser_type( | |
1010 static_cast<Browser::Type>(window->type), | |
1011 app_type)) { | |
1012 delete window; | |
1013 windows->erase(i++); | |
1014 } else { | |
1015 // Valid window; sort the tabs and add it to the list of valid windows. | |
1016 std::sort(window->tabs.begin(), window->tabs.end(), | |
1017 &TabVisualIndexSortFunction); | |
1018 // Otherwise, add the window such that older windows appear first. | |
1019 if (valid_windows->empty()) { | |
1020 valid_windows->push_back(window); | |
1021 } else { | |
1022 valid_windows->insert( | |
1023 std::upper_bound(valid_windows->begin(), valid_windows->end(), | |
1024 window, &WindowOrderSortFunction), | |
1025 window); | |
1026 } | |
1027 ++i; | |
1028 } | |
1029 } | |
1030 } | |
1031 | |
1032 void SessionService::AddTabsToWindows(std::map<int, SessionTab*>* tabs, | |
1033 std::map<int, SessionWindow*>* windows) { | |
1034 VLOG(1) << "AddTabsToWindws"; | |
1035 VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size(); | |
1036 std::map<int, SessionTab*>::iterator i = tabs->begin(); | |
1037 while (i != tabs->end()) { | |
1038 SessionTab* tab = i->second; | |
1039 if (tab->window_id.id() && !tab->navigations.empty()) { | |
1040 SessionWindow* window = GetWindow(tab->window_id.id(), windows); | |
1041 window->tabs.push_back(tab); | |
1042 tabs->erase(i++); | |
1043 | |
1044 // See note in SessionTab as to why we do this. | |
1045 std::vector<SerializedNavigationEntry>::iterator j = | |
1046 FindClosestNavigationWithIndex(&(tab->navigations), | |
1047 tab->current_navigation_index); | |
1048 if (j == tab->navigations.end()) { | |
1049 tab->current_navigation_index = | |
1050 static_cast<int>(tab->navigations.size() - 1); | |
1051 } else { | |
1052 tab->current_navigation_index = | |
1053 static_cast<int>(j - tab->navigations.begin()); | |
1054 } | |
1055 } else { | |
1056 // Never got a set tab index in window, or tabs are empty, nothing | |
1057 // to do. | |
1058 ++i; | |
1059 } | |
1060 } | |
1061 } | |
1062 | |
1063 bool SessionService::CreateTabsAndWindows( | |
1064 const std::vector<SessionCommand*>& data, | |
1065 std::map<int, SessionTab*>* tabs, | |
1066 std::map<int, SessionWindow*>* windows, | |
1067 SessionID::id_type* active_window_id) { | |
1068 // If the file is corrupt (command with wrong size, or unknown command), we | |
1069 // still return true and attempt to restore what we we can. | |
1070 VLOG(1) << "CreateTabsAndWindows"; | |
1071 | |
1072 startup_metric_utils::ScopedSlowStartupUMA | |
1073 scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows"); | |
1074 | |
1075 for (std::vector<SessionCommand*>::const_iterator i = data.begin(); | |
1076 i != data.end(); ++i) { | |
1077 const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | |
1078 const SessionCommand* command = *i; | |
1079 | |
1080 VLOG(1) << "Read command " << (int) command->id(); | |
1081 switch (command->id()) { | |
1082 case kCommandSetTabWindow: { | |
1083 SessionID::id_type payload[2]; | |
1084 if (!command->GetPayload(payload, sizeof(payload))) { | |
1085 VLOG(1) << "Failed reading command " << command->id(); | |
1086 return true; | |
1087 } | |
1088 GetTab(payload[1], tabs)->window_id.set_id(payload[0]); | |
1089 break; | |
1090 } | |
1091 | |
1092 // This is here for forward migration only. New data is saved with | |
1093 // |kCommandSetWindowBounds3|. | |
1094 case kCommandSetWindowBounds2: { | |
1095 WindowBoundsPayload2 payload; | |
1096 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1097 VLOG(1) << "Failed reading command " << command->id(); | |
1098 return true; | |
1099 } | |
1100 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, | |
1101 payload.y, | |
1102 payload.w, | |
1103 payload.h); | |
1104 GetWindow(payload.window_id, windows)->show_state = | |
1105 payload.is_maximized ? | |
1106 ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL; | |
1107 break; | |
1108 } | |
1109 | |
1110 case kCommandSetWindowBounds3: { | |
1111 WindowBoundsPayload3 payload; | |
1112 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1113 VLOG(1) << "Failed reading command " << command->id(); | |
1114 return true; | |
1115 } | |
1116 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x, | |
1117 payload.y, | |
1118 payload.w, | |
1119 payload.h); | |
1120 GetWindow(payload.window_id, windows)->show_state = | |
1121 PersistedShowStateToShowState(payload.show_state); | |
1122 break; | |
1123 } | |
1124 | |
1125 case kCommandSetTabIndexInWindow: { | |
1126 TabIndexInWindowPayload payload; | |
1127 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1128 VLOG(1) << "Failed reading command " << command->id(); | |
1129 return true; | |
1130 } | |
1131 GetTab(payload.id, tabs)->tab_visual_index = payload.index; | |
1132 break; | |
1133 } | |
1134 | |
1135 case kCommandTabClosed: | |
1136 case kCommandWindowClosed: { | |
1137 ClosedPayload payload; | |
1138 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1139 VLOG(1) << "Failed reading command " << command->id(); | |
1140 return true; | |
1141 } | |
1142 if (command->id() == kCommandTabClosed) { | |
1143 delete GetTab(payload.id, tabs); | |
1144 tabs->erase(payload.id); | |
1145 } else { | |
1146 delete GetWindow(payload.id, windows); | |
1147 windows->erase(payload.id); | |
1148 } | |
1149 break; | |
1150 } | |
1151 | |
1152 case kCommandTabNavigationPathPrunedFromBack: { | |
1153 TabNavigationPathPrunedFromBackPayload payload; | |
1154 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1155 VLOG(1) << "Failed reading command " << command->id(); | |
1156 return true; | |
1157 } | |
1158 SessionTab* tab = GetTab(payload.id, tabs); | |
1159 tab->navigations.erase( | |
1160 FindClosestNavigationWithIndex(&(tab->navigations), payload.index), | |
1161 tab->navigations.end()); | |
1162 break; | |
1163 } | |
1164 | |
1165 case kCommandTabNavigationPathPrunedFromFront: { | |
1166 TabNavigationPathPrunedFromFrontPayload payload; | |
1167 if (!command->GetPayload(&payload, sizeof(payload)) || | |
1168 payload.index <= 0) { | |
1169 VLOG(1) << "Failed reading command " << command->id(); | |
1170 return true; | |
1171 } | |
1172 SessionTab* tab = GetTab(payload.id, tabs); | |
1173 | |
1174 // Update the selected navigation index. | |
1175 tab->current_navigation_index = | |
1176 std::max(-1, tab->current_navigation_index - payload.index); | |
1177 | |
1178 // And update the index of existing navigations. | |
1179 for (std::vector<SerializedNavigationEntry>::iterator | |
1180 i = tab->navigations.begin(); | |
1181 i != tab->navigations.end();) { | |
1182 i->set_index(i->index() - payload.index); | |
1183 if (i->index() < 0) | |
1184 i = tab->navigations.erase(i); | |
1185 else | |
1186 ++i; | |
1187 } | |
1188 break; | |
1189 } | |
1190 | |
1191 case kCommandUpdateTabNavigation: { | |
1192 SerializedNavigationEntry navigation; | |
1193 SessionID::id_type tab_id; | |
1194 if (!RestoreUpdateTabNavigationCommand( | |
1195 *command, &navigation, &tab_id)) { | |
1196 VLOG(1) << "Failed reading command " << command->id(); | |
1197 return true; | |
1198 } | |
1199 SessionTab* tab = GetTab(tab_id, tabs); | |
1200 std::vector<SerializedNavigationEntry>::iterator i = | |
1201 FindClosestNavigationWithIndex(&(tab->navigations), | |
1202 navigation.index()); | |
1203 if (i != tab->navigations.end() && i->index() == navigation.index()) | |
1204 *i = navigation; | |
1205 else | |
1206 tab->navigations.insert(i, navigation); | |
1207 break; | |
1208 } | |
1209 | |
1210 case kCommandSetSelectedNavigationIndex: { | |
1211 SelectedNavigationIndexPayload payload; | |
1212 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1213 VLOG(1) << "Failed reading command " << command->id(); | |
1214 return true; | |
1215 } | |
1216 GetTab(payload.id, tabs)->current_navigation_index = payload.index; | |
1217 break; | |
1218 } | |
1219 | |
1220 case kCommandSetSelectedTabInIndex: { | |
1221 SelectedTabInIndexPayload payload; | |
1222 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1223 VLOG(1) << "Failed reading command " << command->id(); | |
1224 return true; | |
1225 } | |
1226 GetWindow(payload.id, windows)->selected_tab_index = payload.index; | |
1227 break; | |
1228 } | |
1229 | |
1230 case kCommandSetWindowType: { | |
1231 WindowTypePayload payload; | |
1232 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1233 VLOG(1) << "Failed reading command " << command->id(); | |
1234 return true; | |
1235 } | |
1236 GetWindow(payload.id, windows)->is_constrained = false; | |
1237 GetWindow(payload.id, windows)->type = | |
1238 BrowserTypeForWindowType( | |
1239 static_cast<WindowType>(payload.index)); | |
1240 break; | |
1241 } | |
1242 | |
1243 case kCommandSetPinnedState: { | |
1244 PinnedStatePayload payload; | |
1245 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1246 VLOG(1) << "Failed reading command " << command->id(); | |
1247 return true; | |
1248 } | |
1249 GetTab(payload.tab_id, tabs)->pinned = payload.pinned_state; | |
1250 break; | |
1251 } | |
1252 | |
1253 case kCommandSetWindowAppName: { | |
1254 SessionID::id_type window_id; | |
1255 std::string app_name; | |
1256 if (!RestoreSetWindowAppNameCommand(*command, &window_id, &app_name)) | |
1257 return true; | |
1258 | |
1259 GetWindow(window_id, windows)->app_name.swap(app_name); | |
1260 break; | |
1261 } | |
1262 | |
1263 case kCommandSetExtensionAppID: { | |
1264 SessionID::id_type tab_id; | |
1265 std::string extension_app_id; | |
1266 if (!RestoreSetTabExtensionAppIDCommand( | |
1267 *command, &tab_id, &extension_app_id)) { | |
1268 VLOG(1) << "Failed reading command " << command->id(); | |
1269 return true; | |
1270 } | |
1271 | |
1272 GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id); | |
1273 break; | |
1274 } | |
1275 | |
1276 case kCommandSetTabUserAgentOverride: { | |
1277 SessionID::id_type tab_id; | |
1278 std::string user_agent_override; | |
1279 if (!RestoreSetTabUserAgentOverrideCommand( | |
1280 *command, &tab_id, &user_agent_override)) { | |
1281 return true; | |
1282 } | |
1283 | |
1284 GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override); | |
1285 break; | |
1286 } | |
1287 | |
1288 case kCommandSessionStorageAssociated: { | |
1289 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle()); | |
1290 SessionID::id_type command_tab_id; | |
1291 std::string session_storage_persistent_id; | |
1292 PickleIterator iter(*command_pickle.get()); | |
1293 if (!command_pickle->ReadInt(&iter, &command_tab_id) || | |
1294 !command_pickle->ReadString(&iter, &session_storage_persistent_id)) | |
1295 return true; | |
1296 // Associate the session storage back. | |
1297 GetTab(command_tab_id, tabs)->session_storage_persistent_id = | |
1298 session_storage_persistent_id; | |
1299 break; | |
1300 } | |
1301 | |
1302 case kCommandSetActiveWindow: { | |
1303 ActiveWindowPayload payload; | |
1304 if (!command->GetPayload(&payload, sizeof(payload))) { | |
1305 VLOG(1) << "Failed reading command " << command->id(); | |
1306 return true; | |
1307 } | |
1308 *active_window_id = payload; | |
1309 break; | |
1310 } | |
1311 | |
1312 default: | |
1313 VLOG(1) << "Failed reading an unknown command " << command->id(); | |
1314 return true; | |
1315 } | |
1316 } | |
1317 return true; | |
1318 } | |
1319 | |
1320 void SessionService::BuildCommandsForTab(const SessionID& window_id, | 651 void SessionService::BuildCommandsForTab(const SessionID& window_id, |
1321 WebContents* tab, | 652 WebContents* tab, |
1322 int index_in_window, | 653 int index_in_window, |
1323 bool is_pinned, | 654 bool is_pinned, |
1324 std::vector<SessionCommand*>* commands, | 655 std::vector<SessionCommand*>* commands, |
1325 IdToRange* tab_to_available_range) { | 656 IdToRange* tab_to_available_range) { |
1326 DCHECK(tab && commands && window_id.id()); | 657 DCHECK(tab && commands && window_id.id()); |
1327 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); | 658 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); |
1328 const SessionID& session_id(session_tab_helper->session_id()); | 659 const SessionID& session_id(session_tab_helper->session_id()); |
1329 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); | 660 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); |
1330 | 661 |
1331 const int current_index = tab->GetController().GetCurrentEntryIndex(); | 662 const int current_index = tab->GetController().GetCurrentEntryIndex(); |
1332 const int min_index = std::max(0, | 663 const int min_index = std::max(0, |
1333 current_index - max_persist_navigation_count); | 664 current_index - max_persist_navigation_count); |
1334 const int max_index = | 665 const int max_index = |
1335 std::min(current_index + max_persist_navigation_count, | 666 std::min(current_index + max_persist_navigation_count, |
1336 tab->GetController().GetEntryCount()); | 667 tab->GetController().GetEntryCount()); |
1337 const int pending_index = tab->GetController().GetPendingEntryIndex(); | 668 const int pending_index = tab->GetController().GetPendingEntryIndex(); |
1338 if (tab_to_available_range) { | 669 if (tab_to_available_range) { |
1339 (*tab_to_available_range)[session_id.id()] = | 670 (*tab_to_available_range)[session_id.id()] = |
1340 std::pair<int, int>(min_index, max_index); | 671 std::pair<int, int>(min_index, max_index); |
1341 } | 672 } |
1342 | 673 |
1343 if (is_pinned) { | 674 if (is_pinned) |
1344 commands->push_back(CreatePinnedStateCommand(session_id, true)); | 675 commands->push_back(CreatePinnedStateCommand(session_id, true)); |
1345 } | |
1346 | 676 |
1347 extensions::TabHelper* extensions_tab_helper = | 677 extensions::TabHelper* extensions_tab_helper = |
1348 extensions::TabHelper::FromWebContents(tab); | 678 extensions::TabHelper::FromWebContents(tab); |
1349 if (extensions_tab_helper->extension_app()) { | 679 if (extensions_tab_helper->extension_app()) { |
1350 commands->push_back( | 680 commands->push_back(CreateSetTabExtensionAppIDCommand( |
1351 CreateSetTabExtensionAppIDCommand( | 681 session_id, |
1352 kCommandSetExtensionAppID, session_id.id(), | 682 extensions_tab_helper->extension_app()->id())); |
1353 extensions_tab_helper->extension_app()->id())); | |
1354 } | 683 } |
1355 | 684 |
1356 const std::string& ua_override = tab->GetUserAgentOverride(); | 685 const std::string& ua_override = tab->GetUserAgentOverride(); |
1357 if (!ua_override.empty()) { | 686 if (!ua_override.empty()) { |
1358 commands->push_back( | 687 commands->push_back(CreateSetTabUserAgentOverrideCommand(session_id, |
1359 CreateSetTabUserAgentOverrideCommand( | 688 ua_override)); |
1360 kCommandSetTabUserAgentOverride, session_id.id(), ua_override)); | |
1361 } | 689 } |
1362 | 690 |
1363 for (int i = min_index; i < max_index; ++i) { | 691 for (int i = min_index; i < max_index; ++i) { |
1364 const NavigationEntry* entry = (i == pending_index) ? | 692 const NavigationEntry* entry = (i == pending_index) ? |
1365 tab->GetController().GetPendingEntry() : | 693 tab->GetController().GetPendingEntry() : |
1366 tab->GetController().GetEntryAtIndex(i); | 694 tab->GetController().GetEntryAtIndex(i); |
1367 DCHECK(entry); | 695 DCHECK(entry); |
1368 if (ShouldTrackEntry(entry->GetVirtualURL())) { | 696 if (ShouldTrackEntry(entry->GetVirtualURL())) { |
1369 const SerializedNavigationEntry navigation = | 697 const SerializedNavigationEntry navigation = |
1370 ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry); | 698 ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry); |
1371 commands->push_back( | 699 commands->push_back( |
1372 CreateUpdateTabNavigationCommand( | 700 CreateUpdateTabNavigationCommand(session_id, navigation)); |
1373 kCommandUpdateTabNavigation, session_id.id(), navigation)); | |
1374 } | 701 } |
1375 } | 702 } |
1376 commands->push_back( | 703 commands->push_back( |
1377 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); | 704 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); |
1378 | 705 |
1379 if (index_in_window != -1) { | 706 if (index_in_window != -1) { |
1380 commands->push_back( | 707 commands->push_back( |
1381 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); | 708 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); |
1382 } | 709 } |
1383 | 710 |
(...skipping 12 matching lines...) Expand all Loading... | |
1396 std::set<SessionID::id_type>* windows_to_track) { | 723 std::set<SessionID::id_type>* windows_to_track) { |
1397 DCHECK(browser && commands); | 724 DCHECK(browser && commands); |
1398 DCHECK(browser->session_id().id()); | 725 DCHECK(browser->session_id().id()); |
1399 | 726 |
1400 commands->push_back( | 727 commands->push_back( |
1401 CreateSetWindowBoundsCommand(browser->session_id(), | 728 CreateSetWindowBoundsCommand(browser->session_id(), |
1402 browser->window()->GetRestoredBounds(), | 729 browser->window()->GetRestoredBounds(), |
1403 browser->window()->GetRestoredState())); | 730 browser->window()->GetRestoredState())); |
1404 | 731 |
1405 commands->push_back(CreateSetWindowTypeCommand( | 732 commands->push_back(CreateSetWindowTypeCommand( |
1406 browser->session_id(), WindowTypeForBrowserType(browser->type()))); | 733 browser->session_id(), |
734 WindowTypeForBrowserType(browser->type()))); | |
1407 | 735 |
1408 if (!browser->app_name().empty()) { | 736 if (!browser->app_name().empty()) { |
1409 commands->push_back(CreateSetWindowAppNameCommand( | 737 commands->push_back(CreateSetWindowAppNameCommand(browser->session_id(), |
1410 kCommandSetWindowAppName, | 738 browser->app_name())); |
1411 browser->session_id().id(), | |
1412 browser->app_name())); | |
1413 } | 739 } |
1414 | 740 |
1415 windows_to_track->insert(browser->session_id().id()); | 741 windows_to_track->insert(browser->session_id().id()); |
1416 TabStripModel* tab_strip = browser->tab_strip_model(); | 742 TabStripModel* tab_strip = browser->tab_strip_model(); |
1417 for (int i = 0; i < tab_strip->count(); ++i) { | 743 for (int i = 0; i < tab_strip->count(); ++i) { |
1418 WebContents* tab = tab_strip->GetWebContentsAt(i); | 744 WebContents* tab = tab_strip->GetWebContentsAt(i); |
1419 DCHECK(tab); | 745 DCHECK(tab); |
1420 BuildCommandsForTab(browser->session_id(), tab, i, | 746 BuildCommandsForTab(browser->session_id(), tab, i, |
1421 tab_strip->IsTabPinned(i), | 747 tab_strip->IsTabPinned(i), |
1422 commands, tab_to_available_range); | 748 commands, tab_to_available_range); |
1423 } | 749 } |
1424 | 750 |
1425 commands->push_back( | 751 commands->push_back(CreateSetSelectedTabInWindowCommand( |
1426 CreateSetSelectedTabInWindow(browser->session_id(), | 752 browser->session_id(), |
1427 browser->tab_strip_model()->active_index())); | 753 browser->tab_strip_model()->active_index())); |
1428 } | 754 } |
1429 | 755 |
1430 void SessionService::BuildCommandsFromBrowsers( | 756 void SessionService::BuildCommandsFromBrowsers( |
1431 std::vector<SessionCommand*>* commands, | 757 std::vector<SessionCommand*>* commands, |
1432 IdToRange* tab_to_available_range, | 758 IdToRange* tab_to_available_range, |
1433 std::set<SessionID::id_type>* windows_to_track) { | 759 std::set<SessionID::id_type>* windows_to_track) { |
1434 DCHECK(commands); | 760 DCHECK(commands); |
1435 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 761 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
1436 Browser* browser = *it; | 762 Browser* browser = *it; |
1437 // Make sure the browser has tabs and a window. Browser's destructor | 763 // Make sure the browser has tabs and a window. Browser's destructor |
1438 // removes itself from the BrowserList. When a browser is closed the | 764 // removes itself from the BrowserList. When a browser is closed the |
1439 // destructor is not necessarily run immediately. This means it's possible | 765 // destructor is not necessarily run immediately. This means it's possible |
1440 // for us to get a handle to a browser that is about to be removed. If | 766 // for us to get a handle to a browser that is about to be removed. If |
1441 // the tab count is 0 or the window is NULL, the browser is about to be | 767 // the tab count is 0 or the window is NULL, the browser is about to be |
1442 // deleted, so we ignore it. | 768 // deleted, so we ignore it. |
1443 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && | 769 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && |
1444 browser->window()) { | 770 browser->window()) { |
1445 BuildCommandsForBrowser(browser, commands, tab_to_available_range, | 771 BuildCommandsForBrowser(browser, commands, tab_to_available_range, |
1446 windows_to_track); | 772 windows_to_track); |
1447 } | 773 } |
1448 } | 774 } |
1449 } | 775 } |
1450 | 776 |
1451 void SessionService::ScheduleReset() { | 777 void SessionService::ScheduleResetCommands() { |
1452 set_pending_reset(true); | 778 set_pending_reset(true); |
1453 STLDeleteElements(&pending_commands()); | 779 STLDeleteElements(&pending_commands()); |
1454 tab_to_available_range_.clear(); | 780 tab_to_available_range_.clear(); |
1455 windows_tracking_.clear(); | 781 windows_tracking_.clear(); |
1456 BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_, | 782 BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_, |
1457 &windows_tracking_); | 783 &windows_tracking_); |
1458 if (!windows_tracking_.empty()) { | 784 if (!windows_tracking_.empty()) { |
1459 // We're lazily created on startup and won't get an initial batch of | 785 // We're lazily created on startup and won't get an initial batch of |
1460 // SetWindowType messages. Set these here to make sure our state is correct. | 786 // SetWindowType messages. Set these here to make sure our state is correct. |
1461 has_open_trackable_browsers_ = true; | 787 has_open_trackable_browsers_ = true; |
1462 move_on_new_browser_ = true; | 788 move_on_new_browser_ = true; |
1463 } | 789 } |
1464 StartSaveTimer(); | 790 StartSaveTimer(); |
1465 } | 791 } |
1466 | 792 |
1467 bool SessionService::ReplacePendingCommand(SessionCommand* command) { | |
1468 // We optimize page navigations, which can happen quite frequently and | |
1469 // are expensive. And activation is like Highlander, there can only be one! | |
1470 if (command->id() != kCommandUpdateTabNavigation && | |
1471 command->id() != kCommandSetActiveWindow) { | |
1472 return false; | |
1473 } | |
1474 for (std::vector<SessionCommand*>::reverse_iterator i = | |
1475 pending_commands().rbegin(); i != pending_commands().rend(); ++i) { | |
1476 SessionCommand* existing_command = *i; | |
1477 if (command->id() == kCommandUpdateTabNavigation && | |
1478 existing_command->id() == kCommandUpdateTabNavigation) { | |
1479 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle()); | |
1480 PickleIterator iterator(*command_pickle); | |
1481 SessionID::id_type command_tab_id; | |
1482 int command_nav_index; | |
1483 if (!command_pickle->ReadInt(&iterator, &command_tab_id) || | |
1484 !command_pickle->ReadInt(&iterator, &command_nav_index)) { | |
1485 return false; | |
1486 } | |
1487 SessionID::id_type existing_tab_id; | |
1488 int existing_nav_index; | |
1489 { | |
1490 // Creating a pickle like this means the Pickle references the data from | |
1491 // the command. Make sure we delete the pickle before the command, else | |
1492 // the pickle references deleted memory. | |
1493 scoped_ptr<Pickle> existing_pickle(existing_command->PayloadAsPickle()); | |
1494 iterator = PickleIterator(*existing_pickle); | |
1495 if (!existing_pickle->ReadInt(&iterator, &existing_tab_id) || | |
1496 !existing_pickle->ReadInt(&iterator, &existing_nav_index)) { | |
1497 return false; | |
1498 } | |
1499 } | |
1500 if (existing_tab_id == command_tab_id && | |
1501 existing_nav_index == command_nav_index) { | |
1502 // existing_command is an update for the same tab/index pair. Replace | |
1503 // it with the new one. We need to add to the end of the list just in | |
1504 // case there is a prune command after the update command. | |
1505 delete existing_command; | |
1506 pending_commands().erase(i.base() - 1); | |
1507 pending_commands().push_back(command); | |
1508 return true; | |
1509 } | |
1510 return false; | |
1511 } | |
1512 if (command->id() == kCommandSetActiveWindow && | |
1513 existing_command->id() == kCommandSetActiveWindow) { | |
1514 *i = command; | |
1515 delete existing_command; | |
1516 return true; | |
1517 } | |
1518 } | |
1519 return false; | |
1520 } | |
1521 | |
1522 void SessionService::ScheduleCommand(SessionCommand* command) { | 793 void SessionService::ScheduleCommand(SessionCommand* command) { |
1523 DCHECK(command); | 794 DCHECK(command); |
1524 if (ReplacePendingCommand(command)) | 795 if (ReplacePendingCommand(command, pending_commands())) |
1525 return; | 796 return; |
1526 BaseSessionService::ScheduleCommand(command); | 797 BaseSessionService::ScheduleCommand(command); |
1527 // Don't schedule a reset on tab closed/window closed. Otherwise we may | 798 // Don't schedule a reset on tab closed/window closed. Otherwise we may |
1528 // lose tabs/windows we want to restore from if we exit right after this. | 799 // lose tabs/windows we want to restore from if we exit right after this. |
1529 if (!pending_reset() && pending_window_close_ids_.empty() && | 800 if (!pending_reset() && pending_window_close_ids_.empty() && |
1530 commands_since_reset() >= kWritesPerReset && | 801 commands_since_reset() >= kWritesPerReset && !IsClosingCommand(command)) { |
1531 (command->id() != kCommandTabClosed && | 802 ScheduleResetCommands(); |
1532 command->id() != kCommandWindowClosed)) { | |
1533 ScheduleReset(); | |
1534 } | 803 } |
1535 } | 804 } |
1536 | 805 |
1537 void SessionService::CommitPendingCloses() { | 806 void SessionService::CommitPendingCloses() { |
1538 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); | 807 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); |
1539 i != pending_tab_close_ids_.end(); ++i) { | 808 i != pending_tab_close_ids_.end(); ++i) { |
1540 ScheduleCommand(CreateTabClosedCommand(*i)); | 809 ScheduleCommand(CreateTabClosedCommand(*i)); |
1541 } | 810 } |
1542 pending_tab_close_ids_.clear(); | 811 pending_tab_close_ids_.clear(); |
1543 | 812 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1598 bool SessionService::ShouldTrackBrowser(Browser* browser) const { | 867 bool SessionService::ShouldTrackBrowser(Browser* browser) const { |
1599 if (browser->profile() != profile()) | 868 if (browser->profile() != profile()) |
1600 return false; | 869 return false; |
1601 // Never track app popup windows that do not have a trusted source (i.e. | 870 // Never track app popup windows that do not have a trusted source (i.e. |
1602 // popup windows spawned by an app). If this logic changes, be sure to also | 871 // popup windows spawned by an app). If this logic changes, be sure to also |
1603 // change SessionRestoreImpl::CreateRestoredBrowser(). | 872 // change SessionRestoreImpl::CreateRestoredBrowser(). |
1604 if (browser->is_app() && browser->is_type_popup() && | 873 if (browser->is_app() && browser->is_type_popup() && |
1605 !browser->is_trusted_source()) { | 874 !browser->is_trusted_source()) { |
1606 return false; | 875 return false; |
1607 } | 876 } |
1608 AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL; | 877 return ShouldRestoreWindowOfType(WindowTypeForBrowserType(browser->type()), |
1609 return should_track_changes_for_browser_type(browser->type(), app_type); | 878 browser->is_app() ? TYPE_APP : TYPE_NORMAL); |
1610 } | |
1611 | |
1612 bool SessionService::should_track_changes_for_browser_type(Browser::Type type, | |
1613 AppType app_type) { | |
1614 #if defined(OS_CHROMEOS) | |
1615 // Restore app popups for chromeos alone. | |
1616 if (type == Browser::TYPE_POPUP && app_type == TYPE_APP) | |
1617 return true; | |
1618 #endif | |
1619 | |
1620 return type == Browser::TYPE_TABBED; | |
1621 } | |
1622 | |
1623 SessionService::WindowType SessionService::WindowTypeForBrowserType( | |
1624 Browser::Type type) { | |
1625 switch (type) { | |
1626 case Browser::TYPE_POPUP: | |
1627 return TYPE_POPUP; | |
1628 case Browser::TYPE_TABBED: | |
1629 return TYPE_TABBED; | |
1630 default: | |
1631 DCHECK(false); | |
1632 return TYPE_TABBED; | |
1633 } | |
1634 } | |
1635 | |
1636 Browser::Type SessionService::BrowserTypeForWindowType(WindowType type) { | |
1637 switch (type) { | |
1638 case TYPE_POPUP: | |
1639 return Browser::TYPE_POPUP; | |
1640 case TYPE_TABBED: | |
1641 default: | |
1642 return Browser::TYPE_TABBED; | |
1643 } | |
1644 } | 879 } |
1645 | 880 |
1646 void SessionService::RecordSessionUpdateHistogramData(int type, | 881 void SessionService::RecordSessionUpdateHistogramData(int type, |
1647 base::TimeTicks* last_updated_time) { | 882 base::TimeTicks* last_updated_time) { |
1648 if (!last_updated_time->is_null()) { | 883 if (!last_updated_time->is_null()) { |
1649 base::TimeDelta delta = base::TimeTicks::Now() - *last_updated_time; | 884 base::TimeDelta delta = base::TimeTicks::Now() - *last_updated_time; |
1650 // We're interested in frequent updates periods longer than | 885 // We're interested in frequent updates periods longer than |
1651 // 10 minutes. | 886 // 10 minutes. |
1652 bool use_long_period = false; | 887 bool use_long_period = false; |
1653 if (delta >= save_delay_in_mins_) { | 888 if (delta >= save_delay_in_mins_) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1834 return; | 1069 return; |
1835 } | 1070 } |
1836 | 1071 |
1837 // Check for any open windows for the current profile that we aren't tracking. | 1072 // Check for any open windows for the current profile that we aren't tracking. |
1838 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 1073 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
1839 if ((*it)->profile() == profile()) | 1074 if ((*it)->profile() == profile()) |
1840 return; | 1075 return; |
1841 } | 1076 } |
1842 DeleteSessionOnlyData(profile()); | 1077 DeleteSessionOnlyData(profile()); |
1843 } | 1078 } |
OLD | NEW |