Commit 5a25f300 authored by mathp's avatar mathp Committed by Commit bot

[Suggestions] Move ImageManager to the component

Keeps the fetcher functionality as ImageFetcherImpl in chrome/browser/search/suggestions.

BUG=387751
TBR=blundell
TEST=ImageManagerTest,ImageFetcherBrowserTest

Review URL: https://codereview.chromium.org/543753002

Cr-Commit-Position: refs/heads/master@{#296503}
parent ee652576
// Copyright 2014 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/search/suggestions/image_fetcher_impl.h"
#include <string>
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request_context_getter.h"
namespace suggestions {
ImageFetcherImpl::ImageFetcherImpl(
net::URLRequestContextGetter* url_request_context)
: url_request_context_(url_request_context) {}
ImageFetcherImpl::~ImageFetcherImpl() {}
ImageFetcherImpl::ImageRequest::ImageRequest() : fetcher(NULL) {}
ImageFetcherImpl::ImageRequest::ImageRequest(chrome::BitmapFetcher* f)
: fetcher(f) {}
ImageFetcherImpl::ImageRequest::~ImageRequest() { delete fetcher; }
void ImageFetcherImpl::SetImageFetcherDelegate(ImageFetcherDelegate* delegate) {
DCHECK(delegate);
delegate_ = delegate;
}
void ImageFetcherImpl::StartOrQueueNetworkRequest(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback) {
// Before starting to fetch the image. Look for a request in progress for
// |image_url|, and queue if appropriate.
ImageRequestMap::iterator it = pending_net_requests_.find(image_url);
if (it == pending_net_requests_.end()) {
// |image_url| is not being fetched, so create a request and initiate
// the fetch.
ImageRequest request(new chrome::BitmapFetcher(image_url, this));
request.url = url;
request.callbacks.push_back(callback);
request.fetcher->Start(
url_request_context_, std::string(),
net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
net::LOAD_NORMAL);
pending_net_requests_[image_url].swap(&request);
} else {
// Request in progress. Register as an interested callback.
it->second.callbacks.push_back(callback);
}
}
void ImageFetcherImpl::OnFetchComplete(const GURL image_url,
const SkBitmap* bitmap) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
ImageRequestMap::iterator image_iter = pending_net_requests_.find(image_url);
DCHECK(image_iter != pending_net_requests_.end());
ImageRequest* request = &image_iter->second;
// Here |bitmap| could be NULL or a pointer to a bitmap which is owned by the
// BitmapFetcher and which ceases to exist after this function. Pass the
// un-owned pointer to the registered callbacks.
for (CallbackVector::iterator callback_iter = request->callbacks.begin();
callback_iter != request->callbacks.end(); ++callback_iter) {
callback_iter->Run(request->url, bitmap);
}
// Inform the ImageFetcherDelegate.
if (delegate_) {
delegate_->OnImageFetched(request->url, bitmap);
}
// Erase the completed ImageRequest.
pending_net_requests_.erase(image_iter);
}
} // namespace suggestions
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_SEARCH_SUGGESTIONS_IMAGE_MANAGER_IMPL_H_ #ifndef CHROME_BROWSER_SEARCH_SUGGESTIONS_IMAGE_FETCHER_IMPL_H_
#define CHROME_BROWSER_SEARCH_SUGGESTIONS_IMAGE_MANAGER_IMPL_H_ #define CHROME_BROWSER_SEARCH_SUGGESTIONS_IMAGE_FETCHER_IMPL_H_
#include <map> #include <map>
#include <utility> #include <utility>
...@@ -11,13 +11,8 @@ ...@@ -11,13 +11,8 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "components/leveldb_proto/proto_database.h" #include "components/suggestions/image_fetcher.h"
#include "components/suggestions/image_manager.h"
#include "components/suggestions/proto/suggestions.pb.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -27,49 +22,32 @@ class URLRequestContextGetter; ...@@ -27,49 +22,32 @@ class URLRequestContextGetter;
namespace suggestions { namespace suggestions {
class ImageData; // A class used to fetch server images.
class SuggestionsProfile; class ImageFetcherImpl : public ImageFetcher,
// A class used to fetch server images asynchronously and manage the caching
// layer (both in memory and on disk).
class ImageManagerImpl : public ImageManager,
public chrome::BitmapFetcherDelegate { public chrome::BitmapFetcherDelegate {
public: public:
typedef std::vector<ImageData> ImageDataVector; explicit ImageFetcherImpl(net::URLRequestContextGetter* url_request_context);
virtual ~ImageFetcherImpl();
ImageManagerImpl(
net::URLRequestContextGetter* url_request_context, virtual void SetImageFetcherDelegate(ImageFetcherDelegate* delegate) OVERRIDE;
scoped_ptr<leveldb_proto::ProtoDatabase<ImageData> > database,
const base::FilePath& database_dir); virtual void StartOrQueueNetworkRequest(
virtual ~ImageManagerImpl(); const GURL& url, const GURL& image_url,
// Overrides from ImageManager.
virtual void Initialize(const SuggestionsProfile& suggestions) OVERRIDE;
// Should be called from the UI thread.
virtual void GetImageForURL(
const GURL& url,
base::Callback<void(const GURL&, const SkBitmap*)> callback) OVERRIDE; base::Callback<void(const GURL&, const SkBitmap*)> callback) OVERRIDE;
private: private:
friend class MockImageManagerImpl; // Inherited from BitmapFetcherDelegate. Runs on the UI thread.
friend class ImageManagerImplBrowserTest; virtual void OnFetchComplete(const GURL image_url,
FRIEND_TEST_ALL_PREFIXES(ImageManagerImplTest, InitializeTest); const SkBitmap* bitmap) OVERRIDE;
FRIEND_TEST_ALL_PREFIXES(ImageManagerImplBrowserTest,
GetImageForURLNetworkCacheHit);
FRIEND_TEST_ALL_PREFIXES(ImageManagerImplBrowserTest,
GetImageForURLNetworkCacheNotInitialized);
// Used for testing.
ImageManagerImpl();
typedef std::vector<base::Callback<void(const GURL&, const SkBitmap*)> > typedef std::vector<base::Callback<void(const GURL&, const SkBitmap*)> >
CallbackVector; CallbackVector;
typedef base::hash_map<std::string, SkBitmap> ImageMap;
// State related to an image fetch (associated website url, image_url, // State related to an image fetch (associated website url, image_url,
// fetcher, pending callbacks). // fetcher, pending callbacks).
struct ImageRequest { struct ImageRequest {
ImageRequest(); ImageRequest();
// Struct takes ownership of |f|.
explicit ImageRequest(chrome::BitmapFetcher* f); explicit ImageRequest(chrome::BitmapFetcher* f);
~ImageRequest(); ~ImageRequest();
...@@ -90,81 +68,17 @@ class ImageManagerImpl : public ImageManager, ...@@ -90,81 +68,17 @@ class ImageManagerImpl : public ImageManager,
typedef std::map<const GURL, ImageRequest> ImageRequestMap; typedef std::map<const GURL, ImageRequest> ImageRequestMap;
// Looks up image URL for |url|. If found, writes the result to |image_url|
// and returns true. Otherwise just returns false.
bool GetImageURL(const GURL& url, GURL* image_url);
void QueueCacheRequest(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
void ServeFromCacheOrNetwork(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
// Will return false if no bitmap was found corresponding to |url|, else
// return true and call |callback| with the found bitmap.
bool ServeFromCache(
const GURL& url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
// Returns null if the |url| had no entry in the cache.
SkBitmap* GetBitmapFromCache(const GURL& url);
void StartOrQueueNetworkRequest(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
// Inherited from BitmapFetcherDelegate. Runs on the UI thread.
virtual void OnFetchComplete(const GURL image_url,
const SkBitmap* bitmap) OVERRIDE;
// Save the image bitmap in the cache and in the database.
void SaveImage(const GURL& url, const SkBitmap& bitmap);
// Database callback methods.
// Will initiate loading the entries.
void OnDatabaseInit(bool success);
// Will transfer the loaded |entries| in memory (|image_map_|).
void OnDatabaseLoad(bool success, scoped_ptr<ImageDataVector> entries);
void OnDatabaseSave(bool success);
// Take entries from the database and put them in the local cache.
void LoadEntriesInCache(scoped_ptr<ImageDataVector> entries);
void ServePendingCacheRequests();
// From SkBitmap to the vector of JPEG-encoded bytes, |dst|. Visible only for
// testing.
static bool EncodeImage(const SkBitmap& bitmap,
std::vector<unsigned char>* dest);
// Map from URL to image URL. Should be kept up to date when a new
// SuggestionsProfile is available.
std::map<GURL, GURL> image_url_map_;
// Map from each image URL to the request information (associated website // Map from each image URL to the request information (associated website
// url, fetcher, pending callbacks). // url, fetcher, pending callbacks).
ImageRequestMap pending_net_requests_; ImageRequestMap pending_net_requests_;
// Map from website URL to request information, used for pending cache ImageFetcherDelegate* delegate_;
// requests while the database hasn't loaded.
ImageRequestMap pending_cache_requests_;
// Holding the bitmaps in memory, keyed by website URL string.
ImageMap image_map_;
net::URLRequestContextGetter* url_request_context_; net::URLRequestContextGetter* url_request_context_;
scoped_ptr<leveldb_proto::ProtoDatabase<ImageData> > database_; DISALLOW_COPY_AND_ASSIGN(ImageFetcherImpl);
bool database_ready_;
base::WeakPtrFactory<ImageManagerImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ImageManagerImpl);
}; };
} // namespace suggestions } // namespace suggestions
#endif // CHROME_BROWSER_SEARCH_SUGGESTIONS_IMAGE_MANAGER_IMPL_H_ #endif // CHROME_BROWSER_SEARCH_SUGGESTIONS_IMAGE_FETCHER_IMPL_H_
// Copyright 2014 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/search/suggestions/image_fetcher_impl.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/suggestions/image_fetcher_delegate.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
class SkBitmap;
namespace suggestions {
namespace {
const char kTestUrl[] = "http://go.com/";
const char kTestImagePath[] = "files/image_decoding/droids.png";
const char kInvalidImagePath[] = "files/DOESNOTEXIST";
const base::FilePath::CharType kDocRoot[] =
FILE_PATH_LITERAL("chrome/test/data");
class TestImageFetcherDelegate : public ImageFetcherDelegate {
public:
TestImageFetcherDelegate()
: num_delegate_valid_called_(0),
num_delegate_null_called_(0) {}
virtual ~TestImageFetcherDelegate() {};
// Perform additional tasks when an image has been fetched.
virtual void OnImageFetched(const GURL& url, const SkBitmap* bitmap)
OVERRIDE {
if (bitmap) {
num_delegate_valid_called_++;
} else {
num_delegate_null_called_++;
}
};
int num_delegate_valid_called() { return num_delegate_valid_called_; }
int num_delegate_null_called() { return num_delegate_null_called_; }
private:
int num_delegate_valid_called_;
int num_delegate_null_called_;
};
} // end namespace
class ImageFetcherImplBrowserTest : public InProcessBrowserTest {
protected:
ImageFetcherImplBrowserTest()
: num_callback_valid_called_(0),
num_callback_null_called_(0),
test_server_(net::SpawnedTestServer::TYPE_HTTP,
net::SpawnedTestServer::kLocalhost,
base::FilePath(kDocRoot)) {}
virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
ASSERT_TRUE(test_server_.Start());
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
}
virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
test_server_.Stop();
}
ImageFetcherImpl* CreateImageFetcher() {
ImageFetcherImpl* fetcher =
new ImageFetcherImpl(browser()->profile()->GetRequestContext());
fetcher->SetImageFetcherDelegate(&delegate_);
return fetcher;
}
void OnImageAvailable(base::RunLoop* loop,
const GURL& url,
const SkBitmap* bitmap) {
if (bitmap) {
num_callback_valid_called_++;
} else {
num_callback_null_called_++;
}
loop->Quit();
}
void StartOrQueueNetworkRequestHelper(const GURL& image_url) {
scoped_ptr<ImageFetcherImpl> image_fetcher_(CreateImageFetcher());
base::RunLoop run_loop;
image_fetcher_->StartOrQueueNetworkRequest(
GURL(kTestUrl),
image_url,
base::Bind(&ImageFetcherImplBrowserTest::OnImageAvailable,
base::Unretained(this), &run_loop));
run_loop.Run();
}
int num_callback_valid_called_;
int num_callback_null_called_;
net::SpawnedTestServer test_server_;
TestImageFetcherDelegate delegate_;
DISALLOW_COPY_AND_ASSIGN(ImageFetcherImplBrowserTest);
};
IN_PROC_BROWSER_TEST_F(ImageFetcherImplBrowserTest, NormalFetch) {
GURL image_url(test_server_.GetURL(kTestImagePath).spec());
StartOrQueueNetworkRequestHelper(image_url);
EXPECT_EQ(1, num_callback_valid_called_);
EXPECT_EQ(0, num_callback_null_called_);
EXPECT_EQ(1, delegate_.num_delegate_valid_called());
EXPECT_EQ(0, delegate_.num_delegate_null_called());
}
IN_PROC_BROWSER_TEST_F(ImageFetcherImplBrowserTest, MultipleFetch) {
GURL image_url(test_server_.GetURL(kTestImagePath).spec());
for (int i = 0; i < 5; i++) {
StartOrQueueNetworkRequestHelper(image_url);
}
EXPECT_EQ(5, num_callback_valid_called_);
EXPECT_EQ(0, num_callback_null_called_);
EXPECT_EQ(5, delegate_.num_delegate_valid_called());
EXPECT_EQ(0, delegate_.num_delegate_null_called());
}
IN_PROC_BROWSER_TEST_F(ImageFetcherImplBrowserTest, InvalidFetch) {
GURL invalid_image_url(test_server_.GetURL(kInvalidImagePath).spec());
StartOrQueueNetworkRequestHelper(invalid_image_url);
EXPECT_EQ(0, num_callback_valid_called_);
EXPECT_EQ(1, num_callback_null_called_);
EXPECT_EQ(0, delegate_.num_delegate_valid_called());
EXPECT_EQ(1, delegate_.num_delegate_null_called());
}
} // namespace suggestions
// Copyright 2014 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 <string>
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/search/suggestions/image_manager_impl.h"
#include "chrome/test/base/testing_profile.h"
#include "components/leveldb_proto/proto_database.h"
#include "components/leveldb_proto/testing/fake_db.h"
#include "components/suggestions/proto/suggestions.pb.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace {
using leveldb_proto::test::FakeDB;
using suggestions::ImageData;
using suggestions::ImageManagerImpl;
typedef base::hash_map<std::string, ImageData> EntryMap;
const char kTestUrl[] = "http://go.com/";
const char kTestImageUrl[] = "http://thumb.com/anchor_download_test.png";
class ImageManagerImplTest : public testing::Test {
protected:
ImageManagerImpl* CreateImageManager(Profile* profile) {
FakeDB<ImageData>* fake_db = new FakeDB<ImageData>(&db_model_);
return new ImageManagerImpl(
profile->GetRequestContext(),
scoped_ptr<leveldb_proto::ProtoDatabase<ImageData> >(fake_db),
FakeDB<ImageData>::DirectoryForTestDB());
}
content::TestBrowserThreadBundle thread_bundle_;
EntryMap db_model_;
};
} // namespace
namespace suggestions {
TEST_F(ImageManagerImplTest, InitializeTest) {
SuggestionsProfile suggestions_profile;
ChromeSuggestion* suggestion = suggestions_profile.add_suggestions();
suggestion->set_url(kTestUrl);
suggestion->set_thumbnail(kTestImageUrl);
TestingProfile profile;
scoped_ptr<ImageManagerImpl> image_manager(
CreateImageManager(&profile));
image_manager->Initialize(suggestions_profile);
GURL output;
EXPECT_TRUE(image_manager->GetImageURL(GURL(kTestUrl), &output));
EXPECT_EQ(GURL(kTestImageUrl), output);
EXPECT_FALSE(image_manager->GetImageURL(GURL("http://b.com"), &output));
}
} // namespace suggestions
...@@ -8,12 +8,13 @@ ...@@ -8,12 +8,13 @@
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/suggestions/image_manager_impl.h" #include "chrome/browser/search/suggestions/image_fetcher_impl.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/leveldb_proto/proto_database.h" #include "components/leveldb_proto/proto_database.h"
#include "components/leveldb_proto/proto_database_impl.h" #include "components/leveldb_proto/proto_database_impl.h"
#include "components/pref_registry/pref_registry_syncable.h" #include "components/pref_registry/pref_registry_syncable.h"
#include "components/suggestions/blacklist_store.h" #include "components/suggestions/blacklist_store.h"
#include "components/suggestions/image_fetcher.h"
#include "components/suggestions/image_manager.h" #include "components/suggestions/image_manager.h"
#include "components/suggestions/proto/suggestions.pb.h" #include "components/suggestions/proto/suggestions.pb.h"
#include "components/suggestions/suggestions_service.h" #include "components/suggestions/suggestions_service.h"
...@@ -66,18 +67,19 @@ KeyedService* SuggestionsServiceFactory::BuildServiceInstanceFor( ...@@ -66,18 +67,19 @@ KeyedService* SuggestionsServiceFactory::BuildServiceInstanceFor(
new BlacklistStore(the_profile->GetPrefs())); new BlacklistStore(the_profile->GetPrefs()));
scoped_ptr<leveldb_proto::ProtoDatabaseImpl<ImageData> > db( scoped_ptr<leveldb_proto::ProtoDatabaseImpl<ImageData> > db(
new leveldb_proto::ProtoDatabaseImpl<ImageData>( new leveldb_proto::ProtoDatabaseImpl<ImageData>(background_task_runner));
background_task_runner));
base::FilePath database_dir( base::FilePath database_dir(
the_profile->GetPath().Append(FILE_PATH_LITERAL("Thumbnails"))); the_profile->GetPath().Append(FILE_PATH_LITERAL("Thumbnails")));
scoped_ptr<ImageManagerImpl> thumbnail_manager(new ImageManagerImpl( scoped_ptr<ImageFetcherImpl> image_fetcher(
the_profile->GetRequestContext(), new ImageFetcherImpl(the_profile->GetRequestContext()));
scoped_ptr<ImageManager> thumbnail_manager(new ImageManager(
image_fetcher.PassAs<ImageFetcher>(),
db.PassAs<leveldb_proto::ProtoDatabase<ImageData> >(), database_dir)); db.PassAs<leveldb_proto::ProtoDatabase<ImageData> >(), database_dir));
return new SuggestionsService( return new SuggestionsService(
the_profile->GetRequestContext(), suggestions_store.Pass(), the_profile->GetRequestContext(), suggestions_store.Pass(),
thumbnail_manager.PassAs<ImageManager>(), blacklist_store.Pass()); thumbnail_manager.Pass(), blacklist_store.Pass());
} }
void SuggestionsServiceFactory::RegisterProfilePrefs( void SuggestionsServiceFactory::RegisterProfilePrefs(
......
...@@ -1070,8 +1070,8 @@ ...@@ -1070,8 +1070,8 @@
'browser/search/most_visited_iframe_source.h', 'browser/search/most_visited_iframe_source.h',
'browser/search/search.cc', 'browser/search/search.cc',
'browser/search/search.h', 'browser/search/search.h',
'browser/search/suggestions/image_manager_impl.cc', 'browser/search/suggestions/image_fetcher_impl.cc',
'browser/search/suggestions/image_manager_impl.h', 'browser/search/suggestions/image_fetcher_impl.h',
'browser/search/suggestions/suggestions_service_factory.cc', 'browser/search/suggestions/suggestions_service_factory.cc',
'browser/search/suggestions/suggestions_service_factory.h', 'browser/search/suggestions/suggestions_service_factory.h',
'browser/search/suggestions/suggestions_source.cc', 'browser/search/suggestions/suggestions_source.cc',
......
...@@ -1376,7 +1376,7 @@ ...@@ -1376,7 +1376,7 @@
'browser/safe_browsing/safe_browsing_blocking_page_test.cc', 'browser/safe_browsing/safe_browsing_blocking_page_test.cc',
'browser/safe_browsing/safe_browsing_service_browsertest.cc', 'browser/safe_browsing/safe_browsing_service_browsertest.cc',
'browser/safe_browsing/safe_browsing_test.cc', 'browser/safe_browsing/safe_browsing_test.cc',
'browser/search/suggestions/image_manager_impl_browsertest.cc', 'browser/search/suggestions/image_fetcher_impl_browsertest.cc',
'browser/service_process/service_process_control_browsertest.cc', 'browser/service_process/service_process_control_browsertest.cc',
'browser/services/gcm/fake_gcm_profile_service.cc', 'browser/services/gcm/fake_gcm_profile_service.cc',
'browser/services/gcm/fake_gcm_profile_service.h', 'browser/services/gcm/fake_gcm_profile_service.h',
......
...@@ -696,7 +696,6 @@ ...@@ -696,7 +696,6 @@
'browser/search/most_visited_iframe_source_unittest.cc', 'browser/search/most_visited_iframe_source_unittest.cc',
'browser/search/search_android_unittest.cc', 'browser/search/search_android_unittest.cc',
'browser/search/search_unittest.cc', 'browser/search/search_unittest.cc',
'browser/search/suggestions/image_manager_impl_unittest.cc',
'browser/search_engines/default_search_pref_migration_unittest.cc', 'browser/search_engines/default_search_pref_migration_unittest.cc',
'browser/search_engines/search_provider_install_data_unittest.cc', 'browser/search_engines/search_provider_install_data_unittest.cc',
'browser/search_engines/template_url_scraper_unittest.cc', 'browser/search_engines/template_url_scraper_unittest.cc',
......
...@@ -216,6 +216,7 @@ ...@@ -216,6 +216,7 @@
'storage_monitor/storage_monitor_unittest.cc', 'storage_monitor/storage_monitor_unittest.cc',
'storage_monitor/storage_monitor_win_unittest.cc', 'storage_monitor/storage_monitor_win_unittest.cc',
'suggestions/blacklist_store_unittest.cc', 'suggestions/blacklist_store_unittest.cc',
'suggestions/image_manager_unittest.cc',
'suggestions/suggestions_service_unittest.cc', 'suggestions/suggestions_service_unittest.cc',
'suggestions/suggestions_store_unittest.cc', 'suggestions/suggestions_store_unittest.cc',
'sync_driver/non_ui_data_type_controller_unittest.cc', 'sync_driver/non_ui_data_type_controller_unittest.cc',
......
...@@ -19,10 +19,14 @@ ...@@ -19,10 +19,14 @@
'components.gyp:keyed_service_core', 'components.gyp:keyed_service_core',
'components.gyp:pref_registry', 'components.gyp:pref_registry',
'components.gyp:variations', 'components.gyp:variations',
'components.gyp:variations_http_provider',
], ],
'sources': [ 'sources': [
'suggestions/blacklist_store.cc', 'suggestions/blacklist_store.cc',
'suggestions/blacklist_store.h', 'suggestions/blacklist_store.h',
'suggestions/image_fetcher.h',
'suggestions/image_fetcher_delegate.h',
'suggestions/image_manager.cc',
'suggestions/image_manager.h', 'suggestions/image_manager.h',
'suggestions/proto/suggestions.proto', 'suggestions/proto/suggestions.proto',
'suggestions/suggestions_pref_names.cc', 'suggestions/suggestions_pref_names.cc',
......
...@@ -6,6 +6,9 @@ static_library("suggestions") { ...@@ -6,6 +6,9 @@ static_library("suggestions") {
sources = [ sources = [
"blacklist_store.cc", "blacklist_store.cc",
"blacklist_store.h", "blacklist_store.h",
"image_fetcher.h",
"image_fetcher_delegate.h",
"image_manager.cc",
"image_manager.h", "image_manager.h",
"suggestions_pref_names.cc", "suggestions_pref_names.cc",
"suggestions_pref_names.h", "suggestions_pref_names.h",
......
include_rules = [ include_rules = [
"+components/keyed_service/core", "+components/keyed_service/core",
"+components/leveldb_proto",
"+components/pref_registry", "+components/pref_registry",
"+components/variations", "+components/variations",
"+net", "+net",
......
// Copyright 2014 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_SUGGESTIONS_IMAGE_FETCHER_H_
#define COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_H_
#include "base/callback.h"
#include "components/suggestions/image_fetcher_delegate.h"
#include "url/gurl.h"
class SkBitmap;
namespace suggestions {
// A class used to fetch server images.
class ImageFetcher {
public:
ImageFetcher() {}
virtual ~ImageFetcher() {}
virtual void SetImageFetcherDelegate(ImageFetcherDelegate* delegate) = 0;
virtual void StartOrQueueNetworkRequest(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ImageFetcher);
};
} // namespace suggestions
#endif // COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_H_
// Copyright 2014 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_SUGGESTIONS_IMAGE_FETCHER_DELEGATE_H_
#define COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_DELEGATE_H_
class GURL;
class SkBitmap;
namespace suggestions {
class ImageFetcherDelegate {
public:
ImageFetcherDelegate() {}
// Called when an image was fetched. |url| represents the website for which
// the image was fetched. |bitmap| is deleted once out of scope.
virtual void OnImageFetched(const GURL& url, const SkBitmap* bitmap) = 0;
protected:
virtual ~ImageFetcherDelegate() {}
DISALLOW_COPY_AND_ASSIGN(ImageFetcherDelegate);
};
} // namespace suggestions
#endif // COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_DELEGATE_H_
...@@ -5,31 +5,146 @@ ...@@ -5,31 +5,146 @@
#ifndef COMPONENTS_SUGGESTIONS_IMAGE_MANAGER_H_ #ifndef COMPONENTS_SUGGESTIONS_IMAGE_MANAGER_H_
#define COMPONENTS_SUGGESTIONS_IMAGE_MANAGER_H_ #define COMPONENTS_SUGGESTIONS_IMAGE_MANAGER_H_
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "components/leveldb_proto/proto_database.h"
#include "components/suggestions/image_fetcher_delegate.h"
#include "components/suggestions/proto/suggestions.pb.h" #include "components/suggestions/proto/suggestions.pb.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace net {
class URLRequestContextGetter;
}
namespace suggestions { namespace suggestions {
// An interface to retrieve images related to a specific URL. class ImageData;
class ImageManager { class ImageFetcher;
class SuggestionsProfile;
// A class used to fetch server images asynchronously and manage the caching
// layer (both in memory and on disk).
class ImageManager : public ImageFetcherDelegate {
public: public:
ImageManager() {} typedef std::vector<ImageData> ImageDataVector;
virtual ~ImageManager() {}
ImageManager(scoped_ptr<ImageFetcher> image_fetcher,
scoped_ptr<leveldb_proto::ProtoDatabase<ImageData> > database,
const base::FilePath& database_dir);
virtual ~ImageManager();
// (Re)Initializes states using data received from a SuggestionService. We're virtual void Initialize(const SuggestionsProfile& suggestions);
// not doing this in the constructor because an instance may be long-lived.
virtual void Initialize(const SuggestionsProfile& suggestions) = 0;
// Retrieves stored image for website |url| asynchronously. Calls |callback| // Should be called from the UI thread.
// with Bitmap pointer if found, and NULL otherwise.
virtual void GetImageForURL( virtual void GetImageForURL(
const GURL& url, const GURL& url,
base::Callback<void(const GURL&, const SkBitmap*)> callback) = 0; base::Callback<void(const GURL&, const SkBitmap*)> callback);
protected:
// Perform additional tasks when an image has been fetched.
virtual void OnImageFetched(const GURL& url, const SkBitmap* bitmap) OVERRIDE;
private: private:
friend class MockImageManager;
friend class ImageManagerTest;
FRIEND_TEST_ALL_PREFIXES(ImageManagerTest, InitializeTest);
FRIEND_TEST_ALL_PREFIXES(ImageManagerTest, GetImageForURLNetworkCacheHit);
FRIEND_TEST_ALL_PREFIXES(ImageManagerTest,
GetImageForURLNetworkCacheNotInitialized);
// Used for testing.
ImageManager();
typedef std::vector<base::Callback<void(const GURL&, const SkBitmap*)> >
CallbackVector;
typedef base::hash_map<std::string, SkBitmap> ImageMap;
// State related to an image fetch (associated website url, image_url,
// pending callbacks).
struct ImageCacheRequest {
ImageCacheRequest();
~ImageCacheRequest();
GURL url;
GURL image_url;
// Queue for pending callbacks, which may accumulate while the request is in
// flight.
CallbackVector callbacks;
};
typedef std::map<const GURL, ImageCacheRequest> ImageCacheRequestMap;
// Looks up image URL for |url|. If found, writes the result to |image_url|
// and returns true. Otherwise just returns false.
bool GetImageURL(const GURL& url, GURL* image_url);
void QueueCacheRequest(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
void ServeFromCacheOrNetwork(
const GURL& url, const GURL& image_url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
// Will return false if no bitmap was found corresponding to |url|, else
// return true and call |callback| with the found bitmap.
bool ServeFromCache(
const GURL& url,
base::Callback<void(const GURL&, const SkBitmap*)> callback);
// Returns null if the |url| had no entry in the cache.
SkBitmap* GetBitmapFromCache(const GURL& url);
// Save the image bitmap in the cache and in the database.
void SaveImage(const GURL& url, const SkBitmap& bitmap);
// Database callback methods.
// Will initiate loading the entries.
void OnDatabaseInit(bool success);
// Will transfer the loaded |entries| in memory (|image_map_|).
void OnDatabaseLoad(bool success, scoped_ptr<ImageDataVector> entries);
void OnDatabaseSave(bool success);
// Take entries from the database and put them in the local cache.
void LoadEntriesInCache(scoped_ptr<ImageDataVector> entries);
void ServePendingCacheRequests();
// From SkBitmap to the vector of JPEG-encoded bytes, |dst|. Visible only for
// testing.
static bool EncodeImage(const SkBitmap& bitmap,
std::vector<unsigned char>* dest);
// Map from URL to image URL. Should be kept up to date when a new
// SuggestionsProfile is available.
std::map<GURL, GURL> image_url_map_;
// Map from website URL to request information, used for pending cache
// requests while the database hasn't loaded.
ImageCacheRequestMap pending_cache_requests_;
// Holding the bitmaps in memory, keyed by website URL string.
ImageMap image_map_;
scoped_ptr<ImageFetcher> image_fetcher_;
scoped_ptr<leveldb_proto::ProtoDatabase<ImageData> > database_;
bool database_ready_;
base::WeakPtrFactory<ImageManager> weak_ptr_factory_;
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(ImageManager); DISALLOW_COPY_AND_ASSIGN(ImageManager);
}; };
......
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