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

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

Issue 2931023002: [TooManyTabs] Add TabNavigationThrottle (Closed)
Patch Set: add more tests Created 3 years, 5 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 #include "chrome/browser/resource_coordinator/tab_manager.h" 5 #include "chrome/browser/resource_coordinator/tab_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <set> 10 #include <set>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/command_line.h"
15 #include "base/feature_list.h" 14 #include "base/feature_list.h"
16 #include "base/memory/memory_pressure_monitor.h" 15 #include "base/memory/memory_pressure_monitor.h"
17 #include "base/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
18 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
19 #include "base/observer_list.h" 18 #include "base/observer_list.h"
20 #include "base/process/process.h" 19 #include "base/process/process.h"
21 #include "base/rand_util.h" 20 #include "base/rand_util.h"
22 #include "base/strings/string16.h" 21 #include "base/strings/string16.h"
23 #include "base/strings/string_number_conversions.h" 22 #include "base/strings/string_number_conversions.h"
24 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
(...skipping 10 matching lines...) Expand all
35 #include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h" 34 #include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h"
36 #include "chrome/browser/sessions/session_restore.h" 35 #include "chrome/browser/sessions/session_restore.h"
37 #include "chrome/browser/ui/browser.h" 36 #include "chrome/browser/ui/browser.h"
38 #include "chrome/browser/ui/browser_list.h" 37 #include "chrome/browser/ui/browser_list.h"
39 #include "chrome/browser/ui/browser_window.h" 38 #include "chrome/browser/ui/browser_window.h"
40 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 39 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
41 #include "chrome/browser/ui/tabs/tab_strip_model.h" 40 #include "chrome/browser/ui/tabs/tab_strip_model.h"
42 #include "chrome/browser/ui/tabs/tab_utils.h" 41 #include "chrome/browser/ui/tabs/tab_utils.h"
43 #include "chrome/common/chrome_constants.h" 42 #include "chrome/common/chrome_constants.h"
44 #include "chrome/common/chrome_features.h" 43 #include "chrome/common/chrome_features.h"
45 #include "chrome/common/chrome_switches.h"
46 #include "chrome/common/url_constants.h" 44 #include "chrome/common/url_constants.h"
47 #include "components/metrics/system_memory_stats_recorder.h" 45 #include "components/metrics/system_memory_stats_recorder.h"
48 #include "components/variations/variations_associated_data.h" 46 #include "components/variations/variations_associated_data.h"
49 #include "content/public/browser/browser_thread.h" 47 #include "content/public/browser/browser_thread.h"
50 #include "content/public/browser/navigation_controller.h" 48 #include "content/public/browser/navigation_controller.h"
49 #include "content/public/browser/navigation_handle.h"
51 #include "content/public/browser/render_process_host.h" 50 #include "content/public/browser/render_process_host.h"
52 #include "content/public/browser/web_contents.h" 51 #include "content/public/browser/web_contents.h"
53 #include "content/public/common/content_features.h" 52 #include "content/public/common/content_features.h"
54 #include "content/public/common/page_importance_signals.h" 53 #include "content/public/common/page_importance_signals.h"
55 54
56 #if defined(OS_CHROMEOS) 55 #if defined(OS_CHROMEOS)
57 #include "ash/multi_profile_uma.h" 56 #include "ash/multi_profile_uma.h"
58 #include "ash/shell.h" 57 #include "ash/shell.h"
59 #include "chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h" 58 #include "chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h"
60 #include "components/user_manager/user_manager.h" 59 #include "components/user_manager/user_manager.h"
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 } 833 }
835 834
836 // An active tab is not purged. 835 // An active tab is not purged.
837 GetWebContentsData(new_contents)->set_is_purged(false); 836 GetWebContentsData(new_contents)->set_is_purged(false);
838 837
839 // Reload |web_contents| if it is in an active browser and discarded. 838 // Reload |web_contents| if it is in an active browser and discarded.
840 if (IsActiveWebContentsInActiveBrowser(new_contents)) { 839 if (IsActiveWebContentsInActiveBrowser(new_contents)) {
841 ReloadWebContentsIfDiscarded(new_contents, 840 ReloadWebContentsIfDiscarded(new_contents,
842 GetWebContentsData(new_contents)); 841 GetWebContentsData(new_contents));
843 } 842 }
843
844 ResumeTabNavigationIfNeeded(new_contents);
844 } 845 }
845 846
846 void TabManager::TabInsertedAt(TabStripModel* tab_strip_model, 847 void TabManager::TabInsertedAt(TabStripModel* tab_strip_model,
847 content::WebContents* contents, 848 content::WebContents* contents,
848 int index, 849 int index,
849 bool foreground) { 850 bool foreground) {
850 // Only interested in background tabs, as foreground tabs get taken care of by 851 // Only interested in background tabs, as foreground tabs get taken care of by
851 // ActiveTabChanged. 852 // ActiveTabChanged.
852 if (foreground) 853 if (foreground)
853 return; 854 return;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 } 970 }
970 971
971 void TabManager::RecordSwitchToTab(content::WebContents* contents) const { 972 void TabManager::RecordSwitchToTab(content::WebContents* contents) const {
972 if (is_session_restore_loading_tabs_) { 973 if (is_session_restore_loading_tabs_) {
973 UMA_HISTOGRAM_ENUMERATION("TabManager.SessionRestore.SwitchToTab", 974 UMA_HISTOGRAM_ENUMERATION("TabManager.SessionRestore.SwitchToTab",
974 GetWebContentsData(contents)->tab_loading_state(), 975 GetWebContentsData(contents)->tab_loading_state(),
975 TAB_LOADING_STATE_MAX); 976 TAB_LOADING_STATE_MAX);
976 } 977 }
977 } 978 }
978 979
980 content::NavigationThrottle::ThrottleCheckResult
981 TabManager::MaybeThrottleNavigation(
982 content::NavigationHandle* navigation_handle) {
983 if (!ShouldDelayNavigation(navigation_handle)) {
984 loading_contents_.insert(navigation_handle->GetWebContents());
985 return content::NavigationThrottle::PROCEED;
986 }
987
988 // TODO(zhenw): Try to set the favicon and title from history service if this
989 // navigation will be delayed.
990 GetWebContentsData(navigation_handle->GetWebContents())
991 ->SetTabLoadingState(TAB_IS_NOT_LOADING);
992 pending_navigations_.push_back(navigation_handle);
993
994 return content::NavigationThrottle::DEFER;
995 }
996
997 bool TabManager::ShouldDelayNavigation(
998 content::NavigationHandle* navigation_handle) const {
999 if (!navigation_handle)
1000 return false;
1001
1002 // Do not delay the navigation if no tab is currently loading.
1003 if (loading_contents_.empty()) {
1004 return false;
1005 }
1006
1007 return true;
1008 }
1009
1010 void TabManager::OnNavigationDone(
1011 content::NavigationHandle* navigation_handle) {
1012 auto it = pending_navigations_.begin();
1013 while (it != pending_navigations_.end()) {
1014 content::NavigationHandle* pending_handle = *it;
1015 if (pending_handle == navigation_handle) {
1016 pending_navigations_.erase(it);
1017 break;
1018 }
1019 it++;
1020 }
1021 }
1022
1023 void TabManager::OnLoadingDone(content::WebContents* contents) {
1024 DCHECK(GetWebContentsData(contents)->tab_loading_state() == TAB_IS_LOADED);
Charlie Reis 2017/07/06 23:50:30 nit: Does DCHECK_EQ work here? That would give a
Zhen Wang 2017/07/07 18:06:39 Done.
1025 loading_contents_.erase(contents);
1026 LoadNextBackgroundTabIfNeeded();
1027 }
1028
1029 void TabManager::OnWebContentsDestroyed(content::WebContents* contents) {
1030 RemovePendingNavigationIfNeeded(contents);
1031 loading_contents_.erase(contents);
1032 LoadNextBackgroundTabIfNeeded();
1033 }
1034
1035 void TabManager::LoadNextBackgroundTabIfNeeded() {
1036 // Do not load more background tabs until all currently loading tabs have
1037 // finished.
1038 if (!loading_contents_.empty())
1039 return;
1040
1041 if (pending_navigations_.empty())
1042 return;
1043
1044 content::NavigationHandle* navigation_handle = pending_navigations_.front();
1045 pending_navigations_.erase(pending_navigations_.begin());
1046 ResumeNavigation(navigation_handle);
1047 }
1048
1049 void TabManager::ResumeTabNavigationIfNeeded(content::WebContents* contents) {
1050 content::NavigationHandle* navigation_handle =
1051 RemovePendingNavigationIfNeeded(contents);
1052 if (navigation_handle)
1053 ResumeNavigation(navigation_handle);
1054 }
1055
1056 void TabManager::ResumeNavigation(
1057 content::NavigationHandle* navigation_handle) {
1058 GetWebContentsData(navigation_handle->GetWebContents())
1059 ->SetTabLoadingState(TAB_IS_LOADING);
1060 loading_contents_.insert(navigation_handle->GetWebContents());
1061
1062 navigation_handle->Resume();
1063 }
1064
1065 content::NavigationHandle* TabManager::RemovePendingNavigationIfNeeded(
1066 content::WebContents* contents) {
1067 content::NavigationHandle* navigation_handle = nullptr;
1068 auto it = pending_navigations_.begin();
1069 while (it != pending_navigations_.end()) {
1070 navigation_handle = *it;
1071 if ((*it)->GetWebContents() == contents) {
1072 navigation_handle = *it;
1073 pending_navigations_.erase(it);
1074 break;
1075 }
1076 it++;
1077 }
1078 return navigation_handle;
1079 }
1080
1081 bool TabManager::IsTabLoadingForTest(content::WebContents* contents) const {
1082 if (loading_contents_.count(contents) == 1) {
1083 DCHECK(GetWebContentsData(contents)->tab_loading_state() == TAB_IS_LOADING);
1084 return true;
1085 }
1086
1087 DCHECK(GetWebContentsData(contents)->tab_loading_state() != TAB_IS_LOADING);
1088 return false;
1089 }
1090
1091 bool TabManager::IsNavigationDelayedForTest(
1092 const content::NavigationHandle* navigation_handle) const {
1093 for (const auto* nav : pending_navigations_) {
1094 if (nav == navigation_handle)
1095 return true;
1096 }
1097 return false;
1098 }
1099
979 } // namespace resource_coordinator 1100 } // namespace resource_coordinator
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698