OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/public/browser/browser_thread.h" |
| 6 |
5 #include "chrome/browser/sessions/session_service.h" | 7 #include "chrome/browser/sessions/session_service.h" |
6 | 8 |
7 #include <algorithm> | 9 #include <algorithm> |
8 #include <limits> | 10 #include <limits> |
9 #include <set> | 11 #include <set> |
10 #include <vector> | 12 #include <vector> |
11 | 13 |
12 #include "base/bind.h" | 14 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
14 #include "base/file_util.h" | 16 #include "base/file_util.h" |
(...skipping 10 matching lines...) Expand all Loading... |
25 #include "chrome/browser/sessions/session_command.h" | 27 #include "chrome/browser/sessions/session_command.h" |
26 #include "chrome/browser/sessions/session_restore.h" | 28 #include "chrome/browser/sessions/session_restore.h" |
27 #include "chrome/browser/sessions/session_types.h" | 29 #include "chrome/browser/sessions/session_types.h" |
28 #include "chrome/browser/tabs/tab_strip_model.h" | 30 #include "chrome/browser/tabs/tab_strip_model.h" |
29 #include "chrome/browser/ui/browser_init.h" | 31 #include "chrome/browser/ui/browser_init.h" |
30 #include "chrome/browser/ui/browser_list.h" | 32 #include "chrome/browser/ui/browser_list.h" |
31 #include "chrome/browser/ui/browser_window.h" | 33 #include "chrome/browser/ui/browser_window.h" |
32 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 34 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
33 #include "chrome/common/chrome_notification_types.h" | 35 #include "chrome/common/chrome_notification_types.h" |
34 #include "chrome/common/extensions/extension.h" | 36 #include "chrome/common/extensions/extension.h" |
| 37 #include "content/browser/in_process_webkit/dom_storage_context.h" |
| 38 #include "content/browser/in_process_webkit/dom_storage_namespace.h" |
| 39 #include "content/browser/in_process_webkit/session_storage_namespace.h" |
| 40 #include "content/browser/in_process_webkit/webkit_context.h" |
35 #include "content/public/browser/navigation_details.h" | 41 #include "content/public/browser/navigation_details.h" |
36 #include "content/public/browser/navigation_entry.h" | 42 #include "content/public/browser/navigation_entry.h" |
37 #include "content/public/browser/notification_service.h" | 43 #include "content/public/browser/notification_service.h" |
38 #include "content/public/browser/notification_details.h" | 44 #include "content/public/browser/notification_details.h" |
39 #include "content/public/browser/web_contents.h" | 45 #include "content/public/browser/web_contents.h" |
40 | 46 |
41 #if defined(OS_MACOSX) | 47 #if defined(OS_MACOSX) |
42 #include "chrome/browser/app_controller_cppsafe_mac.h" | 48 #include "chrome/browser/app_controller_cppsafe_mac.h" |
43 #endif | 49 #endif |
44 | 50 |
(...skipping 13 matching lines...) Expand all Loading... |
58 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; | 64 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7; |
59 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; | 65 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8; |
60 static const SessionCommand::id_type kCommandSetWindowType = 9; | 66 static const SessionCommand::id_type kCommandSetWindowType = 9; |
61 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. | 67 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration. |
62 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | 68 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
63 static const SessionCommand::id_type | 69 static const SessionCommand::id_type |
64 kCommandTabNavigationPathPrunedFromFront = 11; | 70 kCommandTabNavigationPathPrunedFromFront = 11; |
65 static const SessionCommand::id_type kCommandSetPinnedState = 12; | 71 static const SessionCommand::id_type kCommandSetPinnedState = 12; |
66 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; | 72 static const SessionCommand::id_type kCommandSetExtensionAppID = 13; |
67 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; | 73 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14; |
| 74 static const SessionCommand::id_type kCommandSessionStorageCreated = 15; |
68 | 75 |
69 // Every kWritesPerReset commands triggers recreating the file. | 76 // Every kWritesPerReset commands triggers recreating the file. |
70 static const int kWritesPerReset = 250; | 77 static const int kWritesPerReset = 250; |
71 | 78 |
72 namespace { | 79 namespace { |
73 | 80 |
74 // The callback from GetLastSession is internally routed to SessionService | 81 // The callback from GetLastSession is internally routed to SessionService |
75 // first and then the caller. This is done so that the SessionWindows can be | 82 // first and then the caller. This is done so that the SessionWindows can be |
76 // recreated from the SessionCommands and the SessionWindows passed to the | 83 // recreated from the SessionCommands and the SessionWindows passed to the |
77 // caller. The following class is used for this. | 84 // caller. The following class is used for this. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 142 |
136 typedef IDAndIndexPayload TabNavigationPathPrunedFromFrontPayload; | 143 typedef IDAndIndexPayload TabNavigationPathPrunedFromFrontPayload; |
137 | 144 |
138 struct PinnedStatePayload { | 145 struct PinnedStatePayload { |
139 SessionID::id_type tab_id; | 146 SessionID::id_type tab_id; |
140 bool pinned_state; | 147 bool pinned_state; |
141 }; | 148 }; |
142 | 149 |
143 } // namespace | 150 } // namespace |
144 | 151 |
| 152 // SessionService needs to read data from DOMStorageContext and it can be only |
| 153 // done on the WEBKIT_DEPRECATED thread. This class is for reading the data. It |
| 154 // also takes into account that SessionService might get deleted before we have |
| 155 // a change to call it back. |
| 156 class SessionService::SessionStorageAssociationReader |
| 157 : public base::RefCountedThreadSafe< |
| 158 SessionService::SessionStorageAssociationReader> { |
| 159 public: |
| 160 SessionStorageAssociationReader(SessionService* session_service, |
| 161 int64 namespace_id, |
| 162 WebKitContext* webkit_context) |
| 163 : session_service_(session_service), |
| 164 namespace_id_(namespace_id), |
| 165 webkit_context_(webkit_context) { |
| 166 content::BrowserThread::PostTask( |
| 167 content::BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
| 168 base::Bind(&SessionStorageAssociationReader::ReadData, this)); |
| 169 } |
| 170 ~SessionStorageAssociationReader() { } |
| 171 |
| 172 private: |
| 173 friend class SessionService; |
| 174 |
| 175 void ReadData() { |
| 176 DOMStorageNamespace* dom_storage_namespace = webkit_context_-> |
| 177 dom_storage_context()->GetStorageNamespace(namespace_id_, false); |
| 178 if (dom_storage_namespace != NULL) { |
| 179 session_storage_directory_ = |
| 180 dom_storage_namespace->session_storage_directory(); |
| 181 } |
| 182 content::BrowserThread::PostTask( |
| 183 content::BrowserThread::UI, FROM_HERE, |
| 184 base::Bind(&SessionStorageAssociationReader::ForwardData, this)); |
| 185 } |
| 186 |
| 187 void ForwardData() { |
| 188 // If SessionService gets destroyed before this object, it nullifies this |
| 189 // pointer. |
| 190 if (session_service_) { |
| 191 session_service_->AssociateSessionStorage(this, namespace_id_, |
| 192 session_storage_directory_); |
| 193 } |
| 194 } |
| 195 |
| 196 SessionService* session_service_; |
| 197 int64 namespace_id_; |
| 198 WebKitContext* webkit_context_; |
| 199 FilePath session_storage_directory_; |
| 200 }; |
| 201 |
145 // SessionService ------------------------------------------------------------- | 202 // SessionService ------------------------------------------------------------- |
146 | 203 |
147 SessionService::SessionService(Profile* profile) | 204 SessionService::SessionService(Profile* profile) |
148 : BaseSessionService(SESSION_RESTORE, profile, FilePath()), | 205 : BaseSessionService(SESSION_RESTORE, profile, FilePath()), |
149 has_open_trackable_browsers_(false), | 206 has_open_trackable_browsers_(false), |
150 move_on_new_browser_(false), | 207 move_on_new_browser_(false), |
151 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), | 208 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), |
152 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), | 209 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), |
153 save_delay_in_hrs_(base::TimeDelta::FromHours(8)) { | 210 save_delay_in_hrs_(base::TimeDelta::FromHours(8)) { |
154 Init(); | 211 Init(); |
155 } | 212 } |
156 | 213 |
157 SessionService::SessionService(const FilePath& save_path) | 214 SessionService::SessionService(const FilePath& save_path) |
158 : BaseSessionService(SESSION_RESTORE, NULL, save_path), | 215 : BaseSessionService(SESSION_RESTORE, NULL, save_path), |
159 has_open_trackable_browsers_(false), | 216 has_open_trackable_browsers_(false), |
160 move_on_new_browser_(false), | 217 move_on_new_browser_(false), |
161 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), | 218 save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)), |
162 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), | 219 save_delay_in_mins_(base::TimeDelta::FromMinutes(10)), |
163 save_delay_in_hrs_(base::TimeDelta::FromHours(8)) { | 220 save_delay_in_hrs_(base::TimeDelta::FromHours(8)) { |
164 Init(); | 221 Init(); |
165 } | 222 } |
166 | 223 |
167 SessionService::~SessionService() { | 224 SessionService::~SessionService() { |
168 Save(); | 225 Save(); |
| 226 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 227 for (SessionStorageAssociationReaders::const_iterator it = |
| 228 session_storage_association_readers_.begin(); |
| 229 it != session_storage_association_readers_.end(); |
| 230 ++it) { |
| 231 // This is done in the UI thread. SessionStorageAssociationReader only |
| 232 // accesses session_service_ in the UI thread, so this is safe. |
| 233 it->first->session_service_ = NULL; |
| 234 } |
| 235 // References from SessionService to SessionStorageAssociationReader will be |
| 236 // automatically dropped as session_storage_association_readers_ is destroyed. |
169 } | 237 } |
170 | 238 |
171 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { | 239 bool SessionService::RestoreIfNecessary(const std::vector<GURL>& urls_to_open) { |
172 return RestoreIfNecessary(urls_to_open, NULL); | 240 return RestoreIfNecessary(urls_to_open, NULL); |
173 } | 241 } |
174 | 242 |
175 void SessionService::ResetFromCurrentBrowsers() { | 243 void SessionService::ResetFromCurrentBrowsers() { |
176 ScheduleReset(); | 244 ScheduleReset(); |
177 } | 245 } |
178 | 246 |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 content::NotificationService::AllSources()); | 518 content::NotificationService::AllSources()); |
451 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, | 519 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED, |
452 content::NotificationService::AllSources()); | 520 content::NotificationService::AllSources()); |
453 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 521 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
454 content::NotificationService::AllSources()); | 522 content::NotificationService::AllSources()); |
455 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED, | 523 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED, |
456 content::NotificationService::AllBrowserContextsAndSources()); | 524 content::NotificationService::AllBrowserContextsAndSources()); |
457 registrar_.Add( | 525 registrar_.Add( |
458 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, | 526 this, chrome::NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, |
459 content::NotificationService::AllSources()); | 527 content::NotificationService::AllSources()); |
| 528 registrar_.Add(this, content::NOTIFICATION_SESSION_STORAGE_NAMESPACE_CREATED, |
| 529 content::NotificationService::AllSources()); |
460 } | 530 } |
461 | 531 |
462 bool SessionService::ShouldNewWindowStartSession() { | 532 bool SessionService::ShouldNewWindowStartSession() { |
463 if (!has_open_trackable_browsers_ && !BrowserInit::InProcessStartup() && | 533 if (!has_open_trackable_browsers_ && !BrowserInit::InProcessStartup() && |
464 !SessionRestore::IsRestoring() | 534 !SessionRestore::IsRestoring() |
465 #if defined(OS_MACOSX) | 535 #if defined(OS_MACOSX) |
466 // OSX has a fairly different idea of application lifetime than the | 536 // OSX has a fairly different idea of application lifetime than the |
467 // other platforms. We need to check that we aren't opening a window | 537 // other platforms. We need to check that we aren't opening a window |
468 // from the dock or the menubar. | 538 // from the dock or the menubar. |
469 && !app_controller_mac::IsOpeningNewWindow() | 539 && !app_controller_mac::IsOpeningNewWindow() |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 RestoreIfNecessary(std::vector<GURL>(), browser); | 582 RestoreIfNecessary(std::vector<GURL>(), browser); |
513 SetWindowType(browser->session_id(), browser->type()); | 583 SetWindowType(browser->session_id(), browser->type()); |
514 break; | 584 break; |
515 } | 585 } |
516 | 586 |
517 case content::NOTIFICATION_TAB_PARENTED: { | 587 case content::NOTIFICATION_TAB_PARENTED: { |
518 TabContentsWrapper* tab = | 588 TabContentsWrapper* tab = |
519 content::Source<TabContentsWrapper>(source).ptr(); | 589 content::Source<TabContentsWrapper>(source).ptr(); |
520 if (tab->profile() != profile()) | 590 if (tab->profile() != profile()) |
521 return; | 591 return; |
| 592 |
| 593 // Record the association between the sessionStorage namespace and the |
| 594 // tab. |
| 595 SessionStorageNamespace* session_storage_namespace = |
| 596 tab->web_contents()->GetController().GetSessionStorageNamespace(); |
| 597 session_storage_namespace_map_[session_storage_namespace->id()] = |
| 598 std::make_pair(tab->restore_tab_helper()->window_id(), |
| 599 tab->restore_tab_helper()->session_id()); |
| 600 |
522 SetTabWindow(tab->restore_tab_helper()->window_id(), | 601 SetTabWindow(tab->restore_tab_helper()->window_id(), |
523 tab->restore_tab_helper()->session_id()); | 602 tab->restore_tab_helper()->session_id()); |
524 if (tab->extension_tab_helper()->extension_app()) { | 603 if (tab->extension_tab_helper()->extension_app()) { |
525 SetTabExtensionAppID( | 604 SetTabExtensionAppID( |
526 tab->restore_tab_helper()->window_id(), | 605 tab->restore_tab_helper()->window_id(), |
527 tab->restore_tab_helper()->session_id(), | 606 tab->restore_tab_helper()->session_id(), |
528 tab->extension_tab_helper()->extension_app()->id()); | 607 tab->extension_tab_helper()->extension_app()->id()); |
529 } | 608 } |
530 break; | 609 break; |
531 } | 610 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 if (extension_tab_helper->extension_app()) { | 699 if (extension_tab_helper->extension_app()) { |
621 RestoreTabHelper* helper = | 700 RestoreTabHelper* helper = |
622 extension_tab_helper->tab_contents_wrapper()->restore_tab_helper(); | 701 extension_tab_helper->tab_contents_wrapper()->restore_tab_helper(); |
623 SetTabExtensionAppID(helper->window_id(), | 702 SetTabExtensionAppID(helper->window_id(), |
624 helper->session_id(), | 703 helper->session_id(), |
625 extension_tab_helper->extension_app()->id()); | 704 extension_tab_helper->extension_app()->id()); |
626 } | 705 } |
627 break; | 706 break; |
628 } | 707 } |
629 | 708 |
| 709 case content::NOTIFICATION_SESSION_STORAGE_NAMESPACE_CREATED: { |
| 710 content::Details<SessionStorageCreatedDetails> |
| 711 namespace_created_details(details); |
| 712 CreateAndScheduleSessionStorageCreatedCommand( |
| 713 namespace_created_details->id, |
| 714 namespace_created_details->session_storage_directory); |
| 715 break; |
| 716 } |
| 717 |
630 default: | 718 default: |
631 NOTREACHED(); | 719 NOTREACHED(); |
632 } | 720 } |
633 } | 721 } |
634 | 722 |
635 void SessionService::SetTabExtensionAppID( | 723 void SessionService::SetTabExtensionAppID( |
636 const SessionID& window_id, | 724 const SessionID& window_id, |
637 const SessionID& tab_id, | 725 const SessionID& tab_id, |
638 const std::string& extension_app_id) { | 726 const std::string& extension_app_id) { |
639 if (!ShouldTrackChangesToWindow(window_id)) | 727 if (!ShouldTrackChangesToWindow(window_id)) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 bool is_pinned) { | 841 bool is_pinned) { |
754 PinnedStatePayload payload = { 0 }; | 842 PinnedStatePayload payload = { 0 }; |
755 payload.tab_id = tab_id.id(); | 843 payload.tab_id = tab_id.id(); |
756 payload.pinned_state = is_pinned; | 844 payload.pinned_state = is_pinned; |
757 SessionCommand* command = | 845 SessionCommand* command = |
758 new SessionCommand(kCommandSetPinnedState, sizeof(payload)); | 846 new SessionCommand(kCommandSetPinnedState, sizeof(payload)); |
759 memcpy(command->contents(), &payload, sizeof(payload)); | 847 memcpy(command->contents(), &payload, sizeof(payload)); |
760 return command; | 848 return command; |
761 } | 849 } |
762 | 850 |
| 851 void SessionService::CreateAndScheduleSessionStorageCreatedCommand( |
| 852 int64 namespace_id, |
| 853 const FilePath& directory) { |
| 854 SessionStorageNamespaceMap::const_iterator it = |
| 855 session_storage_namespace_map_.find(namespace_id); |
| 856 if (it != session_storage_namespace_map_.end()) { |
| 857 Pickle session_storage_created_pickle; |
| 858 session_storage_created_pickle.WriteInt(it->second.first.id()); |
| 859 session_storage_created_pickle.WriteInt(it->second.second.id()); |
| 860 session_storage_created_pickle.WriteString(directory.value()); |
| 861 ScheduleCommand(new SessionCommand(kCommandSessionStorageCreated, |
| 862 session_storage_created_pickle)); |
| 863 } |
| 864 } |
| 865 |
763 void SessionService::OnGotSessionCommands( | 866 void SessionService::OnGotSessionCommands( |
764 Handle handle, | 867 Handle handle, |
765 scoped_refptr<InternalGetCommandsRequest> request) { | 868 scoped_refptr<InternalGetCommandsRequest> request) { |
766 if (request->canceled()) | 869 if (request->canceled()) |
767 return; | 870 return; |
768 | 871 |
769 ScopedVector<SessionWindow> valid_windows; | 872 ScopedVector<SessionWindow> valid_windows; |
770 RestoreSessionFromCommands( | 873 RestoreSessionFromCommands( |
771 request->commands, &(valid_windows.get())); | 874 request->commands, &(valid_windows.get())); |
772 static_cast<InternalSessionRequest*>(request.get())-> | 875 static_cast<InternalSessionRequest*>(request.get())-> |
773 real_callback.Run(request->handle(), &(valid_windows.get())); | 876 real_callback.Run(request->handle(), &(valid_windows.get())); |
774 } | 877 } |
775 | 878 |
776 void SessionService::RestoreSessionFromCommands( | 879 void SessionService::RestoreSessionFromCommands( |
777 const std::vector<SessionCommand*>& commands, | 880 const std::vector<SessionCommand*>& commands, |
778 std::vector<SessionWindow*>* valid_windows) { | 881 std::vector<SessionWindow*>* valid_windows) { |
779 std::map<int, SessionTab*> tabs; | 882 std::map<int, SessionTab*> tabs; |
780 std::map<int, SessionWindow*> windows; | 883 std::map<int, SessionWindow*> windows; |
781 | 884 |
782 if (CreateTabsAndWindows(commands, &tabs, &windows)) { | 885 // Keeps track of which sessionStorages are in use after session restore, so |
| 886 // that the rest can be deleted. |
| 887 std::set<std::string> needed_session_storages; |
| 888 |
| 889 if (CreateTabsAndWindows(commands, &tabs, &windows, |
| 890 &needed_session_storages)) { |
783 AddTabsToWindows(&tabs, &windows); | 891 AddTabsToWindows(&tabs, &windows); |
784 SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows); | 892 SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows); |
785 UpdateSelectedTabIndex(valid_windows); | 893 UpdateSelectedTabIndex(valid_windows); |
786 } | 894 } |
| 895 |
| 896 profile()->GetWebKitContext()->DeleteUnneededSessionStorages( |
| 897 needed_session_storages); |
| 898 |
787 STLDeleteValues(&tabs); | 899 STLDeleteValues(&tabs); |
788 // Don't delete conents of windows, that is done by the caller as all | 900 // Don't delete conents of windows, that is done by the caller as all |
789 // valid windows are added to valid_windows. | 901 // valid windows are added to valid_windows. |
790 } | 902 } |
791 | 903 |
792 void SessionService::UpdateSelectedTabIndex( | 904 void SessionService::UpdateSelectedTabIndex( |
793 std::vector<SessionWindow*>* windows) { | 905 std::vector<SessionWindow*>* windows) { |
794 for (std::vector<SessionWindow*>::const_iterator i = windows->begin(); | 906 for (std::vector<SessionWindow*>::const_iterator i = windows->begin(); |
795 i != windows->end(); ++i) { | 907 i != windows->end(); ++i) { |
796 // See note in SessionWindow as to why we do this. | 908 // See note in SessionWindow as to why we do this. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 // Never got a set tab index in window, or tabs are empty, nothing | 1026 // Never got a set tab index in window, or tabs are empty, nothing |
915 // to do. | 1027 // to do. |
916 ++i; | 1028 ++i; |
917 } | 1029 } |
918 } | 1030 } |
919 } | 1031 } |
920 | 1032 |
921 bool SessionService::CreateTabsAndWindows( | 1033 bool SessionService::CreateTabsAndWindows( |
922 const std::vector<SessionCommand*>& data, | 1034 const std::vector<SessionCommand*>& data, |
923 std::map<int, SessionTab*>* tabs, | 1035 std::map<int, SessionTab*>* tabs, |
924 std::map<int, SessionWindow*>* windows) { | 1036 std::map<int, SessionWindow*>* windows, |
| 1037 std::set<std::string>* needed_session_storages) { |
925 // If the file is corrupt (command with wrong size, or unknown command), we | 1038 // If the file is corrupt (command with wrong size, or unknown command), we |
926 // still return true and attempt to restore what we we can. | 1039 // still return true and attempt to restore what we we can. |
927 | 1040 |
928 for (std::vector<SessionCommand*>::const_iterator i = data.begin(); | 1041 for (std::vector<SessionCommand*>::const_iterator i = data.begin(); |
929 i != data.end(); ++i) { | 1042 i != data.end(); ++i) { |
930 const SessionCommand::id_type kCommandSetWindowBounds2 = 10; | 1043 const SessionCommand::id_type kCommandSetWindowBounds2 = 10; |
931 const SessionCommand* command = *i; | 1044 const SessionCommand* command = *i; |
932 | 1045 |
933 switch (command->id()) { | 1046 switch (command->id()) { |
934 case kCommandSetTabWindow: { | 1047 case kCommandSetTabWindow: { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 SessionID::id_type tab_id; | 1203 SessionID::id_type tab_id; |
1091 std::string extension_app_id; | 1204 std::string extension_app_id; |
1092 if (!RestoreSetTabExtensionAppIDCommand( | 1205 if (!RestoreSetTabExtensionAppIDCommand( |
1093 *command, &tab_id, &extension_app_id)) { | 1206 *command, &tab_id, &extension_app_id)) { |
1094 return true; | 1207 return true; |
1095 } | 1208 } |
1096 | 1209 |
1097 GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id); | 1210 GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id); |
1098 break; | 1211 break; |
1099 } | 1212 } |
| 1213 case kCommandSessionStorageCreated: { |
| 1214 scoped_ptr<Pickle> pickle(command->PayloadAsPickle()); |
| 1215 SessionID::id_type window_id; |
| 1216 SessionID::id_type tab_id; |
| 1217 std::string session_storage_directory; |
| 1218 void* iter = NULL; |
| 1219 pickle->ReadInt(&iter, &window_id); |
| 1220 pickle->ReadInt(&iter, &tab_id); |
| 1221 pickle->ReadString(&iter, &session_storage_directory); |
| 1222 GetTab(tab_id, tabs)->session_storage_directory = |
| 1223 FilePath(session_storage_directory); |
| 1224 needed_session_storages->insert(session_storage_directory); |
| 1225 break; |
| 1226 } |
1100 | 1227 |
1101 default: | 1228 default: |
1102 return true; | 1229 return true; |
1103 } | 1230 } |
1104 } | 1231 } |
1105 return true; | 1232 return true; |
1106 } | 1233 } |
1107 | 1234 |
1108 void SessionService::BuildCommandsForTab( | 1235 void SessionService::BuildCommandsForTab( |
1109 const SessionID& window_id, | 1236 const SessionID& window_id, |
1110 TabContentsWrapper* tab, | 1237 TabContentsWrapper* tab, |
1111 int index_in_window, | 1238 int index_in_window, |
1112 bool is_pinned, | 1239 bool is_pinned, |
1113 std::vector<SessionCommand*>* commands, | 1240 std::vector<SessionCommand*>* commands, |
1114 IdToRange* tab_to_available_range) { | 1241 IdToRange* tab_to_available_range) { |
1115 DCHECK(tab && commands && window_id.id()); | 1242 DCHECK(tab && commands && window_id.id()); |
1116 const SessionID& session_id(tab->restore_tab_helper()->session_id()); | 1243 const SessionID& session_id(tab->restore_tab_helper()->session_id()); |
1117 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); | 1244 commands->push_back(CreateSetTabWindowCommand(window_id, session_id)); |
| 1245 |
| 1246 // Schedule reading the session storage directory on the WEBKIT_DEPRECATED |
| 1247 // thread. |
| 1248 int64 namespace_id = |
| 1249 tab->web_contents()->GetController().GetSessionStorageNamespace()->id(); |
| 1250 WebKitContext* webkit_context = profile()->GetWebKitContext(); |
| 1251 scoped_refptr<SessionStorageAssociationReader> reader = |
| 1252 new SessionStorageAssociationReader(this, namespace_id, webkit_context); |
| 1253 session_storage_association_readers_[reader.get()] = reader; |
| 1254 |
1118 const int current_index = | 1255 const int current_index = |
1119 tab->web_contents()->GetController().GetCurrentEntryIndex(); | 1256 tab->web_contents()->GetController().GetCurrentEntryIndex(); |
1120 const int min_index = std::max(0, | 1257 const int min_index = std::max(0, |
1121 current_index - max_persist_navigation_count); | 1258 current_index - max_persist_navigation_count); |
1122 const int max_index = | 1259 const int max_index = |
1123 std::min(current_index + max_persist_navigation_count, | 1260 std::min(current_index + max_persist_navigation_count, |
1124 tab->web_contents()->GetController().GetEntryCount()); | 1261 tab->web_contents()->GetController().GetEntryCount()); |
1125 const int pending_index = | 1262 const int pending_index = |
1126 tab->web_contents()->GetController().GetPendingEntryIndex(); | 1263 tab->web_contents()->GetController().GetPendingEntryIndex(); |
1127 if (tab_to_available_range) { | 1264 if (tab_to_available_range) { |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 50); | 1649 50); |
1513 if (use_long_period) { | 1650 if (use_long_period) { |
1514 std::string long_name_("SessionRestore.SaveLongPeriod"); | 1651 std::string long_name_("SessionRestore.SaveLongPeriod"); |
1515 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, | 1652 UMA_HISTOGRAM_CUSTOM_TIMES(long_name_, |
1516 delta, | 1653 delta, |
1517 save_delay_in_mins_, | 1654 save_delay_in_mins_, |
1518 save_delay_in_hrs_, | 1655 save_delay_in_hrs_, |
1519 50); | 1656 50); |
1520 } | 1657 } |
1521 } | 1658 } |
| 1659 |
| 1660 void SessionService::AssociateSessionStorage( |
| 1661 SessionStorageAssociationReader* reader, |
| 1662 int64 namespace_id, |
| 1663 const FilePath& directory) { |
| 1664 if (!directory.empty()) { |
| 1665 CreateAndScheduleSessionStorageCreatedCommand( |
| 1666 namespace_id, directory); |
| 1667 } |
| 1668 session_storage_association_readers_.erase(reader); |
| 1669 } |
OLD | NEW |