| 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 #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 <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/gtest_prod_util.h" | 16 #include "base/gtest_prod_util.h" |
| 17 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/memory/memory_pressure_listener.h" | 18 #include "base/memory/memory_pressure_listener.h" |
| 19 #include "base/memory/weak_ptr.h" | 19 #include "base/memory/weak_ptr.h" |
| 20 #include "base/observer_list.h" | 20 #include "base/observer_list.h" |
| 21 #include "base/strings/string16.h" | 21 #include "base/strings/string16.h" |
| 22 #include "base/timer/timer.h" | 22 #include "base/timer/timer.h" |
| 23 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 24 #include "chrome/browser/resource_coordinator/tab_manager_observer.h" | 24 #include "chrome/browser/resource_coordinator/tab_manager_observer.h" |
| 25 #include "chrome/browser/resource_coordinator/tab_stats.h" | 25 #include "chrome/browser/resource_coordinator/tab_stats.h" |
| 26 #include "chrome/browser/sessions/session_restore_observer.h" | 26 #include "chrome/browser/sessions/session_restore_observer.h" |
| 27 #include "chrome/browser/ui/browser_list_observer.h" | 27 #include "chrome/browser/ui/browser_list_observer.h" |
| 28 #include "chrome/browser/ui/browser_tab_strip_tracker.h" | 28 #include "chrome/browser/ui/browser_tab_strip_tracker.h" |
| 29 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" | 29 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" |
| 30 #include "content/public/browser/navigation_throttle.h" |
| 30 | 31 |
| 31 class BrowserList; | 32 class BrowserList; |
| 32 class GURL; | 33 class GURL; |
| 33 class TabStripModel; | 34 class TabStripModel; |
| 34 | 35 |
| 35 namespace base { | 36 namespace base { |
| 36 class TickClock; | 37 class TickClock; |
| 37 } | 38 } |
| 38 | 39 |
| 39 namespace content { | 40 namespace content { |
| 41 class NavigationHandle; |
| 40 class WebContents; | 42 class WebContents; |
| 41 } | 43 } |
| 42 | 44 |
| 43 namespace resource_coordinator { | 45 namespace resource_coordinator { |
| 44 | 46 |
| 45 #if defined(OS_CHROMEOS) | 47 #if defined(OS_CHROMEOS) |
| 46 class TabManagerDelegate; | 48 class TabManagerDelegate; |
| 47 #endif | 49 #endif |
| 48 | 50 |
| 49 // The TabManager periodically updates (see | 51 // The TabManager periodically updates (see |
| 50 // |kAdjustmentIntervalSeconds| in the source) the status of renderers | 52 // |kAdjustmentIntervalSeconds| in the source) the status of renderers |
| 51 // which are then used by the algorithm embedded here for priority in being | 53 // which are then used by the algorithm embedded here for priority in being |
| 52 // killed upon OOM conditions. | 54 // killed upon OOM conditions. |
| 53 // | 55 // |
| 54 // The algorithm used favors killing tabs that are not active, not in an active | 56 // The algorithm used favors killing tabs that are not active, not in an active |
| 55 // window, not in a visible window, not pinned, and have been idle for longest, | 57 // window, not in a visible window, not pinned, and have been idle for longest, |
| 56 // in that order of priority. | 58 // in that order of priority. |
| 57 // | 59 // |
| 58 // On Chrome OS (via the delegate), the kernel (via /proc/<pid>/oom_score_adj) | 60 // On Chrome OS (via the delegate), the kernel (via /proc/<pid>/oom_score_adj) |
| 59 // will be informed of each renderer's score, which is based on the status, so | 61 // will be informed of each renderer's score, which is based on the status, so |
| 60 // in case Chrome is not able to relieve the pressure quickly enough and the | 62 // in case Chrome is not able to relieve the pressure quickly enough and the |
| 61 // kernel is forced to kill processes, it will be able to do so using the same | 63 // kernel is forced to kill processes, it will be able to do so using the same |
| 62 // algorithm as the one used here. | 64 // algorithm as the one used here. |
| 63 // | 65 // |
| 66 // The TabManager also delays background tabs' navigation when needed in order |
| 67 // to improve users' experience with the foreground tab. |
| 68 // |
| 64 // Note that the browser tests are only active for platforms that use | 69 // Note that the browser tests are only active for platforms that use |
| 65 // TabManager (CrOS only for now) and need to be adjusted accordingly if | 70 // TabManager (CrOS only for now) and need to be adjusted accordingly if |
| 66 // support for new platforms is added. | 71 // support for new platforms is added. |
| 67 class TabManager : public TabStripModelObserver, | 72 class TabManager : public TabStripModelObserver, |
| 68 public chrome::BrowserListObserver { | 73 public chrome::BrowserListObserver { |
| 69 public: | 74 public: |
| 70 // Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY. | 75 // Needs to be public for DEFINE_WEB_CONTENTS_USER_DATA_KEY. |
| 71 class WebContentsData; | 76 class WebContentsData; |
| 72 | 77 |
| 73 TabManager(); | 78 TabManager(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 bool IsTabAutoDiscardable(content::WebContents* contents) const; | 148 bool IsTabAutoDiscardable(content::WebContents* contents) const; |
| 144 | 149 |
| 145 // Sets/clears the auto-discardable state of the tab. | 150 // Sets/clears the auto-discardable state of the tab. |
| 146 void SetTabAutoDiscardableState(content::WebContents* contents, bool state); | 151 void SetTabAutoDiscardableState(content::WebContents* contents, bool state); |
| 147 | 152 |
| 148 // Returns true when a given renderer can be purged if the specified | 153 // Returns true when a given renderer can be purged if the specified |
| 149 // renderer is eligible for purging. | 154 // renderer is eligible for purging. |
| 150 // TODO(tasak): rename this to CanPurgeBackgroundedRenderer. | 155 // TODO(tasak): rename this to CanPurgeBackgroundedRenderer. |
| 151 bool CanSuspendBackgroundedRenderer(int render_process_id) const; | 156 bool CanSuspendBackgroundedRenderer(int render_process_id) const; |
| 152 | 157 |
| 158 // Maybe throttle a tab's navigation based on current system status. |
| 159 content::NavigationThrottle::ThrottleCheckResult MaybeThrottleNavigation( |
| 160 content::NavigationHandle* navigation_handle); |
| 161 |
| 162 // Notifies TabManager that one navigation has finished (committed, aborted or |
| 163 // replaced). TabManager should clean up the NavigationHandle objects bookkept |
| 164 // before. |
| 165 void OnDidFinishNavigation(content::NavigationHandle* navigation_handle); |
| 166 |
| 167 // Notifies TabManager that one tab has finished loading. TabManager can |
| 168 // decide which tab to load next. |
| 169 void OnDidStopLoading(content::WebContents* contents); |
| 170 |
| 171 // Notifies TabManager that one tab WebContents has been destroyed. TabManager |
| 172 // needs to clean up data related to that tab. |
| 173 void OnWebContentsDestroyed(content::WebContents* contents); |
| 174 |
| 153 // Returns true if |first| is considered less desirable to be killed than | 175 // Returns true if |first| is considered less desirable to be killed than |
| 154 // |second|. | 176 // |second|. |
| 155 static bool CompareTabStats(const TabStats& first, const TabStats& second); | 177 static bool CompareTabStats(const TabStats& first, const TabStats& second); |
| 156 | 178 |
| 157 // Returns a unique ID for a WebContents. Do not cast back to a pointer, as | 179 // Returns a unique ID for a WebContents. Do not cast back to a pointer, as |
| 158 // the WebContents could be deleted if the user closed the tab. | 180 // the WebContents could be deleted if the user closed the tab. |
| 159 static int64_t IdFromWebContents(content::WebContents* web_contents); | 181 static int64_t IdFromWebContents(content::WebContents* web_contents); |
| 160 | 182 |
| 161 // Return whether tabs are being loaded during session restore. | 183 // Return whether tabs are being loaded during session restore. |
| 162 bool IsSessionRestoreLoadingTabs() const { | 184 bool IsSessionRestoreLoadingTabs() const { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 180 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectPDFPages); | 202 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectPDFPages); |
| 181 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectRecentlyUsedTabs); | 203 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectRecentlyUsedTabs); |
| 182 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectVideoTabs); | 204 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectVideoTabs); |
| 183 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ReloadDiscardedTabContextMenu); | 205 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ReloadDiscardedTabContextMenu); |
| 184 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabManagerBasics); | 206 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabManagerBasics); |
| 185 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, FastShutdownSingleTabProcess); | 207 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, FastShutdownSingleTabProcess); |
| 186 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, | 208 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, |
| 187 GetUnsortedTabStatsIsInVisibleWindow); | 209 GetUnsortedTabStatsIsInVisibleWindow); |
| 188 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, HistogramsSessionRestoreSwitchToTab); | 210 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, HistogramsSessionRestoreSwitchToTab); |
| 189 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardTabWithNonVisibleTabs); | 211 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, DiscardTabWithNonVisibleTabs); |
| 212 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, MaybeThrottleNavigation); |
| 213 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnDidFinishNavigation); |
| 214 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnDidStopLoading); |
| 215 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnWebContentsDestroyed); |
| 216 FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OnDelayedTabSelected); |
| 190 | 217 |
| 191 // Information about a Browser. | 218 // Information about a Browser. |
| 192 struct BrowserInfo { | 219 struct BrowserInfo { |
| 193 TabStripModel* tab_strip_model; | 220 TabStripModel* tab_strip_model; |
| 194 bool window_is_minimized; | 221 bool window_is_minimized; |
| 195 bool browser_is_app; | 222 bool browser_is_app; |
| 196 }; | 223 }; |
| 197 | 224 |
| 198 // The time of the first purging after a renderer is backgrounded. | 225 // The time of the first purging after a renderer is backgrounded. |
| 199 // The initial value was chosen because most of users activate backgrounded | 226 // The initial value was chosen because most of users activate backgrounded |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 // corresponds to the last active Browser. | 359 // corresponds to the last active Browser. |
| 333 std::vector<BrowserInfo> GetBrowserInfoList() const; | 360 std::vector<BrowserInfo> GetBrowserInfoList() const; |
| 334 | 361 |
| 335 void OnSessionRestoreStartedLoadingTabs(); | 362 void OnSessionRestoreStartedLoadingTabs(); |
| 336 void OnSessionRestoreFinishedLoadingTabs(); | 363 void OnSessionRestoreFinishedLoadingTabs(); |
| 337 | 364 |
| 338 // Records UMA histograms for the tab state when switching to a different tab | 365 // Records UMA histograms for the tab state when switching to a different tab |
| 339 // during session restore. | 366 // during session restore. |
| 340 void RecordSwitchToTab(content::WebContents* contents) const; | 367 void RecordSwitchToTab(content::WebContents* contents) const; |
| 341 | 368 |
| 369 // Returns true if the navigation should be delayed. |
| 370 bool ShouldDelayNavigation( |
| 371 content::NavigationHandle* navigation_handle) const; |
| 372 |
| 373 // Start loading the next background tab if needed. |
| 374 void LoadNextBackgroundTabIfNeeded(); |
| 375 |
| 376 // Resume the tab's navigation if it is pending right now. |
| 377 void ResumeTabNavigationIfNeeded(content::WebContents* contents); |
| 378 |
| 379 // Resume navigation. |
| 380 void ResumeNavigation(content::NavigationHandle* navigation_handle); |
| 381 |
| 382 // Remove the pending navigation for the provided WebContents. Return the |
| 383 // removed navigation handle. Return nullptr if it doesn't exists. |
| 384 content::NavigationHandle* RemovePendingNavigationIfNeeded( |
| 385 content::WebContents* contents); |
| 386 |
| 387 // Check if the tab is loading. Use only in tests. |
| 388 bool IsTabLoadingForTest(content::WebContents* contents) const; |
| 389 |
| 390 // Check if the navigation is delayed. Use only in tests. |
| 391 bool IsNavigationDelayedForTest( |
| 392 const content::NavigationHandle* navigation_handle) const; |
| 393 |
| 342 // Timer to periodically update the stats of the renderers. | 394 // Timer to periodically update the stats of the renderers. |
| 343 base::RepeatingTimer update_timer_; | 395 base::RepeatingTimer update_timer_; |
| 344 | 396 |
| 345 // Timer to periodically report whether a tab has been discarded since the | 397 // Timer to periodically report whether a tab has been discarded since the |
| 346 // last time the timer has fired. | 398 // last time the timer has fired. |
| 347 base::RepeatingTimer recent_tab_discard_timer_; | 399 base::RepeatingTimer recent_tab_discard_timer_; |
| 348 | 400 |
| 349 // A listener to global memory pressure events. | 401 // A listener to global memory pressure events. |
| 350 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; | 402 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; |
| 351 | 403 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 std::vector<BrowserInfo> test_browser_info_list_; | 453 std::vector<BrowserInfo> test_browser_info_list_; |
| 402 | 454 |
| 403 // List of observers that will receive notifications on state changes. | 455 // List of observers that will receive notifications on state changes. |
| 404 base::ObserverList<TabManagerObserver> observers_; | 456 base::ObserverList<TabManagerObserver> observers_; |
| 405 | 457 |
| 406 bool is_session_restore_loading_tabs_; | 458 bool is_session_restore_loading_tabs_; |
| 407 | 459 |
| 408 class TabManagerSessionRestoreObserver; | 460 class TabManagerSessionRestoreObserver; |
| 409 std::unique_ptr<TabManagerSessionRestoreObserver> session_restore_observer_; | 461 std::unique_ptr<TabManagerSessionRestoreObserver> session_restore_observer_; |
| 410 | 462 |
| 463 // The list of navigation handles that are delayed. |
| 464 std::vector<content::NavigationHandle*> pending_navigations_; |
| 465 |
| 466 // The tabs that are currently loading. We will consider loading the next |
| 467 // background tab when these tabs have finished loading or a background tab |
| 468 // is brought to foreground. |
| 469 std::set<content::WebContents*> loading_contents_; |
| 470 |
| 411 // Weak pointer factory used for posting delayed tasks. | 471 // Weak pointer factory used for posting delayed tasks. |
| 412 base::WeakPtrFactory<TabManager> weak_ptr_factory_; | 472 base::WeakPtrFactory<TabManager> weak_ptr_factory_; |
| 413 | 473 |
| 414 DISALLOW_COPY_AND_ASSIGN(TabManager); | 474 DISALLOW_COPY_AND_ASSIGN(TabManager); |
| 415 }; | 475 }; |
| 416 | 476 |
| 417 } // namespace resource_coordinator | 477 } // namespace resource_coordinator |
| 418 | 478 |
| 419 #endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_ | 479 #endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_ |
| OLD | NEW |