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

Unified Diff: chrome/browser/extensions/extension_icon_image.cc

Issue 10861034: Supply default icon to extension icon image. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 4 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
Index: chrome/browser/extensions/extension_icon_image.cc
diff --git a/chrome/browser/extensions/extension_icon_image.cc b/chrome/browser/extensions/extension_icon_image.cc
index dcd096815c03ab6c26653705b041539a73703acc..82a86abf9a1e363c2d5680a5aa9083ef996492ff 100644
--- a/chrome/browser/extensions/extension_icon_image.cc
+++ b/chrome/browser/extensions/extension_icon_image.cc
@@ -6,13 +6,17 @@
#include <vector>
+#include "base/message_loop_proxy.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/size.h"
+using content::BrowserThread;
+
namespace {
const int kMatchBiggerTreshold = 32;
@@ -38,7 +42,7 @@ namespace extensions {
class IconImage::Source : public gfx::ImageSkiaSource {
public:
- explicit Source(IconImage* host);
+ explicit Source(IconImage* host, const gfx::ImageSkia& default_image);
virtual ~Source();
void ResetHost();
@@ -50,10 +54,15 @@ class IconImage::Source : public gfx::ImageSkiaSource {
IconImage* host_;
+ // Image whose representation GetImageForScale will return if |host_| supplies
+ // a null representation.
+ gfx::ImageSkia default_image_;
+
DISALLOW_COPY_AND_ASSIGN(Source);
};
-IconImage::Source::Source(IconImage* host) : host_(host) {
+IconImage::Source::Source(IconImage* host, const gfx::ImageSkia& default_image)
+ : host_(host), default_image_(default_image) {
}
IconImage::Source::~Source() {
@@ -65,9 +74,15 @@ void IconImage::Source::ResetHost() {
gfx::ImageSkiaRep IconImage::Source::GetImageForScale(
ui::ScaleFactor scale_factor) {
+ gfx::ImageSkiaRep representation;
if (host_)
- host_->LoadImageForScaleFactor(scale_factor);
- return gfx::ImageSkiaRep();
+ representation = host_->LoadImageForScaleFactor(scale_factor);
+
+ if (!representation.is_null())
+ return representation;
+
+ representation = default_image_.GetRepresentation(scale_factor);
+ return gfx::ImageSkiaRep(representation.sk_bitmap(), scale_factor);
tbarzic 2012/08/22 02:39:10 pkotwicz: is it safe to assume that e.g. ui::Resou
pkotwicz 2012/08/22 23:17:55 If the default icon comes from the resource bundle
}
////////////////////////////////////////////////////////////////////////////////
@@ -77,6 +92,7 @@ IconImage::IconImage(
const Extension* extension,
const ExtensionIconSet& icon_set,
int resource_size_in_dip,
+ const gfx::ImageSkia& default_icon,
Observer* observer)
: extension_(extension),
icon_set_(icon_set),
@@ -84,8 +100,9 @@ IconImage::IconImage(
desired_size_in_dip_(resource_size_in_dip, resource_size_in_dip),
observer_(observer),
source_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {
- source_ = new Source(this);
+ ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ source_ = new Source(this, default_icon);
image_skia_ = gfx::ImageSkia(source_, desired_size_in_dip_);
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
@@ -98,10 +115,11 @@ IconImage::~IconImage() {
source_->ResetHost();
}
-void IconImage::LoadImageForScaleFactor(ui::ScaleFactor scale_factor) {
+gfx::ImageSkiaRep IconImage::LoadImageForScaleFactor(
+ ui::ScaleFactor scale_factor) {
// Do nothing if extension is unloaded.
if (!extension_)
- return;
+ return gfx::ImageSkiaRep();
const float scale = ui::GetScaleFactorScale(scale_factor);
const int resource_size_in_pixel =
@@ -122,13 +140,15 @@ void IconImage::LoadImageForScaleFactor(ui::ScaleFactor scale_factor) {
// If there is no resource found, bail out and notify observer of failure.
if (resource.empty()) {
- if (observer_)
- observer_->OnIconImageLoadFailed(this, scale_factor);
- return;
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(&IconImage::NotifyFail, weak_ptr_factory_.GetWeakPtr(),
+ scale_factor));
+ return gfx::ImageSkiaRep();
}
int id = tracker_.next_id();
- load_map_[id] = scale_factor;
+ load_map_[id].scale_factor = scale_factor;
+ load_map_[id].is_async = false;
std::vector<ImageLoadingTracker::ImageRepresentation> info_list;
info_list.push_back(ImageLoadingTracker::ImageRepresentation(
@@ -137,6 +157,18 @@ void IconImage::LoadImageForScaleFactor(ui::ScaleFactor scale_factor) {
desired_size_in_dip_.Scale(scale),
scale_factor));
tracker_.LoadImages(extension_, info_list, ImageLoadingTracker::DONT_CACHE);
+
+ // If requested image has been cached, we may already have the wanted
+ // representation.
pkotwicz 2012/08/22 23:17:55 Nit: return representation if we have cached it a
tbarzic 2012/08/23 00:06:09 are you sure, we could paint two different images
pkotwicz 2012/08/23 13:59:09 I should have been clearer. My nit was about chang
pkotwicz 2012/08/23 14:09:45 Ok, I see what you are doing. Sorry about that. Ch
tbarzic 2012/08/23 17:41:53 Done.
+ if (image_skia_.HasRepresentation(scale_factor))
+ return image_skia_.GetRepresentation(scale_factor);
+
+ // If we have not received |OnImageLoaded|, note that iamge load request is
+ // asynchronous.
pkotwicz 2012/08/22 23:17:55 Nit: I think it might be a bit more understandable
tbarzic 2012/08/23 00:06:09 Done.
+ if (load_map_.find(id) != load_map_.end())
+ load_map_[id].is_async = true;
+
+ return gfx::ImageSkiaRep();
}
void IconImage::OnImageLoaded(const gfx::Image& image,
@@ -145,26 +177,37 @@ void IconImage::OnImageLoaded(const gfx::Image& image,
LoadMap::iterator load_map_it = load_map_.find(index);
DCHECK(load_map_it != load_map_.end());
- ui::ScaleFactor scale_factor = load_map_it->second;
+ ui::ScaleFactor scale_factor = load_map_it->second.scale_factor;
+ bool is_async = load_map_it->second.is_async;
load_map_.erase(load_map_it);
-
if (image.IsEmpty()) {
- // There waas an error loading the image.
- if (observer_)
- observer_->OnIconImageLoadFailed(this, scale_factor);
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(&IconImage::NotifyFail, weak_ptr_factory_.GetWeakPtr(),
+ scale_factor));
return;
}
DCHECK(image.ToImageSkia()->HasRepresentation(scale_factor));
gfx::ImageSkiaRep rep = image.ToImageSkia()->GetRepresentation(scale_factor);
DCHECK(!rep.is_null());
+
+ // Remove old representation if there is one.
+ image_skia_.RemoveRepresentation(rep.scale_factor());
image_skia_.AddRepresentation(rep);
- if (observer_)
+ // If |tracker_| called us synchronously the image did not really change from
+ // the observers perspective, since we still haven't returned the initial
+ // image representation.
+ if (is_async && observer_)
observer_->OnExtensionIconImageChanged(this);
}
+void IconImage::NotifyFail(ui::ScaleFactor scale_factor) {
+ if (observer_)
+ observer_->OnIconImageLoadFailed(this, scale_factor);
+}
+
void IconImage::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {

Powered by Google App Engine
This is Rietveld 408576698