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

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: addressed feedback 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. Bug 624216.
fgorski 2016/06/29 17:01:15 https://bugs.chromium.org/p/chromium/issues/detail
Dmitry Titov 2016/06/29 18:25:43 Thanks! Added reference to the tracking bug to lin
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(
100 RedirectReason::DISCONNECTED_NETWORK); 101 navigated_url, RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK);
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 ReportRedirectResultUMA(RedirectResult::SHOW_NET_ERROR_PAGE);
144 return; 146 return;
145 } 147 }
146 148
147 // Otherwise, get the offline URL for this url, and attempt a redirect if 149 // Don't actually want to redirect on a forward/back nav.
148 // necessary. 150 // TODO(dimich): Clarify and possibly redirect as well. Bug 624216.
149 RedirectReason reason = 151 if (ui::PageTransitionTypeIncludingQualifiersIs(
150 ui::PageTransitionTypeIncludingQualifiersIs(
151 navigation_handle->GetPageTransition(), 152 navigation_handle->GetPageTransition(),
152 ui::PAGE_TRANSITION_FORWARD_BACK) 153 ui::PAGE_TRANSITION_FORWARD_BACK)) {
153 ? RedirectReason::FLAKY_NETWORK_FORWARD_BACK 154 ReportRedirectResultUMA(RedirectResult::IGNORED_FLAKY_NETWORK_FORWARD_BACK);
fgorski 2016/06/29 17:01:16 Cool find.
Dmitry Titov 2016/06/29 18:25:44 Acknowledged.
154 : RedirectReason::FLAKY_NETWORK; 155 return;
155 GetPagesForRedirectToOffline(navigated_url, reason); 156 }
157
158 GetPagesForRedirectToOffline(
159 navigated_url, RedirectResult::REDIRECTED_ON_FLAKY_NETWORK);
156 } 160 }
157 161
158 void OfflinePageTabHelper::RedirectToOnline( 162 void OfflinePageTabHelper::RedirectToOnline(
159 const GURL& navigated_url, 163 const GURL& navigated_url,
160 const OfflinePageItem* offline_page) { 164 const OfflinePageItem* offline_page) {
161 // Bails out if no redirection is needed. 165 // Bails out if no redirection is needed.
162 if (!offline_page) 166 if (!offline_page)
163 return; 167 return;
164 168
165 GURL redirect_url = offline_page->url; 169 GURL redirect_url = offline_page->url;
166 170 if (IsInRedirectLoop(redirect_url)) {
167 const content::NavigationController& controller = 171 ReportRedirectResultUMA(RedirectResult::REDIRECT_LOOP_ONLINE);
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; 172 return;
175 } 173 }
176 174
177 Redirect(navigated_url, redirect_url); 175 Redirect(navigated_url, redirect_url);
178 // Clear the offline page since we are redirecting to online. 176 // Clear the offline page since we are redirecting to online.
179 offline_page_ = nullptr; 177 offline_page_ = nullptr;
180 178
181 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOnlineCount", 1); 179 ReportRedirectResultUMA(RedirectResult::REDIRECTED_ON_CONNECTED_NETWORK);
182 } 180 }
183 181
184 void OfflinePageTabHelper::GetPagesForRedirectToOffline(const GURL& online_url, 182 void OfflinePageTabHelper::GetPagesForRedirectToOffline(const GURL& online_url,
185 RedirectReason reason) { 183 RedirectResult result) {
186 OfflinePageModel* offline_page_model = 184 OfflinePageModel* offline_page_model =
187 OfflinePageModelFactory::GetForBrowserContext( 185 OfflinePageModelFactory::GetForBrowserContext(
188 web_contents()->GetBrowserContext()); 186 web_contents()->GetBrowserContext());
189 if (!offline_page_model) 187 if (!offline_page_model)
190 return; 188 return;
191 189
192 offline_page_model->GetPagesByOnlineURL( 190 offline_page_model->GetPagesByOnlineURL(
193 online_url, 191 online_url,
194 base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline, 192 base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline,
195 weak_ptr_factory_.GetWeakPtr(), online_url, reason)); 193 weak_ptr_factory_.GetWeakPtr(), online_url, result));
196 } 194 }
197 195
198 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( 196 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline(
199 const GURL& online_url, 197 const GURL& online_url,
200 RedirectReason reason, 198 RedirectResult result,
201 const MultipleOfflinePageItemResult& pages) { 199 const MultipleOfflinePageItemResult& pages) {
200 DCHECK(result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK ||
201 result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK);
202
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 ReportRedirectResultUMA(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 if (result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK)
225 result = RedirectResult::PAGE_NOT_FOUND_ON_FLAKY_NETWORK;
fgorski 2016/06/29 17:01:15 nit: I am mildly bothered by overwriting input par
Dmitry Titov 2016/06/29 18:25:44 Done.
226 else
227 result = RedirectResult::PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK;
228 ReportRedirectResultUMA(result); // Report offline page not found.
221 return; 229 return;
230 }
222 231
223 TryRedirectToOffline(reason, online_url, *selected_page); 232 TryRedirectToOffline(result, online_url, *selected_page);
224 } 233 }
225 234
226 void OfflinePageTabHelper::TryRedirectToOffline( 235 void OfflinePageTabHelper::TryRedirectToOffline(
227 RedirectReason redirect_reason, 236 RedirectResult result,
228 const GURL& from_url, 237 const GURL& from_url,
229 const OfflinePageItem& offline_page) { 238 const OfflinePageItem& offline_page) {
230 GURL redirect_url = offline_page.GetOfflineURL(); 239 GURL redirect_url = offline_page.GetOfflineURL();
231 if (!redirect_url.is_valid()) 240 if (!redirect_url.is_valid())
232 return; 241 return;
233 242
234 if (redirect_reason == RedirectReason::FLAKY_NETWORK || 243 if (IsInRedirectLoop(redirect_url)) {
235 redirect_reason == RedirectReason::FLAKY_NETWORK_FORWARD_BACK) { 244 ReportRedirectResultUMA(RedirectResult::REDIRECT_LOOP_OFFLINE);
236 UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork", 245 return;
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 } 246 }
252 247
253 Redirect(from_url, redirect_url); 248 Redirect(from_url, redirect_url);
254 offline_page_ = base::MakeUnique<OfflinePageItem>(offline_page); 249 offline_page_ = base::MakeUnique<OfflinePageItem>(offline_page);
255 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOfflineCount", 1); 250 ReportRedirectResultUMA(result);
256 } 251 }
257 252
258 void OfflinePageTabHelper::Redirect(const GURL& from_url, const GURL& to_url) { 253 void OfflinePageTabHelper::Redirect(const GURL& from_url, const GURL& to_url) {
259 content::NavigationController::LoadURLParams load_params(to_url); 254 content::NavigationController::LoadURLParams load_params(to_url);
260 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT; 255 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
261 load_params.redirect_chain.push_back(from_url); 256 load_params.redirect_chain.push_back(from_url);
262 web_contents()->GetController().LoadURLWithParams(load_params); 257 web_contents()->GetController().LoadURLWithParams(load_params);
263 } 258 }
264 259
260 bool OfflinePageTabHelper::IsInRedirectLoop(const GURL& to_url) const {
261 // Avoids looping between online and offline redirections.
fgorski 2016/06/29 17:01:15 Update comment: Detects looping...
Dmitry Titov 2016/06/29 18:25:43 Done.
262 const content::NavigationController& controller =
263 web_contents()->GetController();
264 content::NavigationEntry* entry = controller.GetPendingEntry();
265 return entry &&
266 !entry->GetRedirectChain().empty() &&
267 entry->GetRedirectChain().back() == to_url;
268 }
269
270 void OfflinePageTabHelper::ReportRedirectResultUMA(RedirectResult result) {
271 UMA_HISTOGRAM_ENUMERATION("OfflinePages.RedirectResult",
272 static_cast<int>(result),
273 static_cast<int>(RedirectResult::REDIRECT_RESULT_MAX));
274 }
265 } // namespace offline_pages 275 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698