Chromium Code Reviews| Index: chrome/browser/android/offline_pages/offline_page_tab_helper.cc |
| diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc |
| index b56b7d1c9b1900edebc3161908adc05a9fe83519..73193a16cb5b49e276f70684f76030bcf003de45 100644 |
| --- a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc |
| +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc |
| @@ -3,60 +3,88 @@ |
| // found in the LICENSE file. |
| #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h" |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/metrics/histogram.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| +#include "base/time/time.h" |
| #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" |
| #include "chrome/browser/android/offline_pages/offline_page_utils.h" |
| +#include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h" |
| +#include "chrome/browser/net/nqe/ui_network_quality_estimator_service_factory.h" |
| +#include "chrome/browser/profiles/profile.h" |
| #include "components/offline_pages/client_namespace_constants.h" |
| #include "components/offline_pages/offline_page_model.h" |
| +#include "components/previews/previews_experiments.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/navigation_controller.h" |
| #include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/navigation_handle.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/network_change_notifier.h" |
| +#include "net/nqe/network_quality_estimator.h" |
| #include "ui/base/page_transition_types.h" |
| DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinePageTabHelper); |
| namespace offline_pages { |
| namespace { |
| void ReportAccessedOfflinePage(content::BrowserContext* browser_context, |
| const GURL& navigated_url, |
| const GURL& online_url) { |
| // If there is a valid online URL for this navigated URL, then we are looking |
| // at an offline page. |
| if (online_url.is_valid()) |
| OfflinePageUtils::MarkPageAccessed(browser_context, navigated_url); |
| } |
| +// Whether using offline pages for slow networks is allowed and the network is |
| +// currently estimated to be prohibitively slow. |
| +bool ShouldUseOfflineForSlowNetwork(content::BrowserContext* context) { |
| + if (!previews::IsOfflinePreviewsEnabled()) |
| + return false; |
| + Profile* profile = Profile::FromBrowserContext(context); |
| + UINetworkQualityEstimatorService* nqe_service = |
| + UINetworkQualityEstimatorServiceFactory::GetForProfile(profile); |
| + if (!nqe_service) |
| + return false; |
| + net::NetworkQualityEstimator::EffectiveConnectionType |
| + effective_connection_type = nqe_service->GetEffectiveConnectionType(); |
| + if (effective_connection_type >= |
|
Lei Zhang
2016/07/28 20:41:52
if (comparision_evals_to_bool)
return true;
retu
RyanSturm
2016/07/28 22:07:18
Done.
|
| + net::NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_OFFLINE && |
| + effective_connection_type <= |
| + net::NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_SLOW_2G) { |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| class DefaultDelegate : public OfflinePageTabHelper::Delegate { |
| public: |
| DefaultDelegate() {} |
| // offline_pages::OfflinePageTabHelper::Delegate implementation: |
| bool GetTabId(content::WebContents* web_contents, |
| std::string* tab_id) const override { |
| int temp_tab_id; |
| if (!OfflinePageUtils::GetTabId(web_contents, &temp_tab_id)) |
| return false; |
| *tab_id = base::IntToString(temp_tab_id); |
| return true; |
| } |
| + base::Time Now() const override { return base::Time::Now(); } |
| }; |
| } // namespace |
| OfflinePageTabHelper::OfflinePageTabHelper(content::WebContents* web_contents) |
| : content::WebContentsObserver(web_contents), |
| delegate_(new DefaultDelegate()), |
| weak_ptr_factory_(this) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| } |
| @@ -88,27 +116,34 @@ void OfflinePageTabHelper::DidStartNavigation( |
| // which are not at the head of the stack. |
| // TODO(dimich): Not sure this is needed. Clarify and remove. Bug 624216. |
| const content::NavigationController& controller = |
| web_contents()->GetController(); |
| if (controller.GetEntryCount() > 0 && |
| controller.GetCurrentEntryIndex() != -1 && |
| controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) { |
| return; |
| } |
| - content::BrowserContext* context = web_contents()->GetBrowserContext(); |
| if (net::NetworkChangeNotifier::IsOffline()) { |
| GetPagesForRedirectToOffline( |
| RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK, navigated_url); |
| return; |
| } |
| + content::BrowserContext* context = web_contents()->GetBrowserContext(); |
| + if (ShouldUseOfflineForSlowNetwork(context)) { |
| + GetPagesForRedirectToOffline( |
| + RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK, |
| + navigated_url); |
| + return; |
| + } |
| + |
| OfflinePageModel* offline_page_model = |
| OfflinePageModelFactory::GetForBrowserContext(context); |
| if (!offline_page_model) |
| return; |
| offline_page_model->GetPageByOfflineURL( |
| navigated_url, base::Bind(&OfflinePageTabHelper::RedirectToOnline, |
| weak_ptr_factory_.GetWeakPtr(), navigated_url)); |
| } |
| @@ -192,21 +227,22 @@ void OfflinePageTabHelper::GetPagesForRedirectToOffline( |
| online_url, |
| base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline, |
| weak_ptr_factory_.GetWeakPtr(), result, online_url)); |
| } |
| void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( |
| RedirectResult result, |
| const GURL& online_url, |
| const MultipleOfflinePageItemResult& pages) { |
| DCHECK(result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK || |
| - result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK); |
| + result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK || |
| + result == RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK); |
| // When there is no valid tab android there is nowhere to show the offline |
| // page, so we can leave. |
| std::string tab_id; |
| if (!delegate_->GetTabId(web_contents(), &tab_id)) { |
| ReportRedirectResultUMA(RedirectResult::NO_TAB_ID); |
| return; |
| } |
| const OfflinePageItem* selected_page = nullptr; |
| @@ -216,24 +252,46 @@ void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( |
| (offline_page.client_id.name_space == kLastNNamespace && |
| offline_page.client_id.id == tab_id)) { |
| if (!selected_page || |
| offline_page.creation_time > selected_page->creation_time) { |
| selected_page = &offline_page; |
| } |
| } |
| } |
| if (!selected_page) { |
| + switch (result) { |
| + case RedirectResult::REDIRECTED_ON_FLAKY_NETWORK: |
| + ReportRedirectResultUMA( |
| + RedirectResult::PAGE_NOT_FOUND_ON_FLAKY_NETWORK); |
| + return; |
| + case RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK: |
| + ReportRedirectResultUMA( |
| + RedirectResult::PAGE_NOT_FOUND_ON_PROHIBITIVELY_SLOW_NETWORK); |
| + return; |
| + case RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK: |
| + ReportRedirectResultUMA( |
| + RedirectResult::PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK); |
| + return; |
| + default: |
| + NOTREACHED(); |
| + return; |
| + } |
| + } |
| + |
| + // If the page is being loaded on a slow network, only use the offline page |
| + // if it was created within the past day. |
| + if (result == RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK && |
| + delegate_->Now() - selected_page->creation_time > |
| + base::TimeDelta::FromDays(1)) { |
| ReportRedirectResultUMA( |
| - result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK ? |
| - RedirectResult::PAGE_NOT_FOUND_ON_FLAKY_NETWORK : |
| - RedirectResult::PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK); |
| + RedirectResult::PAGE_NOT_FRESH_ON_PROHIBITIVELY_SLOW_NETWORK); |
| return; |
| } |
| TryRedirectToOffline(result, online_url, *selected_page); |
| } |
| void OfflinePageTabHelper::TryRedirectToOffline( |
| RedirectResult result, |
| const GURL& from_url, |
| const OfflinePageItem& offline_page) { |
| @@ -266,11 +324,12 @@ bool OfflinePageTabHelper::IsInRedirectLoop(const GURL& to_url) const { |
| return entry && |
| !entry->GetRedirectChain().empty() && |
| entry->GetRedirectChain().back() == to_url; |
| } |
| void OfflinePageTabHelper::ReportRedirectResultUMA(RedirectResult result) { |
| UMA_HISTOGRAM_ENUMERATION("OfflinePages.RedirectResult", |
| static_cast<int>(result), |
| static_cast<int>(RedirectResult::REDIRECT_RESULT_MAX)); |
| } |
| + |
| } // namespace offline_pages |