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

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

Issue 2105173002: Add enum-based UMA reporting to automatic redirect logic of Offline Pages. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 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"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 weak_ptr_factory_.InvalidateWeakPtrs(); 79 weak_ptr_factory_.InvalidateWeakPtrs();
80 80
81 // Since this is a new navigation, we will reset the cached offline page, 81 // Since this is a new navigation, we will reset the cached offline page,
82 // unless we are currently looking at an offline page. 82 // unless we are currently looking at an offline page.
83 GURL navigated_url = navigation_handle->GetURL(); 83 GURL navigated_url = navigation_handle->GetURL();
84 if (offline_page_ && navigated_url != offline_page_->GetOfflineURL()) 84 if (offline_page_ && navigated_url != offline_page_->GetOfflineURL())
85 offline_page_ = nullptr; 85 offline_page_ = nullptr;
86 86
87 // Ignore navigations that are forward or back transitions in the nav stack 87 // Ignore navigations that are forward or back transitions in the nav stack
88 // which are not at the head of the stack. 88 // which are not at the head of the stack.
89 // TODO(dimich): Not sure this is needed. Clarify and remove.
dewittj 2016/06/29 00:16:31 maybe add a tracking bug reference here?
Dmitry Titov 2016/06/29 01:51:31 Done.
89 const content::NavigationController& controller = 90 const content::NavigationController& controller =
90 web_contents()->GetController(); 91 web_contents()->GetController();
91 if (controller.GetEntryCount() > 0 && 92 if (controller.GetEntryCount() > 0 &&
92 controller.GetCurrentEntryIndex() != -1 && 93 controller.GetCurrentEntryIndex() != -1 &&
93 controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) { 94 controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) {
94 return; 95 return;
95 } 96 }
96 97
97 content::BrowserContext* context = web_contents()->GetBrowserContext(); 98 content::BrowserContext* context = web_contents()->GetBrowserContext();
98 if (net::NetworkChangeNotifier::IsOffline()) { 99 if (net::NetworkChangeNotifier::IsOffline()) {
99 GetPagesForRedirectToOffline(navigated_url, 100 GetPagesForRedirectToOffline(navigated_url,
100 RedirectReason::DISCONNECTED_NETWORK); 101 RedirectResult::DISCONNECTED_NETWORK);
dewittj 2016/06/29 00:16:31 It feels like there are actually two enums here: o
Dmitry Titov 2016/06/29 01:51:31 I removed that switch but still want to have a den
dewittj 2016/06/29 17:36:06 I was actually requesting two enums in code: one f
101 return; 102 return;
102 } 103 }
103 104
104 OfflinePageModel* offline_page_model = 105 OfflinePageModel* offline_page_model =
105 OfflinePageModelFactory::GetForBrowserContext(context); 106 OfflinePageModelFactory::GetForBrowserContext(context);
106 if (!offline_page_model) 107 if (!offline_page_model)
107 return; 108 return;
108 109
109 offline_page_model->GetPageByOfflineURL( 110 offline_page_model->GetPageByOfflineURL(
110 navigated_url, base::Bind(&OfflinePageTabHelper::RedirectToOnline, 111 navigated_url, base::Bind(&OfflinePageTabHelper::RedirectToOnline,
(...skipping 23 matching lines...) Expand all
134 // When the navigation starts, we redirect immediately from online page to 135 // When the navigation starts, we redirect immediately from online page to
135 // offline version on the case that there is no network connection. If there 136 // offline version on the case that there is no network connection. If there
136 // is still network connection but with no or poor network connectivity, the 137 // is still network connection but with no or poor network connectivity, the
137 // navigation will eventually fail and we want to redirect to offline copy 138 // navigation will eventually fail and we want to redirect to offline copy
138 // in this case. If error code doesn't match this list, then we still show 139 // in this case. If error code doesn't match this list, then we still show
139 // the error page and not an offline page, so do nothing. 140 // the error page and not an offline page, so do nothing.
140 if (error_code != net::ERR_INTERNET_DISCONNECTED && 141 if (error_code != net::ERR_INTERNET_DISCONNECTED &&
141 error_code != net::ERR_NAME_NOT_RESOLVED && 142 error_code != net::ERR_NAME_NOT_RESOLVED &&
142 error_code != net::ERR_ADDRESS_UNREACHABLE && 143 error_code != net::ERR_ADDRESS_UNREACHABLE &&
143 error_code != net::ERR_PROXY_CONNECTION_FAILED) { 144 error_code != net::ERR_PROXY_CONNECTION_FAILED) {
145 ReportUMARedirectResult(RedirectResult::SHOW_NET_ERROR_PAGE);
146 return;
147 }
148 // Otherwise, get the offline URL for this url, and attempt a redirect if
149 // necessary.
150 RedirectResult result =
151 ui::PageTransitionTypeIncludingQualifiersIs(
152 navigation_handle->GetPageTransition(),
153 ui::PAGE_TRANSITION_FORWARD_BACK)
154 ? RedirectResult::FLAKY_NETWORK_FORWARD_BACK
155 : RedirectResult::FLAKY_NETWORK;
156
157 // Don't actually want to redirect on a forward/back nav.
158 // TODO(dimich): why is this? Clarify and possibly redirect as well.
jianli 2016/06/29 00:19:30 This is because doing redirect here does not work
Dmitry Titov 2016/06/29 01:51:30 I don't understand *why* it doesn't work so I'll l
159 if (result == RedirectResult::FLAKY_NETWORK_FORWARD_BACK) {
jianli 2016/06/29 00:19:29 Can we rewrite line 148-164 to the following: if
Dmitry Titov 2016/06/29 01:51:31 Done.
160 ReportUMARedirectResult(RedirectResult::FLAKY_NETWORK_FORWARD_BACK);
144 return; 161 return;
145 } 162 }
146 163
147 // Otherwise, get the offline URL for this url, and attempt a redirect if 164 GetPagesForRedirectToOffline(navigated_url, result);
148 // necessary.
149 RedirectReason reason =
150 ui::PageTransitionTypeIncludingQualifiersIs(
151 navigation_handle->GetPageTransition(),
152 ui::PAGE_TRANSITION_FORWARD_BACK)
153 ? RedirectReason::FLAKY_NETWORK_FORWARD_BACK
154 : RedirectReason::FLAKY_NETWORK;
155 GetPagesForRedirectToOffline(navigated_url, reason);
156 } 165 }
157 166
158 void OfflinePageTabHelper::RedirectToOnline( 167 void OfflinePageTabHelper::RedirectToOnline(
159 const GURL& navigated_url, 168 const GURL& navigated_url,
160 const OfflinePageItem* offline_page) { 169 const OfflinePageItem* offline_page) {
161 // Bails out if no redirection is needed. 170 // Bails out if no redirection is needed.
162 if (!offline_page) 171 if (!offline_page)
163 return; 172 return;
164 173
165 GURL redirect_url = offline_page->url; 174 GURL redirect_url = offline_page->url;
166 175 if (IsInRedirectLoop(redirect_url))
167 const content::NavigationController& controller =
168 web_contents()->GetController();
169
170 // Avoids looping between online and offline redirections.
171 content::NavigationEntry* entry = controller.GetPendingEntry();
172 if (entry && !entry->GetRedirectChain().empty() &&
173 entry->GetRedirectChain().back() == redirect_url) {
174 return; 176 return;
dewittj 2016/06/29 00:16:31 Do we want to UMA the redirect loop?
Dmitry Titov 2016/06/29 01:51:31 Done. I think it might be a fringe condition, but
175 }
176 177
177 Redirect(navigated_url, redirect_url); 178 Redirect(navigated_url, redirect_url);
178 // Clear the offline page since we are redirecting to online. 179 // Clear the offline page since we are redirecting to online.
179 offline_page_ = nullptr; 180 offline_page_ = nullptr;
180 181
181 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOnlineCount", 1); 182 ReportUMARedirectResult(RedirectResult::CONNECTED_NETWORK);
182 } 183 }
183 184
184 void OfflinePageTabHelper::GetPagesForRedirectToOffline(const GURL& online_url, 185 void OfflinePageTabHelper::GetPagesForRedirectToOffline(const GURL& online_url,
185 RedirectReason reason) { 186 RedirectResult result) {
186 OfflinePageModel* offline_page_model = 187 OfflinePageModel* offline_page_model =
187 OfflinePageModelFactory::GetForBrowserContext( 188 OfflinePageModelFactory::GetForBrowserContext(
188 web_contents()->GetBrowserContext()); 189 web_contents()->GetBrowserContext());
189 if (!offline_page_model) 190 if (!offline_page_model)
190 return; 191 return;
191 192
192 offline_page_model->GetPagesByOnlineURL( 193 offline_page_model->GetPagesByOnlineURL(
193 online_url, 194 online_url,
194 base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline, 195 base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline,
195 weak_ptr_factory_.GetWeakPtr(), online_url, reason)); 196 weak_ptr_factory_.GetWeakPtr(), online_url, result));
196 } 197 }
197 198
198 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( 199 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline(
199 const GURL& online_url, 200 const GURL& online_url,
200 RedirectReason reason, 201 RedirectResult result,
201 const MultipleOfflinePageItemResult& pages) { 202 const MultipleOfflinePageItemResult& pages) {
202 // When there is no valid tab android there is nowhere to show the offline 203 // When there is no valid tab android there is nowhere to show the offline
203 // page, so we can leave. 204 // page, so we can leave.
204 std::string tab_id; 205 std::string tab_id;
205 if (!delegate_->GetTabId(web_contents(), &tab_id)) 206 if (!delegate_->GetTabId(web_contents(), &tab_id)) {
207 ReportUMARedirectResult(RedirectResult::NO_TAB_ID);
206 return; 208 return;
209 }
207 210
208 const OfflinePageItem* selected_page = nullptr; 211 const OfflinePageItem* selected_page = nullptr;
209 for (const auto& offline_page : pages) { 212 for (const auto& offline_page : pages) {
210 if ((offline_page.client_id.name_space == kBookmarkNamespace) || 213 if ((offline_page.client_id.name_space == kBookmarkNamespace) ||
211 (offline_page.client_id.name_space == kLastNNamespace && 214 (offline_page.client_id.name_space == kLastNNamespace &&
212 offline_page.client_id.id == tab_id)) { 215 offline_page.client_id.id == tab_id)) {
213 if (!selected_page || 216 if (!selected_page ||
214 offline_page.creation_time > selected_page->creation_time) { 217 offline_page.creation_time > selected_page->creation_time) {
215 selected_page = &offline_page; 218 selected_page = &offline_page;
216 } 219 }
217 } 220 }
218 } 221 }
219 222
220 if (!selected_page) 223 if (!selected_page) {
224 ReportUMARedirectResult(result, true); // Report offline page not found.
221 return; 225 return;
226 }
222 227
223 TryRedirectToOffline(reason, online_url, *selected_page); 228 TryRedirectToOffline(result, online_url, *selected_page);
224 } 229 }
225 230
226 void OfflinePageTabHelper::TryRedirectToOffline( 231 void OfflinePageTabHelper::TryRedirectToOffline(
227 RedirectReason redirect_reason, 232 RedirectResult result,
228 const GURL& from_url, 233 const GURL& from_url,
229 const OfflinePageItem& offline_page) { 234 const OfflinePageItem& offline_page) {
230 GURL redirect_url = offline_page.GetOfflineURL(); 235 GURL redirect_url = offline_page.GetOfflineURL();
231 if (!redirect_url.is_valid()) 236 if (!redirect_url.is_valid())
232 return; 237 return;
233 238
234 if (redirect_reason == RedirectReason::FLAKY_NETWORK || 239 if (IsInRedirectLoop(redirect_url))
235 redirect_reason == RedirectReason::FLAKY_NETWORK_FORWARD_BACK) { 240 return;
236 UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork",
237 redirect_reason == RedirectReason::FLAKY_NETWORK);
238 // Don't actually want to redirect on a forward/back nav.
239 if (redirect_reason == RedirectReason::FLAKY_NETWORK_FORWARD_BACK)
240 return;
241 } else {
242 const content::NavigationController& controller =
243 web_contents()->GetController();
244
245 // Avoids looping between online and offline redirections.
246 content::NavigationEntry* entry = controller.GetPendingEntry();
247 if (entry && !entry->GetRedirectChain().empty() &&
248 entry->GetRedirectChain().back() == redirect_url) {
249 return;
250 }
251 }
252 241
253 Redirect(from_url, redirect_url); 242 Redirect(from_url, redirect_url);
254 offline_page_ = base::MakeUnique<OfflinePageItem>(offline_page); 243 offline_page_ = base::MakeUnique<OfflinePageItem>(offline_page);
255 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOfflineCount", 1); 244 ReportUMARedirectResult(result);
256 } 245 }
257 246
258 void OfflinePageTabHelper::Redirect(const GURL& from_url, const GURL& to_url) { 247 void OfflinePageTabHelper::Redirect(const GURL& from_url, const GURL& to_url) {
259 content::NavigationController::LoadURLParams load_params(to_url); 248 content::NavigationController::LoadURLParams load_params(to_url);
260 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT; 249 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
261 load_params.redirect_chain.push_back(from_url); 250 load_params.redirect_chain.push_back(from_url);
262 web_contents()->GetController().LoadURLWithParams(load_params); 251 web_contents()->GetController().LoadURLWithParams(load_params);
263 } 252 }
264 253
254 bool OfflinePageTabHelper::IsInRedirectLoop(const GURL& to_url) {
255 // Avoids looping between online and offline redirections.
256 const content::NavigationController& controller =
257 web_contents()->GetController();
258 content::NavigationEntry* entry = controller.GetPendingEntry();
259 return entry &&
260 !entry->GetRedirectChain().empty() &&
261 entry->GetRedirectChain().back() == to_url;
262 }
263
264 void OfflinePageTabHelper::ReportUMARedirectResult(
265 RedirectResult result, bool page_not_found) {
266 if (page_not_found) {
267 switch (result) {
dewittj 2016/06/29 00:16:31 This logic is a bit hard to read, it feels like th
Dmitry Titov 2016/06/29 01:51:30 Done.
268 case RedirectResult::DISCONNECTED_NETWORK:
269 result = RedirectResult::DISCONNECTED_NETWORK_NOT_FOUND;
270 break;
271 case RedirectResult::FLAKY_NETWORK:
272 result = RedirectResult::FLAKY_NETWORK_NOT_FOUND;
273 break;
274 case RedirectResult::FLAKY_NETWORK_FORWARD_BACK:
275 result = RedirectResult::FLAKY_NETWORK_FORWARD_BACK_NOT_FOUND;
276 break;
277 default:
278 NOTREACHED();
279 }
280 }
281 UMA_HISTOGRAM_ENUMERATION("OfflinePages.RedirectResult",
282 static_cast<int>(result),
283 static_cast<int>(RedirectResult::REDIRECT_RESULT_MAX));
284 }
265 } // namespace offline_pages 285 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698