| 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 |