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

Unified Diff: chrome/browser/resource_coordinator/tab_manager.cc

Issue 2931023002: [TooManyTabs] Add TabNavigationThrottle (Closed)
Patch Set: add comments 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resource_coordinator/tab_manager.cc
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc
index 9db21d6569932f5287a3937a778a60f2b2db8b68..7e3f0c7d721f6642c49c364490b377594402ade6 100644
--- a/chrome/browser/resource_coordinator/tab_manager.cc
+++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/memory/memory_pressure_monitor.h"
#include "base/metrics/field_trial.h"
@@ -42,12 +41,12 @@
#include "chrome/browser/ui/tabs/tab_utils.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "components/metrics/system_memory_stats_recorder.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
@@ -841,6 +840,8 @@ void TabManager::ActiveTabChanged(content::WebContents* old_contents,
ReloadWebContentsIfDiscarded(new_contents,
GetWebContentsData(new_contents));
}
+
+ ResumeTabNavigationIfNeeded(new_contents);
}
void TabManager::TabInsertedAt(TabStripModel* tab_strip_model,
@@ -976,4 +977,121 @@ void TabManager::RecordSwitchToTab(content::WebContents* contents) const {
}
}
+content::NavigationThrottle::ThrottleCheckResult
+TabManager::MaybeThrottleNavigation(
+ content::NavigationHandle* navigation_handle) {
+ if (!ShouldDelayNavigation(navigation_handle)) {
+ loading_contents_.insert(navigation_handle->GetWebContents());
+ return content::NavigationThrottle::PROCEED;
+ }
+
+ // TODO(zhenw): Try to set the favicon and title from history service if this
+ // navigation will be delayed.
+ GetWebContentsData(navigation_handle->GetWebContents())
+ ->SetTabLoadingState(TAB_IS_NOT_LOADING);
+ pending_navigations_.push_back(navigation_handle);
+
+ return content::NavigationThrottle::DEFER;
+}
+
+bool TabManager::ShouldDelayNavigation(
+ content::NavigationHandle* navigation_handle) const {
+ // Do not delay the navigation if no tab is currently loading.
+ if (loading_contents_.empty())
+ return false;
+
+ return true;
+}
+
+void TabManager::OnDidFinishNavigation(
+ content::NavigationHandle* navigation_handle) {
+ auto it = pending_navigations_.begin();
+ while (it != pending_navigations_.end()) {
+ content::NavigationHandle* pending_handle = *it;
+ if (pending_handle == navigation_handle) {
+ pending_navigations_.erase(it);
+ break;
+ }
+ it++;
+ }
+}
+
+void TabManager::OnDidStopLoading(content::WebContents* contents) {
+ DCHECK_EQ(TAB_IS_LOADED, GetWebContentsData(contents)->tab_loading_state());
+ loading_contents_.erase(contents);
+ LoadNextBackgroundTabIfNeeded();
+}
+
+void TabManager::OnWebContentsDestroyed(content::WebContents* contents) {
+ RemovePendingNavigationIfNeeded(contents);
+ loading_contents_.erase(contents);
+ LoadNextBackgroundTabIfNeeded();
+}
+
+void TabManager::LoadNextBackgroundTabIfNeeded() {
+ // Do not load more background tabs until all currently loading tabs have
+ // finished.
+ if (!loading_contents_.empty())
+ return;
+
+ if (pending_navigations_.empty())
+ return;
+
+ content::NavigationHandle* navigation_handle = pending_navigations_.front();
+ pending_navigations_.erase(pending_navigations_.begin());
+ ResumeNavigation(navigation_handle);
+}
+
+void TabManager::ResumeTabNavigationIfNeeded(content::WebContents* contents) {
+ content::NavigationHandle* navigation_handle =
+ RemovePendingNavigationIfNeeded(contents);
+ if (navigation_handle)
+ ResumeNavigation(navigation_handle);
+}
+
+void TabManager::ResumeNavigation(
+ content::NavigationHandle* navigation_handle) {
+ GetWebContentsData(navigation_handle->GetWebContents())
+ ->SetTabLoadingState(TAB_IS_LOADING);
+ loading_contents_.insert(navigation_handle->GetWebContents());
+
+ navigation_handle->Resume();
+}
+
+content::NavigationHandle* TabManager::RemovePendingNavigationIfNeeded(
+ content::WebContents* contents) {
+ content::NavigationHandle* navigation_handle = nullptr;
+ auto it = pending_navigations_.begin();
+ while (it != pending_navigations_.end()) {
+ navigation_handle = *it;
+ if ((*it)->GetWebContents() == contents) {
+ navigation_handle = *it;
+ pending_navigations_.erase(it);
+ break;
+ }
+ it++;
+ }
+ return navigation_handle;
+}
+
+bool TabManager::IsTabLoadingForTest(content::WebContents* contents) const {
+ if (loading_contents_.count(contents) == 1) {
+ DCHECK_EQ(TAB_IS_LOADING,
+ GetWebContentsData(contents)->tab_loading_state());
+ return true;
+ }
+
+ DCHECK_NE(TAB_IS_LOADING, GetWebContentsData(contents)->tab_loading_state());
+ return false;
+}
+
+bool TabManager::IsNavigationDelayedForTest(
+ const content::NavigationHandle* navigation_handle) const {
+ for (const auto* nav : pending_navigations_) {
+ if (nav == navigation_handle)
+ return true;
+ }
+ return false;
+}
+
} // namespace resource_coordinator
« no previous file with comments | « chrome/browser/resource_coordinator/tab_manager.h ('k') | chrome/browser/resource_coordinator/tab_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698