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 "chrome/browser/sessions/session_restore.h" | 5 #include "chrome/browser/sessions/session_restore.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <list> | 8 #include <list> |
9 #include <set> | 9 #include <set> |
10 #include <vector> | 10 #include <vector> |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "chrome/browser/ui/browser_navigator.h" | 27 #include "chrome/browser/ui/browser_navigator.h" |
28 #include "chrome/browser/ui/browser_window.h" | 28 #include "chrome/browser/ui/browser_window.h" |
29 #include "chrome/common/chrome_notification_types.h" | 29 #include "chrome/common/chrome_notification_types.h" |
30 #include "content/browser/renderer_host/render_widget_host.h" | 30 #include "content/browser/renderer_host/render_widget_host.h" |
31 #include "content/browser/renderer_host/render_widget_host_view.h" | 31 #include "content/browser/renderer_host/render_widget_host_view.h" |
32 #include "content/browser/tab_contents/navigation_controller.h" | 32 #include "content/browser/tab_contents/navigation_controller.h" |
33 #include "content/browser/tab_contents/tab_contents.h" | 33 #include "content/browser/tab_contents/tab_contents.h" |
34 #include "content/browser/tab_contents/tab_contents_view.h" | 34 #include "content/browser/tab_contents/tab_contents_view.h" |
35 #include "content/common/notification_registrar.h" | 35 #include "content/common/notification_registrar.h" |
36 #include "content/common/notification_service.h" | 36 #include "content/common/notification_service.h" |
| 37 #include "net/base/network_change_notifier.h" |
37 | 38 |
38 #if defined(OS_CHROMEOS) | 39 #if defined(OS_CHROMEOS) |
39 #include "chrome/browser/chromeos/boot_times_loader.h" | 40 #include "chrome/browser/chromeos/boot_times_loader.h" |
40 #include "chrome/browser/chromeos/network_state_notifier.h" | |
41 #endif | 41 #endif |
42 | 42 |
43 // Are we in the process of restoring? | 43 // Are we in the process of restoring? |
44 static bool restoring = false; | 44 static bool restoring = false; |
45 | 45 |
46 namespace { | 46 namespace { |
47 | 47 |
48 // TabLoader ------------------------------------------------------------------ | 48 // TabLoader ------------------------------------------------------------------ |
49 | 49 |
50 // Initial delay (see class decription for details). | 50 // Initial delay (see class decription for details). |
51 static const int kInitialDelayTimerMS = 100; | 51 static const int kInitialDelayTimerMS = 100; |
52 | 52 |
53 // TabLoader is responsible for loading tabs after session restore creates | 53 // TabLoader is responsible for loading tabs after session restore creates |
54 // tabs. New tabs are loaded after the current tab finishes loading, or a delay | 54 // tabs. New tabs are loaded after the current tab finishes loading, or a delay |
55 // is reached (initially kInitialDelayTimerMS). If the delay is reached before | 55 // is reached (initially kInitialDelayTimerMS). If the delay is reached before |
56 // a tab finishes loading a new tab is loaded and the time of the delay | 56 // a tab finishes loading a new tab is loaded and the time of the delay |
57 // doubled. When all tabs are loading TabLoader deletes itself. | 57 // doubled. When all tabs are loading TabLoader deletes itself. |
58 // | 58 // |
59 // This is not part of SessionRestoreImpl so that synchronous destruction | 59 // This is not part of SessionRestoreImpl so that synchronous destruction |
60 // of SessionRestoreImpl doesn't have timing problems. | 60 // of SessionRestoreImpl doesn't have timing problems. |
61 class TabLoader : public NotificationObserver { | 61 class TabLoader : public NotificationObserver, |
| 62 public net::NetworkChangeNotifier::OnlineStateObserver { |
62 public: | 63 public: |
63 explicit TabLoader(base::TimeTicks restore_started); | 64 explicit TabLoader(base::TimeTicks restore_started); |
64 ~TabLoader(); | 65 virtual ~TabLoader(); |
65 | 66 |
66 // Schedules a tab for loading. | 67 // Schedules a tab for loading. |
67 void ScheduleLoad(NavigationController* controller); | 68 void ScheduleLoad(NavigationController* controller); |
68 | 69 |
69 // Notifies the loader that a tab has been scheduled for loading through | 70 // Notifies the loader that a tab has been scheduled for loading through |
70 // some other mechanism. | 71 // some other mechanism. |
71 void TabIsLoading(NavigationController* controller); | 72 void TabIsLoading(NavigationController* controller); |
72 | 73 |
73 // Invokes |LoadNextTab| to load a tab. | 74 // Invokes |LoadNextTab| to load a tab. |
74 // | 75 // |
75 // This must be invoked once to start loading. | 76 // This must be invoked once to start loading. |
76 void StartLoading(); | 77 void StartLoading(); |
77 | 78 |
78 private: | 79 private: |
79 typedef std::set<NavigationController*> TabsLoading; | 80 typedef std::set<NavigationController*> TabsLoading; |
80 typedef std::list<NavigationController*> TabsToLoad; | 81 typedef std::list<NavigationController*> TabsToLoad; |
81 typedef std::set<RenderWidgetHost*> RenderWidgetHostSet; | 82 typedef std::set<RenderWidgetHost*> RenderWidgetHostSet; |
82 | 83 |
83 // Loads the next tab. If there are no more tabs to load this deletes itself, | 84 // Loads the next tab. If there are no more tabs to load this deletes itself, |
84 // otherwise |force_load_timer_| is restarted. | 85 // otherwise |force_load_timer_| is restarted. |
85 void LoadNextTab(); | 86 void LoadNextTab(); |
86 | 87 |
87 // NotificationObserver method. Removes the specified tab and loads the next | 88 // NotificationObserver method. Removes the specified tab and loads the next |
88 // tab. | 89 // tab. |
89 virtual void Observe(int type, | 90 virtual void Observe(int type, |
90 const NotificationSource& source, | 91 const NotificationSource& source, |
91 const NotificationDetails& details); | 92 const NotificationDetails& details) OVERRIDE; |
| 93 |
| 94 // net::NetworkChangeNotifier::OnlineStateObserver overrides. |
| 95 virtual void OnOnlineStateChanged(bool online) OVERRIDE; |
92 | 96 |
93 // Removes the listeners from the specified tab and removes the tab from | 97 // Removes the listeners from the specified tab and removes the tab from |
94 // the set of tabs to load and list of tabs we're waiting to get a load | 98 // the set of tabs to load and list of tabs we're waiting to get a load |
95 // from. | 99 // from. |
96 void RemoveTab(NavigationController* tab); | 100 void RemoveTab(NavigationController* tab); |
97 | 101 |
98 // Invoked from |force_load_timer_|. Doubles |force_load_delay_| and invokes | 102 // Invoked from |force_load_timer_|. Doubles |force_load_delay_| and invokes |
99 // |LoadNextTab| to load the next tab | 103 // |LoadNextTab| to load the next tab |
100 void ForceLoadTimerFired(); | 104 void ForceLoadTimerFired(); |
101 | 105 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 : force_load_delay_(kInitialDelayTimerMS), | 153 : force_load_delay_(kInitialDelayTimerMS), |
150 loading_(false), | 154 loading_(false), |
151 got_first_paint_(false), | 155 got_first_paint_(false), |
152 tab_count_(0), | 156 tab_count_(0), |
153 restore_started_(restore_started) { | 157 restore_started_(restore_started) { |
154 } | 158 } |
155 | 159 |
156 TabLoader::~TabLoader() { | 160 TabLoader::~TabLoader() { |
157 DCHECK((got_first_paint_ || render_widget_hosts_to_paint_.empty()) && | 161 DCHECK((got_first_paint_ || render_widget_hosts_to_paint_.empty()) && |
158 tabs_loading_.empty() && tabs_to_load_.empty()); | 162 tabs_loading_.empty() && tabs_to_load_.empty()); |
| 163 net::NetworkChangeNotifier::RemoveOnlineStateObserver(this); |
159 } | 164 } |
160 | 165 |
161 void TabLoader::ScheduleLoad(NavigationController* controller) { | 166 void TabLoader::ScheduleLoad(NavigationController* controller) { |
162 DCHECK(controller); | 167 DCHECK(controller); |
163 DCHECK(find(tabs_to_load_.begin(), tabs_to_load_.end(), controller) == | 168 DCHECK(find(tabs_to_load_.begin(), tabs_to_load_.end(), controller) == |
164 tabs_to_load_.end()); | 169 tabs_to_load_.end()); |
165 tabs_to_load_.push_back(controller); | 170 tabs_to_load_.push_back(controller); |
166 RegisterForNotifications(controller); | 171 RegisterForNotifications(controller); |
167 } | 172 } |
168 | 173 |
169 void TabLoader::TabIsLoading(NavigationController* controller) { | 174 void TabLoader::TabIsLoading(NavigationController* controller) { |
170 DCHECK(controller); | 175 DCHECK(controller); |
171 DCHECK(find(tabs_loading_.begin(), tabs_loading_.end(), controller) == | 176 DCHECK(find(tabs_loading_.begin(), tabs_loading_.end(), controller) == |
172 tabs_loading_.end()); | 177 tabs_loading_.end()); |
173 tabs_loading_.insert(controller); | 178 tabs_loading_.insert(controller); |
174 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(controller); | 179 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(controller); |
175 DCHECK(render_widget_host); | 180 DCHECK(render_widget_host); |
176 render_widget_hosts_loading_.insert(render_widget_host); | 181 render_widget_hosts_loading_.insert(render_widget_host); |
177 RegisterForNotifications(controller); | 182 RegisterForNotifications(controller); |
178 } | 183 } |
179 | 184 |
180 void TabLoader::StartLoading() { | 185 void TabLoader::StartLoading() { |
181 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, | 186 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, |
182 NotificationService::AllSources()); | 187 NotificationService::AllSources()); |
183 #if defined(OS_CHROMEOS) | 188 #if defined(OS_CHROMEOS) |
184 if (chromeos::NetworkStateNotifier::is_connected()) { | 189 if (!net::NetworkChangeNotifier::IsOffline()) { |
185 loading_ = true; | 190 loading_ = true; |
186 LoadNextTab(); | 191 LoadNextTab(); |
187 } else { | 192 } else { |
188 // Start listening to network state notification now. | 193 net::NetworkChangeNotifier::AddOnlineStateObserver(this); |
189 registrar_.Add(this, chrome::NOTIFICATION_NETWORK_STATE_CHANGED, | |
190 NotificationService::AllSources()); | |
191 } | 194 } |
192 #else | 195 #else |
193 loading_ = true; | 196 loading_ = true; |
194 LoadNextTab(); | 197 LoadNextTab(); |
195 #endif | 198 #endif |
196 } | 199 } |
197 | 200 |
198 void TabLoader::LoadNextTab() { | 201 void TabLoader::LoadNextTab() { |
199 if (!tabs_to_load_.empty()) { | 202 if (!tabs_to_load_.empty()) { |
200 NavigationController* tab = tabs_to_load_.front(); | 203 NavigationController* tab = tabs_to_load_.front(); |
(...skipping 24 matching lines...) Expand all Loading... |
225 force_load_timer_.Start(FROM_HERE, | 228 force_load_timer_.Start(FROM_HERE, |
226 base::TimeDelta::FromMilliseconds(force_load_delay_), | 229 base::TimeDelta::FromMilliseconds(force_load_delay_), |
227 this, &TabLoader::ForceLoadTimerFired); | 230 this, &TabLoader::ForceLoadTimerFired); |
228 } | 231 } |
229 } | 232 } |
230 | 233 |
231 void TabLoader::Observe(int type, | 234 void TabLoader::Observe(int type, |
232 const NotificationSource& source, | 235 const NotificationSource& source, |
233 const NotificationDetails& details) { | 236 const NotificationDetails& details) { |
234 switch (type) { | 237 switch (type) { |
235 #if defined(OS_CHROMEOS) | |
236 case chrome::NOTIFICATION_NETWORK_STATE_CHANGED: { | |
237 chromeos::NetworkStateDetails* state_details = | |
238 Details<chromeos::NetworkStateDetails>(details).ptr(); | |
239 switch (state_details->state()) { | |
240 case chromeos::NetworkStateDetails::CONNECTED: | |
241 if (!loading_) { | |
242 loading_ = true; | |
243 LoadNextTab(); | |
244 } | |
245 // Start loading | |
246 break; | |
247 case chromeos::NetworkStateDetails::CONNECTING: | |
248 case chromeos::NetworkStateDetails::DISCONNECTED: | |
249 // Disconnected while loading. Set loading_ false so | |
250 // that it stops trying to load next tab. | |
251 loading_ = false; | |
252 break; | |
253 default: | |
254 NOTREACHED() << "Unknown nework state notification:" | |
255 << state_details->state(); | |
256 } | |
257 break; | |
258 } | |
259 #endif | |
260 case content::NOTIFICATION_LOAD_START: { | 238 case content::NOTIFICATION_LOAD_START: { |
261 // Add this render_widget_host to the set of those we're waiting for | 239 // Add this render_widget_host to the set of those we're waiting for |
262 // paints on. We want to only record stats for paints that occur after | 240 // paints on. We want to only record stats for paints that occur after |
263 // a load has finished. | 241 // a load has finished. |
264 NavigationController* tab = Source<NavigationController>(source).ptr(); | 242 NavigationController* tab = Source<NavigationController>(source).ptr(); |
265 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(tab); | 243 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(tab); |
266 DCHECK(render_widget_host); | 244 DCHECK(render_widget_host); |
267 render_widget_hosts_loading_.insert(render_widget_host); | 245 render_widget_hosts_loading_.insert(render_widget_host); |
268 break; | 246 break; |
269 } | 247 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 } | 303 } |
326 default: | 304 default: |
327 NOTREACHED() << "Unknown notification received:" << type; | 305 NOTREACHED() << "Unknown notification received:" << type; |
328 } | 306 } |
329 // Delete ourselves when we're not waiting for any more notifications. | 307 // Delete ourselves when we're not waiting for any more notifications. |
330 if ((got_first_paint_ || render_widget_hosts_to_paint_.empty()) && | 308 if ((got_first_paint_ || render_widget_hosts_to_paint_.empty()) && |
331 tabs_loading_.empty() && tabs_to_load_.empty()) | 309 tabs_loading_.empty() && tabs_to_load_.empty()) |
332 delete this; | 310 delete this; |
333 } | 311 } |
334 | 312 |
| 313 void TabLoader::OnOnlineStateChanged(bool online) { |
| 314 if (online) { |
| 315 if (!loading_) { |
| 316 loading_ = true; |
| 317 LoadNextTab(); |
| 318 } |
| 319 } else { |
| 320 loading_ = false; |
| 321 } |
| 322 } |
| 323 |
335 void TabLoader::RemoveTab(NavigationController* tab) { | 324 void TabLoader::RemoveTab(NavigationController* tab) { |
336 registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED, | 325 registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DESTROYED, |
337 Source<TabContents>(tab->tab_contents())); | 326 Source<TabContents>(tab->tab_contents())); |
338 registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP, | 327 registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP, |
339 Source<NavigationController>(tab)); | 328 Source<NavigationController>(tab)); |
340 registrar_.Remove(this, content::NOTIFICATION_LOAD_START, | 329 registrar_.Remove(this, content::NOTIFICATION_LOAD_START, |
341 Source<NavigationController>(tab)); | 330 Source<NavigationController>(tab)); |
342 | 331 |
343 TabsLoading::iterator i = tabs_loading_.find(tab); | 332 TabsLoading::iterator i = tabs_loading_.find(tab); |
344 if (i != tabs_loading_.end()) | 333 if (i != tabs_loading_.end()) |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 std::vector<GURL> gurls; | 858 std::vector<GURL> gurls; |
870 SessionRestoreImpl restorer(profile, | 859 SessionRestoreImpl restorer(profile, |
871 static_cast<Browser*>(NULL), true, false, true, gurls); | 860 static_cast<Browser*>(NULL), true, false, true, gurls); |
872 restorer.RestoreForeignTab(tab); | 861 restorer.RestoreForeignTab(tab); |
873 } | 862 } |
874 | 863 |
875 // static | 864 // static |
876 bool SessionRestore::IsRestoring() { | 865 bool SessionRestore::IsRestoring() { |
877 return restoring; | 866 return restoring; |
878 } | 867 } |
OLD | NEW |