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/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
17 #include "base/message_loop.h" | 17 #include "base/message_loop.h" |
18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
19 #include "base/pickle.h" | 19 #include "base/pickle.h" |
20 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
21 #include "content/browser/dom_storage/session_storage_namespace_impl.h" | |
michaeln
2012/05/30 01:29:19
we shouldn't be using interfaces that aren't in th
marja
2012/05/31 14:41:34
Removed this, but now session_restore needs to inc
| |
21 #include "chrome/browser/extensions/extension_tab_helper.h" | 22 #include "chrome/browser/extensions/extension_tab_helper.h" |
22 #include "chrome/browser/prefs/session_startup_pref.h" | 23 #include "chrome/browser/prefs/session_startup_pref.h" |
23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/browser/sessions/restore_tab_helper.h" | 25 #include "chrome/browser/sessions/restore_tab_helper.h" |
25 #include "chrome/browser/sessions/session_backend.h" | 26 #include "chrome/browser/sessions/session_backend.h" |
26 #include "chrome/browser/sessions/session_command.h" | 27 #include "chrome/browser/sessions/session_command.h" |
27 #include "chrome/browser/sessions/session_restore.h" | 28 #include "chrome/browser/sessions/session_restore.h" |
28 #include "chrome/browser/sessions/session_types.h" | 29 #include "chrome/browser/sessions/session_types.h" |
29 #include "chrome/browser/ui/browser_list.h" | 30 #include "chrome/browser/ui/browser_list.h" |
30 #include "chrome/browser/ui/browser_window.h" | 31 #include "chrome/browser/ui/browser_window.h" |
31 #include "chrome/browser/ui/startup/startup_browser_creator.h" | 32 #include "chrome/browser/ui/startup/startup_browser_creator.h" |
32 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 33 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
33 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
34 #include "chrome/common/chrome_notification_types.h" | 35 #include "chrome/common/chrome_notification_types.h" |
35 #include "chrome/common/extensions/extension.h" | 36 #include "chrome/common/extensions/extension.h" |
36 #include "content/public/browser/navigation_details.h" | 37 #include "content/public/browser/navigation_details.h" |
37 #include "content/public/browser/navigation_entry.h" | 38 #include "content/public/browser/navigation_entry.h" |
38 #include "content/public/browser/notification_details.h" | 39 #include "content/public/browser/notification_details.h" |
39 #include "content/public/browser/notification_service.h" | 40 #include "content/public/browser/notification_service.h" |
41 #include "content/public/browser/session_storage_namespace.h" | |
40 #include "content/public/browser/web_contents.h" | 42 #include "content/public/browser/web_contents.h" |
41 | 43 |
42 #if defined(OS_MACOSX) | 44 #if defined(OS_MACOSX) |
43 #include "chrome/browser/app_controller_mac.h" | 45 #include "chrome/browser/app_controller_mac.h" |
44 #endif | 46 #endif |
45 | 47 |
46 using base::Time; | 48 using base::Time; |
47 using content::NavigationEntry; | 49 using content::NavigationEntry; |
48 | 50 |
49 // Identifier for commands written to file. | 51 // Identifier for commands written to file. |
(...skipping 15 matching lines...) Expand all Loading... | |
65 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | 67 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
66 static const SessionCommand::id_type | 68 static const SessionCommand::id_type |
67 kCommandTabNavigationPathPrunedFromFront = 11; | 69 kCommandTabNavigationPathPrunedFromFront = 11; |
68 static const SessionCommand::id_type kCommandSetPinnedState = 12; | 70 static const SessionCommand::id_type kCommandSetPinnedState = 12; |
69 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; | 71 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; |
70 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; | 72 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; |
71 static const SessionCommand::id_type kCommandSetWindowAppName = 15; | 73 static const SessionCommand::id_type kCommandSetWindowAppName = 15; |
72 static const SessionCommand::id_type kCommandTabClosed = 16; | 74 static const SessionCommand::id_type kCommandTabClosed = 16; |
73 static const SessionCommand::id_type kCommandWindowClosed = 17; | 75 static const SessionCommand::id_type kCommandWindowClosed = 17; |
74 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18; | 76 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18; |
77 static const SessionCommand::id_type kCommandSessionStorageAssociated = 19; | |
75 | 78 |
76 // Every kWritesPerReset commands triggers recreating the file. | 79 // Every kWritesPerReset commands triggers recreating the file. |
77 static const int kWritesPerReset = 250; | 80 static const int kWritesPerReset = 250; |
78 | 81 |
79 namespace { | 82 namespace { |
80 | 83 |
81 // The callback from GetLastSession is internally routed to SessionService | 84 // The callback from GetLastSession is internally routed to SessionService |
82 // first and then the caller. This is done so that the SessionWindows can be | 85 // first and then the caller. This is done so that the SessionWindows can be |
83 // recreated from the SessionCommands and the SessionWindows passed to the | 86 // recreated from the SessionCommands and the SessionWindows passed to the |
84 // caller. The following class is used for this. | 87 // caller. The following class is used for this. |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, | 518 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, |
516 content::NotificationService::AllSources()); | 519 content::NotificationService::AllSources()); |
517 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 520 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
518 content::NotificationService::AllSources()); | 521 content::NotificationService::AllSources()); |
519 // Wait for NOTIFICATION_BROWSER_WINDOW_READY so that is_app() is set. | 522 // Wait for NOTIFICATION_BROWSER_WINDOW_READY so that is_app() is set. |
520 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, | 523 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
521 content::NotificationService::AllBrowserContextsAndSources()); | 524 content::NotificationService::AllBrowserContextsAndSources()); |
522 registrar_.Add( | 525 registrar_.Add( |
523 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, | 526 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, |
524 content::NotificationService::AllSources()); | 527 content::NotificationService::AllSources()); |
528 registrar_.Add(this, content::NOTIFICATION_SESSION_STORAGE_ASSOCIATED, | |
529 content::NotificationService::AllSources()); | |
525 } | 530 } |
526 | 531 |
527 bool SessionService::ShouldNewWindowStartSession() { | 532 bool SessionService::ShouldNewWindowStartSession() { |
528 // ChromeOS and OSX have different ideas of application lifetime than | 533 // ChromeOS and OSX have different ideas of application lifetime than |
529 // the other platforms. | 534 // the other platforms. |
530 // On ChromeOS opening a new window should never start a new session. | 535 // On ChromeOS opening a new window should never start a new session. |
531 #if defined(OS_CHROMEOS) | 536 #if defined(OS_CHROMEOS) |
532 if (!force_browser_not_alive_with_no_windows_) | 537 if (!force_browser_not_alive_with_no_windows_) |
533 return false; | 538 return false; |
534 #endif | 539 #endif |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
593 if (tab->profile() != profile()) | 598 if (tab->profile() != profile()) |
594 return; | 599 return; |
595 SetTabWindow(tab->restore_tab_helper()->window_id(), | 600 SetTabWindow(tab->restore_tab_helper()->window_id(), |
596 tab->restore_tab_helper()->session_id()); | 601 tab->restore_tab_helper()->session_id()); |
597 if (tab->extension_tab_helper()->extension_app()) { | 602 if (tab->extension_tab_helper()->extension_app()) { |
598 SetTabExtensionAppID( | 603 SetTabExtensionAppID( |
599 tab->restore_tab_helper()->window_id(), | 604 tab->restore_tab_helper()->window_id(), |
600 tab->restore_tab_helper()->session_id(), | 605 tab->restore_tab_helper()->session_id(), |
601 tab->extension_tab_helper()->extension_app()->id()); | 606 tab->extension_tab_helper()->extension_app()->id()); |
602 } | 607 } |
608 | |
609 // Record the association between the sessionStorage namespace and the | |
610 // tab. | |
611 content::SessionStorageNamespace* session_storage_namespace = | |
612 tab->web_contents()->GetController().GetSessionStorageNamespace(); | |
613 session_storage_id_to_tab_[session_storage_namespace->id()] = | |
614 std::make_pair(tab->restore_tab_helper()->window_id(), | |
615 tab->restore_tab_helper()->session_id()); | |
603 break; | 616 break; |
604 } | 617 } |
605 | 618 |
606 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | 619 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
607 TabContentsWrapper* tab = | 620 TabContentsWrapper* tab = |
608 TabContentsWrapper::GetCurrentWrapperForContents( | 621 TabContentsWrapper::GetCurrentWrapperForContents( |
609 content::Source<content::WebContents>(source).ptr()); | 622 content::Source<content::WebContents>(source).ptr()); |
610 if (!tab || tab->profile() != profile()) | 623 if (!tab || tab->profile() != profile()) |
611 return; | 624 return; |
612 TabClosed(tab->restore_tab_helper()->window_id(), | 625 TabClosed(tab->restore_tab_helper()->window_id(), |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
693 if (extension_tab_helper->extension_app()) { | 706 if (extension_tab_helper->extension_app()) { |
694 RestoreTabHelper* helper = | 707 RestoreTabHelper* helper = |
695 extension_tab_helper->tab_contents_wrapper()->restore_tab_helper(); | 708 extension_tab_helper->tab_contents_wrapper()->restore_tab_helper(); |
696 SetTabExtensionAppID(helper->window_id(), | 709 SetTabExtensionAppID(helper->window_id(), |
697 helper->session_id(), | 710 helper->session_id(), |
698 extension_tab_helper->extension_app()->id()); | 711 extension_tab_helper->extension_app()->id()); |
699 } | 712 } |
700 break; | 713 break; |
701 } | 714 } |
702 | 715 |
716 case content::NOTIFICATION_SESSION_STORAGE_ASSOCIATED: { | |
717 // FIXME: Read the association also when recreating the window & tab data. | |
718 content::Details<SessionStorageAssociatedDetails> | |
719 session_storage_associated_details(details); | |
720 CreateAndScheduleSessionStorageAssociatedCommand( | |
721 session_storage_associated_details->id, | |
722 session_storage_associated_details->real_id); | |
723 break; | |
724 } | |
725 | |
703 default: | 726 default: |
704 NOTREACHED(); | 727 NOTREACHED(); |
705 } | 728 } |
706 } | 729 } |
707 | 730 |
708 void SessionService::SetTabExtensionAppID( | 731 void SessionService::SetTabExtensionAppID( |
709 const SessionID& window_id, | 732 const SessionID& window_id, |
710 const SessionID& tab_id, | 733 const SessionID& tab_id, |
711 const std::string& extension_app_id) { | 734 const std::string& extension_app_id) { |
712 if (!ShouldTrackChangesToWindow(window_id)) | 735 if (!ShouldTrackChangesToWindow(window_id)) |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 bool is_pinned) { | 862 bool is_pinned) { |
840 PinnedStatePayload payload = { 0 }; | 863 PinnedStatePayload payload = { 0 }; |
841 payload.tab_id = tab_id.id(); | 864 payload.tab_id = tab_id.id(); |
842 payload.pinned_state = is_pinned; | 865 payload.pinned_state = is_pinned; |
843 SessionCommand* command = | 866 SessionCommand* command = |
844 new SessionCommand(kCommandSetPinnedState, sizeof(payload)); | 867 new SessionCommand(kCommandSetPinnedState, sizeof(payload)); |
845 memcpy(command->contents(), &payload, sizeof(payload)); | 868 memcpy(command->contents(), &payload, sizeof(payload)); |
846 return command; | 869 return command; |
847 } | 870 } |
848 | 871 |
872 void SessionService::CreateAndScheduleSessionStorageAssociatedCommand( | |
873 int64 id, int64 real_id) { | |
874 SessionStorageIdToTab::const_iterator it = | |
875 session_storage_id_to_tab_.find(id); | |
876 if (it == session_storage_id_to_tab_.end()) | |
877 return; | |
878 Pickle pickle; | |
879 pickle.WriteInt(it->second.first.id()); | |
880 pickle.WriteInt(it->second.second.id()); | |
881 pickle.WriteInt64(real_id); | |
882 ScheduleCommand(new SessionCommand(kCommandSessionStorageAssociated, pickle)); | |
883 } | |
884 | |
849 void SessionService::OnGotSessionCommands( | 885 void SessionService::OnGotSessionCommands( |
850 Handle handle, | 886 Handle handle, |
851 scoped_refptr<InternalGetCommandsRequest> request) { | 887 scoped_refptr<InternalGetCommandsRequest> request) { |
852 if (request->canceled()) | 888 if (request->canceled()) |
853 return; | 889 return; |
854 | 890 |
855 ScopedVector<SessionWindow> valid_windows; | 891 ScopedVector<SessionWindow> valid_windows; |
856 RestoreSessionFromCommands( | 892 RestoreSessionFromCommands( |
857 request->commands, &(valid_windows.get())); | 893 request->commands, &(valid_windows.get())); |
858 static_cast<InternalSessionRequest*>(request.get())-> | 894 static_cast<InternalSessionRequest*>(request.get())-> |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1235 std::string user_agent_override; | 1271 std::string user_agent_override; |
1236 if (!RestoreSetTabUserAgentOverrideCommand( | 1272 if (!RestoreSetTabUserAgentOverrideCommand( |
1237 *command, &tab_id, &user_agent_override)) { | 1273 *command, &tab_id, &user_agent_override)) { |
1238 return true; | 1274 return true; |
1239 } | 1275 } |
1240 | 1276 |
1241 GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override); | 1277 GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override); |
1242 break; | 1278 break; |
1243 } | 1279 } |
1244 | 1280 |
1281 case kCommandSessionStorageAssociated: { | |
1282 scoped_ptr<Pickle> pickle(command->PayloadAsPickle()); | |
1283 SessionID::id_type window_id; | |
1284 SessionID::id_type tab_id; | |
1285 int64 session_storage_id; | |
1286 PickleIterator iter(*pickle.get()); | |
1287 pickle->ReadInt(&iter, &window_id); | |
1288 pickle->ReadInt(&iter, &tab_id); | |
1289 pickle->ReadInt64(&iter, &session_storage_id); | |
1290 // Associate the session storage back. | |
1291 GetTab(tab_id, tabs)->session_storage_real_id = session_storage_id; | |
1292 GetTab(tab_id, tabs)->session_storage_real_id_associated = true; | |
1293 break; | |
1294 } | |
1295 | |
1245 default: | 1296 default: |
1246 VLOG(1) << "Failed reading an unknown command " << command->id(); | 1297 VLOG(1) << "Failed reading an unknown command " << command->id(); |
1247 return true; | 1298 return true; |
1248 } | 1299 } |
1249 } | 1300 } |
1250 return true; | 1301 return true; |
1251 } | 1302 } |
1252 | 1303 |
1253 void SessionService::BuildCommandsForTab( | 1304 void SessionService::BuildCommandsForTab( |
1254 const SessionID& window_id, | 1305 const SessionID& window_id, |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1688 50); | 1739 50); |
1689 if (use_long_period) { | 1740 if (use_long_period) { |
1690 std::string long_name_("SessionRestore.SaveLongPeriod"); | 1741 std::string long_name_("SessionRestore.SaveLongPeriod"); |
1691 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, | 1742 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, |
1692 delta, | 1743 delta, |
1693 save_delay_in_mins_, | 1744 save_delay_in_mins_, |
1694 save_delay_in_hrs_, | 1745 save_delay_in_hrs_, |
1695 50); | 1746 50); |
1696 } | 1747 } |
1697 } | 1748 } |
OLD | NEW |