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

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

Issue 2040163003: Refactors offline page tab helper to stash the offline page item on redirect. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@single-result
Patch Set: remove move. Created 4 years, 6 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/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
10 #include "base/threading/thread_task_runner_handle.h" 11 #include "base/threading/thread_task_runner_handle.h"
12 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
11 #include "chrome/browser/android/offline_pages/offline_page_utils.h" 13 #include "chrome/browser/android/offline_pages/offline_page_utils.h"
14 #include "components/offline_pages/offline_page_model.h"
12 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/navigation_controller.h" 16 #include "content/public/browser/navigation_controller.h"
14 #include "content/public/browser/navigation_entry.h" 17 #include "content/public/browser/navigation_entry.h"
15 #include "content/public/browser/navigation_handle.h" 18 #include "content/public/browser/navigation_handle.h"
16 #include "content/public/browser/render_frame_host.h" 19 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
18 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
19 #include "net/base/network_change_notifier.h" 22 #include "net/base/network_change_notifier.h"
20 #include "ui/base/page_transition_types.h" 23 #include "ui/base/page_transition_types.h"
21 24
(...skipping 23 matching lines...) Expand all
45 48
46 void OfflinePageTabHelper::DidStartNavigation( 49 void OfflinePageTabHelper::DidStartNavigation(
47 content::NavigationHandle* navigation_handle) { 50 content::NavigationHandle* navigation_handle) {
48 // Skips non-main frame. 51 // Skips non-main frame.
49 if (!navigation_handle->IsInMainFrame()) 52 if (!navigation_handle->IsInMainFrame())
50 return; 53 return;
51 54
52 // This is a new navigation so we can invalidate any previously scheduled 55 // This is a new navigation so we can invalidate any previously scheduled
53 // operations. 56 // operations.
54 weak_ptr_factory_.InvalidateWeakPtrs(); 57 weak_ptr_factory_.InvalidateWeakPtrs();
58 offline_page_.reset(nullptr);
55 59
56 // Ignore navigations that are forward or back transitions in the nav stack 60 // Ignore navigations that are forward or back transitions in the nav stack
57 // which are not at the head of the stack. 61 // which are not at the head of the stack.
58 const content::NavigationController& controller = 62 const content::NavigationController& controller =
59 web_contents()->GetController(); 63 web_contents()->GetController();
60 if (controller.GetEntryCount() > 0 && 64 if (controller.GetEntryCount() > 0 &&
61 controller.GetCurrentEntryIndex() != -1 && 65 controller.GetCurrentEntryIndex() != -1 &&
62 controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) { 66 controller.GetCurrentEntryIndex() < controller.GetEntryCount() - 1) {
63 return; 67 return;
64 } 68 }
65 69
66 content::BrowserContext* context = web_contents()->GetBrowserContext(); 70 content::BrowserContext* context = web_contents()->GetBrowserContext();
71 OfflinePageModel* offline_page_model =
72 OfflinePageModelFactory::GetForBrowserContext(context);
73 if (!offline_page_model)
74 return;
75
67 GURL navigated_url = navigation_handle->GetURL(); 76 GURL navigated_url = navigation_handle->GetURL();
68 auto redirect_url_callback = 77
69 base::Bind(&OfflinePageTabHelper::GotRedirectURLForStartedNavigation,
70 weak_ptr_factory_.GetWeakPtr(), navigated_url);
71 if (net::NetworkChangeNotifier::IsOffline()) { 78 if (net::NetworkChangeNotifier::IsOffline()) {
72 OfflinePageUtils::GetOfflineURLForOnlineURL(context, navigated_url, 79 offline_page_model->GetBestPageForOnlineURL(
73 redirect_url_callback); 80 navigated_url,
81 base::Bind(&OfflinePageTabHelper::TryRedirectToOffline,
82 weak_ptr_factory_.GetWeakPtr(),
83 RedirectReason::DISCONNECTED_NETWORK, navigated_url));
74 } else { 84 } else {
75 OfflinePageUtils::GetOnlineURLForOfflineURL(context, navigated_url, 85 offline_page_model->GetPageByOfflineURL(
76 redirect_url_callback); 86 navigated_url,
87 base::Bind(&OfflinePageTabHelper::RedirectToOnline,
88 weak_ptr_factory_.GetWeakPtr(), navigated_url));
77 } 89 }
78 } 90 }
79 91
80 void OfflinePageTabHelper::DidFinishNavigation( 92 void OfflinePageTabHelper::DidFinishNavigation(
81 content::NavigationHandle* navigation_handle) { 93 content::NavigationHandle* navigation_handle) {
82 // Skips non-main frame. 94 // Skips non-main frame.
83 if (!navigation_handle->IsInMainFrame()) 95 if (!navigation_handle->IsInMainFrame())
84 return; 96 return;
85 97
86 GURL navigated_url = navigation_handle->GetURL(); 98 GURL navigated_url = navigation_handle->GetURL();
(...skipping 16 matching lines...) Expand all
103 // navigation will eventually fail and we want to redirect to offline copy 115 // navigation will eventually fail and we want to redirect to offline copy
104 // in this case. If error code doesn't match this list, then we still show 116 // in this case. If error code doesn't match this list, then we still show
105 // the error page and not an offline page, so do nothing. 117 // the error page and not an offline page, so do nothing.
106 if (error_code != net::ERR_INTERNET_DISCONNECTED && 118 if (error_code != net::ERR_INTERNET_DISCONNECTED &&
107 error_code != net::ERR_NAME_NOT_RESOLVED && 119 error_code != net::ERR_NAME_NOT_RESOLVED &&
108 error_code != net::ERR_ADDRESS_UNREACHABLE && 120 error_code != net::ERR_ADDRESS_UNREACHABLE &&
109 error_code != net::ERR_PROXY_CONNECTION_FAILED) { 121 error_code != net::ERR_PROXY_CONNECTION_FAILED) {
110 return; 122 return;
111 } 123 }
112 124
125 OfflinePageModel* offline_page_model =
126 OfflinePageModelFactory::GetForBrowserContext(browser_context);
127 if (!offline_page_model)
128 return;
129
113 // Otherwise, get the offline URL for this url, and attempt a redirect if 130 // Otherwise, get the offline URL for this url, and attempt a redirect if
114 // necessary. 131 // necessary.
115 OfflinePageUtils::GetOfflineURLForOnlineURL( 132 RedirectReason reason =
116 browser_context, navigated_url, 133 navigation_handle->GetPageTransition() == ui::PAGE_TRANSITION_FORWARD_BACK
117 base::Bind(&OfflinePageTabHelper::GotRedirectURLForSupportedErrorCode, 134 ? RedirectReason::FLAKY_NETWORK_FORWARD_BACK
118 weak_ptr_factory_.GetWeakPtr(), 135 : RedirectReason::FLAKY_NETWORK;
119 navigation_handle->GetPageTransition(), navigated_url)); 136 offline_page_model->GetBestPageForOnlineURL(
137 navigated_url,
138 base::Bind(&OfflinePageTabHelper::TryRedirectToOffline,
139 weak_ptr_factory_.GetWeakPtr(), reason, navigated_url));
120 } 140 }
121 141
122 void OfflinePageTabHelper::GotRedirectURLForSupportedErrorCode( 142 void OfflinePageTabHelper::RedirectToOnline(
123 ui::PageTransition transition, 143 const GURL& navigated_url,
124 const GURL& from_url, 144 const OfflinePageItem* offline_page) {
125 const GURL& redirect_url) { 145 // Bails out if no redirection is needed.
126 // If we didn't find an offline URL, or we are doing a forward/back 146 if (!offline_page)
127 // transition, don't redirect.
128 bool do_redirect =
129 redirect_url.is_valid() && transition != ui::PAGE_TRANSITION_FORWARD_BACK;
130 UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork",
131 do_redirect);
132 if (!do_redirect)
133 return; 147 return;
134 148
135 base::ThreadTaskRunnerHandle::Get()->PostTask( 149 GURL redirect_url = offline_page->url;
136 FROM_HERE,
137 base::Bind(&OfflinePageTabHelper::Redirect,
138 weak_ptr_factory_.GetWeakPtr(), from_url, redirect_url));
139 }
140
141 void OfflinePageTabHelper::GotRedirectURLForStartedNavigation(
142 const GURL& from_url,
143 const GURL& redirect_url) {
144 // Bails out if no redirection is needed.
145 if (!redirect_url.is_valid())
146 return;
147 150
148 const content::NavigationController& controller = 151 const content::NavigationController& controller =
149 web_contents()->GetController(); 152 web_contents()->GetController();
150 153
151 // Avoids looping between online and offline redirections. 154 // Avoids looping between online and offline redirections.
152 content::NavigationEntry* entry = controller.GetPendingEntry(); 155 content::NavigationEntry* entry = controller.GetPendingEntry();
153 if (entry && !entry->GetRedirectChain().empty() && 156 if (entry && !entry->GetRedirectChain().empty() &&
154 entry->GetRedirectChain().back() == redirect_url) { 157 entry->GetRedirectChain().back() == redirect_url) {
155 return; 158 return;
156 } 159 }
157 160
158 base::ThreadTaskRunnerHandle::Get()->PostTask( 161 Redirect(navigated_url, redirect_url, nullptr);
159 FROM_HERE,
160 base::Bind(&OfflinePageTabHelper::Redirect,
161 weak_ptr_factory_.GetWeakPtr(), from_url, redirect_url));
162 } 162 }
163 163
164 void OfflinePageTabHelper::Redirect( 164 void OfflinePageTabHelper::TryRedirectToOffline(
165 const GURL& from_url, const GURL& to_url) { 165 RedirectReason redirect_reason,
166 const GURL& from_url,
167 const OfflinePageItem* offline_page) {
168 if (!offline_page)
169 return;
170
171 GURL redirect_url = offline_page->GetOfflineURL();
172
173 if (!redirect_url.is_valid())
174 return;
175
176 if (redirect_reason == RedirectReason::FLAKY_NETWORK ||
177 redirect_reason == RedirectReason::FLAKY_NETWORK_FORWARD_BACK) {
178 UMA_HISTOGRAM_BOOLEAN("OfflinePages.ShowOfflinePageOnBadNetwork",
179 redirect_reason == RedirectReason::FLAKY_NETWORK);
180 // Don't actually want to redirect on a forward/back nav.
181 if (redirect_reason == RedirectReason::FLAKY_NETWORK_FORWARD_BACK)
182 return;
183 } else {
184 const content::NavigationController& controller =
185 web_contents()->GetController();
186
187 // Avoids looping between online and offline redirections.
188 content::NavigationEntry* entry = controller.GetPendingEntry();
189 if (entry && !entry->GetRedirectChain().empty() &&
190 entry->GetRedirectChain().back() == redirect_url) {
191 return;
192 }
193 }
194
195 Redirect(from_url, redirect_url, offline_page);
196 }
197
198 void OfflinePageTabHelper::Redirect(const GURL& from_url,
199 const GURL& to_url,
200 const OfflinePageItem* offline_page) {
166 if (to_url.SchemeIsFile()) { 201 if (to_url.SchemeIsFile()) {
167 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOfflineCount", 1); 202 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOfflineCount", 1);
168 } else { 203 } else {
169 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOnlineCount", 1); 204 UMA_HISTOGRAM_COUNTS("OfflinePages.RedirectToOnlineCount", 1);
170 } 205 }
171 206
172 content::NavigationController::LoadURLParams load_params(to_url); 207 content::NavigationController::LoadURLParams load_params(to_url);
173 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT; 208 load_params.transition_type = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
174 load_params.redirect_chain.push_back(from_url); 209 load_params.redirect_chain.push_back(from_url);
175 web_contents()->GetController().LoadURLWithParams(load_params); 210 web_contents()->GetController().LoadURLWithParams(load_params);
211
212 // We will always set the offline page if we redirect. Note that this will
213 // clear the offline page if we redirect to online.
214 offline_page_ =
215 offline_page ? base::MakeUnique<OfflinePageItem>(*offline_page) : nullptr;
jianli 2016/06/15 00:44:00 I think whether redirecting to online should be ch
dewittj 2016/06/15 17:21:05 PTAL, I removed the SchemeIsFile call altogether.
176 } 216 }
177 217
178 } // namespace offline_pages 218 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698