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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 RunTaskOnBackendThread( | 147 RunTaskOnBackendThread( |
148 FROM_HERE, base::Bind(&SessionBackend::MoveCurrentSessionToLastSession, | 148 FROM_HERE, base::Bind(&SessionBackend::MoveCurrentSessionToLastSession, |
149 backend())); | 149 backend())); |
150 } | 150 } |
151 | 151 |
152 void SessionService::SetTabWindow(const SessionID& window_id, | 152 void SessionService::SetTabWindow(const SessionID& window_id, |
153 const SessionID& tab_id) { | 153 const SessionID& tab_id) { |
154 if (!ShouldTrackChangesToWindow(window_id)) | 154 if (!ShouldTrackChangesToWindow(window_id)) |
155 return; | 155 return; |
156 | 156 |
157 ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id)); | 157 ScheduleCommand(CreateSetTabWindowCommand(window_id, tab_id).Pass()); |
158 } | 158 } |
159 | 159 |
160 void SessionService::SetWindowBounds(const SessionID& window_id, | 160 void SessionService::SetWindowBounds(const SessionID& window_id, |
161 const gfx::Rect& bounds, | 161 const gfx::Rect& bounds, |
162 ui::WindowShowState show_state) { | 162 ui::WindowShowState show_state) { |
163 if (!ShouldTrackChangesToWindow(window_id)) | 163 if (!ShouldTrackChangesToWindow(window_id)) |
164 return; | 164 return; |
165 | 165 |
166 ScheduleCommand(CreateSetWindowBoundsCommand(window_id, bounds, show_state)); | 166 ScheduleCommand( |
| 167 CreateSetWindowBoundsCommand(window_id, bounds, show_state).Pass()); |
167 } | 168 } |
168 | 169 |
169 void SessionService::SetTabIndexInWindow(const SessionID& window_id, | 170 void SessionService::SetTabIndexInWindow(const SessionID& window_id, |
170 const SessionID& tab_id, | 171 const SessionID& tab_id, |
171 int new_index) { | 172 int new_index) { |
172 if (!ShouldTrackChangesToWindow(window_id)) | 173 if (!ShouldTrackChangesToWindow(window_id)) |
173 return; | 174 return; |
174 | 175 |
175 ScheduleCommand(CreateSetTabIndexInWindowCommand(tab_id, new_index)); | 176 ScheduleCommand(CreateSetTabIndexInWindowCommand(tab_id, new_index).Pass()); |
176 } | 177 } |
177 | 178 |
178 void SessionService::SetPinnedState(const SessionID& window_id, | 179 void SessionService::SetPinnedState(const SessionID& window_id, |
179 const SessionID& tab_id, | 180 const SessionID& tab_id, |
180 bool is_pinned) { | 181 bool is_pinned) { |
181 if (!ShouldTrackChangesToWindow(window_id)) | 182 if (!ShouldTrackChangesToWindow(window_id)) |
182 return; | 183 return; |
183 | 184 |
184 ScheduleCommand(CreatePinnedStateCommand(tab_id, is_pinned)); | 185 ScheduleCommand(CreatePinnedStateCommand(tab_id, is_pinned).Pass()); |
185 } | 186 } |
186 | 187 |
187 void SessionService::TabClosed(const SessionID& window_id, | 188 void SessionService::TabClosed(const SessionID& window_id, |
188 const SessionID& tab_id, | 189 const SessionID& tab_id, |
189 bool closed_by_user_gesture) { | 190 bool closed_by_user_gesture) { |
190 if (!tab_id.id()) | 191 if (!tab_id.id()) |
191 return; // Hapens when the tab is replaced. | 192 return; // Hapens when the tab is replaced. |
192 | 193 |
193 if (!ShouldTrackChangesToWindow(window_id)) | 194 if (!ShouldTrackChangesToWindow(window_id)) |
194 return; | 195 return; |
(...skipping 10 matching lines...) Expand all Loading... |
205 pending_tab_close_ids_.insert(tab_id.id()); | 206 pending_tab_close_ids_.insert(tab_id.id()); |
206 } else if (find(window_closing_ids_.begin(), window_closing_ids_.end(), | 207 } else if (find(window_closing_ids_.begin(), window_closing_ids_.end(), |
207 window_id.id()) != window_closing_ids_.end() || | 208 window_id.id()) != window_closing_ids_.end() || |
208 !IsOnlyOneTabLeft() || | 209 !IsOnlyOneTabLeft() || |
209 closed_by_user_gesture) { | 210 closed_by_user_gesture) { |
210 // Close is the result of one of the following: | 211 // Close is the result of one of the following: |
211 // . window close (and it isn't the last window). | 212 // . window close (and it isn't the last window). |
212 // . closing a tab and there are other windows/tabs open. | 213 // . closing a tab and there are other windows/tabs open. |
213 // . closed by a user gesture. | 214 // . closed by a user gesture. |
214 // In all cases we need to mark the tab as explicitly closed. | 215 // In all cases we need to mark the tab as explicitly closed. |
215 ScheduleCommand(CreateTabClosedCommand(tab_id.id())); | 216 ScheduleCommand(CreateTabClosedCommand(tab_id.id()).Pass()); |
216 } else { | 217 } else { |
217 // User closed the last tab in the last tabbed browser. Don't mark the | 218 // User closed the last tab in the last tabbed browser. Don't mark the |
218 // tab closed. | 219 // tab closed. |
219 pending_tab_close_ids_.insert(tab_id.id()); | 220 pending_tab_close_ids_.insert(tab_id.id()); |
220 has_open_trackable_browsers_ = false; | 221 has_open_trackable_browsers_ = false; |
221 } | 222 } |
222 } | 223 } |
223 | 224 |
224 void SessionService::WindowOpened(Browser* browser) { | 225 void SessionService::WindowOpened(Browser* browser) { |
225 if (!ShouldTrackBrowser(browser)) | 226 if (!ShouldTrackBrowser(browser)) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 if (!ShouldTrackChangesToWindow(window_id)) { | 280 if (!ShouldTrackChangesToWindow(window_id)) { |
280 // The last window may be one that is not tracked. | 281 // The last window may be one that is not tracked. |
281 MaybeDeleteSessionOnlyData(); | 282 MaybeDeleteSessionOnlyData(); |
282 return; | 283 return; |
283 } | 284 } |
284 | 285 |
285 windows_tracking_.erase(window_id.id()); | 286 windows_tracking_.erase(window_id.id()); |
286 | 287 |
287 if (window_closing_ids_.find(window_id.id()) != window_closing_ids_.end()) { | 288 if (window_closing_ids_.find(window_id.id()) != window_closing_ids_.end()) { |
288 window_closing_ids_.erase(window_id.id()); | 289 window_closing_ids_.erase(window_id.id()); |
289 ScheduleCommand(CreateWindowClosedCommand(window_id.id())); | 290 ScheduleCommand(CreateWindowClosedCommand(window_id.id()).Pass()); |
290 } else if (pending_window_close_ids_.find(window_id.id()) == | 291 } else if (pending_window_close_ids_.find(window_id.id()) == |
291 pending_window_close_ids_.end()) { | 292 pending_window_close_ids_.end()) { |
292 // We'll hit this if user closed the last tab in a window. | 293 // We'll hit this if user closed the last tab in a window. |
293 has_open_trackable_browsers_ = HasOpenTrackableBrowsers(window_id); | 294 has_open_trackable_browsers_ = HasOpenTrackableBrowsers(window_id); |
294 if (!has_open_trackable_browsers_) | 295 if (!has_open_trackable_browsers_) |
295 pending_window_close_ids_.insert(window_id.id()); | 296 pending_window_close_ids_.insert(window_id.id()); |
296 else | 297 else |
297 ScheduleCommand(CreateWindowClosedCommand(window_id.id())); | 298 ScheduleCommand(CreateWindowClosedCommand(window_id.id()).Pass()); |
298 } | 299 } |
299 MaybeDeleteSessionOnlyData(); | 300 MaybeDeleteSessionOnlyData(); |
300 } | 301 } |
301 | 302 |
302 void SessionService::TabInserted(WebContents* contents) { | 303 void SessionService::TabInserted(WebContents* contents) { |
303 SessionTabHelper* session_tab_helper = | 304 SessionTabHelper* session_tab_helper = |
304 SessionTabHelper::FromWebContents(contents); | 305 SessionTabHelper::FromWebContents(contents); |
305 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) | 306 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) |
306 return; | 307 return; |
307 SetTabWindow(session_tab_helper->window_id(), | 308 SetTabWindow(session_tab_helper->window_id(), |
(...skipping 11 matching lines...) Expand all Loading... |
319 // Record the association between the SessionStorageNamespace and the | 320 // Record the association between the SessionStorageNamespace and the |
320 // tab. | 321 // tab. |
321 // | 322 // |
322 // TODO(ajwong): This should be processing the whole map rather than | 323 // TODO(ajwong): This should be processing the whole map rather than |
323 // just the default. This in particular will not work for tabs with only | 324 // just the default. This in particular will not work for tabs with only |
324 // isolated apps which won't have a default partition. | 325 // isolated apps which won't have a default partition. |
325 content::SessionStorageNamespace* session_storage_namespace = | 326 content::SessionStorageNamespace* session_storage_namespace = |
326 contents->GetController().GetDefaultSessionStorageNamespace(); | 327 contents->GetController().GetDefaultSessionStorageNamespace(); |
327 ScheduleCommand(CreateSessionStorageAssociatedCommand( | 328 ScheduleCommand(CreateSessionStorageAssociatedCommand( |
328 session_tab_helper->session_id(), | 329 session_tab_helper->session_id(), |
329 session_storage_namespace->persistent_id())); | 330 session_storage_namespace->persistent_id()).Pass()); |
330 session_storage_namespace->SetShouldPersist(true); | 331 session_storage_namespace->SetShouldPersist(true); |
331 } | 332 } |
332 | 333 |
333 void SessionService::TabClosing(WebContents* contents) { | 334 void SessionService::TabClosing(WebContents* contents) { |
334 // Allow the associated sessionStorage to get deleted; it won't be needed | 335 // Allow the associated sessionStorage to get deleted; it won't be needed |
335 // in the session restore. | 336 // in the session restore. |
336 content::SessionStorageNamespace* session_storage_namespace = | 337 content::SessionStorageNamespace* session_storage_namespace = |
337 contents->GetController().GetDefaultSessionStorageNamespace(); | 338 contents->GetController().GetDefaultSessionStorageNamespace(); |
338 session_storage_namespace->SetShouldPersist(false); | 339 session_storage_namespace->SetShouldPersist(false); |
339 SessionTabHelper* session_tab_helper = | 340 SessionTabHelper* session_tab_helper = |
(...skipping 14 matching lines...) Expand all Loading... |
354 | 355 |
355 windows_tracking_.insert(window_id.id()); | 356 windows_tracking_.insert(window_id.id()); |
356 | 357 |
357 // The user created a new tabbed browser with our profile. Commit any | 358 // The user created a new tabbed browser with our profile. Commit any |
358 // pending closes. | 359 // pending closes. |
359 CommitPendingCloses(); | 360 CommitPendingCloses(); |
360 | 361 |
361 has_open_trackable_browsers_ = true; | 362 has_open_trackable_browsers_ = true; |
362 move_on_new_browser_ = true; | 363 move_on_new_browser_ = true; |
363 | 364 |
364 ScheduleCommand(CreateSetWindowTypeCommand(window_id, window_type)); | 365 ScheduleCommand(CreateSetWindowTypeCommand(window_id, window_type).Pass()); |
365 } | 366 } |
366 | 367 |
367 void SessionService::SetWindowAppName( | 368 void SessionService::SetWindowAppName( |
368 const SessionID& window_id, | 369 const SessionID& window_id, |
369 const std::string& app_name) { | 370 const std::string& app_name) { |
370 if (!ShouldTrackChangesToWindow(window_id)) | 371 if (!ShouldTrackChangesToWindow(window_id)) |
371 return; | 372 return; |
372 | 373 |
373 ScheduleCommand(CreateSetWindowAppNameCommand(window_id, app_name)); | 374 ScheduleCommand(CreateSetWindowAppNameCommand(window_id, app_name).Pass()); |
374 } | 375 } |
375 | 376 |
376 void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id, | 377 void SessionService::TabNavigationPathPrunedFromBack(const SessionID& window_id, |
377 const SessionID& tab_id, | 378 const SessionID& tab_id, |
378 int count) { | 379 int count) { |
379 if (!ShouldTrackChangesToWindow(window_id)) | 380 if (!ShouldTrackChangesToWindow(window_id)) |
380 return; | 381 return; |
381 | 382 |
382 ScheduleCommand(CreateTabNavigationPathPrunedFromBackCommand(tab_id, count)); | 383 ScheduleCommand( |
| 384 CreateTabNavigationPathPrunedFromBackCommand(tab_id, count).Pass()); |
383 } | 385 } |
384 | 386 |
385 void SessionService::TabNavigationPathPrunedFromFront( | 387 void SessionService::TabNavigationPathPrunedFromFront( |
386 const SessionID& window_id, | 388 const SessionID& window_id, |
387 const SessionID& tab_id, | 389 const SessionID& tab_id, |
388 int count) { | 390 int count) { |
389 if (!ShouldTrackChangesToWindow(window_id)) | 391 if (!ShouldTrackChangesToWindow(window_id)) |
390 return; | 392 return; |
391 | 393 |
392 // Update the range of indices. | 394 // Update the range of indices. |
393 if (tab_to_available_range_.find(tab_id.id()) != | 395 if (tab_to_available_range_.find(tab_id.id()) != |
394 tab_to_available_range_.end()) { | 396 tab_to_available_range_.end()) { |
395 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 397 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
396 range.first = std::max(0, range.first - count); | 398 range.first = std::max(0, range.first - count); |
397 range.second = std::max(0, range.second - count); | 399 range.second = std::max(0, range.second - count); |
398 } | 400 } |
399 | 401 |
400 ScheduleCommand(CreateTabNavigationPathPrunedFromFrontCommand(tab_id, count)); | 402 ScheduleCommand( |
| 403 CreateTabNavigationPathPrunedFromFrontCommand(tab_id, count).Pass()); |
401 } | 404 } |
402 | 405 |
403 void SessionService::UpdateTabNavigation( | 406 void SessionService::UpdateTabNavigation( |
404 const SessionID& window_id, | 407 const SessionID& window_id, |
405 const SessionID& tab_id, | 408 const SessionID& tab_id, |
406 const SerializedNavigationEntry& navigation) { | 409 const SerializedNavigationEntry& navigation) { |
407 if (!ShouldTrackEntry(navigation.virtual_url()) || | 410 if (!ShouldTrackEntry(navigation.virtual_url()) || |
408 !ShouldTrackChangesToWindow(window_id)) { | 411 !ShouldTrackChangesToWindow(window_id)) { |
409 return; | 412 return; |
410 } | 413 } |
411 | 414 |
412 if (tab_to_available_range_.find(tab_id.id()) != | 415 if (tab_to_available_range_.find(tab_id.id()) != |
413 tab_to_available_range_.end()) { | 416 tab_to_available_range_.end()) { |
414 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; | 417 std::pair<int, int>& range = tab_to_available_range_[tab_id.id()]; |
415 range.first = std::min(navigation.index(), range.first); | 418 range.first = std::min(navigation.index(), range.first); |
416 range.second = std::max(navigation.index(), range.second); | 419 range.second = std::max(navigation.index(), range.second); |
417 } | 420 } |
418 ScheduleCommand(CreateUpdateTabNavigationCommand(tab_id, navigation)); | 421 ScheduleCommand(CreateUpdateTabNavigationCommand(tab_id, navigation).Pass()); |
419 } | 422 } |
420 | 423 |
421 void SessionService::TabRestored(WebContents* tab, bool pinned) { | 424 void SessionService::TabRestored(WebContents* tab, bool pinned) { |
422 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); | 425 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); |
423 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) | 426 if (!ShouldTrackChangesToWindow(session_tab_helper->window_id())) |
424 return; | 427 return; |
425 | 428 |
426 BuildCommandsForTab(session_tab_helper->window_id(), tab, -1, | 429 BuildCommandsForTab(session_tab_helper->window_id(), |
427 pinned, &pending_commands(), NULL); | 430 tab, |
| 431 -1, |
| 432 pinned, |
| 433 &pending_commands(), |
| 434 NULL); |
428 StartSaveTimer(); | 435 StartSaveTimer(); |
429 } | 436 } |
430 | 437 |
431 void SessionService::SetSelectedNavigationIndex(const SessionID& window_id, | 438 void SessionService::SetSelectedNavigationIndex(const SessionID& window_id, |
432 const SessionID& tab_id, | 439 const SessionID& tab_id, |
433 int index) { | 440 int index) { |
434 if (!ShouldTrackChangesToWindow(window_id)) | 441 if (!ShouldTrackChangesToWindow(window_id)) |
435 return; | 442 return; |
436 | 443 |
437 if (tab_to_available_range_.find(tab_id.id()) != | 444 if (tab_to_available_range_.find(tab_id.id()) != |
438 tab_to_available_range_.end()) { | 445 tab_to_available_range_.end()) { |
439 if (index < tab_to_available_range_[tab_id.id()].first || | 446 if (index < tab_to_available_range_[tab_id.id()].first || |
440 index > tab_to_available_range_[tab_id.id()].second) { | 447 index > tab_to_available_range_[tab_id.id()].second) { |
441 // The new index is outside the range of what we've archived, schedule | 448 // The new index is outside the range of what we've archived, schedule |
442 // a reset. | 449 // a reset. |
443 ResetFromCurrentBrowsers(); | 450 ResetFromCurrentBrowsers(); |
444 return; | 451 return; |
445 } | 452 } |
446 } | 453 } |
447 ScheduleCommand(CreateSetSelectedNavigationIndexCommand(tab_id, index)); | 454 ScheduleCommand( |
| 455 CreateSetSelectedNavigationIndexCommand(tab_id, index).Pass()); |
448 } | 456 } |
449 | 457 |
450 void SessionService::SetSelectedTabInWindow(const SessionID& window_id, | 458 void SessionService::SetSelectedTabInWindow(const SessionID& window_id, |
451 int index) { | 459 int index) { |
452 if (!ShouldTrackChangesToWindow(window_id)) | 460 if (!ShouldTrackChangesToWindow(window_id)) |
453 return; | 461 return; |
454 | 462 |
455 ScheduleCommand(CreateSetSelectedTabInWindowCommand(window_id, index)); | 463 ScheduleCommand(CreateSetSelectedTabInWindowCommand(window_id, index).Pass()); |
456 } | 464 } |
457 | 465 |
458 void SessionService::SetTabUserAgentOverride( | 466 void SessionService::SetTabUserAgentOverride( |
459 const SessionID& window_id, | 467 const SessionID& window_id, |
460 const SessionID& tab_id, | 468 const SessionID& tab_id, |
461 const std::string& user_agent_override) { | 469 const std::string& user_agent_override) { |
462 if (!ShouldTrackChangesToWindow(window_id)) | 470 if (!ShouldTrackChangesToWindow(window_id)) |
463 return; | 471 return; |
464 | 472 |
465 ScheduleCommand(CreateSetTabUserAgentOverrideCommand(tab_id, | 473 ScheduleCommand( |
466 user_agent_override)); | 474 CreateSetTabUserAgentOverrideCommand(tab_id, user_agent_override).Pass()); |
467 } | 475 } |
468 | 476 |
469 void SessionService::SetTabExtensionAppID( | 477 void SessionService::SetTabExtensionAppID( |
470 const SessionID& window_id, | 478 const SessionID& window_id, |
471 const SessionID& tab_id, | 479 const SessionID& tab_id, |
472 const std::string& extension_app_id) { | 480 const std::string& extension_app_id) { |
473 if (!ShouldTrackChangesToWindow(window_id)) | 481 if (!ShouldTrackChangesToWindow(window_id)) |
474 return; | 482 return; |
475 | 483 |
476 ScheduleCommand(CreateSetTabExtensionAppIDCommand(tab_id, extension_app_id)); | 484 ScheduleCommand( |
| 485 CreateSetTabExtensionAppIDCommand(tab_id, extension_app_id).Pass()); |
477 } | 486 } |
478 | 487 |
479 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( | 488 base::CancelableTaskTracker::TaskId SessionService::GetLastSession( |
480 const SessionCallback& callback, | 489 const SessionCallback& callback, |
481 base::CancelableTaskTracker* tracker) { | 490 base::CancelableTaskTracker* tracker) { |
482 // OnGotSessionCommands maps the SessionCommands to browser state, then run | 491 // OnGotSessionCommands maps the SessionCommands to browser state, then run |
483 // the callback. | 492 // the callback. |
484 return ScheduleGetLastSessionCommands( | 493 return ScheduleGetLastSessionCommands( |
485 base::Bind(&SessionService::OnGotSessionCommands, | 494 base::Bind(&SessionService::OnGotSessionCommands, |
486 weak_factory_.GetWeakPtr(), callback), | 495 weak_factory_.GetWeakPtr(), |
| 496 callback), |
487 tracker); | 497 tracker); |
488 } | 498 } |
489 | 499 |
490 void SessionService::Save() { | 500 void SessionService::Save() { |
491 bool had_commands = !pending_commands().empty(); | 501 bool had_commands = !pending_commands().empty(); |
492 BaseSessionService::Save(); | 502 BaseSessionService::Save(); |
493 if (had_commands) { | 503 if (had_commands) { |
494 RecordSessionUpdateHistogramData(chrome::NOTIFICATION_SESSION_SERVICE_SAVED, | 504 RecordSessionUpdateHistogramData(chrome::NOTIFICATION_SESSION_SERVICE_SAVED, |
495 &last_updated_save_time_); | 505 &last_updated_save_time_); |
496 content::NotificationService::current()->Notify( | 506 content::NotificationService::current()->Notify( |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 break; | 679 break; |
670 } | 680 } |
671 | 681 |
672 default: | 682 default: |
673 NOTREACHED(); | 683 NOTREACHED(); |
674 } | 684 } |
675 } | 685 } |
676 | 686 |
677 void SessionService::OnBrowserSetLastActive(Browser* browser) { | 687 void SessionService::OnBrowserSetLastActive(Browser* browser) { |
678 if (ShouldTrackBrowser(browser)) | 688 if (ShouldTrackBrowser(browser)) |
679 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); | 689 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id()).Pass()); |
680 } | 690 } |
681 | 691 |
682 void SessionService::OnGotSessionCommands( | 692 void SessionService::OnGotSessionCommands( |
683 const SessionCallback& callback, | 693 const SessionCallback& callback, |
684 ScopedVector<SessionCommand> commands) { | 694 ScopedVector<SessionCommand> commands) { |
685 ScopedVector<SessionWindow> valid_windows; | 695 ScopedVector<SessionWindow> valid_windows; |
686 SessionID::id_type active_window_id = 0; | 696 SessionID::id_type active_window_id = 0; |
687 | 697 |
688 startup_metric_utils::ScopedSlowStartupUMA | 698 startup_metric_utils::ScopedSlowStartupUMA |
689 scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows"); | 699 scoped_timer("Startup.SlowStartupSessionServiceCreateTabsAndWindows"); |
690 | 700 |
691 RestoreSessionFromCommands( | 701 RestoreSessionFromCommands(commands, &valid_windows.get(), &active_window_id); |
692 commands.get(), &valid_windows.get(), &active_window_id); | |
693 RemoveUnusedRestoreWindows(&valid_windows.get()); | 702 RemoveUnusedRestoreWindows(&valid_windows.get()); |
694 | 703 |
695 callback.Run(valid_windows.Pass(), active_window_id); | 704 callback.Run(valid_windows.Pass(), active_window_id); |
696 } | 705 } |
697 | 706 |
698 void SessionService::BuildCommandsForTab(const SessionID& window_id, | 707 void SessionService::BuildCommandsForTab(const SessionID& window_id, |
699 WebContents* tab, | 708 WebContents* tab, |
700 int index_in_window, | 709 int index_in_window, |
701 bool is_pinned, | 710 bool is_pinned, |
702 std::vector<SessionCommand*>* commands, | 711 ScopedVector<SessionCommand>* commands, |
703 IdToRange* tab_to_available_range) { | 712 IdToRange* tab_to_available_range) { |
704 DCHECK(tab && commands && window_id.id()); | 713 DCHECK(tab && commands && window_id.id()); |
705 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); | 714 SessionTabHelper* session_tab_helper = SessionTabHelper::FromWebContents(tab); |
706 const SessionID& session_id(session_tab_helper->session_id()); | 715 const SessionID& session_id(session_tab_helper->session_id()); |
707 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); | 716 commands->push_back( |
| 717 CreateSetTabWindowCommand(window_id, session_id).release()); |
708 | 718 |
709 const int current_index = tab->GetController().GetCurrentEntryIndex(); | 719 const int current_index = tab->GetController().GetCurrentEntryIndex(); |
710 const int min_index = std::max(0, | 720 const int min_index = std::max(0, |
711 current_index - max_persist_navigation_count); | 721 current_index - max_persist_navigation_count); |
712 const int max_index = | 722 const int max_index = |
713 std::min(current_index + max_persist_navigation_count, | 723 std::min(current_index + max_persist_navigation_count, |
714 tab->GetController().GetEntryCount()); | 724 tab->GetController().GetEntryCount()); |
715 const int pending_index = tab->GetController().GetPendingEntryIndex(); | 725 const int pending_index = tab->GetController().GetPendingEntryIndex(); |
716 if (tab_to_available_range) { | 726 if (tab_to_available_range) { |
717 (*tab_to_available_range)[session_id.id()] = | 727 (*tab_to_available_range)[session_id.id()] = |
718 std::pair<int, int>(min_index, max_index); | 728 std::pair<int, int>(min_index, max_index); |
719 } | 729 } |
720 | 730 |
721 if (is_pinned) | 731 if (is_pinned) |
722 commands->push_back(CreatePinnedStateCommand(session_id, true)); | 732 commands->push_back(CreatePinnedStateCommand(session_id, true).release()); |
723 | 733 |
724 extensions::TabHelper* extensions_tab_helper = | 734 extensions::TabHelper* extensions_tab_helper = |
725 extensions::TabHelper::FromWebContents(tab); | 735 extensions::TabHelper::FromWebContents(tab); |
726 if (extensions_tab_helper->extension_app()) { | 736 if (extensions_tab_helper->extension_app()) { |
727 commands->push_back(CreateSetTabExtensionAppIDCommand( | 737 commands->push_back(CreateSetTabExtensionAppIDCommand( |
728 session_id, | 738 session_id, |
729 extensions_tab_helper->extension_app()->id())); | 739 extensions_tab_helper->extension_app()->id()).release()); |
730 } | 740 } |
731 | 741 |
732 const std::string& ua_override = tab->GetUserAgentOverride(); | 742 const std::string& ua_override = tab->GetUserAgentOverride(); |
733 if (!ua_override.empty()) { | 743 if (!ua_override.empty()) { |
734 commands->push_back(CreateSetTabUserAgentOverrideCommand(session_id, | 744 commands->push_back( |
735 ua_override)); | 745 CreateSetTabUserAgentOverrideCommand(session_id, ua_override).release()); |
736 } | 746 } |
737 | 747 |
738 for (int i = min_index; i < max_index; ++i) { | 748 for (int i = min_index; i < max_index; ++i) { |
739 const NavigationEntry* entry = (i == pending_index) ? | 749 const NavigationEntry* entry = (i == pending_index) ? |
740 tab->GetController().GetPendingEntry() : | 750 tab->GetController().GetPendingEntry() : |
741 tab->GetController().GetEntryAtIndex(i); | 751 tab->GetController().GetEntryAtIndex(i); |
742 DCHECK(entry); | 752 DCHECK(entry); |
743 if (ShouldTrackEntry(entry->GetVirtualURL())) { | 753 if (ShouldTrackEntry(entry->GetVirtualURL())) { |
744 const SerializedNavigationEntry navigation = | 754 const SerializedNavigationEntry navigation = |
745 ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry); | 755 ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry); |
746 commands->push_back( | 756 commands->push_back( |
747 CreateUpdateTabNavigationCommand(session_id, navigation)); | 757 CreateUpdateTabNavigationCommand(session_id, navigation).release()); |
748 } | 758 } |
749 } | 759 } |
750 commands->push_back( | 760 commands->push_back( |
751 CreateSetSelectedNavigationIndexCommand(session_id, current_index)); | 761 CreateSetSelectedNavigationIndexCommand(session_id, |
| 762 current_index).release()); |
752 | 763 |
753 if (index_in_window != -1) { | 764 if (index_in_window != -1) { |
754 commands->push_back( | 765 commands->push_back(CreateSetTabIndexInWindowCommand( |
755 CreateSetTabIndexInWindowCommand(session_id, index_in_window)); | 766 session_id, |
| 767 index_in_window).release()); |
756 } | 768 } |
757 | 769 |
758 // Record the association between the sessionStorage namespace and the tab. | 770 // Record the association between the sessionStorage namespace and the tab. |
759 content::SessionStorageNamespace* session_storage_namespace = | 771 content::SessionStorageNamespace* session_storage_namespace = |
760 tab->GetController().GetDefaultSessionStorageNamespace(); | 772 tab->GetController().GetDefaultSessionStorageNamespace(); |
761 ScheduleCommand(CreateSessionStorageAssociatedCommand( | 773 ScheduleCommand(CreateSessionStorageAssociatedCommand( |
762 session_tab_helper->session_id(), | 774 session_tab_helper->session_id(), |
763 session_storage_namespace->persistent_id())); | 775 session_storage_namespace->persistent_id()).Pass()); |
764 } | 776 } |
765 | 777 |
766 void SessionService::BuildCommandsForBrowser( | 778 void SessionService::BuildCommandsForBrowser( |
767 Browser* browser, | 779 Browser* browser, |
768 std::vector<SessionCommand*>* commands, | 780 ScopedVector<SessionCommand>* commands, |
769 IdToRange* tab_to_available_range, | 781 IdToRange* tab_to_available_range, |
770 std::set<SessionID::id_type>* windows_to_track) { | 782 std::set<SessionID::id_type>* windows_to_track) { |
771 DCHECK(browser && commands); | 783 DCHECK(browser && commands); |
772 DCHECK(browser->session_id().id()); | 784 DCHECK(browser->session_id().id()); |
773 | 785 |
774 commands->push_back( | 786 commands->push_back(CreateSetWindowBoundsCommand( |
775 CreateSetWindowBoundsCommand(browser->session_id(), | 787 browser->session_id(), |
776 browser->window()->GetRestoredBounds(), | 788 browser->window()->GetRestoredBounds(), |
777 browser->window()->GetRestoredState())); | 789 browser->window()->GetRestoredState()).release()); |
778 | 790 |
779 commands->push_back(CreateSetWindowTypeCommand( | 791 commands->push_back(CreateSetWindowTypeCommand( |
780 browser->session_id(), | 792 browser->session_id(), |
781 WindowTypeForBrowserType(browser->type()))); | 793 WindowTypeForBrowserType(browser->type())).release()); |
782 | 794 |
783 if (!browser->app_name().empty()) { | 795 if (!browser->app_name().empty()) { |
784 commands->push_back(CreateSetWindowAppNameCommand(browser->session_id(), | 796 commands->push_back(CreateSetWindowAppNameCommand( |
785 browser->app_name())); | 797 browser->session_id(), |
| 798 browser->app_name()).release()); |
786 } | 799 } |
787 | 800 |
788 windows_to_track->insert(browser->session_id().id()); | 801 windows_to_track->insert(browser->session_id().id()); |
789 TabStripModel* tab_strip = browser->tab_strip_model(); | 802 TabStripModel* tab_strip = browser->tab_strip_model(); |
790 for (int i = 0; i < tab_strip->count(); ++i) { | 803 for (int i = 0; i < tab_strip->count(); ++i) { |
791 WebContents* tab = tab_strip->GetWebContentsAt(i); | 804 WebContents* tab = tab_strip->GetWebContentsAt(i); |
792 DCHECK(tab); | 805 DCHECK(tab); |
793 BuildCommandsForTab(browser->session_id(), tab, i, | 806 BuildCommandsForTab(browser->session_id(), tab, i, |
794 tab_strip->IsTabPinned(i), | 807 tab_strip->IsTabPinned(i), |
795 commands, tab_to_available_range); | 808 commands, tab_to_available_range); |
796 } | 809 } |
797 | 810 |
798 commands->push_back(CreateSetSelectedTabInWindowCommand( | 811 commands->push_back(CreateSetSelectedTabInWindowCommand( |
799 browser->session_id(), | 812 browser->session_id(), |
800 browser->tab_strip_model()->active_index())); | 813 browser->tab_strip_model()->active_index()).release()); |
801 } | 814 } |
802 | 815 |
803 void SessionService::BuildCommandsFromBrowsers( | 816 void SessionService::BuildCommandsFromBrowsers( |
804 std::vector<SessionCommand*>* commands, | 817 ScopedVector<SessionCommand>* commands, |
805 IdToRange* tab_to_available_range, | 818 IdToRange* tab_to_available_range, |
806 std::set<SessionID::id_type>* windows_to_track) { | 819 std::set<SessionID::id_type>* windows_to_track) { |
807 DCHECK(commands); | 820 DCHECK(commands); |
808 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 821 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
809 Browser* browser = *it; | 822 Browser* browser = *it; |
810 // Make sure the browser has tabs and a window. Browser's destructor | 823 // Make sure the browser has tabs and a window. Browser's destructor |
811 // removes itself from the BrowserList. When a browser is closed the | 824 // removes itself from the BrowserList. When a browser is closed the |
812 // destructor is not necessarily run immediately. This means it's possible | 825 // destructor is not necessarily run immediately. This means it's possible |
813 // for us to get a handle to a browser that is about to be removed. If | 826 // for us to get a handle to a browser that is about to be removed. If |
814 // the tab count is 0 or the window is NULL, the browser is about to be | 827 // the tab count is 0 or the window is NULL, the browser is about to be |
815 // deleted, so we ignore it. | 828 // deleted, so we ignore it. |
816 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && | 829 if (ShouldTrackBrowser(browser) && browser->tab_strip_model()->count() && |
817 browser->window()) { | 830 browser->window()) { |
818 BuildCommandsForBrowser(browser, commands, tab_to_available_range, | 831 BuildCommandsForBrowser(browser, commands, tab_to_available_range, |
819 windows_to_track); | 832 windows_to_track); |
820 } | 833 } |
821 } | 834 } |
822 } | 835 } |
823 | 836 |
824 void SessionService::ScheduleResetCommands() { | 837 void SessionService::ScheduleResetCommands() { |
825 set_pending_reset(true); | 838 set_pending_reset(true); |
826 STLDeleteElements(&pending_commands()); | 839 pending_commands().clear(); |
827 tab_to_available_range_.clear(); | 840 tab_to_available_range_.clear(); |
828 windows_tracking_.clear(); | 841 windows_tracking_.clear(); |
829 BuildCommandsFromBrowsers(&pending_commands(), &tab_to_available_range_, | 842 BuildCommandsFromBrowsers(&pending_commands(), |
| 843 &tab_to_available_range_, |
830 &windows_tracking_); | 844 &windows_tracking_); |
831 if (!windows_tracking_.empty()) { | 845 if (!windows_tracking_.empty()) { |
832 // We're lazily created on startup and won't get an initial batch of | 846 // We're lazily created on startup and won't get an initial batch of |
833 // SetWindowType messages. Set these here to make sure our state is correct. | 847 // SetWindowType messages. Set these here to make sure our state is correct. |
834 has_open_trackable_browsers_ = true; | 848 has_open_trackable_browsers_ = true; |
835 move_on_new_browser_ = true; | 849 move_on_new_browser_ = true; |
836 } | 850 } |
837 StartSaveTimer(); | 851 StartSaveTimer(); |
838 } | 852 } |
839 | 853 |
840 void SessionService::ScheduleCommand(SessionCommand* command) { | 854 void SessionService::ScheduleCommand(scoped_ptr<SessionCommand> command) { |
841 DCHECK(command); | 855 DCHECK(command); |
842 if (ReplacePendingCommand(command, pending_commands())) | 856 if (ReplacePendingCommand(pending_commands(), &command)) |
843 return; | 857 return; |
844 BaseSessionService::ScheduleCommand(command); | 858 bool is_closing_command = IsClosingCommand(command.get()); |
| 859 BaseSessionService::ScheduleCommand(command.Pass()); |
845 // Don't schedule a reset on tab closed/window closed. Otherwise we may | 860 // Don't schedule a reset on tab closed/window closed. Otherwise we may |
846 // lose tabs/windows we want to restore from if we exit right after this. | 861 // lose tabs/windows we want to restore from if we exit right after this. |
847 if (!pending_reset() && pending_window_close_ids_.empty() && | 862 if (!pending_reset() && pending_window_close_ids_.empty() && |
848 commands_since_reset() >= kWritesPerReset && !IsClosingCommand(command)) { | 863 commands_since_reset() >= kWritesPerReset && is_closing_command) { |
849 ScheduleResetCommands(); | 864 ScheduleResetCommands(); |
850 } | 865 } |
851 } | 866 } |
852 | 867 |
853 void SessionService::CommitPendingCloses() { | 868 void SessionService::CommitPendingCloses() { |
854 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); | 869 for (PendingTabCloseIDs::iterator i = pending_tab_close_ids_.begin(); |
855 i != pending_tab_close_ids_.end(); ++i) { | 870 i != pending_tab_close_ids_.end(); ++i) { |
856 ScheduleCommand(CreateTabClosedCommand(*i)); | 871 ScheduleCommand(CreateTabClosedCommand(*i).Pass()); |
857 } | 872 } |
858 pending_tab_close_ids_.clear(); | 873 pending_tab_close_ids_.clear(); |
859 | 874 |
860 for (PendingWindowCloseIDs::iterator i = pending_window_close_ids_.begin(); | 875 for (PendingWindowCloseIDs::iterator i = pending_window_close_ids_.begin(); |
861 i != pending_window_close_ids_.end(); ++i) { | 876 i != pending_window_close_ids_.end(); ++i) { |
862 ScheduleCommand(CreateWindowClosedCommand(*i)); | 877 ScheduleCommand(CreateWindowClosedCommand(*i).Pass()); |
863 } | 878 } |
864 pending_window_close_ids_.clear(); | 879 pending_window_close_ids_.clear(); |
865 } | 880 } |
866 | 881 |
867 bool SessionService::IsOnlyOneTabLeft() const { | 882 bool SessionService::IsOnlyOneTabLeft() const { |
868 if (!profile() || profile()->AsTestingProfile()) { | 883 if (!profile() || profile()->AsTestingProfile()) { |
869 // We're testing, always return false. | 884 // We're testing, always return false. |
870 return false; | 885 return false; |
871 } | 886 } |
872 | 887 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 return; | 1085 return; |
1071 } | 1086 } |
1072 | 1087 |
1073 // Check for any open windows for the current profile that we aren't tracking. | 1088 // Check for any open windows for the current profile that we aren't tracking. |
1074 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 1089 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
1075 if ((*it)->profile() == profile()) | 1090 if ((*it)->profile() == profile()) |
1076 return; | 1091 return; |
1077 } | 1092 } |
1078 DeleteSessionOnlyData(profile()); | 1093 DeleteSessionOnlyData(profile()); |
1079 } | 1094 } |
OLD | NEW |