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

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

Issue 2337363002: Load live version when reloading an offline page on connected network (Closed)
Patch Set: Update BUILD.gn Created 4 years, 3 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_request_job.h" 5 #include "chrome/browser/android/offline_pages/offline_page_request_job.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_tokenizer.h"
15 #include "base/strings/string_util.h"
16 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
17 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" 15 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
18 #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h" 16 #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h"
19 #include "chrome/browser/android/offline_pages/offline_page_utils.h" 17 #include "chrome/browser/android/offline_pages/offline_page_utils.h"
20 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/profiles/profile_manager.h" 19 #include "chrome/browser/profiles/profile_manager.h"
22 #include "components/offline_pages/offline_page_model.h" 20 #include "components/offline_pages/offline_page_model.h"
21 #include "components/offline_pages/request_header/offline_page_header.h"
23 #include "components/previews/core/previews_experiments.h" 22 #include "components/previews/core/previews_experiments.h"
24 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/resource_request_info.h" 24 #include "content/public/browser/resource_request_info.h"
26 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/resource_type.h" 26 #include "content/public/common/resource_type.h"
28 #include "net/base/network_change_notifier.h" 27 #include "net/base/network_change_notifier.h"
29 #include "net/http/http_request_headers.h" 28 #include "net/http/http_request_headers.h"
30 #include "net/nqe/network_quality_estimator.h" 29 #include "net/nqe/network_quality_estimator.h"
31 #include "net/url_request/url_request.h" 30 #include "net/url_request/url_request.h"
32 #include "net/url_request/url_request_context.h" 31 #include "net/url_request/url_request_context.h"
33 32
34 namespace offline_pages { 33 namespace offline_pages {
35 34
36 const char kOfflinePageHeader[] = "X-Chrome-offline";
37 const char kOfflinePageHeaderReasonKey[] = "reason";
38 const char kOfflinePageHeaderReasonValueDueToNetError[] = "error";
39 const char kOfflinePageHeaderReasonValueFromDownload[] = "download";
40 const char kOfflinePageHeaderPersistKey[] = "persist";
41 const char kOfflinePageHeaderIDKey[] = "id";
42
43 namespace { 35 namespace {
44 36
45 enum class NetworkState { 37 enum class NetworkState {
46 // No network connection. 38 // No network connection.
47 DISCONNECTED_NETWORK, 39 DISCONNECTED_NETWORK,
48 // Prohibitively slow means that the NetworkQualityEstimator reported a 40 // Prohibitively slow means that the NetworkQualityEstimator reported a
49 // connection slow enough to warrant showing an offline page if available. 41 // connection slow enough to warrant showing an offline page if available.
50 PROHIBITIVELY_SLOW_NETWORK, 42 PROHIBITIVELY_SLOW_NETWORK,
51 // Network error received due to bad network, i.e. connected to a hotspot or 43 // Network error received due to bad network, i.e. connected to a hotspot or
52 // proxy that does not have a working network. 44 // proxy that does not have a working network.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 101 }
110 102
111 private: 103 private:
112 static bool GetTabId(content::WebContents* web_contents, int* tab_id) { 104 static bool GetTabId(content::WebContents* web_contents, int* tab_id) {
113 return OfflinePageUtils::GetTabId(web_contents, tab_id); 105 return OfflinePageUtils::GetTabId(web_contents, tab_id);
114 } 106 }
115 107
116 DISALLOW_COPY_AND_ASSIGN(DefaultDelegate); 108 DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
117 }; 109 };
118 110
119 // Used to parse the extra request header string that defines offline page
120 // loading behaviors.
121 class OfflinePageHeader {
122 public:
123 enum class Reason {
124 NET_ERROR,
125 DOWNLOAD,
126 UNKNOWN
127 };
128
129 explicit OfflinePageHeader(const std::string& header_string);
130 ~OfflinePageHeader() {}
131
132 bool successfully_parsed() const { return successfully_parsed_; }
133 bool need_to_persist() const { return need_to_persist_; }
134 Reason reason() const { return reason_; }
135 const std::string& id() const { return id_; }
136
137 private:
138 // True if the header is present and parsed successfully.
139 bool successfully_parsed_;
140 // Flag to indicate if the header should be persisted across session restore.
141 bool need_to_persist_;
142 // Describes the reason to load offline page.
143 Reason reason_;
144 // The offline ID of the page to load.
145 std::string id_;
146
147 DISALLOW_COPY_AND_ASSIGN(OfflinePageHeader);
148 };
149
150 OfflinePageHeader::OfflinePageHeader(const std::string& header_string)
151 : successfully_parsed_(false),
152 need_to_persist_(false),
153 reason_(Reason::UNKNOWN) {
154 // If the offline header is not present, treat it as not parsed successfully.
155 if (header_string.empty())
156 return;
157
158 base::StringTokenizer tokenizer(header_string, ", ");
159 while (tokenizer.GetNext()) {
160 std::string pair = tokenizer.token();
161 std::size_t pos = pair.find('=');
162 if (pos == std::string::npos)
163 return;
164 std::string key = base::ToLowerASCII(pair.substr(0, pos));
165 std::string value = base::ToLowerASCII(pair.substr(pos + 1));
166 if (key == kOfflinePageHeaderPersistKey) {
167 need_to_persist_ = (value == "1");
168 } else if (key == kOfflinePageHeaderReasonKey) {
169 if (value == kOfflinePageHeaderReasonValueDueToNetError)
170 reason_ = Reason::NET_ERROR;
171 else if (value == kOfflinePageHeaderReasonValueFromDownload)
172 reason_ = Reason::DOWNLOAD;
173 else
174 reason_ = Reason::UNKNOWN;
175 } else if (key == kOfflinePageHeaderIDKey) {
176 id_ = value;
177 }
178 }
179
180 successfully_parsed_ = true;
181 }
182
183 bool IsNetworkProhibitivelySlow(net::URLRequest* request) { 111 bool IsNetworkProhibitivelySlow(net::URLRequest* request) {
184 // NetworkQualityEstimator only works when it is enabled. 112 // NetworkQualityEstimator only works when it is enabled.
185 if (!previews::IsOfflinePreviewsEnabled()) 113 if (!previews::IsOfflinePreviewsEnabled())
186 return false; 114 return false;
187 115
188 if (!request->context()) 116 if (!request->context())
189 return false; 117 return false;
190 118
191 net::NetworkQualityEstimator* network_quality_estimator = 119 net::NetworkQualityEstimator* network_quality_estimator =
192 request->context()->network_quality_estimator(); 120 request->context()->network_quality_estimator();
193 if (!network_quality_estimator) 121 if (!network_quality_estimator)
194 return false; 122 return false;
195 123
196 net::EffectiveConnectionType effective_connection_type = 124 net::EffectiveConnectionType effective_connection_type =
197 network_quality_estimator->GetEffectiveConnectionType(); 125 network_quality_estimator->GetEffectiveConnectionType();
198 return effective_connection_type >= net::EFFECTIVE_CONNECTION_TYPE_OFFLINE && 126 return effective_connection_type >= net::EFFECTIVE_CONNECTION_TYPE_OFFLINE &&
199 effective_connection_type <= net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G; 127 effective_connection_type <= net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
200 } 128 }
201 129
202 NetworkState GetNetworkState(net::URLRequest* request) { 130 NetworkState GetNetworkState(net::URLRequest* request,
131 const OfflinePageHeader& offline_header) {
203 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 132 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
204 133
205 std::string offline_header_string; 134 if (offline_header.reason == OfflinePageHeader::Reason::NET_ERROR)
206 request->extra_request_headers().GetHeader(
207 kOfflinePageHeader, &offline_header_string);
208 OfflinePageHeader offline_header(offline_header_string);
209 if (offline_header.reason() == OfflinePageHeader::Reason::NET_ERROR)
210 return NetworkState::FLAKY_NETWORK; 135 return NetworkState::FLAKY_NETWORK;
211 136
212 if (net::NetworkChangeNotifier::IsOffline()) 137 if (net::NetworkChangeNotifier::IsOffline())
213 return NetworkState::DISCONNECTED_NETWORK; 138 return NetworkState::DISCONNECTED_NETWORK;
214 139
215 if (IsNetworkProhibitivelySlow(request)) 140 if (IsNetworkProhibitivelySlow(request))
216 return NetworkState::PROHIBITIVELY_SLOW_NETWORK; 141 return NetworkState::PROHIBITIVELY_SLOW_NETWORK;
217 142
218 // If custom offline header is present, the offline page should be forced to 143 // If offline header contains a reason other than RELOAD, the offline page
219 // load even when the network is connected. 144 // should be forced to load even when the network is connected.
220 return offline_header.successfully_parsed() 145 return (offline_header.reason != OfflinePageHeader::Reason::NONE &&
146 offline_header.reason != OfflinePageHeader::Reason::RELOAD)
221 ? NetworkState::FORCE_OFFLINE_ON_CONNECTED_NETWORK 147 ? NetworkState::FORCE_OFFLINE_ON_CONNECTED_NETWORK
222 : NetworkState::CONNECTED_NETWORK; 148 : NetworkState::CONNECTED_NETWORK;
223 } 149 }
224 150
225 OfflinePageRequestJob::AggregatedRequestResult 151 OfflinePageRequestJob::AggregatedRequestResult
226 RequestResultToAggregatedRequestResult( 152 RequestResultToAggregatedRequestResult(
227 RequestResult request_result, NetworkState network_state) { 153 RequestResult request_result, NetworkState network_state) {
228 if (request_result == RequestResult::NO_TAB_ID) 154 if (request_result == RequestResult::NO_TAB_ID)
229 return OfflinePageRequestJob::AggregatedRequestResult::NO_TAB_ID; 155 return OfflinePageRequestJob::AggregatedRequestResult::NO_TAB_ID;
230 156
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 // from IO thread. 241 // from IO thread.
316 content::BrowserThread::PostTask( 242 content::BrowserThread::PostTask(
317 content::BrowserThread::IO, 243 content::BrowserThread::IO,
318 FROM_HERE, 244 FROM_HERE,
319 base::Bind(&NotifyOfflineFilePathOnIO, job, offline_file_path)); 245 base::Bind(&NotifyOfflineFilePathOnIO, job, offline_file_path));
320 } 246 }
321 247
322 // Finds the offline file path based on the select page result and network 248 // Finds the offline file path based on the select page result and network
323 // state and marks it as accessed. 249 // state and marks it as accessed.
324 RequestResult AccessOfflineFile( 250 RequestResult AccessOfflineFile(
251 const OfflinePageHeader& offline_header,
325 NetworkState network_state, 252 NetworkState network_state,
326 base::WeakPtr<OfflinePageRequestJob> job, 253 base::WeakPtr<OfflinePageRequestJob> job,
327 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, 254 content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
328 const OfflinePageItem* offline_page, 255 const OfflinePageItem* offline_page,
329 base::FilePath* offline_file_path) { 256 base::FilePath* offline_file_path) {
330 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 257 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
331 258
332 if (!offline_page) 259 if (!offline_page)
333 return RequestResult::OFFLINE_PAGE_NOT_FOUND; 260 return RequestResult::OFFLINE_PAGE_NOT_FOUND;
334 261
(...skipping 20 matching lines...) Expand all
355 // will not be created under incognito mode. 282 // will not be created under incognito mode.
356 DCHECK(offline_page_model); 283 DCHECK(offline_page_model);
357 offline_page_model->MarkPageAccessed(offline_page->offline_id); 284 offline_page_model->MarkPageAccessed(offline_page->offline_id);
358 285
359 // Save an cached copy of OfflinePageItem such that Tab code can get 286 // Save an cached copy of OfflinePageItem such that Tab code can get
360 // the loaded offline page immediately. 287 // the loaded offline page immediately.
361 OfflinePageTabHelper* tab_helper = 288 OfflinePageTabHelper* tab_helper =
362 OfflinePageTabHelper::FromWebContents(web_contents); 289 OfflinePageTabHelper::FromWebContents(web_contents);
363 DCHECK(tab_helper); 290 DCHECK(tab_helper);
364 tab_helper->SetOfflinePage( 291 tab_helper->SetOfflinePage(
365 *offline_page, network_state == NetworkState::PROHIBITIVELY_SLOW_NETWORK); 292 *offline_page,
293 offline_header,
294 network_state == NetworkState::PROHIBITIVELY_SLOW_NETWORK);
366 295
367 *offline_file_path = offline_page->file_path; 296 *offline_file_path = offline_page->file_path;
368 return RequestResult::OFFLINE_PAGE_SERVED; 297 return RequestResult::OFFLINE_PAGE_SERVED;
369 } 298 }
370 299
371 // Handles the result of finding an offline page. 300 // Handles the result of finding an offline page.
372 void SucceededToFindOfflinePage( 301 void SucceededToFindOfflinePage(
302 const OfflinePageHeader& offline_header,
373 NetworkState network_state, 303 NetworkState network_state,
374 base::WeakPtr<OfflinePageRequestJob> job, 304 base::WeakPtr<OfflinePageRequestJob> job,
375 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, 305 content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
376 const OfflinePageItem* offline_page) { 306 const OfflinePageItem* offline_page) {
377 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 307 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
378 308
379 base::FilePath offline_file_path; 309 base::FilePath offline_file_path;
380 RequestResult request_result = AccessOfflineFile( 310 RequestResult request_result = AccessOfflineFile(
381 network_state, job, web_contents_getter, offline_page, 311 offline_header, network_state, job, web_contents_getter, offline_page,
382 &offline_file_path); 312 &offline_file_path);
383 313
384 ReportRequestResult(request_result, network_state); 314 ReportRequestResult(request_result, network_state);
385 315
386 // NotifyOfflineFilePathOnUI should always be called regardless the failure 316 // NotifyOfflineFilePathOnUI should always be called regardless the failure
387 // result and empty file path such that OfflinePageRequestJob will be notified 317 // result and empty file path such that OfflinePageRequestJob will be notified
388 // on failure. 318 // on failure.
389 NotifyOfflineFilePathOnUI(job, offline_file_path); 319 NotifyOfflineFilePathOnUI(job, offline_file_path);
390 } 320 }
391 321
392 void FailedToFindOfflinePage(base::WeakPtr<OfflinePageRequestJob> job) { 322 void FailedToFindOfflinePage(base::WeakPtr<OfflinePageRequestJob> job) {
393 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 323 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
394 324
395 // Proceed with empty file path in order to notify the OfflinePageRequestJob 325 // Proceed with empty file path in order to notify the OfflinePageRequestJob
396 // about the failure. 326 // about the failure.
397 base::FilePath empty_file_path; 327 base::FilePath empty_file_path;
398 NotifyOfflineFilePathOnUI(job, empty_file_path); 328 NotifyOfflineFilePathOnUI(job, empty_file_path);
399 } 329 }
400 330
401 // Tries to find the offline page to serve for |online_url|. 331 // Tries to find the offline page to serve for |online_url|.
402 void SelectPageForOnlineURL( 332 void SelectPageForOnlineURL(
403 const GURL& online_url, 333 const GURL& online_url,
334 const OfflinePageHeader& offline_header,
404 NetworkState network_state, 335 NetworkState network_state,
405 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, 336 content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
406 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter, 337 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter,
407 base::WeakPtr<OfflinePageRequestJob> job) { 338 base::WeakPtr<OfflinePageRequestJob> job) {
408 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 339 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
409 340
410 content::WebContents* web_contents = web_contents_getter.Run(); 341 content::WebContents* web_contents = web_contents_getter.Run();
411 if (!web_contents){ 342 if (!web_contents){
412 ReportRequestResult(RequestResult::NO_WEB_CONTENTS, network_state); 343 ReportRequestResult(RequestResult::NO_WEB_CONTENTS, network_state);
413 FailedToFindOfflinePage(job); 344 FailedToFindOfflinePage(job);
414 return; 345 return;
415 } 346 }
416 int tab_id; 347 int tab_id;
417 if (!tab_id_getter.Run(web_contents, &tab_id)) { 348 if (!tab_id_getter.Run(web_contents, &tab_id)) {
418 ReportRequestResult(RequestResult::NO_TAB_ID, network_state); 349 ReportRequestResult(RequestResult::NO_TAB_ID, network_state);
419 FailedToFindOfflinePage(job); 350 FailedToFindOfflinePage(job);
420 return; 351 return;
421 } 352 }
422 353
423 OfflinePageUtils::SelectPageForOnlineURL( 354 OfflinePageUtils::SelectPageForOnlineURL(
424 web_contents->GetBrowserContext(), 355 web_contents->GetBrowserContext(),
425 online_url, 356 online_url,
426 tab_id, 357 tab_id,
427 base::Bind(&SucceededToFindOfflinePage, 358 base::Bind(&SucceededToFindOfflinePage,
359 offline_header,
428 network_state, 360 network_state,
429 job, 361 job,
430 web_contents_getter)); 362 web_contents_getter));
431 } 363 }
432 364
433 void FindPageWithOfflineIDDone( 365 void FindPageWithOfflineIDDone(
434 const GURL& online_url, 366 const GURL& online_url,
367 const OfflinePageHeader& offline_header,
435 NetworkState network_state, 368 NetworkState network_state,
436 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, 369 content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
437 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter, 370 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter,
438 base::WeakPtr<OfflinePageRequestJob> job, 371 base::WeakPtr<OfflinePageRequestJob> job,
439 const OfflinePageItem* offline_page) { 372 const OfflinePageItem* offline_page) {
440 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 373 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
441 374
442 // If the found offline page does not has same URL as the request URL, fall 375 // If the found offline page does not has same URL as the request URL, fall
443 // back to find the offline page based on the URL. 376 // back to find the offline page based on the URL.
444 if (!offline_page || offline_page->url != online_url) { 377 if (!offline_page || offline_page->url != online_url) {
445 SelectPageForOnlineURL( 378 SelectPageForOnlineURL(
446 online_url, network_state, web_contents_getter, tab_id_getter, job); 379 online_url, offline_header, network_state, web_contents_getter,
380 tab_id_getter, job);
447 return; 381 return;
448 } 382 }
449 383
450 SucceededToFindOfflinePage( 384 SucceededToFindOfflinePage(
451 network_state, job, web_contents_getter, offline_page); 385 offline_header, network_state, job, web_contents_getter, offline_page);
452 } 386 }
453 387
454 // Tries to find an offline page associated with |offline_id|. 388 // Tries to find an offline page associated with |offline_id|.
455 void FindPageWithOfflineID( 389 void FindPageWithOfflineID(
456 const GURL& online_url, 390 const GURL& online_url,
391 const OfflinePageHeader& offline_header,
457 int64_t offline_id, 392 int64_t offline_id,
458 NetworkState network_state, 393 NetworkState network_state,
459 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, 394 content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
460 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter, 395 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter,
461 base::WeakPtr<OfflinePageRequestJob> job) { 396 base::WeakPtr<OfflinePageRequestJob> job) {
462 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 397 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
463 398
464 OfflinePageModel* offline_page_model = 399 OfflinePageModel* offline_page_model =
465 GetOfflinePageModel(web_contents_getter); 400 GetOfflinePageModel(web_contents_getter);
466 if (!offline_page_model) { 401 if (!offline_page_model) {
467 FailedToFindOfflinePage(job); 402 FailedToFindOfflinePage(job);
468 return; 403 return;
469 } 404 }
470 405
471 offline_page_model->GetPageByOfflineId( 406 offline_page_model->GetPageByOfflineId(
472 offline_id, 407 offline_id,
473 base::Bind(&FindPageWithOfflineIDDone, 408 base::Bind(&FindPageWithOfflineIDDone,
474 online_url, 409 online_url,
410 offline_header,
475 network_state, 411 network_state,
476 web_contents_getter, 412 web_contents_getter,
477 tab_id_getter, 413 tab_id_getter,
478 job)); 414 job));
479 } 415 }
480 416
481 // Tries to find the offline page to serve for |online_url|. 417 // Tries to find the offline page to serve for |online_url|.
482 void SelectPage( 418 void SelectPage(
483 const GURL& online_url, 419 const GURL& online_url,
484 const std::string& offline_header_string, 420 const OfflinePageHeader& offline_header,
485 NetworkState network_state, 421 NetworkState network_state,
486 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, 422 content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
487 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter, 423 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter,
488 base::WeakPtr<OfflinePageRequestJob> job) { 424 base::WeakPtr<OfflinePageRequestJob> job) {
489 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 425 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
490 426
491 OfflinePageHeader offline_header(offline_header_string);
492
493 // If an offline ID is present in the offline header, try to load that 427 // If an offline ID is present in the offline header, try to load that
494 // particular version. 428 // particular version.
495 if (!offline_header.id().empty()) { 429 if (!offline_header.id.empty()) {
496 // if the id string cannot be converted to int64 id, fall through to 430 // if the id string cannot be converted to int64 id, fall through to
497 // select page via online URL. 431 // select page via online URL.
498 int64_t offline_id; 432 int64_t offline_id;
499 if (base::StringToInt64(offline_header.id(), &offline_id)) { 433 if (base::StringToInt64(offline_header.id, &offline_id)) {
500 FindPageWithOfflineID(online_url, offline_id, network_state, 434 FindPageWithOfflineID(online_url, offline_header, offline_id,
501 web_contents_getter, tab_id_getter, job); 435 network_state, web_contents_getter, tab_id_getter,
436 job);
502 return; 437 return;
503 } 438 }
504 } 439 }
505 440
506 SelectPageForOnlineURL(online_url, network_state, web_contents_getter, 441 SelectPageForOnlineURL(online_url, offline_header, network_state,
507 tab_id_getter, job); 442 web_contents_getter, tab_id_getter, job);
508 } 443 }
509 444
510 } // namespace 445 } // namespace
511 446
512 // static 447 // static
513 void OfflinePageRequestJob::ReportAggregatedRequestResult( 448 void OfflinePageRequestJob::ReportAggregatedRequestResult(
514 AggregatedRequestResult result) { 449 AggregatedRequestResult result) {
515 UMA_HISTOGRAM_ENUMERATION("OfflinePages.AggregatedRequestResult", 450 UMA_HISTOGRAM_ENUMERATION("OfflinePages.AggregatedRequestResult",
516 static_cast<int>(result), 451 static_cast<int>(result),
517 static_cast<int>(AggregatedRequestResult::AGGREGATED_REQUEST_RESULT_MAX)); 452 static_cast<int>(AggregatedRequestResult::AGGREGATED_REQUEST_RESULT_MAX));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 OfflinePageRequestJob::~OfflinePageRequestJob() { 506 OfflinePageRequestJob::~OfflinePageRequestJob() {
572 } 507 }
573 508
574 void OfflinePageRequestJob::Start() { 509 void OfflinePageRequestJob::Start() {
575 base::ThreadTaskRunnerHandle::Get()->PostTask( 510 base::ThreadTaskRunnerHandle::Get()->PostTask(
576 FROM_HERE, base::Bind(&OfflinePageRequestJob::StartAsync, 511 FROM_HERE, base::Bind(&OfflinePageRequestJob::StartAsync,
577 weak_ptr_factory_.GetWeakPtr())); 512 weak_ptr_factory_.GetWeakPtr()));
578 } 513 }
579 514
580 void OfflinePageRequestJob::StartAsync() { 515 void OfflinePageRequestJob::StartAsync() {
581 NetworkState network_state = GetNetworkState(request()); 516 std::string offline_header_value;
517 request()->extra_request_headers().GetHeader(
518 kOfflinePageHeader, &offline_header_value);
519 // Note that |offline_header| will be empty if parsing from the header value
520 // fails.
521 OfflinePageHeader offline_header(offline_header_value);
522
523 NetworkState network_state = GetNetworkState(request(), offline_header);
582 if (network_state == NetworkState::CONNECTED_NETWORK) { 524 if (network_state == NetworkState::CONNECTED_NETWORK) {
583 FallbackToDefault(); 525 FallbackToDefault();
584 return; 526 return;
585 } 527 }
586 528
587 std::string offline_header_string;
588 request()->extra_request_headers().GetHeader(kOfflinePageHeader,
589 &offline_header_string);
590 content::BrowserThread::PostTask( 529 content::BrowserThread::PostTask(
591 content::BrowserThread::UI, 530 content::BrowserThread::UI,
592 FROM_HERE, 531 FROM_HERE,
593 base::Bind(&SelectPage, 532 base::Bind(&SelectPage,
594 request()->url(), 533 request()->url(),
595 offline_header_string, 534 offline_header,
596 network_state, 535 network_state,
597 delegate_->GetWebContentsGetter(request()), 536 delegate_->GetWebContentsGetter(request()),
598 delegate_->GetTabIdGetter(), 537 delegate_->GetTabIdGetter(),
599 weak_ptr_factory_.GetWeakPtr())); 538 weak_ptr_factory_.GetWeakPtr()));
600 } 539 }
601 540
602 void OfflinePageRequestJob::Kill() { 541 void OfflinePageRequestJob::Kill() {
603 net::URLRequestJob::Kill(); 542 net::URLRequestJob::Kill();
604 weak_ptr_factory_.InvalidateWeakPtrs(); 543 weak_ptr_factory_.InvalidateWeakPtrs();
605 } 544 }
(...skipping 20 matching lines...) Expand all
626 file_path_ = offline_file_path; 565 file_path_ = offline_file_path;
627 URLRequestFileJob::Start(); 566 URLRequestFileJob::Start();
628 } 567 }
629 568
630 void OfflinePageRequestJob::SetDelegateForTesting( 569 void OfflinePageRequestJob::SetDelegateForTesting(
631 std::unique_ptr<Delegate> delegate) { 570 std::unique_ptr<Delegate> delegate) {
632 delegate_ = std::move(delegate); 571 delegate_ = std::move(delegate);
633 } 572 }
634 573
635 } // namespace offline_pages 574 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698