| OLD | NEW |
| 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/bind_helpers.h" |
| 10 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" | 16 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" |
| 16 #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h" | 17 #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h" |
| 17 #include "chrome/browser/android/offline_pages/offline_page_utils.h" | 18 #include "chrome/browser/android/offline_pages/offline_page_utils.h" |
| 18 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/profiles/profile_manager.h" | 20 #include "chrome/browser/profiles/profile_manager.h" |
| 21 #include "components/offline_pages/loaded_offline_page_info.h" |
| 22 #include "components/offline_pages/offline_page_item.h" |
| 20 #include "components/offline_pages/offline_page_model.h" | 23 #include "components/offline_pages/offline_page_model.h" |
| 21 #include "components/offline_pages/request_header/offline_page_header.h" | 24 #include "components/offline_pages/request_header/offline_page_header.h" |
| 22 #include "components/previews/core/previews_decider.h" | 25 #include "components/previews/core/previews_decider.h" |
| 23 #include "components/previews/core/previews_opt_out_store.h" | 26 #include "components/previews/core/previews_opt_out_store.h" |
| 24 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/browser/resource_request_info.h" | 28 #include "content/public/browser/resource_request_info.h" |
| 26 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
| 27 #include "content/public/common/resource_type.h" | 30 #include "content/public/common/resource_type.h" |
| 28 #include "net/base/network_change_notifier.h" | 31 #include "net/base/network_change_notifier.h" |
| 29 #include "net/http/http_request_headers.h" | 32 #include "net/http/http_request_headers.h" |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 content::ResourceRequestInfo::WebContentsGetter web_contents_getter) { | 205 content::ResourceRequestInfo::WebContentsGetter web_contents_getter) { |
| 203 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 206 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 204 | 207 |
| 205 content::WebContents* web_contents = web_contents_getter.Run(); | 208 content::WebContents* web_contents = web_contents_getter.Run(); |
| 206 return web_contents ? | 209 return web_contents ? |
| 207 OfflinePageModelFactory::GetForBrowserContext( | 210 OfflinePageModelFactory::GetForBrowserContext( |
| 208 web_contents->GetBrowserContext()) : | 211 web_contents->GetBrowserContext()) : |
| 209 nullptr; | 212 nullptr; |
| 210 } | 213 } |
| 211 | 214 |
| 212 void NotifyOfflineFilePathOnIO(base::WeakPtr<OfflinePageRequestJob> job, | 215 void NotifyOfflineFilePathOnIO( |
| 213 const base::FilePath& offline_file_path) { | 216 base::WeakPtr<OfflinePageRequestJob> job, |
| 217 const base::FilePath& offline_file_path, |
| 218 std::unique_ptr<OfflinePageHeader> offline_header, |
| 219 std::unique_ptr<OfflinePageItem> offline_page) { |
| 214 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 220 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 215 | 221 |
| 216 if (!job) | 222 if (!job) |
| 217 return; | 223 return; |
| 218 job->OnOfflineFilePathAvailable(offline_file_path); | 224 job->OnOfflineFilePathAvailable(offline_file_path, std::move(offline_header), |
| 225 std::move(offline_page)); |
| 219 } | 226 } |
| 220 | 227 |
| 221 // Notifies OfflinePageRequestJob about the offline file path. Note that the | 228 // Notifies OfflinePageRequestJob about the offline file path. Note that the |
| 222 // file path may be empty if not found or on error. | 229 // file path may be empty if not found or on error. |
| 223 void NotifyOfflineFilePathOnUI(base::WeakPtr<OfflinePageRequestJob> job, | 230 void NotifyOfflineFilePathOnUI(base::WeakPtr<OfflinePageRequestJob> job, |
| 224 const base::FilePath& offline_file_path) { | 231 const base::FilePath& offline_file_path, |
| 232 const OfflinePageHeader* offline_header, |
| 233 const OfflinePageItem* offline_page) { |
| 225 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 234 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 226 | 235 |
| 236 std::unique_ptr<OfflinePageHeader> offline_page_header; |
| 237 std::unique_ptr<OfflinePageItem> offline_page_item; |
| 238 |
| 239 if (offline_header && offline_page) { |
| 240 offline_page_header.reset(new OfflinePageHeader(*offline_header)); |
| 241 offline_page_item.reset(new OfflinePageItem(*offline_page)); |
| 242 } |
| 243 |
| 227 // Delegates to IO thread since OfflinePageRequestJob should only be accessed | 244 // Delegates to IO thread since OfflinePageRequestJob should only be accessed |
| 228 // from IO thread. | 245 // from IO thread. |
| 229 content::BrowserThread::PostTask( | 246 content::BrowserThread::PostTask( |
| 230 content::BrowserThread::IO, | 247 content::BrowserThread::IO, FROM_HERE, |
| 231 FROM_HERE, | 248 base::Bind(&NotifyOfflineFilePathOnIO, job, offline_file_path, |
| 232 base::Bind(&NotifyOfflineFilePathOnIO, job, offline_file_path)); | 249 base::Passed(&offline_page_header), |
| 250 base::Passed(&offline_page_item))); |
| 233 } | 251 } |
| 234 | 252 |
| 235 // Finds the offline file path based on the select page result and network | 253 // Finds the offline file path based on the select page result and network |
| 236 // state and marks it as accessed. | 254 // state and marks it as accessed. |
| 237 RequestResult AccessOfflineFile( | 255 RequestResult AccessOfflineFile( |
| 238 const OfflinePageHeader& offline_header, | 256 const OfflinePageHeader& offline_header, |
| 239 NetworkState network_state, | 257 NetworkState network_state, |
| 240 base::WeakPtr<OfflinePageRequestJob> job, | 258 base::WeakPtr<OfflinePageRequestJob> job, |
| 241 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, | 259 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, |
| 242 const OfflinePageItem* offline_page, | 260 const OfflinePageItem* offline_page, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 263 | 281 |
| 264 // Since offline page will be loaded, it should be marked as accessed. | 282 // Since offline page will be loaded, it should be marked as accessed. |
| 265 OfflinePageModel* offline_page_model = | 283 OfflinePageModel* offline_page_model = |
| 266 OfflinePageModelFactory::GetForBrowserContext( | 284 OfflinePageModelFactory::GetForBrowserContext( |
| 267 web_contents->GetBrowserContext()); | 285 web_contents->GetBrowserContext()); |
| 268 // |offline_page_model| cannot be null because OfflinePageRequestInterceptor | 286 // |offline_page_model| cannot be null because OfflinePageRequestInterceptor |
| 269 // will not be created under incognito mode. | 287 // will not be created under incognito mode. |
| 270 DCHECK(offline_page_model); | 288 DCHECK(offline_page_model); |
| 271 offline_page_model->MarkPageAccessed(offline_page->offline_id); | 289 offline_page_model->MarkPageAccessed(offline_page->offline_id); |
| 272 | 290 |
| 273 // Save an cached copy of OfflinePageItem such that Tab code can get | |
| 274 // the loaded offline page immediately. | |
| 275 OfflinePageTabHelper* tab_helper = | |
| 276 OfflinePageTabHelper::FromWebContents(web_contents); | |
| 277 DCHECK(tab_helper); | |
| 278 tab_helper->SetOfflinePage( | |
| 279 *offline_page, | |
| 280 offline_header, | |
| 281 network_state == NetworkState::PROHIBITIVELY_SLOW_NETWORK); | |
| 282 | |
| 283 *offline_file_path = offline_page->file_path; | 291 *offline_file_path = offline_page->file_path; |
| 284 return RequestResult::OFFLINE_PAGE_SERVED; | 292 return RequestResult::OFFLINE_PAGE_SERVED; |
| 285 } | 293 } |
| 286 | 294 |
| 287 // Handles the result of finding an offline page. | 295 // Handles the result of finding an offline page. |
| 288 void SucceededToFindOfflinePage( | 296 void SucceededToFindOfflinePage( |
| 289 const OfflinePageHeader& offline_header, | 297 const OfflinePageHeader& offline_header, |
| 290 NetworkState network_state, | 298 NetworkState network_state, |
| 291 base::WeakPtr<OfflinePageRequestJob> job, | 299 base::WeakPtr<OfflinePageRequestJob> job, |
| 292 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, | 300 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, |
| 293 const OfflinePageItem* offline_page) { | 301 const OfflinePageItem* offline_page) { |
| 294 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 302 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 295 | 303 |
| 296 base::FilePath offline_file_path; | 304 base::FilePath offline_file_path; |
| 297 RequestResult request_result = AccessOfflineFile( | 305 RequestResult request_result = AccessOfflineFile( |
| 298 offline_header, network_state, job, web_contents_getter, offline_page, | 306 offline_header, network_state, job, web_contents_getter, offline_page, |
| 299 &offline_file_path); | 307 &offline_file_path); |
| 300 | 308 |
| 301 ReportRequestResult(request_result, network_state); | 309 ReportRequestResult(request_result, network_state); |
| 302 | 310 |
| 303 // NotifyOfflineFilePathOnUI should always be called regardless the failure | 311 // NotifyOfflineFilePathOnUI should always be called regardless the failure |
| 304 // result and empty file path such that OfflinePageRequestJob will be notified | 312 // result and empty file path such that OfflinePageRequestJob will be notified |
| 305 // on failure. | 313 // on failure. |
| 306 NotifyOfflineFilePathOnUI(job, offline_file_path); | 314 NotifyOfflineFilePathOnUI(job, offline_file_path, &offline_header, |
| 315 offline_page); |
| 307 } | 316 } |
| 308 | 317 |
| 309 void FailedToFindOfflinePage(base::WeakPtr<OfflinePageRequestJob> job) { | 318 void FailedToFindOfflinePage(base::WeakPtr<OfflinePageRequestJob> job) { |
| 310 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 319 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 311 | 320 |
| 312 // Proceed with empty file path in order to notify the OfflinePageRequestJob | 321 // Proceed with empty file path in order to notify the OfflinePageRequestJob |
| 313 // about the failure. | 322 // about the failure. |
| 314 base::FilePath empty_file_path; | 323 base::FilePath empty_file_path; |
| 315 NotifyOfflineFilePathOnUI(job, empty_file_path); | 324 NotifyOfflineFilePathOnUI(job, empty_file_path, nullptr, nullptr); |
| 316 } | 325 } |
| 317 | 326 |
| 318 // Tries to find the offline page to serve for |online_url|. | 327 // Tries to find the offline page to serve for |online_url|. |
| 319 void SelectPageForOnlineURL( | 328 void SelectPageForOnlineURL( |
| 320 const GURL& online_url, | 329 const GURL& online_url, |
| 321 const OfflinePageHeader& offline_header, | 330 const OfflinePageHeader& offline_header, |
| 322 NetworkState network_state, | 331 NetworkState network_state, |
| 323 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, | 332 content::ResourceRequestInfo::WebContentsGetter web_contents_getter, |
| 324 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter, | 333 OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter, |
| 325 base::WeakPtr<OfflinePageRequestJob> job) { | 334 base::WeakPtr<OfflinePageRequestJob> job) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 void OfflinePageRequestJob::StartAsync() { | 513 void OfflinePageRequestJob::StartAsync() { |
| 505 std::string offline_header_value; | 514 std::string offline_header_value; |
| 506 request()->extra_request_headers().GetHeader( | 515 request()->extra_request_headers().GetHeader( |
| 507 kOfflinePageHeader, &offline_header_value); | 516 kOfflinePageHeader, &offline_header_value); |
| 508 // Note that |offline_header| will be empty if parsing from the header value | 517 // Note that |offline_header| will be empty if parsing from the header value |
| 509 // fails. | 518 // fails. |
| 510 OfflinePageHeader offline_header(offline_header_value); | 519 OfflinePageHeader offline_header(offline_header_value); |
| 511 | 520 |
| 512 NetworkState network_state = | 521 NetworkState network_state = |
| 513 GetNetworkState(request(), offline_header, previews_decider_); | 522 GetNetworkState(request(), offline_header, previews_decider_); |
| 523 was_started_as_preview_ = |
| 524 network_state == NetworkState::PROHIBITIVELY_SLOW_NETWORK; |
| 514 if (network_state == NetworkState::CONNECTED_NETWORK) { | 525 if (network_state == NetworkState::CONNECTED_NETWORK) { |
| 515 FallbackToDefault(); | 526 FallbackToDefault(); |
| 516 return; | 527 return; |
| 517 } | 528 } |
| 518 | 529 |
| 519 content::BrowserThread::PostTask( | 530 content::BrowserThread::PostTask( |
| 520 content::BrowserThread::UI, | 531 content::BrowserThread::UI, |
| 521 FROM_HERE, | 532 FROM_HERE, |
| 522 base::Bind(&SelectPage, | 533 base::Bind(&SelectPage, |
| 523 request()->url(), | 534 request()->url(), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 536 void OfflinePageRequestJob::FallbackToDefault() { | 547 void OfflinePageRequestJob::FallbackToDefault() { |
| 537 OfflinePageRequestInfo* info = | 548 OfflinePageRequestInfo* info = |
| 538 OfflinePageRequestInfo::GetFromRequest(request()); | 549 OfflinePageRequestInfo::GetFromRequest(request()); |
| 539 DCHECK(info); | 550 DCHECK(info); |
| 540 info->set_use_default(true); | 551 info->set_use_default(true); |
| 541 | 552 |
| 542 URLRequestJob::NotifyRestartRequired(); | 553 URLRequestJob::NotifyRestartRequired(); |
| 543 } | 554 } |
| 544 | 555 |
| 545 void OfflinePageRequestJob::OnOfflineFilePathAvailable( | 556 void OfflinePageRequestJob::OnOfflineFilePathAvailable( |
| 546 const base::FilePath& offline_file_path) { | 557 const base::FilePath& offline_file_path, |
| 558 std::unique_ptr<OfflinePageHeader> offline_header, |
| 559 std::unique_ptr<OfflinePageItem> offline_page) { |
| 547 // If offline file path is empty, it means that offline page cannot be found | 560 // If offline file path is empty, it means that offline page cannot be found |
| 548 // and we want to restart the job to fall back to the default handling. | 561 // and we want to restart the job to fall back to the default handling. |
| 549 if (offline_file_path.empty()) { | 562 if (offline_file_path.empty()) { |
| 550 FallbackToDefault(); | 563 FallbackToDefault(); |
| 551 return; | 564 return; |
| 552 } | 565 } |
| 553 | 566 |
| 567 // Add LoadedOfflinePageInfo to the request. |
| 568 if (offline_header && offline_page) { |
| 569 LoadedOfflinePageInfo::CreateInfoForRequest( |
| 570 request(), std::move(offline_page), std::move(offline_header), |
| 571 was_started_as_preview_); |
| 572 } |
| 573 |
| 554 // Sets the file path and lets URLRequestFileJob start to read from the file. | 574 // Sets the file path and lets URLRequestFileJob start to read from the file. |
| 555 file_path_ = offline_file_path; | 575 file_path_ = offline_file_path; |
| 556 URLRequestFileJob::Start(); | 576 URLRequestFileJob::Start(); |
| 557 } | 577 } |
| 558 | 578 |
| 559 void OfflinePageRequestJob::SetDelegateForTesting( | 579 void OfflinePageRequestJob::SetDelegateForTesting( |
| 560 std::unique_ptr<Delegate> delegate) { | 580 std::unique_ptr<Delegate> delegate) { |
| 561 delegate_ = std::move(delegate); | 581 delegate_ = std::move(delegate); |
| 562 } | 582 } |
| 563 | 583 |
| 564 } // namespace offline_pages | 584 } // namespace offline_pages |
| OLD | NEW |