Commit a84153a6 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Query Tiles: Add prefetch image API to image loader.

This CL adds a prefetch image API to image loader. Must be called in
reduced mode.

In reduced mode, currently it can't start utility process to decode
image, so we need to use the correct image fetcher api to do prefetch.

Bug: 1058534
Change-Id: Iaed251b2cf2760fbca154b14db6f6c8e4840e52d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2146304
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarHesen Zhang <hesen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#758677}
parent 14c3a396
......@@ -10,10 +10,17 @@
#include "base/callback.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/image_fetcher_service.h"
#include "components/image_fetcher/core/request_metadata.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image.h"
using image_fetcher::ImageDataFetcherCallback;
using image_fetcher::ImageFetcher;
using image_fetcher::ImageFetcherParams;
using image_fetcher::RequestMetadata;
namespace upboarding {
namespace {
......@@ -50,6 +57,13 @@ constexpr net::NetworkTrafficAnnotationTag kQueryTilesTrafficAnnotation =
}
})");
ImageFetcherParams CreateImageFetcherParams() {
ImageFetcherParams params(kQueryTilesTrafficAnnotation,
kImageFetcherUmaClientName);
params.set_hold_for_expiration_interval(kImageCacheExpirationInterval);
return params;
}
void OnImageFetched(ImageLoader::BitmapCallback callback,
const gfx::Image& image,
const image_fetcher::RequestMetadata&) {
......@@ -57,22 +71,38 @@ void OnImageFetched(ImageLoader::BitmapCallback callback,
std::move(callback).Run(image.AsBitmap());
}
void OnImageDataPrefetched(ImageLoader::SuccessCallback callback,
const std::string&,
const RequestMetadata& request_metadata) {
bool success = request_metadata.http_response_code == net::OK;
if (callback)
std::move(callback).Run(success);
}
} // namespace
CachedImageLoader::CachedImageLoader(image_fetcher::ImageFetcher* image_fetcher)
: image_fetcher_(image_fetcher) {
DCHECK(image_fetcher_);
CachedImageLoader::CachedImageLoader(ImageFetcher* cached_image_fetcher,
ImageFetcher* reduced_mode_image_fetcher)
: cached_image_fetcher_(cached_image_fetcher),
reduced_mode_image_fetcher_(reduced_mode_image_fetcher) {
DCHECK(cached_image_fetcher_);
DCHECK(reduced_mode_image_fetcher_);
}
CachedImageLoader::~CachedImageLoader() = default;
void CachedImageLoader::FetchImage(const GURL& url, BitmapCallback callback) {
// Fetch and decode the image from network or disk cache.
image_fetcher::ImageFetcherParams params(kQueryTilesTrafficAnnotation,
kImageFetcherUmaClientName);
params.set_hold_for_expiration_interval(kImageCacheExpirationInterval);
image_fetcher_->FetchImage(
url, base::BindOnce(&OnImageFetched, std::move(callback)), params);
cached_image_fetcher_->FetchImage(
url, base::BindOnce(&OnImageFetched, std::move(callback)),
CreateImageFetcherParams());
}
void CachedImageLoader::PrefetchImage(const GURL& url,
SuccessCallback callback) {
reduced_mode_image_fetcher_->FetchImageData(
url, base::BindOnce(&OnImageDataPrefetched, std::move(callback)),
CreateImageFetcherParams());
}
} // namespace upboarding
......@@ -20,16 +20,22 @@ namespace upboarding {
// network data consumption.
class CachedImageLoader : public ImageLoader {
public:
explicit CachedImageLoader(image_fetcher::ImageFetcher* image_fetcher);
CachedImageLoader(image_fetcher::ImageFetcher* cached_image_fetcher,
image_fetcher::ImageFetcher* reduced_mode_image_fetcher);
~CachedImageLoader() override;
private:
// ImageLoader implementation.
void FetchImage(const GURL& url, BitmapCallback callback) override;
void PrefetchImage(const GURL& url, SuccessCallback callback) override;
// Owned by ImageFetcherService. Outlives TileService, the owner of this
// class.
image_fetcher::ImageFetcher* image_fetcher_;
// Used to load the image bitmap for UI. Owned by ImageFetcherService.
// Outlives TileService.
image_fetcher::ImageFetcher* cached_image_fetcher_;
// Used to prefetch the image in reduced mode. The data is downloaded to disk
// without decoding. Owned by ImageFetcherService. Outlives TileService.
image_fetcher::ImageFetcher* reduced_mode_image_fetcher_;
};
} // namespace upboarding
......
......@@ -8,13 +8,19 @@
#include <utility>
#include "base/memory/weak_ptr.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "components/image_fetcher/core/mock_image_fetcher.h"
#include "components/image_fetcher/core/request_metadata.h"
#include "net/http/http_status_code.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image.h"
using image_fetcher::ImageDataFetcherCallback;
using image_fetcher::ImageFetcherCallback;
using image_fetcher::ImageFetcherParams;
using image_fetcher::RequestMetadata;
using ::testing::_;
using ::testing::Invoke;
......@@ -27,7 +33,8 @@ class CachedImageLoaderTest : public testing::Test {
~CachedImageLoaderTest() override = default;
void SetUp() override {
image_loader_ = std::make_unique<CachedImageLoader>(&mock_fetcher_);
image_loader_ = std::make_unique<CachedImageLoader>(
&mock_fetcher_, &mock_reduced_mode_fetcher_);
}
protected:
......@@ -38,8 +45,28 @@ class CachedImageLoaderTest : public testing::Test {
weak_ptr_factory_.GetWeakPtr()));
}
void PrefetchImage(int http_response_code, bool expected_success) {
base::MockCallback<ImageLoader::SuccessCallback> mock_callback;
EXPECT_CALL(mock_callback, Run(expected_success));
EXPECT_CALL(*mock_reduced_mode_fetcher(), FetchImageAndData_(_, _, _, _))
.WillRepeatedly(
Invoke([http_response_code](
const GURL&, ImageDataFetcherCallback* data_callback,
ImageFetcherCallback*, ImageFetcherParams) {
RequestMetadata request_metadata;
request_metadata.http_response_code = http_response_code;
std::move(*data_callback).Run("test_data", request_metadata);
}));
image_loader_->PrefetchImage(GURL("https://www.example.com/dummy_image"),
mock_callback.Get());
}
image_fetcher::MockImageFetcher* mock_fetcher() { return &mock_fetcher_; }
image_fetcher::MockImageFetcher* mock_reduced_mode_fetcher() {
return &mock_reduced_mode_fetcher_;
}
const SkBitmap& result() const { return result_; }
private:
......@@ -47,6 +74,7 @@ class CachedImageLoaderTest : public testing::Test {
base::test::TaskEnvironment task_environment_;
image_fetcher::MockImageFetcher mock_fetcher_;
image_fetcher::MockImageFetcher mock_reduced_mode_fetcher_;
std::unique_ptr<ImageLoader> image_loader_;
SkBitmap result_;
......@@ -63,17 +91,20 @@ TEST_F(CachedImageLoaderTest, FetchImage) {
auto image = gfx::Image::CreateFrom1xBitmap(bitmap);
EXPECT_CALL(*mock_fetcher(), FetchImageAndData_(_, _, _, _))
.WillRepeatedly(
Invoke([&image](const GURL&, image_fetcher::ImageDataFetcherCallback*,
image_fetcher::ImageFetcherCallback* fetch_callback,
image_fetcher::ImageFetcherParams) {
std::move(*fetch_callback)
.Run(image, image_fetcher::RequestMetadata());
}));
.WillRepeatedly(Invoke([&image](const GURL&, ImageDataFetcherCallback*,
ImageFetcherCallback* fetch_callback,
ImageFetcherParams) {
std::move(*fetch_callback).Run(image, image_fetcher::RequestMetadata());
}));
FetchImage();
EXPECT_FALSE(result().empty());
EXPECT_EQ(result().width(), 32);
}
TEST_F(CachedImageLoaderTest, PrefetchImage) {
PrefetchImage(net::OK, true /*expected_succes*/);
PrefetchImage(net::HTTP_NOT_FOUND, false /*expected_succes*/);
}
} // namespace
} // namespace upboarding
......@@ -20,6 +20,7 @@ namespace upboarding {
class ImageLoader {
public:
using BitmapCallback = base::OnceCallback<void(SkBitmap bitmap)>;
using SuccessCallback = base::OnceCallback<void(bool)>;
ImageLoader() = default;
virtual ~ImageLoader() = default;
......@@ -29,6 +30,11 @@ class ImageLoader {
// Fetches the bitmap of an image based on its URL. Callback will be invoked
// with the bitmap of the image, or an empty bitmap on failure.
virtual void FetchImage(const GURL& url, BitmapCallback callback) = 0;
// Prefetches the image data. The decoding will be deferred to next full
// browser mode launch. Must be called in reduced mode. The |callback| will be
// invoked after network fetch is done.
virtual void PrefetchImage(const GURL& url, SuccessCallback callback) = 0;
};
} // namespace upboarding
......
......@@ -33,11 +33,8 @@ TileServiceFactory::~TileServiceFactory() {}
std::unique_ptr<KeyedService> TileServiceFactory::BuildServiceInstanceFor(
SimpleFactoryKey* key) const {
// TODO(xingliu): Add reduced mode image fetcher for prefetch.
auto* image_fetcher =
ImageFetcherServiceFactory::GetForKey(key)->GetImageFetcher(
image_fetcher::ImageFetcherConfig::kDiskCacheOnly);
return CreateTileService(image_fetcher);
auto* image_fetcher_service = ImageFetcherServiceFactory::GetForKey(key);
return CreateTileService(image_fetcher_service);
}
} // namespace upboarding
......@@ -6,13 +6,19 @@
#include "chrome/browser/upboarding/query_tiles/internal/cached_image_loader.h"
#include "chrome/browser/upboarding/query_tiles/internal/tile_service_impl.h"
#include "components/image_fetcher/core/image_fetcher_service.h"
#include "components/keyed_service/core/keyed_service.h"
namespace upboarding {
std::unique_ptr<TileService> CreateTileService(
image_fetcher::ImageFetcher* image_fetcher) {
auto image_loader = std::make_unique<CachedImageLoader>(image_fetcher);
image_fetcher::ImageFetcherService* image_fetcher_service) {
auto* cached_image_fetcher = image_fetcher_service->GetImageFetcher(
image_fetcher::ImageFetcherConfig::kDiskCacheOnly);
auto* reduced_mode_image_fetcher = image_fetcher_service->GetImageFetcher(
image_fetcher::ImageFetcherConfig::kReducedMode);
auto image_loader = std::make_unique<CachedImageLoader>(
cached_image_fetcher, reduced_mode_image_fetcher);
return std::make_unique<TileServiceImpl>(std::move(image_loader));
}
......
......@@ -8,7 +8,7 @@
#include <memory>
namespace image_fetcher {
class ImageFetcher;
class ImageFetcherService;
} // namespace image_fetcher
namespace upboarding {
......@@ -16,7 +16,7 @@ namespace upboarding {
class TileService;
std::unique_ptr<TileService> CreateTileService(
image_fetcher::ImageFetcher* image_fetcher);
image_fetcher::ImageFetcherService* image_fetcher_service);
} // namespace upboarding
......
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