| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/sessions/tab_loader_delegate.h" |
| |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "chrome/browser/resource_coordinator/session_restore_policy.h" |
| #include "chrome/browser/resource_coordinator/tab_manager_features.h" |
| #include "chrome/browser/sessions/session_restore_observer.h" |
| #include "components/variations/variations_associated_data.h" |
| #include "content/public/browser/network_service_instance.h" |
| #include "services/network/public/cpp/network_connection_tracker.h" |
| |
| namespace { |
| |
| // The timeout time after which the next tab gets loaded if the previous tab did |
| // not finish loading yet. The used value is half of the median value of all |
| // ChromeOS devices loading the 25 most common web pages. Half is chosen since |
| // the loading time is a mix of server response and data bandwidth. |
| static const int kInitialDelayTimerMS = 1500; |
| |
| // Similar to the above constant, but the timeout that is afforded to the |
| // visible tab only. Having this be a longer value ensures the visible time has |
| // more time during which it is the only one loading, decreasing the time to |
| // first paint and interactivity of the foreground tab. |
| static const int kFirstTabLoadTimeoutMS = 60000; |
| |
| class TabLoaderDelegateImpl |
| : public TabLoaderDelegate, |
| public network::NetworkConnectionTracker::NetworkConnectionObserver { |
| public: |
| explicit TabLoaderDelegateImpl(TabLoaderCallback* callback); |
| ~TabLoaderDelegateImpl() override; |
| |
| // TabLoaderDelegate: |
| base::TimeDelta GetFirstTabLoadingTimeout() const override { |
| return resource_coordinator::GetTabLoadTimeout(first_timeout_); |
| } |
| |
| // TabLoaderDelegate: |
| base::TimeDelta GetTimeoutBeforeLoadingNextTab() const override { |
| return resource_coordinator::GetTabLoadTimeout(timeout_); |
| } |
| |
| // TabLoaderDelegate: |
| size_t GetMaxSimultaneousTabLoads() const override { |
| return policy_.simultaneous_tab_loads(); |
| } |
| |
| // TabLoaderDelegate: |
| bool ShouldLoad(content::WebContents* contents) const override { |
| return policy_.ShouldLoad(contents); |
| } |
| |
| // TabLoaderDelegate: |
| void NotifyTabLoadStarted() override { policy_.NotifyTabLoadStarted(); } |
| |
| // network::NetworkConnectionTracker::NetworkConnectionObserver: |
| void OnConnectionChanged(network::mojom::ConnectionType type) override; |
| |
| private: |
| // The policy engine used to implement ShouldLoad. |
| resource_coordinator::SessionRestorePolicy policy_; |
| |
| // The function to call when the connection type changes. |
| TabLoaderCallback* callback_; |
| |
| // The timeouts to use in tab loading. |
| base::TimeDelta first_timeout_; |
| base::TimeDelta timeout_; |
| |
| base::WeakPtrFactory<TabLoaderDelegateImpl> weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TabLoaderDelegateImpl); |
| }; |
| |
| TabLoaderDelegateImpl::TabLoaderDelegateImpl(TabLoaderCallback* callback) |
| : callback_(callback), weak_factory_(this) { |
| content::GetNetworkConnectionTracker()->AddNetworkConnectionObserver(this); |
| auto type = network::mojom::ConnectionType::CONNECTION_UNKNOWN; |
| content::GetNetworkConnectionTracker()->GetConnectionType( |
| &type, base::BindOnce(&TabLoaderDelegateImpl::OnConnectionChanged, |
| weak_factory_.GetWeakPtr())); |
| if (type == network::mojom::ConnectionType::CONNECTION_NONE) { |
| // When we are off-line we do not allow loading of tabs, since each of |
| // these tabs would start loading simultaneously when going online. |
| // TODO(skuhne): Once we get a higher level resource control logic which |
| // distributes network access, we can remove this. |
| callback->SetTabLoadingEnabled(false); |
| } |
| |
| first_timeout_ = base::TimeDelta::FromMilliseconds(kFirstTabLoadTimeoutMS); |
| timeout_ = base::TimeDelta::FromMilliseconds(kInitialDelayTimerMS); |
| } |
| |
| TabLoaderDelegateImpl::~TabLoaderDelegateImpl() { |
| content::GetNetworkConnectionTracker()->RemoveNetworkConnectionObserver(this); |
| } |
| |
| void TabLoaderDelegateImpl::OnConnectionChanged( |
| network::mojom::ConnectionType type) { |
| callback_->SetTabLoadingEnabled( |
| type != network::mojom::ConnectionType::CONNECTION_NONE); |
| } |
| |
| } // namespace |
| |
| // static |
| std::unique_ptr<TabLoaderDelegate> TabLoaderDelegate::Create( |
| TabLoaderCallback* callback) { |
| return std::unique_ptr<TabLoaderDelegate>( |
| new TabLoaderDelegateImpl(callback)); |
| } |