1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SESSIONS_TAB_LOADER_H_
6 #define CHROME_BROWSER_SESSIONS_TAB_LOADER_H_
11 #include "base/memory/memory_pressure_listener.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/timer/timer.h"
14 #include "chrome/browser/sessions/session_restore_delegate.h"
15 #include "chrome/browser/sessions/tab_loader_delegate.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
20 class NavigationController
;
21 class RenderWidgetHost
;
24 class SessionRestoreStatsCollector
;
26 // TabLoader is responsible for loading tabs after session restore has finished
27 // creating all the tabs. Tabs are loaded after a previously tab finishes
28 // loading or a timeout is reached. If the timeout is reached before a tab
29 // finishes loading the timeout delay is doubled.
31 // TabLoader keeps a reference to itself when it's loading. When it has finished
32 // loading, it drops the reference. If another profile is restored while the
33 // TabLoader is loading, it will schedule its tabs to get loaded by the same
34 // TabLoader. When doing the scheduling, it holds a reference to the TabLoader.
36 // This is not part of SessionRestoreImpl so that synchronous destruction
37 // of SessionRestoreImpl doesn't have timing problems.
38 class TabLoader
: public content::NotificationObserver
,
39 public base::RefCounted
<TabLoader
>,
40 public TabLoaderCallback
{
42 using RestoredTab
= SessionRestoreDelegate::RestoredTab
;
44 // NotificationObserver method. Removes the specified tab and loads the next
46 void Observe(int type
,
47 const content::NotificationSource
& source
,
48 const content::NotificationDetails
& details
) override
;
51 void SetTabLoadingEnabled(bool enable_tab_loading
) override
;
53 // Called to start restoring tabs.
54 static void RestoreTabs(const std::vector
<RestoredTab
>& tabs_
,
55 const base::TimeTicks
& restore_started
);
58 friend class base::RefCounted
<TabLoader
>;
60 using TabsLoading
= std::set
<content::NavigationController
*>;
61 using TabsToLoad
= std::list
<content::NavigationController
*>;
63 explicit TabLoader(base::TimeTicks restore_started
);
64 ~TabLoader() override
;
66 // This is invoked once by RestoreTabs to start loading.
67 void StartLoading(const std::vector
<RestoredTab
>& tabs
);
69 // Loads the next tab. If there are no more tabs to load this deletes itself,
70 // otherwise |force_load_timer_| is restarted.
73 // Starts |force_load_timer_| to load the first non-visible tab if the timer
74 // expires before a visible tab has finished loading. This uses the same
75 // timer but a different timeout value than StartTimer.
76 void StartFirstTimer();
78 // Starts |force_load_timer_| to load the next tab if the timer expires
79 // before the current tab loading is finished. This uses the same timer but a
80 // different timeout value than StartFirstTimer.
83 // Removes the listeners from the specified tab and removes the tab from
84 // the set of tabs to load and list of tabs we're waiting to get a load
86 void RemoveTab(content::NavigationController
* controller
);
88 // Invoked from |force_load_timer_|. Doubles |force_load_delay_multiplier_|
89 // and invokes |LoadNextTab| to load the next tab
90 void ForceLoadTimerFired();
92 // Returns the RenderWidgetHost associated with a tab if there is one,
94 static content::RenderWidgetHost
* GetRenderWidgetHost(
95 content::NavigationController
* controller
);
97 // Register for necessary notifications on a tab navigation controller.
98 void RegisterForNotifications(content::NavigationController
* controller
);
100 // Called when a tab goes away or a load completes.
101 void HandleTabClosedOrLoaded(content::NavigationController
* controller
);
103 // Convenience function returning the current memory pressure level.
104 base::MemoryPressureListener::MemoryPressureLevel
105 CurrentMemoryPressureLevel();
107 // React to memory pressure by stopping to load any more tabs.
108 void OnMemoryPressure(
109 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level
);
111 scoped_ptr
<TabLoaderDelegate
> delegate_
;
113 // Listens for system under memory pressure notifications and stops loading
114 // of tabs when we start running out of memory.
115 base::MemoryPressureListener memory_pressure_listener_
;
117 content::NotificationRegistrar registrar_
;
119 // The delay timer multiplier. See class description for details.
120 size_t force_load_delay_multiplier_
;
122 // True if the tab loading is enabled.
123 bool loading_enabled_
;
125 // The set of tabs we've initiated loading on. This does NOT include the
127 TabsLoading tabs_loading_
;
129 // The tabs we need to load.
130 TabsToLoad tabs_to_load_
;
132 base::OneShotTimer
<TabLoader
> force_load_timer_
;
134 // The time the restore process started.
135 base::TimeTicks restore_started_
;
137 // For keeping TabLoader alive while it's loading even if no
138 // SessionRestoreImpls reference it.
139 scoped_refptr
<TabLoader
> this_retainer_
;
141 // The SessionRestoreStatsCollector associated with this TabLoader. This is
142 // explicitly referenced so that it can be notified of deferred tab loads due
143 // to memory pressure.
144 scoped_refptr
<SessionRestoreStatsCollector
> stats_collector_
;
146 static TabLoader
* shared_tab_loader_
;
148 DISALLOW_COPY_AND_ASSIGN(TabLoader
);
151 #endif // CHROME_BROWSER_SESSIONS_TAB_LOADER_H_