| Index: chrome/browser/android/offline_pages/offline_page_request_job.cc
|
| diff --git a/chrome/browser/android/offline_pages/offline_page_request_job.cc b/chrome/browser/android/offline_pages/offline_page_request_job.cc
|
| index 5f161416f40d0223d35eaf4c058085e8962459ee..ee7766147bc1c1a1bea362eb0d39db77de44774c 100644
|
| --- a/chrome/browser/android/offline_pages/offline_page_request_job.cc
|
| +++ b/chrome/browser/android/offline_pages/offline_page_request_job.cc
|
| @@ -1,29 +1,32 @@
|
| // Copyright 2016 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| #include "chrome/browser/android/offline_pages/offline_page_request_job.h"
|
|
|
| #include <string>
|
|
|
| #include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| #include "base/files/file_path.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram_macros.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
|
| #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h"
|
| #include "chrome/browser/android/offline_pages/offline_page_utils.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/profiles/profile_manager.h"
|
| +#include "components/offline_pages/loaded_offline_page_info.h"
|
| +#include "components/offline_pages/offline_page_item.h"
|
| #include "components/offline_pages/offline_page_model.h"
|
| #include "components/offline_pages/request_header/offline_page_header.h"
|
| #include "components/previews/core/previews_decider.h"
|
| #include "components/previews/core/previews_opt_out_store.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/resource_request_info.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "content/public/common/resource_type.h"
|
| #include "net/base/network_change_notifier.h"
|
| #include "net/http/http_request_headers.h"
|
| @@ -103,22 +106,21 @@ class DefaultDelegate : public OfflinePageRequestJob::Delegate {
|
|
|
| private:
|
| static bool GetTabId(content::WebContents* web_contents, int* tab_id) {
|
| return OfflinePageUtils::GetTabId(web_contents, tab_id);
|
| }
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
|
| };
|
|
|
| NetworkState GetNetworkState(net::URLRequest* request,
|
| - const OfflinePageHeader& offline_header,
|
| - previews::PreviewsDecider* previews_decider) {
|
| + const OfflinePageHeader& offline_header) {
|
| DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
|
|
| if (offline_header.reason == OfflinePageHeader::Reason::NET_ERROR)
|
| return NetworkState::FLAKY_NETWORK;
|
|
|
| if (net::NetworkChangeNotifier::IsOffline())
|
| return NetworkState::DISCONNECTED_NETWORK;
|
| // Checks if previews are allowed, the network is slow, and the request is
|
| // allowed to be shown for previews.
|
| if (previews_decider &&
|
| @@ -202,41 +204,56 @@ OfflinePageModel* GetOfflinePageModel(
|
| content::ResourceRequestInfo::WebContentsGetter web_contents_getter) {
|
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
|
| content::WebContents* web_contents = web_contents_getter.Run();
|
| return web_contents ?
|
| OfflinePageModelFactory::GetForBrowserContext(
|
| web_contents->GetBrowserContext()) :
|
| nullptr;
|
| }
|
|
|
| -void NotifyOfflineFilePathOnIO(base::WeakPtr<OfflinePageRequestJob> job,
|
| - const base::FilePath& offline_file_path) {
|
| +void NotifyOfflineFilePathOnIO(
|
| + base::WeakPtr<OfflinePageRequestJob> job,
|
| + const base::FilePath& offline_file_path,
|
| + std::unique_ptr<OfflinePageHeader> offline_header,
|
| + std::unique_ptr<OfflinePageItem> offline_page) {
|
| DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
|
|
| if (!job)
|
| return;
|
| - job->OnOfflineFilePathAvailable(offline_file_path);
|
| + job->OnOfflineFilePathAvailable(offline_file_path, std::move(offline_header),
|
| + std::move(offline_page));
|
| }
|
|
|
| // Notifies OfflinePageRequestJob about the offline file path. Note that the
|
| // file path may be empty if not found or on error.
|
| void NotifyOfflineFilePathOnUI(base::WeakPtr<OfflinePageRequestJob> job,
|
| - const base::FilePath& offline_file_path) {
|
| + const base::FilePath& offline_file_path,
|
| + const OfflinePageHeader* offline_header,
|
| + const OfflinePageItem* offline_page) {
|
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
|
| + std::unique_ptr<OfflinePageHeader> offline_page_header;
|
| + std::unique_ptr<OfflinePageItem> offline_page_item;
|
| +
|
| + if (offline_header && offline_page) {
|
| + offline_page_header.reset(new OfflinePageHeader(*offline_header));
|
| + offline_page_item.reset(new OfflinePageItem(*offline_page));
|
| + }
|
| +
|
| // Delegates to IO thread since OfflinePageRequestJob should only be accessed
|
| // from IO thread.
|
| content::BrowserThread::PostTask(
|
| - content::BrowserThread::IO,
|
| - FROM_HERE,
|
| - base::Bind(&NotifyOfflineFilePathOnIO, job, offline_file_path));
|
| + content::BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&NotifyOfflineFilePathOnIO, job, offline_file_path,
|
| + base::Passed(&offline_page_header),
|
| + base::Passed(&offline_page_item)));
|
| }
|
|
|
| // Finds the offline file path based on the select page result and network
|
| // state and marks it as accessed.
|
| RequestResult AccessOfflineFile(
|
| const OfflinePageHeader& offline_header,
|
| NetworkState network_state,
|
| base::WeakPtr<OfflinePageRequestJob> job,
|
| content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
| const OfflinePageItem* offline_page,
|
| @@ -263,30 +280,20 @@ RequestResult AccessOfflineFile(
|
|
|
| // Since offline page will be loaded, it should be marked as accessed.
|
| OfflinePageModel* offline_page_model =
|
| OfflinePageModelFactory::GetForBrowserContext(
|
| web_contents->GetBrowserContext());
|
| // |offline_page_model| cannot be null because OfflinePageRequestInterceptor
|
| // will not be created under incognito mode.
|
| DCHECK(offline_page_model);
|
| offline_page_model->MarkPageAccessed(offline_page->offline_id);
|
|
|
| - // Save an cached copy of OfflinePageItem such that Tab code can get
|
| - // the loaded offline page immediately.
|
| - OfflinePageTabHelper* tab_helper =
|
| - OfflinePageTabHelper::FromWebContents(web_contents);
|
| - DCHECK(tab_helper);
|
| - tab_helper->SetOfflinePage(
|
| - *offline_page,
|
| - offline_header,
|
| - network_state == NetworkState::PROHIBITIVELY_SLOW_NETWORK);
|
| -
|
| *offline_file_path = offline_page->file_path;
|
| return RequestResult::OFFLINE_PAGE_SERVED;
|
| }
|
|
|
| // Handles the result of finding an offline page.
|
| void SucceededToFindOfflinePage(
|
| const OfflinePageHeader& offline_header,
|
| NetworkState network_state,
|
| base::WeakPtr<OfflinePageRequestJob> job,
|
| content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
| @@ -296,30 +303,31 @@ void SucceededToFindOfflinePage(
|
| base::FilePath offline_file_path;
|
| RequestResult request_result = AccessOfflineFile(
|
| offline_header, network_state, job, web_contents_getter, offline_page,
|
| &offline_file_path);
|
|
|
| ReportRequestResult(request_result, network_state);
|
|
|
| // NotifyOfflineFilePathOnUI should always be called regardless the failure
|
| // result and empty file path such that OfflinePageRequestJob will be notified
|
| // on failure.
|
| - NotifyOfflineFilePathOnUI(job, offline_file_path);
|
| + NotifyOfflineFilePathOnUI(job, offline_file_path, &offline_header,
|
| + offline_page);
|
| }
|
|
|
| void FailedToFindOfflinePage(base::WeakPtr<OfflinePageRequestJob> job) {
|
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
|
| // Proceed with empty file path in order to notify the OfflinePageRequestJob
|
| // about the failure.
|
| base::FilePath empty_file_path;
|
| - NotifyOfflineFilePathOnUI(job, empty_file_path);
|
| + NotifyOfflineFilePathOnUI(job, empty_file_path, nullptr, nullptr);
|
| }
|
|
|
| // Tries to find the offline page to serve for |online_url|.
|
| void SelectPageForOnlineURL(
|
| const GURL& online_url,
|
| const OfflinePageHeader& offline_header,
|
| NetworkState network_state,
|
| content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
|
| OfflinePageRequestJob::Delegate::TabIdGetter tab_id_getter,
|
| base::WeakPtr<OfflinePageRequestJob> job) {
|
| @@ -504,20 +512,22 @@ void OfflinePageRequestJob::Start() {
|
| void OfflinePageRequestJob::StartAsync() {
|
| std::string offline_header_value;
|
| request()->extra_request_headers().GetHeader(
|
| kOfflinePageHeader, &offline_header_value);
|
| // Note that |offline_header| will be empty if parsing from the header value
|
| // fails.
|
| OfflinePageHeader offline_header(offline_header_value);
|
|
|
| NetworkState network_state =
|
| GetNetworkState(request(), offline_header, previews_decider_);
|
| + was_started_as_preview_ =
|
| + network_state == NetworkState::PROHIBITIVELY_SLOW_NETWORK;
|
| if (network_state == NetworkState::CONNECTED_NETWORK) {
|
| FallbackToDefault();
|
| return;
|
| }
|
|
|
| content::BrowserThread::PostTask(
|
| content::BrowserThread::UI,
|
| FROM_HERE,
|
| base::Bind(&SelectPage,
|
| request()->url(),
|
| @@ -536,28 +546,37 @@ void OfflinePageRequestJob::Kill() {
|
| void OfflinePageRequestJob::FallbackToDefault() {
|
| OfflinePageRequestInfo* info =
|
| OfflinePageRequestInfo::GetFromRequest(request());
|
| DCHECK(info);
|
| info->set_use_default(true);
|
|
|
| URLRequestJob::NotifyRestartRequired();
|
| }
|
|
|
| void OfflinePageRequestJob::OnOfflineFilePathAvailable(
|
| - const base::FilePath& offline_file_path) {
|
| + const base::FilePath& offline_file_path,
|
| + std::unique_ptr<OfflinePageHeader> offline_header,
|
| + std::unique_ptr<OfflinePageItem> offline_page) {
|
| // If offline file path is empty, it means that offline page cannot be found
|
| // and we want to restart the job to fall back to the default handling.
|
| if (offline_file_path.empty()) {
|
| FallbackToDefault();
|
| return;
|
| }
|
|
|
| + // Add LoadedOfflinePageInfo to the request.
|
| + if (offline_header && offline_page) {
|
| + LoadedOfflinePageInfo::CreateInfoForRequest(
|
| + request(), std::move(offline_page), std::move(offline_header),
|
| + was_started_as_preview_);
|
| + }
|
| +
|
| // Sets the file path and lets URLRequestFileJob start to read from the file.
|
| file_path_ = offline_file_path;
|
| URLRequestFileJob::Start();
|
| }
|
|
|
| void OfflinePageRequestJob::SetDelegateForTesting(
|
| std::unique_ptr<Delegate> delegate) {
|
| delegate_ = std::move(delegate);
|
| }
|
|
|
|
|