Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3554)

Unified Diff: chrome/browser/extensions/image_loader.h

Issue 11027044: Add a class to replace ImageLoadingTracker with a nicer API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: SkBitmap* -> SkBitmap Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/extensions/extension_web_ui.cc ('k') | chrome/browser/extensions/image_loader.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/image_loader.h
diff --git a/chrome/browser/extensions/image_loading_tracker.h b/chrome/browser/extensions/image_loader.h
similarity index 38%
copy from chrome/browser/extensions/image_loading_tracker.h
copy to chrome/browser/extensions/image_loader.h
index 5eefcd1840f2a66637a06a13204562ae1f476b04..273682122ba76ea037857929743e9aa06f735e42 100644
--- a/chrome/browser/extensions/image_loading_tracker.h
+++ b/chrome/browser/extensions/image_loader.h
@@ -2,71 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTENSIONS_IMAGE_LOADING_TRACKER_H_
-#define CHROME_BROWSER_EXTENSIONS_IMAGE_LOADING_TRACKER_H_
+#ifndef CHROME_BROWSER_EXTENSIONS_IMAGE_LOADER_H_
+#define CHROME_BROWSER_EXTENSIONS_IMAGE_LOADER_H_
#include <map>
-#include <string>
-#include <vector>
+#include <set>
-#include "base/compiler_specific.h"
+#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/extension_resource.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/layout.h"
-#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/size.h"
-class SkBitmap;
+template <typename T> struct DefaultSingletonTraits;
-namespace extensions {
-class Extension;
-}
+FORWARD_DECLARE_TEST(ImageLoaderTest, Cache);
+FORWARD_DECLARE_TEST(ImageLoaderTest, DeleteExtensionWhileWaitingForCache);
+FORWARD_DECLARE_TEST(ImageLoaderTest, MultipleImages);
namespace gfx {
class Image;
}
-// The views need to load their icons asynchronously but might be deleted before
-// the images have loaded. This class encapsulates a loader class that stays
-// alive while the request is in progress (manages its own lifetime) and keeps
-// track of whether the view still cares about the icon loading.
+namespace extensions {
+
+class Extension;
+
+// This class is responsible for asynchronously loading extension images and
+// calling a callback when an image is loaded.
+// The views need to load their icons asynchronously might be deleted before
+// the images have loaded. If you pass your callback using a weak_ptr, this
+// will make sure the callback won't be called after the view is deleted.
//
-// To use this class, have your class derive from ImageLoadingTracker::Observer,
-// and add a member variable ImageLoadingTracker tracker_. Then override
-// Observer::OnImageLoaded and call:
-// tracker_.LoadImage(extension, resource, max_size, false);
-// ... and wait for OnImageLoaded to be called back on you with a pointer to the
-// ImageSkia loaded.
-// NOTE: if the image is available already (or the resource is not valid), the
-// Observer is notified immediately from the call to LoadImage. In other words,
-// by the time LoadImage returns the observer has been notified.
+// NOTE: if the image is available already, the callback is called immediately
+// from the call to LoadImageAsync. In other words, by the time LoadImageAsync
+// returns the callback has been notified.
Aaron Boodman 2012/10/17 17:15:13 I think "reentrant" is the right word here?
//
-class ImageLoadingTracker : public content::NotificationObserver {
+class ImageLoader : public content::NotificationObserver {
public:
- enum CacheParam {
- CACHE,
- DONT_CACHE
- };
-
- class Observer {
- public:
- // Will be called when the image with the given index has loaded.
- // |image| can be empty if a valid image was not found or it failed to
- // decode. |extension_id| is the ID of the extension the images are loaded
- // from. |index| represents the index of the image just loaded (starts at 0
- // and increments every time LoadImage is called).
- virtual void OnImageLoaded(const gfx::Image& image,
- const std::string& extension_id,
- int index) = 0;
-
- protected:
- virtual ~Observer();
- };
-
// Information about a singe image representation to load from an extension
// resource.
struct ImageRepresentation {
@@ -78,7 +54,7 @@ class ImageLoadingTracker : public content::NotificationObserver {
};
ImageRepresentation(const ExtensionResource& resource,
- ResizeCondition resize_method,
+ ResizeCondition resize_condition,
const gfx::Size& desired_size,
ui::ScaleFactor scale_factor);
~ImageRepresentation();
@@ -86,7 +62,7 @@ class ImageLoadingTracker : public content::NotificationObserver {
// Extension resource to load.
ExtensionResource resource;
- ResizeCondition resize_method;
+ ResizeCondition resize_condition;
// When |resize_method| is ALWAYS_RESIZE or when the loaded image is larger
// than |desired_size| it will be resized to these dimensions.
@@ -96,91 +72,116 @@ class ImageLoadingTracker : public content::NotificationObserver {
ui::ScaleFactor scale_factor;
};
- explicit ImageLoadingTracker(Observer* observer);
- virtual ~ImageLoadingTracker();
+ static ImageLoader* GetInstance();
+
+ // Checks whether image is a component extension resource. Returns false
+ // if a given |resource| does not have a corresponding image in bundled
+ // resources. Otherwise fills |resource_id|.
+ static bool IsComponentExtensionResource(
+ const extensions::Extension* extension,
+ const FilePath& resource_path,
+ int* resource_id);
// Specify image resource to load. If the loaded image is larger than
// |max_size| it will be resized to those dimensions. IMPORTANT NOTE: this
- // function may call back your observer synchronously (ie before it returns)
+ // function may call back your callback synchronously (ie before it returns)
// if the image was found in the cache.
// Note this method loads a raw bitmap from the resource. All sizes given are
// assumed to be in pixels.
- void LoadImage(const extensions::Extension* extension,
- const ExtensionResource& resource,
- const gfx::Size& max_size,
- CacheParam cache);
+ void LoadImageAsync(const extensions::Extension* extension,
+ const ExtensionResource& resource,
+ const gfx::Size& max_size,
+ const base::Callback<void(const gfx::Image&)>& callback);
// Same as LoadImage() above except it loads multiple images from the same
// extension. This is used to load multiple resolutions of the same image
// type.
- void LoadImages(const extensions::Extension* extension,
- const std::vector<ImageRepresentation>& info_list,
- CacheParam cache);
-
- // Returns the ID used for the next image that is loaded. That is, the return
- // value from this method corresponds to the int that is passed to
- // OnImageLoaded() the next time LoadImage() is invoked.
- int next_id() const { return next_id_; }
+ void LoadImagesAsync(const extensions::Extension* extension,
+ const std::vector<ImageRepresentation>& info_list,
+ const base::Callback<void(const gfx::Image&)>& callback);
- // Checks whether image is a component extension resource. Returns false
- // if a given |resource| does not have a corresponding image in bundled
- // resources. Otherwise fills |resource_id|.
- static bool IsComponentExtensionResource(
- const extensions::Extension* extension,
- const FilePath& resource_path,
- int* resource_id);
+ void SetCachedImage(const ExtensionResource& source,
+ const SkBitmap& image,
+ const gfx::Size& original_size) const;
private:
- // Information for pending resource load operation for one or more image
- // representations.
+ friend struct DefaultSingletonTraits<ImageLoader>;
+
+ // We keep a cache of images loaded from extension resources based on their
+ // path and a string representation of a size that may have been used to
+ // scale it (or the empty string if the image is at its original size).
+ typedef std::pair<FilePath, std::string> ImageCacheKey;
+ typedef std::map<ImageCacheKey, SkBitmap> ImageCache;
+
struct PendingLoadInfo {
PendingLoadInfo();
~PendingLoadInfo();
- const extensions::Extension* extension;
- // This is cached separate from |extension| in case the extension is
- // unloaded.
std::string extension_id;
- CacheParam cache;
- size_t pending_count;
- gfx::ImageSkia image_skia;
+ bool save_to_cache;
};
- // Maps an integer identifying a load request to a PendingLoadInfo.
- typedef std::map<int, PendingLoadInfo> LoadMap;
+ typedef std::set<PendingLoadInfo*> LoadSet;
+
+ struct LoadResult {
+ LoadResult(const SkBitmap& bitmap,
+ const gfx::Size& original_size,
+ const ImageRepresentation& image_representation);
+ ~LoadResult();
+
+ SkBitmap bitmap;
+ gfx::Size original_size;
+ ImageRepresentation image_representation;
+ };
- class ImageLoader;
+ ImageLoader();
+ virtual ~ImageLoader();
- // Called on the calling thread when the bitmap finishes loading.
- // |bitmap| may be null if the image file failed to decode.
- void OnBitmapLoaded(const SkBitmap* bitmap,
- const ImageRepresentation& image_info,
- const gfx::Size& original_size,
- int id,
- bool should_cache);
+ void LoadImagesOnBlockingPool(
+ const std::vector<ImageRepresentation>& info_list,
+ const std::vector<SkBitmap>& bitmaps,
+ PendingLoadInfo* load_info,
+ const base::Callback<void(const gfx::Image&)>& callback);
+
+ void ReplyBack(
+ const std::vector<LoadResult>& load_result,
+ PendingLoadInfo* load_info,
+ const base::Callback<void(const gfx::Image&)>& callback);
// content::NotificationObserver method. If an extension is uninstalled while
- // we're waiting for the image we remove the entry from load_map_.
+ // we're waiting for the image we make sure it won't be cached.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
- // The view that is waiting for the image to load.
- Observer* observer_;
+ void SetCachedImageImpl(const std::string& extension_id,
+ const ImageCacheKey& key,
+ const SkBitmap& image);
+
+ const SkBitmap* GetCachedImage(const ExtensionResource& source,
+ const gfx::Size& max_size) const;
- // ID to use for next image requested. This is an ever increasing integer.
- int next_id_;
+ bool ShouldCacheImage(const ImageRepresentation& image_info) const;
+ void SetImageSizesToCache(const std::set<int> image_sizes_);
- // The object responsible for loading the image on the File thread.
- scoped_refptr<ImageLoader> loader_;
+ // Cached images for extensions. This should only be touched on the UI thread.
+ std::map<std::string, ImageCache> image_cache_;
- // Information for each LoadImage request is cached here. The integer
- // identifies the id assigned to the request.
- LoadMap load_map_;
+ // Set of all pending image loads that should be cached unless the extension
+ // they are loaded from gets unloaded before the load finishes.
+ LoadSet pending_;
+
+ // Sizes of images to cache
+ std::set<int> image_sizes_to_cache_;
content::NotificationRegistrar registrar_;
- DISALLOW_COPY_AND_ASSIGN(ImageLoadingTracker);
+ FRIEND_TEST_ALL_PREFIXES(::ImageLoaderTest, Cache);
+ FRIEND_TEST_ALL_PREFIXES(::ImageLoaderTest,
+ DeleteExtensionWhileWaitingForCache);
+ FRIEND_TEST_ALL_PREFIXES(::ImageLoaderTest, MultipleImages);
};
-#endif // CHROME_BROWSER_EXTENSIONS_IMAGE_LOADING_TRACKER_H_
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_IMAGE_LOADER_H_
« no previous file with comments | « chrome/browser/extensions/extension_web_ui.cc ('k') | chrome/browser/extensions/image_loader.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698