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

Side by Side Diff: chrome/browser/android/offline_pages/offline_page_tab_helper.cc

Issue 2166363003: Offline pages using NQE 2G Slow (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tbansal nits (switching to consuming previews component) Created 4 years, 4 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/android/offline_pages/offline_page_tab_helper.h" 5 #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
13 #include "base/time/clock.h"
14 #include "base/time/default_clock.h"
15 #include "base/time/time.h"
13 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" 16 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
14 #include "chrome/browser/android/offline_pages/offline_page_utils.h" 17 #include "chrome/browser/android/offline_pages/offline_page_utils.h"
18 #include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h"
19 #include "chrome/browser/net/nqe/ui_network_quality_estimator_service_factory.h"
20 #include "chrome/browser/profiles/profile.h"
15 #include "components/offline_pages/client_namespace_constants.h" 21 #include "components/offline_pages/client_namespace_constants.h"
16 #include "components/offline_pages/offline_page_model.h" 22 #include "components/offline_pages/offline_page_model.h"
23 #include "components/previews/previews_experiments.h"
17 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/navigation_controller.h" 25 #include "content/public/browser/navigation_controller.h"
19 #include "content/public/browser/navigation_entry.h" 26 #include "content/public/browser/navigation_entry.h"
20 #include "content/public/browser/navigation_handle.h" 27 #include "content/public/browser/navigation_handle.h"
21 #include "content/public/browser/render_frame_host.h" 28 #include "content/public/browser/render_frame_host.h"
22 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
23 #include "net/base/net_errors.h" 30 #include "net/base/net_errors.h"
24 #include "net/base/network_change_notifier.h" 31 #include "net/base/network_change_notifier.h"
32 #include "net/nqe/network_quality_estimator.h"
25 #include "ui/base/page_transition_types.h" 33 #include "ui/base/page_transition_types.h"
26 34
27 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinePageTabHelper); 35 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinePageTabHelper);
28 36
29 namespace offline_pages { 37 namespace offline_pages {
30 namespace { 38 namespace {
31 39
32 void ReportAccessedOfflinePage(content::BrowserContext* browser_context, 40 void ReportAccessedOfflinePage(content::BrowserContext* browser_context,
33 const GURL& navigated_url, 41 const GURL& navigated_url,
34 const GURL& online_url) { 42 const GURL& online_url) {
35 // If there is a valid online URL for this navigated URL, then we are looking 43 // If there is a valid online URL for this navigated URL, then we are looking
36 // at an offline page. 44 // at an offline page.
37 if (online_url.is_valid()) 45 if (online_url.is_valid())
38 OfflinePageUtils::MarkPageAccessed(browser_context, navigated_url); 46 OfflinePageUtils::MarkPageAccessed(browser_context, navigated_url);
39 } 47 }
40 48
49 // Whether using offline pages for slow networks is allowed and the network is
50 // currently estimated to be prohibitivley slow.
51 bool ShouldUseOfflineForSlowNetwork(content::BrowserContext* context) {
52 if (!previews::IsIncludedInOfflinePagesSlowConnectionFieldTrial()) {
tbansal1 2016/07/26 20:12:48 braces not needed :)
RyanSturm 2016/07/26 21:48:12 Done.
53 return false;
54 }
55 Profile* profile = Profile::FromBrowserContext(context);
56 UINetworkQualityEstimatorService* nqe_service =
57 UINetworkQualityEstimatorServiceFactory::GetForProfile(profile);
58 if (!nqe_service)
59 return false;
60 net::NetworkQualityEstimator::EffectiveConnectionType
61 effective_connection_type = nqe_service->GetEffectiveConnectionType();
62 if (effective_connection_type >
tbansal1 2016/07/26 20:12:48 s/>/>=/
RyanSturm 2016/07/26 21:48:12 I'll make the change, but does this differ from NC
63 net::NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_OFFLINE &&
64 effective_connection_type <=
65 net::NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_SLOW_2G) {
66 return true;
67 }
68 return false;
69 }
70
41 class DefaultDelegate : public OfflinePageTabHelper::Delegate { 71 class DefaultDelegate : public OfflinePageTabHelper::Delegate {
42 public: 72 public:
43 DefaultDelegate() {} 73 DefaultDelegate() {}
44 // offline_pages::OfflinePageTabHelper::Delegate implementation: 74 // offline_pages::OfflinePageTabHelper::Delegate implementation:
45 bool GetTabId(content::WebContents* web_contents, 75 bool GetTabId(content::WebContents* web_contents,
46 std::string* tab_id) const override { 76 std::string* tab_id) const override {
47 int temp_tab_id; 77 int temp_tab_id;
48 if (!OfflinePageUtils::GetTabId(web_contents, &temp_tab_id)) 78 if (!OfflinePageUtils::GetTabId(web_contents, &temp_tab_id))
49 return false; 79 return false;
50 *tab_id = base::IntToString(temp_tab_id); 80 *tab_id = base::IntToString(temp_tab_id);
51 return true; 81 return true;
52 } 82 }
53 }; 83 };
54 } // namespace 84 } // namespace
55 85
56 OfflinePageTabHelper::OfflinePageTabHelper(content::WebContents* web_contents) 86 OfflinePageTabHelper::OfflinePageTabHelper(content::WebContents* web_contents)
57 : content::WebContentsObserver(web_contents), 87 : content::WebContentsObserver(web_contents),
58 delegate_(new DefaultDelegate()), 88 delegate_(new DefaultDelegate()),
89 clock_(new base::DefaultClock),
59 weak_ptr_factory_(this) { 90 weak_ptr_factory_(this) {
60 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 91 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
61 } 92 }
62 93
63 OfflinePageTabHelper::~OfflinePageTabHelper() {} 94 OfflinePageTabHelper::~OfflinePageTabHelper() {}
64 95
65 void OfflinePageTabHelper::SetDelegateForTesting( 96 void OfflinePageTabHelper::SetDelegateForTesting(
66 std::unique_ptr<OfflinePageTabHelper::Delegate> delegate) { 97 std::unique_ptr<OfflinePageTabHelper::Delegate> delegate) {
67 DCHECK(delegate); 98 DCHECK(delegate);
68 delegate_ = std::move(delegate); 99 delegate_ = std::move(delegate);
(...skipping 19 matching lines...) Expand all
88 // which are not at the head of the stack. 119 // which are not at the head of the stack.
89 // TODO(dimich): Not sure this is needed. Clarify and remove. Bug 624216. 120 // TODO(dimich): Not sure this is needed. Clarify and remove. Bug 624216.
90 const content::NavigationController& controller = 121 const content::NavigationController& controller =
91 web_contents()->GetController(); 122 web_contents()->GetController();
92 if (controller.GetEntryCount() > 0 && 123 if (controller.GetEntryCount() > 0 &&
93 controller.GetCurrentEntryIndex() != -1 && 124 controller.GetCurrentEntryIndex() != -1 &&
94 controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) { 125 controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) {
95 return; 126 return;
96 } 127 }
97 128
98 content::BrowserContext* context = web_contents()->GetBrowserContext();
99 if (net::NetworkChangeNotifier::IsOffline()) { 129 if (net::NetworkChangeNotifier::IsOffline()) {
100 GetPagesForRedirectToOffline( 130 GetPagesForRedirectToOffline(
101 RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK, navigated_url); 131 RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK, navigated_url);
102 return; 132 return;
103 } 133 }
104 134
135 content::BrowserContext* context = web_contents()->GetBrowserContext();
136 if (ShouldUseOfflineForSlowNetwork(context)) {
137 GetPagesForRedirectToOffline(
138 RedirectResult::REDIRECTED_ON_PROHIBITVELY_SLOW_NETWORK, navigated_url);
139 return;
140 }
141
105 OfflinePageModel* offline_page_model = 142 OfflinePageModel* offline_page_model =
106 OfflinePageModelFactory::GetForBrowserContext(context); 143 OfflinePageModelFactory::GetForBrowserContext(context);
107 if (!offline_page_model) 144 if (!offline_page_model)
108 return; 145 return;
109 146
110 offline_page_model->GetPageByOfflineURL( 147 offline_page_model->GetPageByOfflineURL(
111 navigated_url, base::Bind(&OfflinePageTabHelper::RedirectToOnline, 148 navigated_url, base::Bind(&OfflinePageTabHelper::RedirectToOnline,
112 weak_ptr_factory_.GetWeakPtr(), navigated_url)); 149 weak_ptr_factory_.GetWeakPtr(), navigated_url));
113 } 150 }
114 151
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 online_url, 229 online_url,
193 base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline, 230 base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline,
194 weak_ptr_factory_.GetWeakPtr(), result, online_url)); 231 weak_ptr_factory_.GetWeakPtr(), result, online_url));
195 } 232 }
196 233
197 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( 234 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline(
198 RedirectResult result, 235 RedirectResult result,
199 const GURL& online_url, 236 const GURL& online_url,
200 const MultipleOfflinePageItemResult& pages) { 237 const MultipleOfflinePageItemResult& pages) {
201 DCHECK(result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK || 238 DCHECK(result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK ||
202 result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK); 239 result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK ||
240 result == RedirectResult::REDIRECTED_ON_PROHIBITVELY_SLOW_NETWORK);
203 241
204 // When there is no valid tab android there is nowhere to show the offline 242 // When there is no valid tab android there is nowhere to show the offline
205 // page, so we can leave. 243 // page, so we can leave.
206 std::string tab_id; 244 std::string tab_id;
207 if (!delegate_->GetTabId(web_contents(), &tab_id)) { 245 if (!delegate_->GetTabId(web_contents(), &tab_id)) {
208 ReportRedirectResultUMA(RedirectResult::NO_TAB_ID); 246 ReportRedirectResultUMA(RedirectResult::NO_TAB_ID);
209 return; 247 return;
210 } 248 }
211 249
212 const OfflinePageItem* selected_page = nullptr; 250 const OfflinePageItem* selected_page = nullptr;
213 for (const auto& offline_page : pages) { 251 for (const auto& offline_page : pages) {
214 if ((offline_page.client_id.name_space == kBookmarkNamespace) || 252 if ((offline_page.client_id.name_space == kBookmarkNamespace) ||
215 (offline_page.client_id.name_space == kAsyncNamespace) || 253 (offline_page.client_id.name_space == kAsyncNamespace) ||
216 (offline_page.client_id.name_space == kLastNNamespace && 254 (offline_page.client_id.name_space == kLastNNamespace &&
217 offline_page.client_id.id == tab_id)) { 255 offline_page.client_id.id == tab_id)) {
218 if (!selected_page || 256 if (!selected_page ||
219 offline_page.creation_time > selected_page->creation_time) { 257 offline_page.creation_time > selected_page->creation_time) {
220 selected_page = &offline_page; 258 selected_page = &offline_page;
221 } 259 }
222 } 260 }
223 } 261 }
224 262
225 if (!selected_page) { 263 if (!selected_page) {
264 switch (result) {
265 case RedirectResult::REDIRECTED_ON_FLAKY_NETWORK:
266 ReportRedirectResultUMA(
267 RedirectResult::PAGE_NOT_FOUND_ON_FLAKY_NETWORK);
268 return;
269 case RedirectResult::REDIRECTED_ON_PROHIBITVELY_SLOW_NETWORK:
270 ReportRedirectResultUMA(
271 RedirectResult::PAGE_NOT_FOUND_ON_PROHIBITVELY_SLOW_NETWORK);
272 return;
273 case RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK:
274 ReportRedirectResultUMA(
275 RedirectResult::PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK);
276 return;
277 default:
278 NOTREACHED();
279 return;
280 }
281 }
282
283 // If the page is being loaded on a slow network, only use the offline page
284 // if it was created within the past day.
285 if (result == RedirectResult::REDIRECTED_ON_PROHIBITVELY_SLOW_NETWORK &&
286 clock_->Now() - selected_page->creation_time >
287 base::TimeDelta::FromDays(1)) {
tbansal1 2016/07/26 20:12:48 Where else is this being "freshness test" done? W
RyanSturm 2016/07/26 21:48:12 We are using 1 day for freshness based on differen
tbansal1 2016/07/26 21:52:43 Acknowledged.
226 ReportRedirectResultUMA( 288 ReportRedirectResultUMA(
227 result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK ? 289 RedirectResult::PAGE_NOT_FRESH_ON_PROHIBITVELY_SLOW_NETWORK);
228 RedirectResult::PAGE_NOT_FOUND_ON_FLAKY_NETWORK :
229 RedirectResult::PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK);
230 return; 290 return;
231 } 291 }
232 292
233 TryRedirectToOffline(result, online_url, *selected_page); 293 TryRedirectToOffline(result, online_url, *selected_page);
234 } 294 }
235 295
236 void OfflinePageTabHelper::TryRedirectToOffline( 296 void OfflinePageTabHelper::TryRedirectToOffline(
237 RedirectResult result, 297 RedirectResult result,
238 const GURL& from_url, 298 const GURL& from_url,
239 const OfflinePageItem& offline_page) { 299 const OfflinePageItem& offline_page) {
(...skipping 26 matching lines...) Expand all
266 return entry && 326 return entry &&
267 !entry->GetRedirectChain().empty() && 327 !entry->GetRedirectChain().empty() &&
268 entry->GetRedirectChain().back() == to_url; 328 entry->GetRedirectChain().back() == to_url;
269 } 329 }
270 330
271 void OfflinePageTabHelper::ReportRedirectResultUMA(RedirectResult result) { 331 void OfflinePageTabHelper::ReportRedirectResultUMA(RedirectResult result) {
272 UMA_HISTOGRAM_ENUMERATION("OfflinePages.RedirectResult", 332 UMA_HISTOGRAM_ENUMERATION("OfflinePages.RedirectResult",
273 static_cast<int>(result), 333 static_cast<int>(result),
274 static_cast<int>(RedirectResult::REDIRECT_RESULT_MAX)); 334 static_cast<int>(RedirectResult::REDIRECT_RESULT_MAX));
275 } 335 }
336
337 void OfflinePageTabHelper::SetClockForTesting(
338 std::unique_ptr<base::Clock> clock) {
339 clock_ = std::move(clock);
340 }
341
276 } // namespace offline_pages 342 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698