Commit 1a157ed5 authored by Dan Harrington's avatar Dan Harrington Committed by Commit Bot

prefetch: Enable thumbnail fetching with feed

Article thumbnails are now fetched for suggestions from feed.
We fetch with the cached image fetcher, which is shared with feed.

Bug: 841522
Change-Id: I283fa2ea145341fb28dd337026a57abbd36aec77
Reviewed-on: https://chromium-review.googlesource.com/c/1344549
Commit-Queue: Dan H <harringtond@google.com>
Reviewed-by: default avatarMartin Šrámek <msramek@chromium.org>
Reviewed-by: default avatarFilip Gorski <fgorski@chromium.org>
Reviewed-by: default avatarCarlos Knippschild <carlosk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612814}
parent c40a10c1
......@@ -11,6 +11,7 @@
#include "base/memory/singleton.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.h"
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/ntp_snippets/content_suggestions_service_factory.h"
#include "chrome/browser/offline_pages/offline_page_model_factory.h"
......@@ -23,6 +24,9 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
#include "components/feed/feed_feature_list.h"
#include "components/image_fetcher/core/cached_image_fetcher.h"
#include "components/image_fetcher/core/cached_image_fetcher_service.h"
#include "components/image_fetcher/core/image_fetcher_impl.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h"
#include "components/offline_pages/core/prefetch/prefetch_downloader_impl.h"
......@@ -43,6 +47,7 @@ PrefetchServiceFactory::PrefetchServiceFactory()
BrowserContextDependencyManager::GetInstance()) {
DependsOn(DownloadServiceFactory::GetInstance());
DependsOn(OfflinePageModelFactory::GetInstance());
DependsOn(image_fetcher::CachedImageFetcherServiceFactory::GetInstance());
}
// static
......@@ -61,7 +66,6 @@ KeyedService* PrefetchServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
const bool feed_enabled =
base::FeatureList::IsEnabled(feed::kInterestFeedContentSuggestions);
Profile* profile = Profile::FromBrowserContext(context);
DCHECK(profile);
OfflinePageModel* offline_page_model =
......@@ -93,9 +97,17 @@ KeyedService* PrefetchServiceFactory::BuildServiceInstanceFor(
// Conditional components for Zine. Not created when using Feed.
std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer;
std::unique_ptr<ThumbnailFetcherImpl> thumbnail_fetcher;
// Conditional components for Feed. Not created when using Zine.
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher;
if (!feed_enabled) {
suggested_articles_observer = std::make_unique<SuggestedArticlesObserver>();
thumbnail_fetcher = std::make_unique<ThumbnailFetcherImpl>();
} else {
image_fetcher::CachedImageFetcherService* image_fetcher_service =
image_fetcher::CachedImageFetcherServiceFactory::GetForBrowserContext(
context);
DCHECK(image_fetcher_service);
thumbnail_image_fetcher = image_fetcher_service->CreateCachedImageFetcher();
}
auto prefetch_downloader = std::make_unique<PrefetchDownloaderImpl>(
......@@ -114,8 +126,8 @@ KeyedService* PrefetchServiceFactory::BuildServiceInstanceFor(
std::move(prefetch_network_request_factory), offline_page_model,
std::move(prefetch_store), std::move(suggested_articles_observer),
std::move(prefetch_downloader), std::move(prefetch_importer),
std::move(prefetch_background_task_handler),
std::move(thumbnail_fetcher));
std::move(prefetch_background_task_handler), std::move(thumbnail_fetcher),
std::move(thumbnail_image_fetcher));
}
} // namespace offline_pages
......@@ -19,8 +19,7 @@
#include "components/offline_pages/core/offline_page_archiver.h"
#include "components/offline_pages/core/offline_page_thumbnail.h"
#include "components/offline_pages/core/offline_page_types.h"
class GURL;
#include "url/gurl.h"
namespace offline_pages {
......
......@@ -74,6 +74,8 @@ static_library("prefetch") {
"tasks/generate_page_bundle_task.h",
"tasks/get_operation_task.cc",
"tasks/get_operation_task.h",
"tasks/get_thumbnail_info_task.cc",
"tasks/get_thumbnail_info_task.h",
"tasks/import_archives_task.cc",
"tasks/import_archives_task.h",
"tasks/import_cleanup_task.cc",
......@@ -90,6 +92,8 @@ static_library("prefetch") {
"tasks/sent_get_operation_cleanup_task.h",
"tasks/stale_entry_finalizer_task.cc",
"tasks/stale_entry_finalizer_task.h",
"thumbnail_fetch_by_url.cc",
"thumbnail_fetch_by_url.h",
"thumbnail_fetcher.h",
]
......@@ -102,6 +106,7 @@ static_library("prefetch") {
"//components/download/public/background_service:public",
"//components/gcm_driver",
"//components/gcm_driver/common",
"//components/image_fetcher/core",
"//components/keyed_service/core",
"//components/ntp_snippets",
"//components/offline_pages/core",
......@@ -163,6 +168,7 @@ static_library("test_support") {
"//components/download/public/background_service:public",
"//components/download/public/background_service/test:test_support",
"//components/gcm_driver/instance_id",
"//components/image_fetcher/core:test_support",
"//components/keyed_service/core",
"//components/offline_pages/core",
"//components/offline_pages/core:switches",
......@@ -227,6 +233,7 @@ source_set("unit_tests") {
"tasks/generate_page_bundle_reconcile_task_unittest.cc",
"tasks/generate_page_bundle_task_unittest.cc",
"tasks/get_operation_task_unittest.cc",
"tasks/get_thumbnail_info_task_unittest.cc",
"tasks/import_archives_task_unittest.cc",
"tasks/import_cleanup_task_unittest.cc",
"tasks/import_completed_task_unittest.cc",
......@@ -245,6 +252,7 @@ source_set("unit_tests") {
"//components/download/public/background_service:public",
"//components/download/public/background_service/test:test_support",
"//components/gcm_driver/instance_id",
"//components/image_fetcher/core:test_support",
"//components/offline_pages/core",
"//components/offline_pages/core:switches",
"//components/offline_pages/core:test_support",
......
include_rules = [
"+components/download/internal/test",
"+components/download/public",
"+components/prefs",
"+google_apis",
"+components/variations",
"+components/gcm_driver",
"+components/image_fetcher",
"+components/ntp_snippets",
"+components/prefs",
"+components/variations",
"+components/version_info",
"+google_apis",
"+net",
"+services/network/public/cpp",
"+services/network/test",
......
......@@ -45,6 +45,7 @@
#include "components/offline_pages/core/prefetch/tasks/page_bundle_update_task.h"
#include "components/offline_pages/core/prefetch/tasks/sent_get_operation_cleanup_task.h"
#include "components/offline_pages/core/prefetch/tasks/stale_entry_finalizer_task.h"
#include "components/offline_pages/core/prefetch/thumbnail_fetch_by_url.h"
#include "components/offline_pages/core/prefetch/thumbnail_fetcher.h"
#include "components/prefs/pref_service.h"
#include "url/gurl.h"
......@@ -58,8 +59,10 @@ void DeleteBackgroundTaskHelper(std::unique_ptr<PrefetchBackgroundTask> task) {
}
PrefetchURL SuggestionToPrefetchURL(PrefetchSuggestion suggestion) {
return PrefetchURL(suggestion.article_url.spec(), suggestion.article_url,
PrefetchURL result(suggestion.article_url.spec(), suggestion.article_url,
base::UTF8ToUTF16(suggestion.article_title));
result.thumbnail_url = suggestion.thumbnail_url;
return result;
}
} // namespace
......@@ -125,8 +128,8 @@ void PrefetchDispatcherImpl::NewSuggestionsAvailable(
SuggestionsProvider* suggestions_provider) {
if (!prefetch_prefs::IsEnabled(pref_service_))
return;
suggestions_provider->GetCurrentArticleSuggestions(base::BindOnce(
&PrefetchDispatcherImpl::AddSuggestions, weak_factory_.GetWeakPtr()));
suggestions_provider->GetCurrentArticleSuggestions(
base::BindOnce(&PrefetchDispatcherImpl::AddSuggestions, GetWeakPtr()));
}
void PrefetchDispatcherImpl::RemoveSuggestion(const GURL& url) {
......@@ -233,7 +236,7 @@ void PrefetchDispatcherImpl::QueueActionTasks() {
service_->GetPrefetchNetworkRequestFactory(),
base::BindOnce(
&PrefetchDispatcherImpl::DidGenerateBundleOrGetOperationRequest,
weak_factory_.GetWeakPtr(), "GetOperationRequest"));
GetWeakPtr(), "GetOperationRequest"));
task_queue_.AddTask(std::move(get_operation_task));
std::unique_ptr<Task> generate_page_bundle_task =
......@@ -242,7 +245,7 @@ void PrefetchDispatcherImpl::QueueActionTasks() {
service_->GetPrefetchNetworkRequestFactory(),
base::BindOnce(
&PrefetchDispatcherImpl::DidGenerateBundleOrGetOperationRequest,
weak_factory_.GetWeakPtr(), "GeneratePageBundleRequest"));
GetWeakPtr(), "GeneratePageBundleRequest"));
task_queue_.AddTask(std::move(generate_page_bundle_task));
}
......@@ -428,11 +431,6 @@ void PrefetchDispatcherImpl::FetchThumbnails(
if (remaining_ids->empty())
return;
// Zine/Feed
// TODO(https://crbug.com/841516): Implement thumbnail fetching with the Feed.
if (!service_->GetThumbnailFetcher())
return;
int64_t offline_id = remaining_ids->back().first;
ClientId client_id = std::move(remaining_ids->back().second);
DCHECK(client_id.name_space == kSuggestedArticlesNamespace);
......@@ -441,7 +439,7 @@ void PrefetchDispatcherImpl::FetchThumbnails(
service_->GetOfflinePageModel()->HasThumbnailForOfflineId(
offline_id,
base::BindOnce(&PrefetchDispatcherImpl::ThumbnailExistenceChecked,
base::Unretained(this), offline_id, std::move(client_id),
GetWeakPtr(), offline_id, std::move(client_id),
std::move(remaining_ids), is_first_attempt));
}
......@@ -454,12 +452,38 @@ void PrefetchDispatcherImpl::ThumbnailExistenceChecked(
if (thumbnail_exists) {
FetchThumbnails(std::move(remaining_ids), is_first_attempt);
} else {
auto complete_callback = base::BindOnce(
&PrefetchDispatcherImpl::ThumbnailFetchComplete, base::Unretained(this),
offline_id, std::move(remaining_ids), is_first_attempt);
service_->GetThumbnailFetcher()->FetchSuggestionImageData(
client_id, is_first_attempt, std::move(complete_callback));
// Zine/Feed: thumbnail_fetcher is non-null only with Zine.
ThumbnailFetcher* thumbnail_fetcher = service_->GetThumbnailFetcher();
if (thumbnail_fetcher) {
auto complete_callback = base::BindOnce(
&PrefetchDispatcherImpl::ThumbnailFetchComplete, GetWeakPtr(),
offline_id, std::move(remaining_ids), is_first_attempt);
thumbnail_fetcher->FetchSuggestionImageData(client_id, is_first_attempt,
std::move(complete_callback));
} else {
task_queue_.AddTask(std::make_unique<GetThumbnailInfoTask>(
service_->GetPrefetchStore(), offline_id,
base::BindOnce(&PrefetchDispatcherImpl::ThumbnailInfoReceived,
GetWeakPtr(), offline_id, std::move(remaining_ids),
is_first_attempt)));
}
}
}
void PrefetchDispatcherImpl::ThumbnailInfoReceived(
const int64_t offline_id,
std::unique_ptr<IdsVector> remaining_ids,
bool is_first_attempt,
GetThumbnailInfoTask::Result result) {
if (result.thumbnail_url.is_empty()) {
FetchThumbnails(std::move(remaining_ids), is_first_attempt);
return; // No thumbnail url was given to us for this page.
}
FetchThumbnailByURL(
base::BindOnce(&PrefetchDispatcherImpl::ThumbnailFetchComplete,
GetWeakPtr(), offline_id, std::move(remaining_ids),
is_first_attempt),
service_->GetThumbnailImageFetcher(), result.thumbnail_url);
}
void PrefetchDispatcherImpl::ThumbnailFetchComplete(
......
......@@ -15,6 +15,8 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
#include "components/offline_pages/core/prefetch/suggestions_provider.h"
#include "components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.h"
#include "components/offline_pages/task/task_queue.h"
#include "components/version_info/channel.h"
#include "net/url_request/url_request_context_getter.h"
......@@ -64,6 +66,10 @@ class PrefetchDispatcherImpl : public PrefetchDispatcher,
private:
friend class PrefetchDispatcherTest;
base::WeakPtr<PrefetchDispatcherImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void DisposeTask();
// Callbacks for network requests.
......@@ -112,6 +118,10 @@ class PrefetchDispatcherImpl : public PrefetchDispatcher,
std::unique_ptr<IdsVector> remaining_ids,
bool is_first_attempt,
bool thumbnail_exists);
void ThumbnailInfoReceived(const int64_t offline_id,
std::unique_ptr<IdsVector> remaining_ids,
bool is_first_attempt,
GetThumbnailInfoTask::Result result);
void ThumbnailFetchComplete(const int64_t offline_id,
std::unique_ptr<IdsVector> remaining_ids,
bool is_first_attempt,
......
......@@ -96,10 +96,9 @@ void PrefetchDownloaderImpl::StartDownload(const std::string& download_id,
policy {
cookies_allowed: NO
setting:
"Users can enable or disable the offline prefetch on desktop by "
"toggling 'Use a prediction service to load pages more quickly' in "
"settings under Privacy and security, or on Android by toggling "
"chrome://flags#offline-prefetch."
"Users can enable or disable offline prefetch by toggling "
"'Download articles for you' in settings under Downloads or "
"by toggling chrome://flags#offline-prefetch."
chrome_policy {
NetworkPredictionOptions {
NetworkPredictionOptions: 2
......
......@@ -22,6 +22,8 @@ namespace offline_pages {
// successfully or not.
// Instances of this class are in-memory representations of items in (or to be
// inserted into) the persistent prefetching data store.
//
// Only used in tests.
struct PrefetchItem {
PrefetchItem();
PrefetchItem(PrefetchItem&& other);
......
......@@ -68,8 +68,9 @@ PrefetchRequestFetcher::PrefetchRequestFetcher(
policy {
cookies_allowed: NO
setting:
"Users can enable or disable the offline prefetch by toggling"
"chrome://flags#offline-prefetch in Chromium on Android."
"Users can enable or disable offline prefetch by toggling "
"'Download articles for you' in settings under Downloads or "
"by toggling chrome://flags#offline-prefetch."
policy_exception_justification:
"Not implemented, considered not useful."
})");
......
......@@ -9,6 +9,9 @@
class GURL;
namespace image_fetcher {
class ImageFetcher;
}
namespace ntp_snippets {
class ContentSuggestionsService;
}
......@@ -92,6 +95,7 @@ class PrefetchService : public KeyedService {
// Zine/Feed: Null when using the Feed.
virtual ThumbnailFetcher* GetThumbnailFetcher() = 0;
virtual OfflinePageModel* GetOfflinePageModel() = 0;
virtual image_fetcher::ImageFetcher* GetThumbnailImageFetcher() = 0;
// Test-only methods.
......
......@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/offline_pages/core/client_id.h"
#include "components/offline_pages/core/client_namespace_constants.h"
#include "components/offline_pages/core/prefetch/offline_metrics_collector.h"
......@@ -36,7 +37,8 @@ PrefetchServiceImpl::PrefetchServiceImpl(
std::unique_ptr<PrefetchImporter> prefetch_importer,
std::unique_ptr<PrefetchBackgroundTaskHandler>
prefetch_background_task_handler,
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher)
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher,
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher)
: offline_metrics_collector_(std::move(offline_metrics_collector)),
prefetch_dispatcher_(std::move(dispatcher)),
prefetch_gcm_handler_(std::move(gcm_handler)),
......@@ -48,7 +50,8 @@ PrefetchServiceImpl::PrefetchServiceImpl(
prefetch_background_task_handler_(
std::move(prefetch_background_task_handler)),
suggested_articles_observer_(std::move(suggested_articles_observer)),
thumbnail_fetcher_(std::move(thumbnail_fetcher)) {
thumbnail_fetcher_(std::move(thumbnail_fetcher)),
thumbnail_image_fetcher_(std::move(thumbnail_image_fetcher)) {
prefetch_dispatcher_->SetService(this);
prefetch_downloader_->SetPrefetchService(this);
prefetch_gcm_handler_->SetService(this);
......@@ -73,6 +76,7 @@ void PrefetchServiceImpl::SetContentSuggestionsService(
DCHECK(suggested_articles_observer_);
DCHECK(!suggestions_provider_);
DCHECK(thumbnail_fetcher_);
DCHECK(!thumbnail_image_fetcher_);
suggested_articles_observer_->SetContentSuggestionsServiceAndObserve(
content_suggestions);
thumbnail_fetcher_->SetContentSuggestionsService(content_suggestions);
......@@ -82,6 +86,7 @@ void PrefetchServiceImpl::SetSuggestionProvider(
SuggestionsProvider* suggestions_provider) {
DCHECK(!suggested_articles_observer_);
DCHECK(!thumbnail_fetcher_);
DCHECK(thumbnail_image_fetcher_);
suggestions_provider_ = suggestions_provider;
}
......@@ -146,6 +151,10 @@ ThumbnailFetcher* PrefetchServiceImpl::GetThumbnailFetcher() {
return thumbnail_fetcher_.get();
}
image_fetcher::ImageFetcher* PrefetchServiceImpl::GetThumbnailImageFetcher() {
return thumbnail_image_fetcher_.get();
}
void PrefetchServiceImpl::Shutdown() {
suggested_articles_observer_.reset();
prefetch_downloader_.reset();
......
......@@ -30,7 +30,8 @@ class PrefetchServiceImpl : public PrefetchService {
std::unique_ptr<PrefetchDownloader> prefetch_downloader,
std::unique_ptr<PrefetchImporter> prefetch_importer,
std::unique_ptr<PrefetchBackgroundTaskHandler> background_task_handler,
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher);
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher,
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher_);
~PrefetchServiceImpl() override;
......@@ -54,9 +55,14 @@ class PrefetchServiceImpl : public PrefetchService {
PrefetchDownloader* GetPrefetchDownloader() override;
PrefetchImporter* GetPrefetchImporter() override;
PrefetchBackgroundTaskHandler* GetPrefetchBackgroundTaskHandler() override;
// Thumbnail fetchers. With Feed, GetThumbnailImageFetcher() is available
// and GetThumbnailFetcher() is null.
ThumbnailFetcher* GetThumbnailFetcher() override;
image_fetcher::ImageFetcher* GetThumbnailImageFetcher() override;
SuggestedArticlesObserver* GetSuggestedArticlesObserverForTesting() override;
// KeyedService implementation:
void Shutdown() override;
......@@ -77,6 +83,7 @@ class PrefetchServiceImpl : public PrefetchService {
// Zine/Feed: only non-null when using Zine.
std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer_;
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher_;
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher_;
// Zine/Feed: only non-null when using Feed.
SuggestionsProvider* suggestions_provider_ = nullptr;
......
......@@ -9,6 +9,8 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/mock_image_fetcher.h"
#include "components/offline_pages/core/offline_page_model.h"
#include "components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h"
#include "components/offline_pages/core/prefetch/offline_metrics_collector.h"
......@@ -79,6 +81,9 @@ PrefetchServiceTestTaco::PrefetchServiceTestTaco(SuggestionSource source) {
// result here. This allows us to not create a ContentSuggestionsService.
suggested_articles_observer_->GetTestingArticles();
thumbnail_fetcher_ = std::make_unique<MockThumbnailFetcher>();
} else {
thumbnail_image_fetcher_ =
std::make_unique<image_fetcher::MockImageFetcher>();
}
prefetch_background_task_handler_ =
......@@ -156,6 +161,12 @@ void PrefetchServiceTestTaco::SetThumbnailFetcher(
thumbnail_fetcher_ = std::move(thumbnail_fetcher);
}
void PrefetchServiceTestTaco::SetThumbnailImageFetcher(
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher) {
CHECK(!prefetch_service_);
thumbnail_image_fetcher_ = std::move(thumbnail_image_fetcher);
}
void PrefetchServiceTestTaco::SetOfflinePageModel(
std::unique_ptr<OfflinePageModel> offline_page_model) {
CHECK(!prefetch_service_);
......@@ -171,7 +182,7 @@ void PrefetchServiceTestTaco::CreatePrefetchService() {
std::move(suggested_articles_observer_), std::move(prefetch_downloader_),
std::move(prefetch_importer_),
std::move(prefetch_background_task_handler_),
std::move(thumbnail_fetcher_));
std::move(thumbnail_fetcher_), std::move(thumbnail_image_fetcher_));
}
std::unique_ptr<PrefetchService>
......
......@@ -11,6 +11,10 @@
#include "base/memory/ref_counted.h"
#include "base/threading/thread_task_runner_handle.h"
namespace image_fetcher {
class ImageFetcher;
}
namespace offline_pages {
class OfflineMetricsCollector;
class OfflinePageModel;
......@@ -71,6 +75,9 @@ class PrefetchServiceTestTaco {
prefetch_background_task_handler);
// Default type: MockThumbnailFetcher.
void SetThumbnailFetcher(std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher);
// Default type: image_fetcher::MockImageFetcher.
void SetThumbnailImageFetcher(
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher);
void SetOfflinePageModel(
std::unique_ptr<OfflinePageModel> offline_page_model);
......@@ -104,6 +111,7 @@ class PrefetchServiceTestTaco {
prefetch_background_task_handler_;
std::unique_ptr<PrefetchService> prefetch_service_;
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher_;
std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher_;
std::unique_ptr<OfflinePageModel> offline_page_model_;
std::unique_ptr<TestDownloadService> download_service_;
std::unique_ptr<TestDownloadClient> download_client_;
......
......@@ -135,6 +135,15 @@ RenderPageInfo::RenderPageInfo() = default;
RenderPageInfo::RenderPageInfo(const RenderPageInfo& other) = default;
PrefetchURL::PrefetchURL(const std::string& id,
const GURL& url,
const base::string16& title)
: id(id), url(url), title(title) {}
PrefetchURL::~PrefetchURL() = default;
PrefetchURL::PrefetchURL(const PrefetchURL& other) = default;
PrefetchDownloadResult::PrefetchDownloadResult() = default;
PrefetchDownloadResult::PrefetchDownloadResult(const std::string& download_id,
......
......@@ -213,8 +213,9 @@ using PrefetchRequestFinishedCallback =
struct PrefetchURL {
PrefetchURL(const std::string& id,
const GURL& url,
const base::string16& title)
: id(id), url(url), title(title) {}
const base::string16& title);
~PrefetchURL();
PrefetchURL(const PrefetchURL& other);
// Client provided ID to allow the matching of provided URLs to the respective
// work item in the prefetching system within that client's assigned
......@@ -227,6 +228,10 @@ struct PrefetchURL {
// The title of the page.
base::string16 title;
// URL for a thumbnail that represents the page. May be empty if no thumbnail
// is available.
GURL thumbnail_url;
};
// Result of a completed download.
......
......@@ -64,6 +64,10 @@ OfflinePageModel* StubPrefetchService::GetOfflinePageModel() {
return nullptr;
}
image_fetcher::ImageFetcher* StubPrefetchService::GetThumbnailImageFetcher() {
return nullptr;
}
SuggestedArticlesObserver*
StubPrefetchService::GetSuggestedArticlesObserverForTesting() {
return nullptr;
......
......@@ -29,6 +29,7 @@ class StubPrefetchService : public PrefetchService {
PrefetchBackgroundTaskHandler* GetPrefetchBackgroundTaskHandler() override;
ThumbnailFetcher* GetThumbnailFetcher() override;
OfflinePageModel* GetOfflinePageModel() override;
image_fetcher::ImageFetcher* GetThumbnailImageFetcher() override;
SuggestedArticlesObserver* GetSuggestedArticlesObserverForTesting() override;
};
......
......@@ -55,9 +55,9 @@ bool CreatePrefetchItemSync(sql::Database* db,
static const char kSql[] =
"INSERT INTO prefetch_items"
" (offline_id, requested_url, client_namespace, client_id, creation_time,"
" freshness_time, title)"
" freshness_time, title, thumbnail_url)"
" VALUES"
" (?, ?, ?, ?, ?, ?, ?)";
" (?, ?, ?, ?, ?, ?, ?, ?)";
sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, store_utils::GenerateOfflineId());
......@@ -67,6 +67,7 @@ bool CreatePrefetchItemSync(sql::Database* db,
statement.BindInt64(4, now_db_time);
statement.BindInt64(5, now_db_time);
statement.BindString16(6, prefetch_url.title);
statement.BindString(7, prefetch_url.thumbnail_url.spec());
return statement.Run();
}
......
......@@ -32,6 +32,7 @@ const char kClientId3[] = "ID-3";
const GURL kTestURL1("https://www.google.com/");
const GURL kTestURL2("http://www.example.com/");
const GURL kTestURL3("https://news.google.com/");
const char kTestThumbnailURL[] = "http://thumbnail.com/";
const base::string16 kTestTitle1 = base::ASCIIToUTF16("Title 1");
const base::string16 kTestTitle2 = base::ASCIIToUTF16("Title 2");
const base::string16 kTestTitle3 = base::ASCIIToUTF16("Title 3");
......@@ -69,8 +70,10 @@ TEST_F(AddUniqueUrlsTaskTest, StoreFailure) {
TEST_F(AddUniqueUrlsTaskTest, AddTaskInEmptyStore) {
std::vector<PrefetchURL> urls;
urls.push_back(PrefetchURL{kClientId1, kTestURL1, kTestTitle1});
urls.push_back(PrefetchURL{kClientId2, kTestURL2, kTestTitle2});
PrefetchURL url1{kClientId1, kTestURL1, kTestTitle1};
url1.thumbnail_url = GURL(kTestThumbnailURL);
urls.push_back(url1);
urls.emplace_back(kClientId2, kTestURL2, kTestTitle2);
RunTask(std::make_unique<AddUniqueUrlsTask>(dispatcher(), store(),
kTestNamespace, urls));
......@@ -81,6 +84,8 @@ TEST_F(AddUniqueUrlsTaskTest, AddTaskInEmptyStore) {
EXPECT_EQ(kTestNamespace, items[kClientId1].client_id.name_space);
EXPECT_EQ(kTestTitle1, items[kClientId1].title);
ASSERT_GT(items.count(kClientId2), 0U);
EXPECT_EQ(kTestThumbnailURL, items[kClientId1].thumbnail_url);
ASSERT_GT(items.count(kClientId2), 0ul);
EXPECT_EQ(kTestURL2, items[kClientId2].url);
EXPECT_EQ(kTestNamespace, items[kClientId2].client_id.name_space);
EXPECT_EQ(kTestTitle2, items[kClientId2].title);
......
// Copyright 2018 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 "components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.h"
#include <utility>
#include "components/offline_pages/core/prefetch/store/prefetch_store.h"
#include "sql/database.h"
#include "sql/statement.h"
namespace offline_pages {
namespace {
GetThumbnailInfoTask::Result GetThumbnailInfoSync(const int64_t offline_id,
sql::Database* db) {
static const char kSql[] = R"(SELECT thumbnail_url FROM prefetch_items
WHERE offline_id=?;)";
sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
DCHECK(statement.is_valid());
GetThumbnailInfoTask::Result result;
statement.BindInt64(0, offline_id);
if (statement.Step())
result.thumbnail_url = GURL(statement.ColumnString(0));
return result;
}
} // namespace
GetThumbnailInfoTask::GetThumbnailInfoTask(PrefetchStore* store,
const int64_t offline_id,
ResultCallback callback)
: prefetch_store_(store),
offline_id_(offline_id),
callback_(std::move(callback)) {}
GetThumbnailInfoTask::~GetThumbnailInfoTask() = default;
void GetThumbnailInfoTask::Run() {
prefetch_store_->Execute(
base::BindOnce(GetThumbnailInfoSync, offline_id_),
base::BindOnce(&GetThumbnailInfoTask::CompleteTaskAndForwardResult,
weak_factory_.GetWeakPtr()),
Result());
}
void GetThumbnailInfoTask::CompleteTaskAndForwardResult(Result result) {
TaskComplete();
std::move(callback_).Run(result);
}
} // namespace offline_pages
// Copyright 2018 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.
#ifndef COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_TASKS_GET_THUMBNAIL_INFO_TASK_H_
#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_TASKS_GET_THUMBNAIL_INFO_TASK_H_
#include <memory>
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "components/offline_pages/task/task.h"
#include "url/gurl.h"
namespace offline_pages {
class PrefetchStore;
// Task that attempts to get thumbnail information about an offline item in the
// prefetch store.
class GetThumbnailInfoTask : public Task {
public:
struct Result {
// The thumbnail URL of the offline item. This is empty if the offline item
// was not found, or if the item had no thumbnail URL.
GURL thumbnail_url;
};
using ResultCallback = base::OnceCallback<void(Result)>;
GetThumbnailInfoTask(PrefetchStore* store,
const int64_t offline_id,
ResultCallback callback);
~GetThumbnailInfoTask() override;
// Task implementation.
void Run() override;
private:
void CompleteTaskAndForwardResult(Result result);
PrefetchStore* prefetch_store_;
int64_t offline_id_;
ResultCallback callback_;
base::WeakPtrFactory<GetThumbnailInfoTask> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(GetThumbnailInfoTask);
};
} // namespace offline_pages
#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_TASKS_GET_THUMBNAIL_INFO_TASK_H_
// Copyright 2018 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 "components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.h"
#include "base/test/mock_callback.h"
#include "components/offline_pages/core/prefetch/tasks/prefetch_task_test_base.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace offline_pages {
namespace {
const char kTestUrl[] = "https://www.test_thumbnail.com/";
class GetThumbnailInfoTaskTest : public PrefetchTaskTestBase {
public:
GetThumbnailInfoTaskTest() = default;
~GetThumbnailInfoTaskTest() override = default;
PrefetchItem TestItem() {
PrefetchItem item =
item_generator()->CreateItem(PrefetchItemState::DOWNLOADED);
item.thumbnail_url = GURL(kTestUrl);
return item;
}
};
MATCHER(IsNullResult, "") {
return arg.thumbnail_url.is_empty();
}
MATCHER(IsTestUrl, "") {
return arg.thumbnail_url.possibly_invalid_spec() == kTestUrl;
}
TEST_F(GetThumbnailInfoTaskTest, NotPresent) {
const PrefetchItem item = TestItem();
store_util()->InsertPrefetchItem(item);
base::MockCallback<GetThumbnailInfoTask::ResultCallback> callback;
EXPECT_CALL(callback, Run(IsNullResult()));
RunTask(std::make_unique<GetThumbnailInfoTask>(store(), item.offline_id + 1,
callback.Get()));
}
TEST_F(GetThumbnailInfoTaskTest, Found) {
const PrefetchItem item = TestItem();
store_util()->InsertPrefetchItem(item);
base::MockCallback<GetThumbnailInfoTask::ResultCallback> callback;
EXPECT_CALL(callback, Run(IsTestUrl()));
RunTask(std::make_unique<GetThumbnailInfoTask>(store(), item.offline_id,
callback.Get()));
}
} // namespace
} // namespace offline_pages
// Copyright 2018 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 "components/offline_pages/core/prefetch/thumbnail_fetch_by_url.h"
#include <utility>
#include "base/bind.h"
#include "components/image_fetcher/core/image_fetcher.h"
namespace offline_pages {
namespace {
net::NetworkTrafficAnnotationTag TrafficAnnotation() {
return net::DefineNetworkTrafficAnnotation("prefetch_thumbnail", R"(
semantics {
sender: "Offline Pages Prefetch"
description:
"Chromium fetches suggested articles for offline viewing. This"
" network request is for a thumbnail that matches the article."
trigger:
"Two attempts, directly before and after the article is fetched."
data:
"The requested thumbnail URL."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"Users can enable or disable offline prefetch by toggling "
"'Download articles for you' in settings under Downloads or "
"by toggling chrome://flags#offline-prefetch."
chrome_policy {
NTPContentSuggestionsEnabled {
policy_options {mode: MANDATORY}
NTPContentSuggestionsEnabled: false
}
}
})");
}
} // namespace
void FetchThumbnailByURL(
base::OnceCallback<void(const std::string& image_data)> callback,
image_fetcher::ImageFetcher* fetcher,
const GURL thumbnail_url) {
auto forward_callback =
[](base::OnceCallback<void(const std::string& image_data)> callback,
const std::string& image_data,
const image_fetcher::RequestMetadata& request_metadata) {
std::move(callback).Run(image_data);
};
fetcher->FetchImageData(/*id=*/std::string(), thumbnail_url,
base::BindOnce(forward_callback, std::move(callback)),
TrafficAnnotation());
}
} // namespace offline_pages
// Copyright 2018 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.
#ifndef COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_THUMBNAIL_FETCH_BY_URL_H_
#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_THUMBNAIL_FETCH_BY_URL_H_
#include <string>
#include "base/callback.h"
#include "url/gurl.h"
namespace image_fetcher {
class ImageFetcher;
} // namespace image_fetcher
namespace offline_pages {
// Attempts to fetch a thumbnail, and returns the result to callback.
// |image_data| will be empty if the thumbnail fetch fails. Otherwise,
// |image_data| contains the raw image data (typically JPEG).
void FetchThumbnailByURL(
base::OnceCallback<void(const std::string& image_data)> callback,
image_fetcher::ImageFetcher* fetcher,
const GURL thumbnail_url);
} // namespace offline_pages
#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_THUMBNAIL_FETCH_BY_URL_H_
......@@ -163,7 +163,7 @@ Refer to README.md for content description and update process.
<item id="oauth2_api_call_flow" hash_code="29188932" type="2" content_hash_code="108831236" os_list="linux,windows" policy_fields="-1" file_path="google_apis/gaia/oauth2_api_call_flow.cc"/>
<item id="oauth2_mint_token_flow" hash_code="1112842" type="1" second_id="29188932" content_hash_code="91581432" os_list="linux,windows" semantics_fields="1,2,3,4,5" policy_fields="3,4" file_path="google_apis/gaia/oauth2_mint_token_flow.cc"/>
<item id="ocsp_start_url_request" hash_code="60921996" type="0" content_hash_code="24127780" os_list="linux" file_path="net/cert_net/nss_ocsp.cc"/>
<item id="offline_prefetch" hash_code="19185953" type="0" content_hash_code="57248156" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_request_fetcher.cc"/>
<item id="offline_prefetch" hash_code="19185953" type="0" content_hash_code="112039446" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_request_fetcher.cc"/>
<item id="omnibox_documentsuggest" hash_code="6055066" type="0" content_hash_code="126973249" os_list="linux,windows" file_path="components/omnibox/browser/document_suggestions_service.cc"/>
<item id="omnibox_navigation_observer" hash_code="61684939" type="0" content_hash_code="70941231" os_list="linux,windows" file_path="chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc"/>
<item id="omnibox_prefetch_image" hash_code="109200878" type="0" content_hash_code="107906693" os_list="linux,windows" file_path="chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc"/>
......@@ -194,7 +194,8 @@ Refer to README.md for content description and update process.
<item id="popular_sites_fetch" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows" file_path="components/ntp_tiles/popular_sites_impl.cc"/>
<item id="port_forwarding_controller_socket" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/>
<item id="ppapi_download_request" hash_code="135967426" type="0" content_hash_code="110461402" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/>
<item id="prefetch_download" hash_code="44583172" type="0" content_hash_code="100587691" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_downloader_impl.cc"/>
<item id="prefetch_download" hash_code="44583172" type="0" content_hash_code="21424542" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_downloader_impl.cc"/>
<item id="prefetch_thumbnail" hash_code="83519268" type="0" content_hash_code="6947363" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/thumbnail_fetch_by_url.cc"/>
<item id="printer_job_handler" hash_code="67638271" type="1" second_id="111712433" content_hash_code="75712693" os_list="linux,windows" semantics_fields="2,3,4" file_path="chrome/service/cloud_print/printer_job_handler.cc"/>
<item id="privet_http_impl" hash_code="71251498" type="0" content_hash_code="107348604" os_list="linux,windows" file_path="chrome/browser/printing/cloud_print/privet_http_impl.cc"/>
<item id="profile_avatar" hash_code="51164680" type="0" content_hash_code="113550845" os_list="linux,windows" file_path="chrome/browser/profiles/profile_avatar_downloader.cc"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment