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

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.
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 RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK, navigated_url);
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);
154 : RedirectReason::FLAKY_NETWORK; 155 return;
155 GetPagesForRedirectToOffline(navigated_url, reason); 156 }
157
158 GetPagesForRedirectToOffline(
159 RedirectResult::REDIRECTED_ON_FLAKY_NETWORK, navigated_url);
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)
jianli 2016/06/29 20:20:16 It seems that we can return PAGE_NOT_FOUND_ON_CONN
Dmitry Titov 2016/06/29 20:38:03 This case includes all regular navigations (when o
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(
185 RedirectReason reason) { 183 RedirectResult result, const GURL& online_url) {
jianli 2016/06/29 20:20:16 Passing RedirectResult at this time seems to be co
Dmitry Titov 2016/06/29 20:38:03 I have a commentin .h file that explains that the
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(), result, online_url));
196 } 194 }
197 195
198 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( 196 void OfflinePageTabHelper::SelectBestPageForRedirectToOffline(
197 RedirectResult result,
199 const GURL& online_url, 198 const GURL& online_url,
200 RedirectReason reason,
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 ReportRedirectResultUMA(
225 result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK ?
226 RedirectResult::PAGE_NOT_FOUND_ON_FLAKY_NETWORK :
227 RedirectResult::PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK);
221 return; 228 return;
229 }
222 230
223 TryRedirectToOffline(reason, online_url, *selected_page); 231 TryRedirectToOffline(result, online_url, *selected_page);
224 } 232 }
225 233
226 void OfflinePageTabHelper::TryRedirectToOffline( 234 void OfflinePageTabHelper::TryRedirectToOffline(
227 RedirectReason redirect_reason, 235 RedirectResult result,
228 const GURL& from_url, 236 const GURL& from_url,
229 const OfflinePageItem& offline_page) { 237 const OfflinePageItem& offline_page) {
230 GURL redirect_url = offline_page.GetOfflineURL(); 238 GURL redirect_url = offline_page.GetOfflineURL();
231 if (!redirect_url.is_valid()) 239 if (!redirect_url.is_valid())
232 return; 240 return;
233 241
234 if (redirect_reason == RedirectReason::FLAKY_NETWORK || 242 if (IsInRedirectLoop(redirect_url)) {
235 redirect_reason == RedirectReason::FLAKY_NETWORK_FORWARD_BACK) { 243 ReportRedirectResultUMA(RedirectResult::REDIRECT_LOOP_OFFLINE);
236 UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork", 244 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 } 245 }
252 246
253 Redirect(from_url, redirect_url); 247 Redirect(from_url, redirect_url);
254 offline_page_ = base::MakeUnique<OfflinePageItem>(offline_page); 248 offline_page_ = base::MakeUnique<OfflinePageItem>(offline_page);
255 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOfflineCount", 1); 249 ReportRedirectResultUMA(result);
256 } 250 }
257 251
258 void OfflinePageTabHelper::Redirect(const GURL& from_url, const GURL& to_url) { 252 void OfflinePageTabHelper::Redirect(const GURL& from_url, const GURL& to_url) {
259 content::NavigationController::LoadURLParams load_params(to_url); 253 content::NavigationController::LoadURLParams load_params(to_url);
260 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT; 254 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
261 load_params.redirect_chain.push_back(from_url); 255 load_params.redirect_chain.push_back(from_url);
262 web_contents()->GetController().LoadURLWithParams(load_params); 256 web_contents()->GetController().LoadURLWithParams(load_params);
263 } 257 }
264 258
259 bool OfflinePageTabHelper::IsInRedirectLoop(const GURL& to_url) const {
260 // Detects looping between online and offline redirections.
261 const content::NavigationController& controller =
262 web_contents()->GetController();
263 content::NavigationEntry* entry = controller.GetPendingEntry();
264 return entry &&
265 !entry->GetRedirectChain().empty() &&
266 entry->GetRedirectChain().back() == to_url;
267 }
268
269 void OfflinePageTabHelper::ReportRedirectResultUMA(RedirectResult result) {
270 UMA_HISTOGRAM_ENUMERATION("OfflinePages.RedirectResult",
271 static_cast<int>(result),
272 static_cast<int>(RedirectResult::REDIRECT_RESULT_MAX));
273 }
265 } // namespace offline_pages 274 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698