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> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
16 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
18 #include "base/pickle.h" | 18 #include "base/pickle.h" |
19 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
20 #include "chrome/browser/extensions/tab_helper.h" | 20 #include "chrome/browser/extensions/tab_helper.h" |
21 #include "chrome/browser/prefs/session_startup_pref.h" | 21 #include "chrome/browser/prefs/session_startup_pref.h" |
22 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/sessions/session_backend.h" | 23 #include "chrome/browser/sessions/session_backend.h" |
24 #include "chrome/browser/sessions/session_command.h" | 24 #include "chrome/browser/sessions/session_command.h" |
25 #include "chrome/browser/sessions/session_restore.h" | 25 #include "chrome/browser/sessions/session_restore.h" |
26 #include "chrome/browser/sessions/session_tab_helper.h" | 26 #include "chrome/browser/sessions/session_tab_helper.h" |
27 #include "chrome/browser/sessions/session_types.h" | 27 #include "chrome/browser/sessions/session_types.h" |
| 28 #include "chrome/browser/sync/glue/synced_tab_delegate.h" |
28 #include "chrome/browser/ui/browser_iterator.h" | 29 #include "chrome/browser/ui/browser_iterator.h" |
29 #include "chrome/browser/ui/browser_list.h" | 30 #include "chrome/browser/ui/browser_list.h" |
30 #include "chrome/browser/ui/browser_tabstrip.h" | 31 #include "chrome/browser/ui/browser_tabstrip.h" |
31 #include "chrome/browser/ui/browser_window.h" | 32 #include "chrome/browser/ui/browser_window.h" |
32 #include "chrome/browser/ui/host_desktop.h" | 33 #include "chrome/browser/ui/host_desktop.h" |
33 #include "chrome/browser/ui/startup/startup_browser_creator.h" | 34 #include "chrome/browser/ui/startup/startup_browser_creator.h" |
34 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 35 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
35 #include "chrome/common/chrome_notification_types.h" | 36 #include "chrome/common/chrome_notification_types.h" |
36 #include "chrome/common/extensions/extension.h" | 37 #include "chrome/common/extensions/extension.h" |
37 #include "chrome/common/startup_metric_utils.h" | 38 #include "chrome/common/startup_metric_utils.h" |
38 #include "content/public/browser/navigation_details.h" | 39 #include "content/public/browser/navigation_details.h" |
39 #include "content/public/browser/navigation_entry.h" | 40 #include "content/public/browser/navigation_entry.h" |
40 #include "content/public/browser/notification_details.h" | 41 #include "content/public/browser/notification_details.h" |
41 #include "content/public/browser/notification_service.h" | 42 #include "content/public/browser/notification_service.h" |
42 #include "content/public/browser/session_storage_namespace.h" | 43 #include "content/public/browser/session_storage_namespace.h" |
43 #include "content/public/browser/web_contents.h" | 44 #include "content/public/browser/web_contents.h" |
44 | 45 |
45 #if defined(OS_MACOSX) | 46 #if defined(OS_MACOSX) |
46 #include "chrome/browser/app_controller_mac.h" | 47 #include "chrome/browser/app_controller_mac.h" |
47 #endif | 48 #endif |
48 | 49 |
49 using base::Time; | 50 using base::Time; |
50 using content::NavigationEntry; | 51 using content::NavigationEntry; |
51 using content::WebContents; | 52 using content::WebContents; |
52 using sessions::SerializedNavigationEntry; | 53 using sessions::SerializedNavigationEntry; |
| 54 using browser_sync::SyncedTabDelegate; |
53 | 55 |
54 // Identifier for commands written to file. | 56 // Identifier for commands written to file. |
55 static const SessionCommand::id_type kCommandSetTabWindow = 0; | 57 static const SessionCommand::id_type kCommandSetTabWindow = 0; |
56 // OBSOLETE Superseded by kCommandSetWindowBounds3. | 58 // OBSOLETE Superseded by kCommandSetWindowBounds3. |
57 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; | 59 // static const SessionCommand::id_type kCommandSetWindowBounds = 1; |
58 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; | 60 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2; |
59 // Original kCommandTabClosed/kCommandWindowClosed. See comment in | 61 // Original kCommandTabClosed/kCommandWindowClosed. See comment in |
60 // MigrateClosedPayload for details on why they were replaced. | 62 // MigrateClosedPayload for details on why they were replaced. |
61 static const SessionCommand::id_type kCommandTabClosedObsolete = 3; | 63 static const SessionCommand::id_type kCommandTabClosedObsolete = 3; |
62 static const SessionCommand::id_type kCommandWindowClosedObsolete = 4; | 64 static const SessionCommand::id_type kCommandWindowClosedObsolete = 4; |
63 static const SessionCommand::id_type | 65 static const SessionCommand::id_type |
64 kCommandTabNavigationPathPrunedFromBack = 5; | 66 kCommandTabNavigationPathPrunedFromBack = 5; |
65 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6; | 67 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6; |
66 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; | 68 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; |
67 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; | 69 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; |
68 static const SessionCommand::id_type kCommandSetWindowType = 9; | 70 static const SessionCommand::id_type kCommandSetWindowType = 9; |
69 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. | 71 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. |
70 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | 72 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
71 static const SessionCommand::id_type | 73 static const SessionCommand::id_type |
72 kCommandTabNavigationPathPrunedFromFront = 11; | 74 kCommandTabNavigationPathPrunedFromFront = 11; |
73 static const SessionCommand::id_type kCommandSetPinnedState = 12; | 75 static const SessionCommand::id_type kCommandSetPinnedState = 12; |
74 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; | 76 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; |
75 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; | 77 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; |
76 static const SessionCommand::id_type kCommandSetWindowAppName = 15; | 78 static const SessionCommand::id_type kCommandSetWindowAppName = 15; |
77 static const SessionCommand::id_type kCommandTabClosed = 16; | 79 static const SessionCommand::id_type kCommandTabClosed = 16; |
78 static const SessionCommand::id_type kCommandWindowClosed = 17; | 80 static const SessionCommand::id_type kCommandWindowClosed = 17; |
79 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18; | 81 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18; |
80 static const SessionCommand::id_type kCommandSessionStorageAssociated = 19; | 82 static const SessionCommand::id_type kCommandSessionStorageAssociated = 19; |
81 static const SessionCommand::id_type kCommandSetActiveWindow = 20; | 83 static const SessionCommand::id_type kCommandSetActiveWindow = 20; |
| 84 static const SessionCommand::id_type kCommandSetTabSessionSyncId = 21; |
82 | 85 |
83 // Every kWritesPerReset commands triggers recreating the file. | 86 // Every kWritesPerReset commands triggers recreating the file. |
84 static const int kWritesPerReset = 250; | 87 static const int kWritesPerReset = 250; |
85 | 88 |
86 namespace { | 89 namespace { |
87 | 90 |
88 // Various payload structures. | 91 // Various payload structures. |
89 struct ClosedPayload { | 92 struct ClosedPayload { |
90 SessionID::id_type id; | 93 SessionID::id_type id; |
91 int64 close_time; | 94 int64 close_time; |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 const SessionID& window_id, | 476 const SessionID& window_id, |
474 const SessionID& tab_id, | 477 const SessionID& tab_id, |
475 const std::string& user_agent_override) { | 478 const std::string& user_agent_override) { |
476 if (!ShouldTrackChangesToWindow(window_id)) | 479 if (!ShouldTrackChangesToWindow(window_id)) |
477 return; | 480 return; |
478 | 481 |
479 ScheduleCommand(CreateSetTabUserAgentOverrideCommand( | 482 ScheduleCommand(CreateSetTabUserAgentOverrideCommand( |
480 kCommandSetTabUserAgentOverride, tab_id.id(), user_agent_override)); | 483 kCommandSetTabUserAgentOverride, tab_id.id(), user_agent_override)); |
481 } | 484 } |
482 | 485 |
| 486 void SessionService::SetTabSessionSyncId(const SessionID& window_id, |
| 487 const SessionID& tab_id, |
| 488 const int64& sync_id) { |
| 489 if (!ShouldTrackChangesToWindow(window_id)) |
| 490 return; |
| 491 ScheduleCommand(CreateSetTabSessionSyncIdCommand( |
| 492 kCommandSetTabSessionSyncId, tab_id.id(), sync_id)); |
| 493 } |
| 494 |
483 CancelableTaskTracker::TaskId SessionService::GetLastSession( | 495 CancelableTaskTracker::TaskId SessionService::GetLastSession( |
484 const SessionCallback& callback, | 496 const SessionCallback& callback, |
485 CancelableTaskTracker* tracker) { | 497 CancelableTaskTracker* tracker) { |
486 // OnGotSessionCommands maps the SessionCommands to browser state, then run | 498 // OnGotSessionCommands maps the SessionCommands to browser state, then run |
487 // the callback. | 499 // the callback. |
488 return ScheduleGetLastSessionCommands( | 500 return ScheduleGetLastSessionCommands( |
489 base::Bind(&SessionService::OnGotSessionCommands, | 501 base::Bind(&SessionService::OnGotSessionCommands, |
490 base::Unretained(this), callback), | 502 base::Unretained(this), callback), |
491 tracker); | 503 tracker); |
492 } | 504 } |
(...skipping 18 matching lines...) Expand all Loading... |
511 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, | 523 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, |
512 content::NotificationService::AllSources()); | 524 content::NotificationService::AllSources()); |
513 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 525 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
514 content::NotificationService::AllSources()); | 526 content::NotificationService::AllSources()); |
515 // Wait for NOTIFICATION_BROWSER_WINDOW_READY so that is_app() is set. | 527 // Wait for NOTIFICATION_BROWSER_WINDOW_READY so that is_app() is set. |
516 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, | 528 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
517 content::NotificationService::AllBrowserContextsAndSources()); | 529 content::NotificationService::AllBrowserContextsAndSources()); |
518 registrar_.Add( | 530 registrar_.Add( |
519 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, | 531 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, |
520 content::NotificationService::AllSources()); | 532 content::NotificationService::AllSources()); |
| 533 registrar_.Add(this, |
| 534 chrome::NOTIFICATION_SESSION_SYNC_ID_GENERATED, |
| 535 content::NotificationService::AllSources()); |
521 | 536 |
522 BrowserList::AddObserver(this); | 537 BrowserList::AddObserver(this); |
523 } | 538 } |
524 | 539 |
525 bool SessionService::processed_any_commands() { | 540 bool SessionService::processed_any_commands() { |
526 return backend()->inited() || !pending_commands().empty(); | 541 return backend()->inited() || !pending_commands().empty(); |
527 } | 542 } |
528 | 543 |
529 bool SessionService::ShouldNewWindowStartSession() { | 544 bool SessionService::ShouldNewWindowStartSession() { |
530 // ChromeOS and OSX have different ideas of application lifetime than | 545 // ChromeOS and OSX have different ideas of application lifetime than |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 } | 688 } |
674 if (extension_tab_helper->extension_app()) { | 689 if (extension_tab_helper->extension_app()) { |
675 SessionTabHelper* session_tab_helper = | 690 SessionTabHelper* session_tab_helper = |
676 SessionTabHelper::FromWebContents( | 691 SessionTabHelper::FromWebContents( |
677 extension_tab_helper->web_contents()); | 692 extension_tab_helper->web_contents()); |
678 SetTabExtensionAppID(session_tab_helper->window_id(), | 693 SetTabExtensionAppID(session_tab_helper->window_id(), |
679 session_tab_helper->session_id(), | 694 session_tab_helper->session_id(), |
680 extension_tab_helper->extension_app()->id()); | 695 extension_tab_helper->extension_app()->id()); |
681 } | 696 } |
682 break; | 697 break; |
| 698 |
| 699 } |
| 700 case chrome::NOTIFICATION_SESSION_SYNC_ID_GENERATED: { |
| 701 content::Details<const SyncedTabDelegate> tab(details); |
| 702 SetTabSessionSyncId( |
| 703 tab->GetWindowId(), tab->GetSessionId(), tab->GetSyncSessionId()); |
| 704 break; |
683 } | 705 } |
684 | 706 |
685 default: | 707 default: |
686 NOTREACHED(); | 708 NOTREACHED(); |
687 } | 709 } |
688 } | 710 } |
689 | 711 |
690 void SessionService::OnBrowserSetLastActive(Browser* browser) { | 712 void SessionService::OnBrowserSetLastActive(Browser* browser) { |
691 if (ShouldTrackBrowser(browser)) | 713 if (ShouldTrackBrowser(browser)) |
692 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); | 714 ScheduleCommand(CreateSetActiveWindowCommand(browser->session_id())); |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 case kCommandSetActiveWindow: { | 1276 case kCommandSetActiveWindow: { |
1255 ActiveWindowPayload payload; | 1277 ActiveWindowPayload payload; |
1256 if (!command->GetPayload(&payload, sizeof(payload))) { | 1278 if (!command->GetPayload(&payload, sizeof(payload))) { |
1257 VLOG(1) << "Failed reading command " << command->id(); | 1279 VLOG(1) << "Failed reading command " << command->id(); |
1258 return true; | 1280 return true; |
1259 } | 1281 } |
1260 *active_window_id = payload; | 1282 *active_window_id = payload; |
1261 break; | 1283 break; |
1262 } | 1284 } |
1263 | 1285 |
| 1286 case kCommandSetTabSessionSyncId: { |
| 1287 SessionID::id_type tab_id; |
| 1288 int64 sync_id = -1; |
| 1289 if (!RestoreSetTabSessionSyncIdCommand(*command, &tab_id, &sync_id)) { |
| 1290 } |
| 1291 GetTab(tab_id, tabs)->sync_session_id = sync_id; |
| 1292 break; |
| 1293 } |
| 1294 |
1264 default: | 1295 default: |
1265 VLOG(1) << "Failed reading an unknown command " << command->id(); | 1296 VLOG(1) << "Failed reading an unknown command " << command->id(); |
1266 return true; | 1297 return true; |
1267 } | 1298 } |
1268 } | 1299 } |
1269 return true; | 1300 return true; |
1270 } | 1301 } |
1271 | 1302 |
1272 void SessionService::BuildCommandsForTab(const SessionID& window_id, | 1303 void SessionService::BuildCommandsForTab(const SessionID& window_id, |
1273 WebContents* tab, | 1304 WebContents* tab, |
(...skipping 30 matching lines...) Expand all Loading... |
1304 kCommandSetExtensionAppID, session_id.id(), | 1335 kCommandSetExtensionAppID, session_id.id(), |
1305 extensions_tab_helper->extension_app()->id())); | 1336 extensions_tab_helper->extension_app()->id())); |
1306 } | 1337 } |
1307 | 1338 |
1308 const std::string& ua_override = tab->GetUserAgentOverride(); | 1339 const std::string& ua_override = tab->GetUserAgentOverride(); |
1309 if (!ua_override.empty()) { | 1340 if (!ua_override.empty()) { |
1310 commands->push_back( | 1341 commands->push_back( |
1311 CreateSetTabUserAgentOverrideCommand( | 1342 CreateSetTabUserAgentOverrideCommand( |
1312 kCommandSetTabUserAgentOverride, session_id.id(), ua_override)); | 1343 kCommandSetTabUserAgentOverride, session_id.id(), ua_override)); |
1313 } | 1344 } |
| 1345 const int64 sync_id = |
| 1346 SessionTabHelper::FromWebContents(tab)->GetSessionSyncId(); |
| 1347 commands->push_back(CreateSetTabSessionSyncIdCommand( |
| 1348 kCommandSetTabSessionSyncId, session_id.id(), sync_id)); |
1314 | 1349 |
1315 for (int i = min_index; i < max_index; ++i) { | 1350 for (int i = min_index; i < max_index; ++i) { |
1316 const NavigationEntry* entry = (i == pending_index) ? | 1351 const NavigationEntry* entry = (i == pending_index) ? |
1317 tab->GetController().GetPendingEntry() : | 1352 tab->GetController().GetPendingEntry() : |
1318 tab->GetController().GetEntryAtIndex(i); | 1353 tab->GetController().GetEntryAtIndex(i); |
1319 DCHECK(entry); | 1354 DCHECK(entry); |
1320 if (ShouldTrackEntry(entry->GetVirtualURL())) { | 1355 if (ShouldTrackEntry(entry->GetVirtualURL())) { |
1321 const SerializedNavigationEntry navigation = | 1356 const SerializedNavigationEntry navigation = |
1322 SerializedNavigationEntry::FromNavigationEntry(i, *entry); | 1357 SerializedNavigationEntry::FromNavigationEntry(i, *entry); |
1323 commands->push_back( | 1358 commands->push_back( |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 contents->GetController().GetDefaultSessionStorageNamespace(); | 1791 contents->GetController().GetDefaultSessionStorageNamespace(); |
1757 session_storage_namespace->SetShouldPersist(false); | 1792 session_storage_namespace->SetShouldPersist(false); |
1758 SessionTabHelper* session_tab_helper = | 1793 SessionTabHelper* session_tab_helper = |
1759 SessionTabHelper::FromWebContents(contents); | 1794 SessionTabHelper::FromWebContents(contents); |
1760 TabClosed(session_tab_helper->window_id(), | 1795 TabClosed(session_tab_helper->window_id(), |
1761 session_tab_helper->session_id(), | 1796 session_tab_helper->session_id(), |
1762 contents->GetClosedByUserGesture()); | 1797 contents->GetClosedByUserGesture()); |
1763 RecordSessionUpdateHistogramData(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 1798 RecordSessionUpdateHistogramData(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
1764 &last_updated_tab_closed_time_); | 1799 &last_updated_tab_closed_time_); |
1765 } | 1800 } |
OLD | NEW |