Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: chrome/browser/resource_coordinator/tab_manager.h

Issue 2931023002: [TooManyTabs] Add TabNavigationThrottle (Closed)
Patch Set: review fix Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_ 5 #ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_
6 #define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_ 6 #define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/gtest_prod_util.h" 17 #include "base/gtest_prod_util.h"
18 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/memory/memory_pressure_listener.h" 19 #include "base/memory/memory_pressure_listener.h"
20 #include "base/memory/weak_ptr.h" 20 #include "base/memory/weak_ptr.h"
21 #include "base/observer_list.h" 21 #include "base/observer_list.h"
22 #include "base/strings/string16.h" 22 #include "base/strings/string16.h"
23 #include "base/timer/timer.h" 23 #include "base/timer/timer.h"
24 #include "build/build_config.h" 24 #include "build/build_config.h"
25 #include "chrome/browser/resource_coordinator/tab_manager_observer.h" 25 #include "chrome/browser/resource_coordinator/tab_manager_observer.h"
26 #include "chrome/browser/resource_coordinator/tab_stats.h" 26 #include "chrome/browser/resource_coordinator/tab_stats.h"
27 #include "chrome/browser/ui/browser_tab_strip_tracker.h" 27 #include "chrome/browser/ui/browser_tab_strip_tracker.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" 28 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
29 #include "content/public/browser/navigation_throttle.h"
29 30
30 class BrowserList; 31 class BrowserList;
31 class GURL; 32 class GURL;
32 class TabStripModel; 33 class TabStripModel;
33 34
34 namespace base { 35 namespace base {
35 class TickClock; 36 class TickClock;
36 } 37 }
37 38
38 namespace content { 39 namespace content {
40 class NavigationHandle;
39 class WebContents; 41 class WebContents;
40 } 42 }
41 43
42 namespace resource_coordinator { 44 namespace resource_coordinator {
43 45
44 #if defined(OS_CHROMEOS) 46 #if defined(OS_CHROMEOS)
45 class TabManagerDelegate; 47 class TabManagerDelegate;
46 #endif 48 #endif
47 49
48 // The TabManager periodically updates (see 50 // The TabManager periodically updates (see
49 // |kAdjustmentIntervalSeconds| in the source) the status of renderers 51 // |kAdjustmentIntervalSeconds| in the source) the status of renderers
50 // which are then used by the algorithm embedded here for priority in being 52 // which are then used by the algorithm embedded here for priority in being
51 // killed upon OOM conditions. 53 // killed upon OOM conditions.
52 // 54 //
53 // The algorithm used favors killing tabs that are not selected, not pinned, 55 // The algorithm used favors killing tabs that are not selected, not pinned,
54 // and have been idle for longest, in that order of priority. 56 // and have been idle for longest, in that order of priority.
55 // 57 //
56 // On Chrome OS (via the delegate), the kernel (via /proc/<pid>/oom_score_adj) 58 // On Chrome OS (via the delegate), the kernel (via /proc/<pid>/oom_score_adj)
57 // will be informed of each renderer's score, which is based on the status, so 59 // will be informed of each renderer's score, which is based on the status, so
58 // in case Chrome is not able to relieve the pressure quickly enough and the 60 // in case Chrome is not able to relieve the pressure quickly enough and the
59 // kernel is forced to kill processes, it will be able to do so using the same 61 // kernel is forced to kill processes, it will be able to do so using the same
60 // algorithm as the one used here. 62 // algorithm as the one used here.
61 // 63 //
64 // The TabManager also delays background tabs' navigation when needed in order
65 // to improve users' experience with the foreground tab.
66 //
62 // Note that the browser tests are only active for platforms that use 67 // Note that the browser tests are only active for platforms that use
63 // TabManager (CrOS only for now) and need to be adjusted accordingly if 68 // TabManager (CrOS only for now) and need to be adjusted accordingly if
64 // support for new platforms is added. 69 // support for new platforms is added.
65 class TabManager : public TabStripModelObserver { 70 class TabManager : public TabStripModelObserver {
66 public: 71 public:
67 // Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY. 72 // Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY.
68 class WebContentsData; 73 class WebContentsData;
69 74
70 TabManager(); 75 TabManager();
71 ~TabManager() override; 76 ~TabManager() override;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 bool IsTabAutoDiscardable(content::WebContents* contents) const; 144 bool IsTabAutoDiscardable(content::WebContents* contents) const;
140 145
141 // Sets/clears the auto-discardable state of the tab. 146 // Sets/clears the auto-discardable state of the tab.
142 void SetTabAutoDiscardableState(content::WebContents* contents, bool state); 147 void SetTabAutoDiscardableState(content::WebContents* contents, bool state);
143 148
144 // Returns true when a given renderer can be purged if the specified 149 // Returns true when a given renderer can be purged if the specified
145 // renderer is eligible for purging. 150 // renderer is eligible for purging.
146 // TODO(tasak): rename this to CanPurgeBackgroundedRenderer. 151 // TODO(tasak): rename this to CanPurgeBackgroundedRenderer.
147 bool CanSuspendBackgroundedRenderer(int render_process_id) const; 152 bool CanSuspendBackgroundedRenderer(int render_process_id) const;
148 153
154 // Maybe throttle a tab's navigation based on current system status.
155 content::NavigationThrottle::ThrottleCheckResult MaybeThrottleNavigation(
156 content::NavigationHandle* navigation_handle);
157
158 // Notifies TabManager that one tab has finished loading. TabManager can
159 // decide which tab to load next.
160 void HasFinishedLoadingTab(content::WebContents* contents);
161
149 // Returns true if |first| is considered less desirable to be killed than 162 // Returns true if |first| is considered less desirable to be killed than
150 // |second|. 163 // |second|.
151 static bool CompareTabStats(const TabStats& first, const TabStats& second); 164 static bool CompareTabStats(const TabStats& first, const TabStats& second);
152 165
153 // Returns a unique ID for a WebContents. Do not cast back to a pointer, as 166 // Returns a unique ID for a WebContents. Do not cast back to a pointer, as
154 // the WebContents could be deleted if the user closed the tab. 167 // the WebContents could be deleted if the user closed the tab.
155 static int64_t IdFromWebContents(content::WebContents* web_contents); 168 static int64_t IdFromWebContents(content::WebContents* web_contents);
156 169
170 // Returns true if the |url| represents an internal Chrome web UI page that
171 // can be easily reloaded and hence makes a good choice to discard.
172 static bool IsInternalPage(const GURL& url);
173
157 private: 174 private:
158 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, PurgeBackgroundRenderer); 175 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, PurgeBackgroundRenderer);
159 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ActivateTabResetPurgeState); 176 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ActivateTabResetPurgeState);
160 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ShouldPurgeAtDefaultTime); 177 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ShouldPurgeAtDefaultTime);
161 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DefaultTimeToPurgeInCorrectRange); 178 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DefaultTimeToPurgeInCorrectRange);
162 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, AutoDiscardable); 179 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, AutoDiscardable);
163 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, CanOnlyDiscardOnce); 180 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, CanOnlyDiscardOnce);
164 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ChildProcessNotifications); 181 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ChildProcessNotifications);
165 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, Comparator); 182 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, Comparator);
166 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardedTabKeepsLastActiveTime); 183 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardedTabKeepsLastActiveTime);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 void OnDiscardedStateChange(content::WebContents* contents, 215 void OnDiscardedStateChange(content::WebContents* contents,
199 bool is_discarded); 216 bool is_discarded);
200 217
201 // Called by WebContentsData whenever the auto-discardable state of a 218 // Called by WebContentsData whenever the auto-discardable state of a
202 // WebContents changes, so that observers can be informed. 219 // WebContents changes, so that observers can be informed.
203 void OnAutoDiscardableStateChange(content::WebContents* contents, 220 void OnAutoDiscardableStateChange(content::WebContents* contents,
204 bool is_auto_discardable); 221 bool is_auto_discardable);
205 222
206 static void PurgeMemoryAndDiscardTab(); 223 static void PurgeMemoryAndDiscardTab();
207 224
208 // Returns true if the |url| represents an internal Chrome web UI page that
209 // can be easily reloaded and hence makes a good choice to discard.
210 static bool IsInternalPage(const GURL& url);
211
212 // Records UMA histogram statistics for a tab discard. Record statistics for 225 // Records UMA histogram statistics for a tab discard. Record statistics for
213 // user triggered discards via chrome://discards/ because that allows to 226 // user triggered discards via chrome://discards/ because that allows to
214 // manually test the system. 227 // manually test the system.
215 void RecordDiscardStatistics(); 228 void RecordDiscardStatistics();
216 229
217 // Record whether an out of memory occured during a recent time interval. This 230 // Record whether an out of memory occured during a recent time interval. This
218 // allows the normalization of low memory statistics versus usage. 231 // allows the normalization of low memory statistics versus usage.
219 void RecordRecentTabDiscard(); 232 void RecordRecentTabDiscard();
220 233
221 // Purges data structures in the browser that can be easily recomputed. 234 // Purges data structures in the browser that can be easily recomputed.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 // for more details. 308 // for more details.
296 base::TimeTicks NowTicks() const; 309 base::TimeTicks NowTicks() const;
297 310
298 // Implementation of DiscardTab. Returns null if no tab was discarded. 311 // Implementation of DiscardTab. Returns null if no tab was discarded.
299 // Otherwise returns the new web_contents of the discarded tab. 312 // Otherwise returns the new web_contents of the discarded tab.
300 content::WebContents* DiscardTabImpl(); 313 content::WebContents* DiscardTabImpl();
301 314
302 // Returns true if tabs can be discarded only once. 315 // Returns true if tabs can be discarded only once.
303 bool CanOnlyDiscardOnce() const; 316 bool CanOnlyDiscardOnce() const;
304 317
318 // Returns true if the navigation should be delay.
chrisha 2017/06/15 21:02:24 delayed*
Zhen Wang 2017/06/19 23:00:12 Done.
319 bool ShouldDelayNavigation(
320 content::NavigationHandle* navigation_handle) const;
321
322 // Resume the tab's navigation if it is pending right now.
323 void ResumeTabNavigationIfNeeded(content::WebContents* contents);
324
305 // Timer to periodically update the stats of the renderers. 325 // Timer to periodically update the stats of the renderers.
306 base::RepeatingTimer update_timer_; 326 base::RepeatingTimer update_timer_;
307 327
308 // Timer to periodically report whether a tab has been discarded since the 328 // Timer to periodically report whether a tab has been discarded since the
309 // last time the timer has fired. 329 // last time the timer has fired.
310 base::RepeatingTimer recent_tab_discard_timer_; 330 base::RepeatingTimer recent_tab_discard_timer_;
311 331
312 // A listener to global memory pressure events. 332 // A listener to global memory pressure events.
313 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; 333 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
314 334
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 // associated Browser objects are crawled. The first of these is considered to 378 // associated Browser objects are crawled. The first of these is considered to
359 // be the 'active' tab strip model. 379 // be the 'active' tab strip model.
360 // TODO(chrisha): Factor out tab-strip model enumeration to a helper class, 380 // TODO(chrisha): Factor out tab-strip model enumeration to a helper class,
361 // and make a delegate that centralizes all testing seams. 381 // and make a delegate that centralizes all testing seams.
362 using TestTabStripModel = std::pair<const TabStripModel*, bool>; 382 using TestTabStripModel = std::pair<const TabStripModel*, bool>;
363 std::vector<TestTabStripModel> test_tab_strip_models_; 383 std::vector<TestTabStripModel> test_tab_strip_models_;
364 384
365 // List of observers that will receive notifications on state changes. 385 // List of observers that will receive notifications on state changes.
366 base::ObserverList<TabManagerObserver> observers_; 386 base::ObserverList<TabManagerObserver> observers_;
367 387
388 // The list of navigation handles that are throttled.
389 std::vector<content::NavigationHandle*> pending_navigations_;
390
391 // The tab that is currently loading. If multiple tabs are loading
392 // simultaneously, it corresponds to the lastest one. We will consider loading
393 // the next background tab when this tab has finished loading.
394 // TODO(zhenw): This is a native algorithm. It should be updated to use
nasko 2017/06/15 20:01:58 nit: Did you mean "naive" instead of "native"?
Zhen Wang 2017/06/19 23:00:12 Right. Updated to naive. Thanks for catching this!
395 // smarter ways, e.g., making sure all loading tabs have finished.
396 content::WebContents* loading_contents_;
chrisha 2017/06/15 21:02:24 We have loading states being worked on in another
Zhen Wang 2017/06/19 23:00:12 Now I have rebased this CL on the other CL and I c
chrisha 2017/06/20 18:26:54 sgtm
397
368 // Weak pointer factory used for posting delayed tasks. 398 // Weak pointer factory used for posting delayed tasks.
369 base::WeakPtrFactory<TabManager> weak_ptr_factory_; 399 base::WeakPtrFactory<TabManager> weak_ptr_factory_;
370 400
371 DISALLOW_COPY_AND_ASSIGN(TabManager); 401 DISALLOW_COPY_AND_ASSIGN(TabManager);
372 }; 402 };
373 403
374 } // namespace resource_coordinator 404 } // namespace resource_coordinator
375 405
376 #endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_ 406 #endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698