summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-03 19:58:06 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-03 19:58:06 +0000
commitbdd6eec2dbd37b2fdc38d32cd69f467bbc2d69cc (patch)
treee99d5669185f6ac8ccd441baa70b69a65a0331c2 /chrome
parent04f050b37f95b156b4b60c9e05e5672bc3388f0f (diff)
downloadchromium_src-bdd6eec2dbd37b2fdc38d32cd69f467bbc2d69cc.zip
chromium_src-bdd6eec2dbd37b2fdc38d32cd69f467bbc2d69cc.tar.gz
chromium_src-bdd6eec2dbd37b2fdc38d32cd69f467bbc2d69cc.tar.bz2
Add support for multiple icon sizes for Mac platform apps
This is the combined version of the following CLs: http://codereview.chromium.org/9428025/ http://codereview.chromium.org/9500007/ http://codereview.chromium.org/9535002/ BUG=112651 TEST= Review URL: https://chromiumcodereview.appspot.com/9586018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124875 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/background/background_application_list_model.cc15
-rw-r--r--chrome/browser/extensions/app_shortcut_manager.cc84
-rw-r--r--chrome/browser/extensions/app_shortcut_manager.h4
-rw-r--r--chrome/browser/extensions/extension_icon_manager.cc11
-rw-r--r--chrome/browser/extensions/extension_icon_manager.h3
-rw-r--r--chrome/browser/extensions/extension_icon_manager_unittest.cc7
-rw-r--r--chrome/browser/extensions/extension_install_ui.cc10
-rw-r--r--chrome/browser/extensions/extension_install_ui.h7
-rw-r--r--chrome/browser/extensions/extension_tab_helper.cc9
-rw-r--r--chrome/browser/extensions/extension_tab_helper.h3
-rw-r--r--chrome/browser/extensions/extension_uninstall_dialog.cc15
-rw-r--r--chrome/browser/extensions/extension_uninstall_dialog.h10
-rw-r--r--chrome/browser/extensions/extension_web_ui.cc10
-rw-r--r--chrome/browser/extensions/image_loading_tracker.cc146
-rw-r--r--chrome/browser/extensions/image_loading_tracker.h60
-rw-r--r--chrome/browser/extensions/image_loading_tracker_unittest.cc63
-rw-r--r--chrome/browser/shell_integration.h3
-rw-r--r--chrome/browser/shell_integration_linux.cc7
-rw-r--r--chrome/browser/ui/cocoa/extensions/browser_action_button.mm10
-rw-r--r--chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm24
-rw-r--r--chrome/browser/ui/cocoa/location_bar/page_action_decoration.h5
-rw-r--r--chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm12
-rw-r--r--chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc13
-rw-r--r--chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc22
-rw-r--r--chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h6
-rw-r--r--chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc25
-rw-r--r--chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h5
-rw-r--r--chrome/browser/ui/gtk/location_bar_view_gtk.cc9
-rw-r--r--chrome/browser/ui/gtk/location_bar_view_gtk.h5
-rw-r--r--chrome/browser/ui/views/ash/app_list/extension_app_item.cc8
-rw-r--r--chrome/browser/ui/views/ash/app_list/extension_app_item.h4
-rw-r--r--chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.cc2
-rw-r--r--chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h2
-rw-r--r--chrome/browser/ui/views/ash/launcher/launcher_icon_loader.cc9
-rw-r--r--chrome/browser/ui/views/ash/launcher/launcher_icon_loader.h4
-rw-r--r--chrome/browser/ui/views/browser_actions_container.cc8
-rw-r--r--chrome/browser/ui/views/browser_actions_container.h4
-rw-r--r--chrome/browser/ui/views/create_application_shortcut_view.cc22
-rw-r--r--chrome/browser/ui/views/create_application_shortcut_view.h4
-rw-r--r--chrome/browser/ui/views/infobars/extension_infobar.cc19
-rw-r--r--chrome/browser/ui/views/infobars/extension_infobar.h4
-rw-r--r--chrome/browser/ui/views/location_bar/page_action_image_view.cc12
-rw-r--r--chrome/browser/ui/views/location_bar/page_action_image_view.h4
-rw-r--r--chrome/browser/ui/web_applications/web_app_ui.cc5
-rw-r--r--chrome/browser/ui/webui/extensions/extension_icon_source.cc21
-rw-r--r--chrome/browser/ui/webui/extensions/extension_icon_source.h6
-rw-r--r--chrome/browser/ui/webui/ntp/favicon_webui_handler.cc8
-rw-r--r--chrome/browser/web_applications/web_app_mac.mm76
-rw-r--r--chrome/browser/web_applications/web_app_mac_unittest.mm8
49 files changed, 539 insertions, 294 deletions
diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc
index 58c815e..dfb4a2d 100644
--- a/chrome/browser/background/background_application_list_model.cc
+++ b/chrome/browser/background/background_application_list_model.cc
@@ -23,6 +23,7 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "ui/base/l10n/l10n_util_collator.h"
+#include "ui/gfx/image/image.h"
class ExtensionNameComparator {
public:
@@ -55,9 +56,9 @@ class BackgroundApplicationListModel::Application
virtual ~Application();
// Invoked when a request icon is available.
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
- int index);
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE;
// Uses the FILE thread to request this extension's icon, sized
// appropriately.
@@ -129,12 +130,12 @@ BackgroundApplicationListModel::Application::Application(
}
void BackgroundApplicationListModel::Application::OnImageLoaded(
- SkBitmap* image,
- const ExtensionResource& resource,
+ const gfx::Image& image,
+ const std::string& extension_id,
int index) {
- if (!image)
+ if (image.IsEmpty())
return;
- icon_.reset(new SkBitmap(*image));
+ icon_.reset(image.CopySkBitmap());
model_->SendApplicationDataChangedNotifications(extension_);
}
diff --git a/chrome/browser/extensions/app_shortcut_manager.cc b/chrome/browser/extensions/app_shortcut_manager.cc
index e96349a..bec3e3d 100644
--- a/chrome/browser/extensions/app_shortcut_manager.cc
+++ b/chrome/browser/extensions/app_shortcut_manager.cc
@@ -6,7 +6,6 @@
#include "base/command_line.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_notification_types.h"
@@ -15,12 +14,20 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "grit/theme_resources.h"
+#include "skia/ext/image_operations.h"
+#include "ui/base/resource/resource_bundle.h"
namespace {
- // Allow tests to disable shortcut creation, to prevent developers' desktops
- // becoming overrun with shortcuts.
- bool disable_shortcut_creation_for_tests = false;
-} // namespace
+// Allow tests to disable shortcut creation, to prevent developers' desktops
+// becoming overrun with shortcuts.
+bool disable_shortcut_creation_for_tests = false;
+
+#if defined(OS_MACOSX)
+const int kDesiredSizes[] = {16, 32, 128, 256, 512};
+#else
+const int kDesiredSizes[] = {32};
+#endif
+} // namespace
AppShortcutManager::AppShortcutManager(Profile* profile)
: profile_(profile),
@@ -29,15 +36,23 @@ AppShortcutManager::AppShortcutManager(Profile* profile)
content::Source<Profile>(profile_));
}
-void AppShortcutManager::OnImageLoaded(SkBitmap *image,
- const ExtensionResource &resource,
+void AppShortcutManager::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
// If the image failed to load (e.g. if the resource being loaded was empty)
// use the standard application icon.
- if (!image || image->isNull())
- image = ExtensionIconSource::LoadImageByResourceId(IDR_APP_DEFAULT_ICON);
+ if (image.IsEmpty()) {
+ gfx::Image default_icon =
+ ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON);
+ int size = kDesiredSizes[arraysize(kDesiredSizes) - 1];
+ SkBitmap bmp = skia::ImageOperations::Resize(
+ *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST,
+ size, size);
+ shortcut_info_.favicon = gfx::Image(bmp);
+ } else {
+ shortcut_info_.favicon = image;
+ }
- shortcut_info_.favicon = *image;
web_app::CreateShortcut(profile_->GetPath(), shortcut_info_);
}
@@ -66,8 +81,6 @@ void AppShortcutManager::InstallApplicationShortcuts(
}
#endif
- const int kAppIconSize = 32;
-
shortcut_info_.extension_id = extension->id();
shortcut_info_.url = GURL(extension->launch_web_url());
shortcut_info_.title = UTF8ToUTF16(extension->name());
@@ -78,29 +91,36 @@ void AppShortcutManager::InstallApplicationShortcuts(
shortcut_info_.create_in_quick_launch_bar = true;
shortcut_info_.create_on_desktop = true;
- // The icon will be resized to |max_size|.
- const gfx::Size max_size(kAppIconSize, kAppIconSize);
+ std::vector<ImageLoadingTracker::ImageInfo> info_list;
+ for (size_t i = 0; i < arraysize(kDesiredSizes); ++i) {
+ int size = kDesiredSizes[i];
+ ExtensionResource resource = extension->GetIconResource(
+ size, ExtensionIconSet::MATCH_EXACTLY);
+ if (!resource.empty()) {
+ info_list.push_back(
+ ImageLoadingTracker::ImageInfo(resource, gfx::Size(size, size)));
+ }
+ }
- // Look for an icon. If there is no icon at the ideal size, we will resize
- // whatever we can get. Making a large icon smaller is prefered to making a
- // small icon larger, so look for a larger icon first:
- ExtensionResource icon_resource = extension->GetIconResource(
- kAppIconSize,
- ExtensionIconSet::MATCH_BIGGER);
+ if (info_list.empty()) {
+ size_t i = arraysize(kDesiredSizes) - 1;
+ int size = kDesiredSizes[i];
- // If no icon exists that is the desired size or larger, get the
- // largest icon available:
- if (icon_resource.empty()) {
- icon_resource = extension->GetIconResource(
- kAppIconSize,
- ExtensionIconSet::MATCH_SMALLER);
+ // If there is no icon at the desired sizes, we will resize what we can get.
+ // Making a large icon smaller is prefered to making a small icon larger, so
+ // look for a larger icon first:
+ ExtensionResource resource = extension->GetIconResource(
+ size, ExtensionIconSet::MATCH_BIGGER);
+ if (resource.empty()) {
+ resource = extension->GetIconResource(
+ size, ExtensionIconSet::MATCH_SMALLER);
+ }
+ info_list.push_back(
+ ImageLoadingTracker::ImageInfo(resource, gfx::Size(size, size)));
}
- // icon_resource may still be empty at this point, in which case LoadImage
- // which call the OnImageLoaded callback with a NULL image and exit
+ // |icon_resources| may still be empty at this point, in which case LoadImage
+ // will call the OnImageLoaded callback with an empty image and exit
// immediately.
- tracker_.LoadImage(extension,
- icon_resource,
- max_size,
- ImageLoadingTracker::DONT_CACHE);
+ tracker_.LoadImages(extension, info_list, ImageLoadingTracker::DONT_CACHE);
}
diff --git a/chrome/browser/extensions/app_shortcut_manager.h b/chrome/browser/extensions/app_shortcut_manager.h
index 7f21f88..d97bbcc2 100644
--- a/chrome/browser/extensions/app_shortcut_manager.h
+++ b/chrome/browser/extensions/app_shortcut_manager.h
@@ -24,8 +24,8 @@ class AppShortcutManager : public ImageLoadingTracker::Observer,
// load the application's icon, which is done when we start creating an
// application's shortcuts. This method receives the icon, and completes
// the process of installing the shortcuts.
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
// content::NotificationObserver
diff --git a/chrome/browser/extensions/extension_icon_manager.cc b/chrome/browser/extensions/extension_icon_manager.cc
index 298ab22..e245a7f 100644
--- a/chrome/browser/extensions/extension_icon_manager.cc
+++ b/chrome/browser/extensions/extension_icon_manager.cc
@@ -15,6 +15,7 @@
#include "ui/gfx/canvas_skia.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/favicon_size.h"
+#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skbitmap_operations.h"
@@ -79,21 +80,19 @@ void ExtensionIconManager::RemoveIcon(const std::string& extension_id) {
pending_icons_.erase(extension_id);
}
-void ExtensionIconManager::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void ExtensionIconManager::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
- if (!image)
+ if (image.IsEmpty())
return;
- const std::string extension_id = resource.extension_id();
-
// We may have removed the icon while waiting for it to load. In that case,
// do nothing.
if (!ContainsKey(pending_icons_, extension_id))
return;
pending_icons_.erase(extension_id);
- icons_[extension_id] = ApplyTransforms(*image);
+ icons_[extension_id] = ApplyTransforms(*image.ToSkBitmap());
}
void ExtensionIconManager::EnsureDefaultIcon() {
diff --git a/chrome/browser/extensions/extension_icon_manager.h b/chrome/browser/extensions/extension_icon_manager.h
index a4a7813..4596d12 100644
--- a/chrome/browser/extensions/extension_icon_manager.h
+++ b/chrome/browser/extensions/extension_icon_manager.h
@@ -34,7 +34,8 @@ class ExtensionIconManager : public ImageLoadingTracker::Observer {
void RemoveIcon(const std::string& extension_id);
// Implements the ImageLoadingTracker::Observer interface.
- virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
void set_monochrome(bool value) { monochrome_ = value; }
diff --git a/chrome/browser/extensions/extension_icon_manager_unittest.cc b/chrome/browser/extensions/extension_icon_manager_unittest.cc
index d0401c9..5fb32d7 100644
--- a/chrome/browser/extensions/extension_icon_manager_unittest.cc
+++ b/chrome/browser/extensions/extension_icon_manager_unittest.cc
@@ -76,9 +76,10 @@ class TestIconManager : public ExtensionIconManager {
// Implements the ImageLoadingTracker::Observer interface, and calls through
// to the base class' implementation. Then it lets the test know that an
// image load was observed.
- virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
- int index) {
- ExtensionIconManager::OnImageLoaded(image, resource, index);
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE {
+ ExtensionIconManager::OnImageLoaded(image, extension_id, index);
test_->ImageLoadObserved();
}
diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc
index 4587422..8052ecb 100644
--- a/chrome/browser/extensions/extension_install_ui.cc
+++ b/chrome/browser/extensions/extension_install_ui.cc
@@ -41,6 +41,7 @@
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image.h"
using content::WebContents;
using extensions::BundleInstaller;
@@ -323,7 +324,7 @@ void ExtensionInstallUI::OnInstallFailure(const string16& error) {
error);
}
-void ExtensionInstallUI::SetIcon(SkBitmap* image) {
+void ExtensionInstallUI::SetIcon(const SkBitmap* image) {
if (image)
icon_ = *image;
else
@@ -332,9 +333,10 @@ void ExtensionInstallUI::SetIcon(SkBitmap* image) {
icon_ = Extension::GetDefaultIcon(extension_->is_app());
}
-void ExtensionInstallUI::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
- SetIcon(image);
+void ExtensionInstallUI::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
+ SetIcon(image.IsEmpty() ? NULL : image.ToSkBitmap());
switch (prompt_type_) {
case PERMISSIONS_PROMPT:
diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h
index bb3ad1d..9a35da0 100644
--- a/chrome/browser/extensions/extension_install_ui.h
+++ b/chrome/browser/extensions/extension_install_ui.h
@@ -174,8 +174,9 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer {
virtual void OnInstallFailure(const string16& error);
// ImageLoadingTracker::Observer:
- virtual void OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) OVERRIDE;
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE;
// Opens a new tab page and animates the app icon for the app with id
// |app_id|.
@@ -201,7 +202,7 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer {
// Sets the icon that will be used in any UI. If |icon| is NULL, or contains
// an empty bitmap, then a default icon will be used instead.
- void SetIcon(SkBitmap* icon);
+ void SetIcon(const SkBitmap* icon);
// Starts the process of showing a confirmation UI, which is split into two.
// 1) Set off a 'load icon' task.
diff --git a/chrome/browser/extensions/extension_tab_helper.cc b/chrome/browser/extensions/extension_tab_helper.cc
index 6ec0221..e7f1fe9 100644
--- a/chrome/browser/extensions/extension_tab_helper.cc
+++ b/chrome/browser/extensions/extension_tab_helper.cc
@@ -23,6 +23,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
+#include "ui/gfx/image/image.h"
using content::WebContents;
@@ -256,11 +257,11 @@ void ExtensionTabHelper::SetAppIcon(const SkBitmap& app_icon) {
web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TITLE);
}
-void ExtensionTabHelper::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void ExtensionTabHelper::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
- if (image) {
- extension_app_icon_ = *image;
+ if (!image.IsEmpty()) {
+ extension_app_icon_ = *image.ToSkBitmap();
web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
}
}
diff --git a/chrome/browser/extensions/extension_tab_helper.h b/chrome/browser/extensions/extension_tab_helper.h
index ef1bd99..dd1edc8 100644
--- a/chrome/browser/extensions/extension_tab_helper.h
+++ b/chrome/browser/extensions/extension_tab_helper.h
@@ -122,7 +122,8 @@ class ExtensionTabHelper
void UpdateExtensionAppIcon(const Extension* extension);
// ImageLoadingTracker::Observer.
- virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
// WebstoreInlineInstaller::Delegate.
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.cc b/chrome/browser/extensions/extension_uninstall_dialog.cc
index d3044d7..554e929 100644
--- a/chrome/browser/extensions/extension_uninstall_dialog.cc
+++ b/chrome/browser/extensions/extension_uninstall_dialog.cc
@@ -13,6 +13,7 @@
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image.h"
// Size of extension icon in top left of dialog.
static const int kIconSize = 69;
@@ -41,12 +42,8 @@ void ExtensionUninstallDialog::ConfirmUninstall(const Extension* extension) {
ImageLoadingTracker::DONT_CACHE);
}
-void ExtensionUninstallDialog::SetIcon(SkBitmap* image) {
- if (image)
- icon_ = *image;
- else
- icon_ = SkBitmap();
- if (icon_.empty()) {
+void ExtensionUninstallDialog::SetIcon(const gfx::Image& image) {
+ if (image.IsEmpty()) {
if (extension_->is_app()) {
icon_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_APP_DEFAULT_ICON);
@@ -54,11 +51,13 @@ void ExtensionUninstallDialog::SetIcon(SkBitmap* image) {
icon_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_EXTENSION_DEFAULT_ICON);
}
+ } else {
+ icon_ = *image.ToSkBitmap();
}
}
-void ExtensionUninstallDialog::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void ExtensionUninstallDialog::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
SetIcon(image);
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.h b/chrome/browser/extensions/extension_uninstall_dialog.h
index a817af3..c0c55ca 100644
--- a/chrome/browser/extensions/extension_uninstall_dialog.h
+++ b/chrome/browser/extensions/extension_uninstall_dialog.h
@@ -56,13 +56,13 @@ class ExtensionUninstallDialog : public ImageLoadingTracker::Observer {
SkBitmap icon_;
private:
- // Sets the icon that will be used in the dialog. If |icon| is NULL, or
- // contains an empty bitmap, then we use a default icon instead.
- void SetIcon(SkBitmap* icon);
+ // Sets the icon that will be used in the dialog. If |icon| contains an empty
+ // bitmap, then we use a default icon instead.
+ void SetIcon(const gfx::Image& image);
// ImageLoadingTracker::Observer:
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
// Displays the prompt. This should only be called after loading the icon.
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc
index a1f48b2..613cb5c 100644
--- a/chrome/browser/extensions/extension_web_ui.cc
+++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -88,11 +88,13 @@ class ExtensionWebUIImageLoadingTracker : public ImageLoadingTracker::Observer {
}
}
- virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
- int index) {
- if (image) {
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE {
+ if (!image.IsEmpty()) {
std::vector<unsigned char> image_data;
- if (!gfx::PNGCodec::EncodeBGRASkBitmap(*image, false, &image_data)) {
+ if (!gfx::PNGCodec::EncodeBGRASkBitmap(*image.ToSkBitmap(), false,
+ &image_data)) {
NOTREACHED() << "Could not encode extension favicon";
}
ForwardResult(RefCountedBytes::TakeVector(&image_data));
diff --git a/chrome/browser/extensions/image_loading_tracker.cc b/chrome/browser/extensions/image_loading_tracker.cc
index ca60dba..edf1f4b 100644
--- a/chrome/browser/extensions/image_loading_tracker.cc
+++ b/chrome/browser/extensions/image_loading_tracker.cc
@@ -13,13 +13,39 @@
#include "content/public/browser/notification_service.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/image/image.h"
#include "webkit/glue/image_decoder.h"
using content::BrowserThread;
+////////////////////////////////////////////////////////////////////////////////
+// ImageLoadingTracker::Observer
+
ImageLoadingTracker::Observer::~Observer() {}
////////////////////////////////////////////////////////////////////////////////
+// ImageLoadingTracker::ImageInfo
+
+ImageLoadingTracker::ImageInfo::ImageInfo(
+ const ExtensionResource resource, gfx::Size max_size)
+ : resource(resource), max_size(max_size) {
+}
+
+ImageLoadingTracker::ImageInfo::~ImageInfo() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ImageLoadingTracker::PendingLoadInfo
+
+ImageLoadingTracker::PendingLoadInfo::PendingLoadInfo()
+ : extension(NULL),
+ pending_count(0) {
+}
+
+ImageLoadingTracker::PendingLoadInfo::~PendingLoadInfo() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ImageLoadingTracker::ImageLoader
// A RefCounted class for loading images on the File thread and reporting back
@@ -102,7 +128,7 @@ class ImageLoadingTracker::ImageLoader
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
if (tracker_)
- tracker_->OnImageLoaded(image, resource, original_size, id);
+ tracker_->OnImageLoaded(image, resource, original_size, id, true);
delete image;
}
@@ -139,46 +165,93 @@ void ImageLoadingTracker::LoadImage(const Extension* extension,
const ExtensionResource& resource,
const gfx::Size& max_size,
CacheParam cache) {
- // If we don't have a path we don't need to do any further work, just respond
- // back.
- int id = next_id_++;
- if (resource.relative_path().empty()) {
- OnImageLoaded(NULL, resource, max_size, id);
- return;
- }
+ std::vector<ImageInfo> info_list;
+ info_list.push_back(ImageInfo(resource, max_size));
+ LoadImages(extension, info_list, cache);
+}
- DCHECK(extension->path() == resource.extension_root());
+void ImageLoadingTracker::LoadImages(const Extension* extension,
+ const std::vector<ImageInfo>& info_list,
+ CacheParam cache) {
+ PendingLoadInfo load_info;
+ load_info.extension = extension;
+ load_info.cache = cache;
+ load_info.extension_id = extension->id();
+ load_info.pending_count = info_list.size();
+ int id = next_id_++;
+ load_map_[id] = load_info;
+
+ for (std::vector<ImageInfo>::const_iterator it = info_list.begin();
+ it != info_list.end(); ++it) {
+ // If we don't have a path we don't need to do any further work, just
+ // respond back.
+ if (it->resource.relative_path().empty()) {
+ OnImageLoaded(NULL, it->resource, it->max_size, id, false);
+ continue;
+ }
- // See if the extension has the image already.
- if (extension->HasCachedImage(resource, max_size)) {
- SkBitmap image = extension->GetCachedImage(resource, max_size);
- OnImageLoaded(&image, resource, max_size, id);
- return;
- }
+ DCHECK(extension->path() == it->resource.extension_root());
- if (cache == CACHE)
- load_map_[id] = extension;
+ // See if the extension has the image already.
+ if (extension->HasCachedImage(it->resource, it->max_size)) {
+ SkBitmap image = extension->GetCachedImage(it->resource, it->max_size);
+ OnImageLoaded(&image, it->resource, it->max_size, id, false);
+ continue;
+ }
- // Instruct the ImageLoader to load this on the File thread. LoadImage does
- // not block.
- if (!loader_)
- loader_ = new ImageLoader(this);
- loader_->LoadImage(resource, max_size, id);
+ // Instruct the ImageLoader to load this on the File thread. LoadImage does
+ // not block.
+ if (!loader_)
+ loader_ = new ImageLoader(this);
+ loader_->LoadImage(it->resource, it->max_size, id);
+ }
}
void ImageLoadingTracker::OnImageLoaded(
SkBitmap* image,
const ExtensionResource& resource,
const gfx::Size& original_size,
- int id) {
- LoadMap::iterator i = load_map_.find(id);
- if (i != load_map_.end()) {
- i->second->SetCachedImage(resource, image ? *image : SkBitmap(),
- original_size);
- load_map_.erase(i);
+ int id,
+ bool should_cache) {
+ LoadMap::iterator load_map_it = load_map_.find(id);
+ DCHECK(load_map_it != load_map_.end());
+ PendingLoadInfo* info = &load_map_it->second;
+
+ // Save the pending results.
+ DCHECK(info->pending_count > 0);
+ info->pending_count--;
+ if (image)
+ info->bitmaps.push_back(*image);
+
+ // Add to the extension's image cache if requested.
+ DCHECK(info->cache != CACHE || info->extension);
+ if (should_cache && info->cache == CACHE &&
+ !info->extension->HasCachedImage(resource, original_size)) {
+ info->extension->SetCachedImage(resource, image ? *image : SkBitmap(),
+ original_size);
}
- observer_->OnImageLoaded(image, resource, id);
+ // If all pending images are done then report back.
+ if (info->pending_count == 0) {
+ gfx::Image image;
+ std::string extension_id = info->extension_id;
+
+ if (info->bitmaps.size() > 0) {
+ std::vector<const SkBitmap*> bitmaps;
+ for (std::vector<SkBitmap>::const_iterator it = info->bitmaps.begin();
+ it != info->bitmaps.end(); ++it) {
+ // gfx::Image takes ownership of this bitmap.
+ bitmaps.push_back(new SkBitmap(*it));
+ }
+ image = gfx::Image(bitmaps);
+ }
+
+ load_map_.erase(load_map_it);
+
+ // ImageLoadingTracker might be deleted after the callback so don't
+ // anything after this statement.
+ observer_->OnImageLoaded(image, extension_id, id);
+ }
}
void ImageLoadingTracker::Observe(int type,
@@ -189,12 +262,13 @@ void ImageLoadingTracker::Observe(int type,
const Extension* extension =
content::Details<UnloadedExtensionInfo>(details)->extension;
- // Remove all entries in the load_map_ referencing the extension. This ensures
- // we don't attempt to cache the image when the load completes.
- for (LoadMap::iterator i = load_map_.begin(); i != load_map_.end();) {
- if (i->second == extension)
- load_map_.erase(i++);
- else
- ++i;
+ // Remove reference to this extension from all pending load entries. This
+ // ensures we don't attempt to cache the image when the load completes.
+ for (LoadMap::iterator i = load_map_.begin(); i != load_map_.end(); ++i) {
+ PendingLoadInfo* info = &i->second;
+ if (info->extension == extension) {
+ info->extension = NULL;
+ info->cache = DONT_CACHE;
+ }
}
}
diff --git a/chrome/browser/extensions/image_loading_tracker.h b/chrome/browser/extensions/image_loading_tracker.h
index e59371d..6363877 100644
--- a/chrome/browser/extensions/image_loading_tracker.h
+++ b/chrome/browser/extensions/image_loading_tracker.h
@@ -10,15 +10,16 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
+#include "chrome/common/extensions/extension_resource.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "ui/gfx/size.h"
class Extension;
-class ExtensionResource;
class SkBitmap;
namespace gfx {
- class Size;
+class Image;
}
// The views need to load their icons asynchronously but might be deleted before
@@ -46,20 +47,28 @@ class ImageLoadingTracker : public content::NotificationObserver {
class Observer {
public:
// Will be called when the image with the given index has loaded.
- // The |image| is owned by the tracker, so the observer should make a copy
- // if they need to access it after this call. |image| can be null if a valid
- // image was not found or it failed to decode. |resource| is the
- // ExtensionResource where the |image| came from and the |index| represents
- // the index of the image just loaded (starts at 0 and increments every
- // time LoadImage is called).
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ // |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 single image to load from a extension resource.
+ struct ImageInfo {
+ ImageInfo(const ExtensionResource resource, gfx::Size max_size);
+ ~ImageInfo();
+ ExtensionResource resource;
+ // If the loaded image is larger than |max_size| it will be resized to those
+ // dimensions.
+ gfx::Size max_size;
+ };
+
explicit ImageLoadingTracker(Observer* observer);
virtual ~ImageLoadingTracker();
@@ -72,13 +81,35 @@ class ImageLoadingTracker : public content::NotificationObserver {
const gfx::Size& max_size,
CacheParam cache);
+ // 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 Extension* extension,
+ const std::vector<ImageInfo>& 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_; }
private:
- typedef std::map<int, const Extension*> LoadMap;
+ // Information for pending image load operation for one or more images.
+ struct PendingLoadInfo {
+ PendingLoadInfo();
+ ~PendingLoadInfo();
+
+ const Extension* extension;
+ // This is cached separate from |extension| in case the extension in
+ // unloaded.
+ std::string extension_id;
+ CacheParam cache;
+ size_t pending_count;
+ std::vector<SkBitmap> bitmaps;
+ };
+
+ // Maps an integer identifying a load request to a PendingLoadInfo.
+ typedef std::map<int, PendingLoadInfo> LoadMap;
class ImageLoader;
@@ -89,7 +120,7 @@ class ImageLoadingTracker : public content::NotificationObserver {
// of the image before any resizing was done.
// |image| may be null if the file failed to decode.
void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
- const gfx::Size& original_size, int id);
+ const gfx::Size& original_size, int id, bool should_cache);
// content::NotificationObserver method. If an extension is uninstalled while
// we're waiting for the image we remove the entry from load_map_.
@@ -106,9 +137,8 @@ class ImageLoadingTracker : public content::NotificationObserver {
// The object responsible for loading the image on the File thread.
scoped_refptr<ImageLoader> loader_;
- // If LoadImage is told to cache the result an entry is added here. The
- // integer identifies the id assigned to the request. If the extension is
- // deleted while fetching the image the entry is removed from the map.
+ // Information for each LoadImage request is cached here. The integer
+ // identifies the id assigned to the request.
LoadMap load_map_;
content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/extensions/image_loading_tracker_unittest.cc b/chrome/browser/extensions/image_loading_tracker_unittest.cc
index 3f4983e..67be34f 100644
--- a/chrome/browser/extensions/image_loading_tracker_unittest.cc
+++ b/chrome/browser/extensions/image_loading_tracker_unittest.cc
@@ -15,6 +15,7 @@
#include "content/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
using content::BrowserThread;
@@ -30,15 +31,13 @@ class ImageLoadingTrackerTest : public testing::Test,
io_thread_(BrowserThread::IO) {
}
- virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
- int index) {
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE {
image_loaded_count_++;
if (quit_in_image_loaded_)
MessageLoop::current()->Quit();
- if (image)
- image_ = *image;
- else
- image_.reset();
+ image_ = image;
}
void WaitForImageLoad() {
@@ -80,7 +79,7 @@ class ImageLoadingTrackerTest : public testing::Test,
Extension::STRICT_ERROR_CHECKS, &error);
}
- SkBitmap image_;
+ gfx::Image image_;
private:
virtual void SetUp() {
@@ -106,7 +105,7 @@ TEST_F(ImageLoadingTrackerTest, Cache) {
ExtensionIconSet::MATCH_EXACTLY);
gfx::Size max_size(ExtensionIconSet::EXTENSION_ICON_SMALLISH,
ExtensionIconSet::EXTENSION_ICON_SMALLISH);
- ImageLoadingTracker loader(static_cast<ImageLoadingTracker::Observer*>(this));
+ ImageLoadingTracker loader(this);
loader.LoadImage(extension.get(),
image_resource,
max_size,
@@ -121,7 +120,8 @@ TEST_F(ImageLoadingTrackerTest, Cache) {
EXPECT_EQ(1, image_loaded_count());
// Check that the image was loaded.
- EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, image_.width());
+ EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH,
+ image_.ToSkBitmap()->width());
// The image should be cached in the Extension.
EXPECT_TRUE(extension->HasCachedImage(image_resource, max_size));
@@ -139,7 +139,8 @@ TEST_F(ImageLoadingTrackerTest, Cache) {
EXPECT_EQ(1, image_loaded_count());
// Check that the image was loaded.
- EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, image_.width());
+ EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH,
+ image_.ToSkBitmap()->width());
}
// Tests deleting an extension while waiting for the image to load doesn't cause
@@ -151,7 +152,7 @@ TEST_F(ImageLoadingTrackerTest, DeleteExtensionWhileWaitingForCache) {
ExtensionResource image_resource =
extension->GetIconResource(ExtensionIconSet::EXTENSION_ICON_SMALLISH,
ExtensionIconSet::MATCH_EXACTLY);
- ImageLoadingTracker loader(static_cast<ImageLoadingTracker::Observer*>(this));
+ ImageLoadingTracker loader(this);
loader.LoadImage(extension.get(),
image_resource,
gfx::Size(ExtensionIconSet::EXTENSION_ICON_SMALLISH,
@@ -180,5 +181,43 @@ TEST_F(ImageLoadingTrackerTest, DeleteExtensionWhileWaitingForCache) {
EXPECT_EQ(1, image_loaded_count());
// Check that the image was loaded.
- EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, image_.width());
+ EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH,
+ image_.ToSkBitmap()->width());
+}
+
+// Tests loading multiple dimensions of the same image.
+TEST_F(ImageLoadingTrackerTest, MultipleImages) {
+ scoped_refptr<Extension> extension(CreateExtension());
+ ASSERT_TRUE(extension.get() != NULL);
+
+ std::vector<ImageLoadingTracker::ImageInfo> info_list;
+ int sizes[] = {ExtensionIconSet::EXTENSION_ICON_SMALLISH,
+ ExtensionIconSet::EXTENSION_ICON_BITTY};
+ for (size_t i = 0; i < arraysize(sizes); ++i) {
+ ExtensionResource resource =
+ extension->GetIconResource(sizes[i], ExtensionIconSet::MATCH_EXACTLY);
+ info_list.push_back(ImageLoadingTracker::ImageInfo(
+ resource, gfx::Size(sizes[i], sizes[i])));
+ }
+
+ ImageLoadingTracker loader(this);
+ loader.LoadImages(extension.get(), info_list, ImageLoadingTracker::CACHE);
+
+ // The image isn't cached, so we should not have received notification.
+ EXPECT_EQ(0, image_loaded_count());
+
+ WaitForImageLoad();
+
+ // We should have gotten the image.
+ EXPECT_EQ(1, image_loaded_count());
+
+ // Check that all images were loaded.
+ ASSERT_EQ(2u, image_.GetNumberOfSkBitmaps());
+ const SkBitmap* bmp1 = image_.GetSkBitmapAtIndex(0);
+ const SkBitmap* bmp2 = image_.GetSkBitmapAtIndex(1);
+ if (bmp1->width() > bmp2->width()) {
+ std::swap(bmp1, bmp2);
+ }
+ EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_BITTY, bmp1->width());
+ EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, bmp2->width());
}
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h
index 21ee71f..8083b6a 100644
--- a/chrome/browser/shell_integration.h
+++ b/chrome/browser/shell_integration.h
@@ -14,6 +14,7 @@
#include "base/string16.h"
#include "googleurl/src/gurl.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/image/image.h"
class CommandLine;
@@ -77,7 +78,7 @@ class ShellIntegration {
string16 title;
string16 description;
FilePath extension_path;
- SkBitmap favicon;
+ gfx::Image favicon;
// Shortcuts to platform apps are created differently. They start up with
// their own user data directory and load the app from |extension_path|.
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc
index 574bd09..d351c35 100644
--- a/chrome/browser/shell_integration_linux.cc
+++ b/chrome/browser/shell_integration_linux.cc
@@ -73,7 +73,7 @@ bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) {
std::string CreateShortcutIcon(
const ShellIntegration::ShortcutInfo& shortcut_info,
const FilePath& shortcut_filename) {
- if (shortcut_info.favicon.isNull())
+ if (shortcut_info.favicon.IsEmpty())
return std::string();
// TODO(phajdan.jr): Report errors from this function, possibly as infobars.
@@ -85,7 +85,8 @@ std::string CreateShortcutIcon(
shortcut_filename.ReplaceExtension("png"));
std::vector<unsigned char> png_data;
- gfx::PNGCodec::EncodeBGRASkBitmap(shortcut_info.favicon, false, &png_data);
+ const SkBitmap* bitmap = shortcut_info.favicon.ToSkBitmap();
+ gfx::PNGCodec::EncodeBGRASkBitmap(*bitmap, false, &png_data);
int bytes_written = file_util::WriteFile(temp_file_path,
reinterpret_cast<char*>(png_data.data()), png_data.size());
@@ -102,7 +103,7 @@ std::string CreateShortcutIcon(
argv.push_back("user");
argv.push_back("--size");
- argv.push_back(base::IntToString(shortcut_info.favicon.width()));
+ argv.push_back(base::IntToString(bitmap->width()));
argv.push_back(temp_file_path.value());
std::string icon_name = temp_file_path.BaseName().RemoveExtension().value();
diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_button.mm b/chrome/browser/ui/cocoa/extensions/browser_action_button.mm
index 836262e..f90ae1d 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_action_button.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_action_button.mm
@@ -22,6 +22,7 @@
#include "skia/ext/skia_utils_mac.h"
#import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h"
#include "ui/gfx/canvas_skia_paint.h"
+#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gfx/size.h"
@@ -66,10 +67,11 @@ class ExtensionImageTrackerBridge : public content::NotificationObserver,
~ExtensionImageTrackerBridge() {}
// ImageLoadingTracker::Observer implementation.
- void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
- int index) {
- if (image)
- [owner_ setDefaultIcon:gfx::SkBitmapToNSImage(*image)];
+ void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE {
+ if (!image.IsEmpty())
+ [owner_ setDefaultIcon:image.ToNSImage()];
[owner_ updateState];
}
diff --git a/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm
index f3353ec..7718e46 100644
--- a/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm
+++ b/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm
@@ -23,6 +23,7 @@
#include "skia/ext/skia_utils_mac.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/image/image.h"
namespace {
const CGFloat kAnimationDuration = 0.12;
@@ -72,32 +73,29 @@ class InfobarBridge : public ExtensionInfoBarDelegate::DelegateObserver,
ExtensionResource icon_resource =
extension->GetIconResource(ExtensionIconSet::EXTENSION_ICON_BITTY,
ExtensionIconSet::MATCH_EXACTLY);
- if (!icon_resource.relative_path().empty()) {
- tracker_.LoadImage(extension, icon_resource,
- gfx::Size(ExtensionIconSet::EXTENSION_ICON_BITTY,
- ExtensionIconSet::EXTENSION_ICON_BITTY),
- ImageLoadingTracker::DONT_CACHE);
- } else {
- OnImageLoaded(NULL, icon_resource, 0);
- }
+ tracker_.LoadImage(extension, icon_resource,
+ gfx::Size(ExtensionIconSet::EXTENSION_ICON_BITTY,
+ ExtensionIconSet::EXTENSION_ICON_BITTY),
+ ImageLoadingTracker::DONT_CACHE);
}
// ImageLoadingTracker::Observer implementation.
// TODO(andybons): The infobar view implementations share a lot of the same
// code. Come up with a strategy to share amongst them.
- virtual void OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE {
if (!delegate_)
return; // The delegate can go away while the image asynchronously loads.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
// Fall back on the default extension icon on failure.
- SkBitmap* icon;
- if (!image || image->empty())
+ const SkBitmap* icon;
+ if (image.IsEmpty())
icon = rb.GetBitmapNamed(IDR_EXTENSIONS_SECTION);
else
- icon = image;
+ icon = image.ToSkBitmap();
SkBitmap* drop_image = rb.GetBitmapNamed(IDR_APP_DROPARROW);
diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h
index 52b019f..0894c5a 100644
--- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h
+++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.h
@@ -37,8 +37,9 @@ class PageActionDecoration : public ImageDecoration,
bool preview_enabled() const { return preview_enabled_; }
// Overridden from |ImageLoadingTracker::Observer|.
- virtual void OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) OVERRIDE;
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE;
// Called to notify the Page Action that it should determine whether
// to be visible or hidden. |contents| is the WebContents that is
diff --git a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
index 39467d9..29a1bcf 100644
--- a/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/page_action_decoration.mm
@@ -114,8 +114,9 @@ bool PageActionDecoration::OnMousePressed(NSRect frame) {
return true;
}
-void PageActionDecoration::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
+void PageActionDecoration::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
// We loaded icons()->size() icons, plus one extra if the Page Action had
// a default icon.
int total_icons = static_cast<int>(page_action_->icon_paths()->size());
@@ -125,11 +126,12 @@ void PageActionDecoration::OnImageLoaded(
// Map the index of the loaded image back to its name. If we ever get an
// index greater than the number of icons, it must be the default icon.
- if (image) {
+ if (!image.IsEmpty()) {
+ const SkBitmap* bitmap = image.ToSkBitmap();
if (index < static_cast<int>(page_action_->icon_paths()->size()))
- page_action_icons_[page_action_->icon_paths()->at(index)] = *image;
+ page_action_icons_[page_action_->icon_paths()->at(index)] = *bitmap;
else
- page_action_icons_[page_action_->default_icon_path()] = *image;
+ page_action_icons_[page_action_->default_icon_path()] = *bitmap;
}
// If we have no owner, that means this class is still being constructed and
diff --git a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
index 31548aa..3c8f616 100644
--- a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc
@@ -39,6 +39,7 @@
#include "ui/base/gtk/gtk_compat.h"
#include "ui/gfx/canvas_skia_paint.h"
#include "ui/gfx/gtk_util.h"
+#include "ui/gfx/image/image.h"
namespace {
@@ -160,11 +161,13 @@ class BrowserActionButton : public content::NotificationObserver,
}
// ImageLoadingTracker::Observer implementation.
- void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
- int index) {
- if (image) {
- default_skbitmap_ = *image;
- default_icon_ = gfx::GdkPixbufFromSkBitmap(image);
+ void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE {
+ if (!image.IsEmpty()) {
+ default_skbitmap_ = *image.ToSkBitmap();
+ default_icon_ =
+ static_cast<GdkPixbuf*>(g_object_ref(image.ToGdkPixbuf()));
}
UpdateState();
}
diff --git a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc
index 92c8bfa..cac3d5a 100644
--- a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc
+++ b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc
@@ -25,6 +25,7 @@
#include "grit/theme_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/gtk_util.h"
using content::BrowserThread;
@@ -66,10 +67,11 @@ CreateApplicationShortcutsDialogGtk::CreateApplicationShortcutsDialogGtk(
}
void CreateApplicationShortcutsDialogGtk::CreateIconPixBuf(
- const SkBitmap& bitmap) {
+ const gfx::Image& image) {
// Prepare the icon. Try to scale it if it's too small, otherwise it would
// look weird.
- GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&shortcut_info_.favicon);
+ GdkPixbuf* pixbuf =
+ static_cast<GdkPixbuf*>(g_object_ref(image.ToGdkPixbuf()));
int pixbuf_width = gdk_pixbuf_get_width(pixbuf);
int pixbuf_height = gdk_pixbuf_get_height(pixbuf);
if (pixbuf_width == pixbuf_height && pixbuf_width < kIconPreviewSizePixels) {
@@ -332,12 +334,16 @@ CreateChromeApplicationShortcutsDialogGtk::
// Called by tracker_ when the app's icon is loaded.
void CreateChromeApplicationShortcutsDialogGtk::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
- if (!image || image->isNull())
- image = ExtensionIconSource::LoadImageByResourceId(IDR_APP_DEFAULT_ICON);
-
- shortcut_info_.favicon = *image;
+ const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
+ if (image.IsEmpty()) {
+ shortcut_info_.favicon =
+ ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON);
+ } else {
+ shortcut_info_.favicon = image;
+ }
- CreateIconPixBuf(*image);
+ CreateIconPixBuf(shortcut_info_.favicon);
CreateDialogBox(parent_);
}
diff --git a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h
index 200f661..2bfeb27 100644
--- a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h
+++ b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h
@@ -43,7 +43,7 @@ class CreateApplicationShortcutsDialogGtk
OnToggleCheckbox);
virtual void CreateDialogBox(GtkWindow* parent);
- virtual void CreateIconPixBuf(const SkBitmap& bitmap);
+ virtual void CreateIconPixBuf(const gfx::Image& image);
// This method is called after a shortcut is created.
// Subclasses can override it to take some action at that time.
@@ -111,8 +111,8 @@ class CreateChromeApplicationShortcutsDialogGtk
// Implement ImageLoadingTracker::Observer. |tracker_| is used to
// load the app's icon. This method recieves the icon, and adds
// it to the "Create Shortcut" dailog box.
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
private:
diff --git a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
index 4251b18..3706ea19 100644
--- a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
@@ -63,17 +63,20 @@ void ExtensionInfoBarGtk::GetBottomColor(InfoBarDelegate::Type type,
*r = *g = *b = 218.0 / 255.0;
}
-void ExtensionInfoBarGtk::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
+void ExtensionInfoBarGtk::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
if (!delegate_)
return; // The delegate can go away while we asynchronously load images.
// TODO(erg): IDR_EXTENSIONS_SECTION should have an IDR_INFOBAR_EXTENSIONS
// icon of the correct size with real subpixel shading and such.
- SkBitmap* icon = image;
+ const SkBitmap* icon = NULL;
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- if (!image || image->empty())
+ if (image.IsEmpty())
icon = rb.GetBitmapNamed(IDR_EXTENSIONS_SECTION);
+ else
+ icon = image.ToSkBitmap();
SkBitmap* drop_image = rb.GetBitmapNamed(IDR_APP_DROPARROW);
@@ -110,15 +113,11 @@ void ExtensionInfoBarGtk::BuildWidgets() {
const Extension* extension = delegate_->extension_host()->extension();
ExtensionResource icon_resource = extension->GetIconResource(
ExtensionIconSet::EXTENSION_ICON_BITTY, ExtensionIconSet::MATCH_EXACTLY);
- if (!icon_resource.relative_path().empty()) {
- // Create a tracker to load the image. It will report back on OnImageLoaded.
- tracker_.LoadImage(extension, icon_resource,
- gfx::Size(ExtensionIconSet::EXTENSION_ICON_BITTY,
- ExtensionIconSet::EXTENSION_ICON_BITTY),
- ImageLoadingTracker::DONT_CACHE);
- } else {
- OnImageLoaded(NULL, icon_resource, 0);
- }
+ // Create a tracker to load the image. It will report back on OnImageLoaded.
+ tracker_.LoadImage(extension, icon_resource,
+ gfx::Size(ExtensionIconSet::EXTENSION_ICON_BITTY,
+ ExtensionIconSet::EXTENSION_ICON_BITTY),
+ ImageLoadingTracker::DONT_CACHE);
// Pad the bottom of the infobar by one pixel for the border.
alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
diff --git a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h
index fd8e7bc..8dc2c9a 100644
--- a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h
+++ b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h
@@ -36,8 +36,9 @@ class ExtensionInfoBarGtk : public InfoBarGtk,
double* r, double* g, double* b) OVERRIDE;
// Overridden from ImageLoadingTracker::Observer:
- virtual void OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) OVERRIDE;
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE;
// Overridden from MenuGtk::Delegate:
virtual void StoppedShowing() OVERRIDE;
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
index 9f95955..9e8712d 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
@@ -1556,7 +1556,9 @@ void LocationBarViewGtk::PageActionViewGtk::UpdateVisibility(
}
void LocationBarViewGtk::PageActionViewGtk::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
+ const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
// We loaded icons()->size() icons, plus one extra if the page action had
// a default icon.
int total_icons = static_cast<int>(page_action_->icon_paths()->size());
@@ -1566,8 +1568,9 @@ void LocationBarViewGtk::PageActionViewGtk::OnImageLoaded(
// Map the index of the loaded image back to its name. If we ever get an
// index greater than the number of icons, it must be the default icon.
- if (image) {
- GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(image);
+ if (!image.IsEmpty()) {
+ GdkPixbuf* pixbuf =
+ static_cast<GdkPixbuf*>(g_object_ref(image.ToGdkPixbuf()));
if (index < static_cast<int>(page_action_->icon_paths()->size()))
pixbufs_[page_action_->icon_paths()->at(index)] = pixbuf;
else
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.h b/chrome/browser/ui/gtk/location_bar_view_gtk.h
index eae6264..3abccb2 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.h
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.h
@@ -228,8 +228,9 @@ class LocationBarViewGtk : public AutocompleteEditController,
void UpdateVisibility(content::WebContents* contents, const GURL& url);
// A callback from ImageLoadingTracker for when the image has loaded.
- virtual void OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) OVERRIDE;
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) OVERRIDE;
// Simulate left mouse click on the page action button.
void TestActivatePageAction();
diff --git a/chrome/browser/ui/views/ash/app_list/extension_app_item.cc b/chrome/browser/ui/views/ash/app_list/extension_app_item.cc
index f796e80..2e815e1 100644
--- a/chrome/browser/ui/views/ash/app_list/extension_app_item.cc
+++ b/chrome/browser/ui/views/ash/app_list/extension_app_item.cc
@@ -137,11 +137,11 @@ void ExtensionAppItem::LoadDefaultImage() {
SetIcon(*rb.GetImageNamed(resource).ToSkBitmap());
}
-void ExtensionAppItem::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void ExtensionAppItem::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int tracker_index) {
- if (image && !image->empty())
- SetIcon(*image);
+ if (!image.IsEmpty())
+ SetIcon(*image.ToSkBitmap());
else
LoadDefaultImage();
}
diff --git a/chrome/browser/ui/views/ash/app_list/extension_app_item.h b/chrome/browser/ui/views/ash/app_list/extension_app_item.h
index a1a56d6..c8aca90 100644
--- a/chrome/browser/ui/views/ash/app_list/extension_app_item.h
+++ b/chrome/browser/ui/views/ash/app_list/extension_app_item.h
@@ -43,8 +43,8 @@ class ExtensionAppItem : public ChromeAppListItem,
void LoadDefaultImage();
// Overridden from ImageLoadingTracker::Observer
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int tracker_index) OVERRIDE;
// Overridden from ChromeAppListItem:
diff --git a/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.cc b/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.cc
index 920bde6..a528729 100644
--- a/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.cc
+++ b/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.cc
@@ -351,7 +351,7 @@ std::string ChromeLauncherDelegate::GetAppID(TabContentsWrapper* tab) {
}
void ChromeLauncherDelegate::SetAppImage(const std::string& id,
- SkBitmap* image) {
+ const SkBitmap* image) {
for (IDToItemMap::const_iterator i = id_to_item_map_.begin();
i != id_to_item_map_.end(); ++i) {
if (i->second.app_id == id) {
diff --git a/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h b/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h
index aa9f360..160cb16 100644
--- a/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h
+++ b/chrome/browser/ui/views/ash/launcher/chrome_launcher_delegate.h
@@ -135,7 +135,7 @@ class ChromeLauncherDelegate : public ash::LauncherDelegate,
// Sets the image for an app tab. This is intended to be invoked from the
// AppIconLoader.
- void SetAppImage(const std::string& app_id, SkBitmap* image);
+ void SetAppImage(const std::string& app_id, const SkBitmap* image);
ash::LauncherModel* model() { return model_; }
diff --git a/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.cc b/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.cc
index 3f3963d..45fd8d6 100644
--- a/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.cc
+++ b/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.cc
@@ -51,8 +51,8 @@ void LauncherIconLoader::FetchImage(const std::string& id) {
ImageLoadingTracker::CACHE);
}
-void LauncherIconLoader::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void LauncherIconLoader::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
ImageLoaderIDToExtensionIDMap::iterator i = map_.find(index);
if (i == map_.end())
@@ -60,7 +60,10 @@ void LauncherIconLoader::OnImageLoaded(SkBitmap* image,
std::string id = i->second;
map_.erase(i);
- host_->SetAppImage(id, image);
+ if (image.IsEmpty())
+ host_->SetAppImage(id, NULL);
+ else
+ host_->SetAppImage(id, image.ToSkBitmap());
}
const Extension* LauncherIconLoader::GetExtensionForTab(
diff --git a/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.h b/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.h
index d26d53a..d4f763a 100644
--- a/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.h
+++ b/chrome/browser/ui/views/ash/launcher/launcher_icon_loader.h
@@ -30,8 +30,8 @@ class LauncherIconLoader : public ChromeLauncherDelegate::AppIconLoader,
virtual void FetchImage(const std::string& id) OVERRIDE;
// ImageLoadingTracker::Observer:
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
private:
diff --git a/chrome/browser/ui/views/browser_actions_container.cc b/chrome/browser/ui/views/browser_actions_container.cc
index ef3dd6e..b86dc14 100644
--- a/chrome/browser/ui/views/browser_actions_container.cc
+++ b/chrome/browser/ui/views/browser_actions_container.cc
@@ -136,11 +136,11 @@ void BrowserActionButton::ButtonPressed(views::Button* sender,
panel_->OnBrowserActionExecuted(this, false);
}
-void BrowserActionButton::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void BrowserActionButton::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
- if (image)
- default_icon_ = *image;
+ if (!image.IsEmpty())
+ default_icon_ = *image.ToSkBitmap();
// Call back to UpdateState() because a more specific icon might have been set
// while the load was outstanding.
diff --git a/chrome/browser/ui/views/browser_actions_container.h b/chrome/browser/ui/views/browser_actions_container.h
index cb20e3a..14a2582 100644
--- a/chrome/browser/ui/views/browser_actions_container.h
+++ b/chrome/browser/ui/views/browser_actions_container.h
@@ -84,8 +84,8 @@ class BrowserActionButton : public views::MenuButton,
const views::Event& event) OVERRIDE;
// Overridden from ImageLoadingTracker.
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
// Overridden from content::NotificationObserver:
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc
index 515d462..7caf2ea 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.cc
+++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -57,7 +57,7 @@ class AppInfoView : public views::View {
void UpdateText(const string16& title, const string16& description);
// Updates the icon of the web app.
- void UpdateIcon(const SkBitmap& new_icon);
+ void UpdateIcon(const gfx::Image& image);
// Overridden from views::View:
virtual void OnPaint(gfx::Canvas* canvas);
@@ -159,8 +159,9 @@ void AppInfoView::UpdateText(const string16& title,
SetupLayout();
}
-void AppInfoView::UpdateIcon(const SkBitmap& new_icon) {
- icon_->SetImage(new_icon);
+void AppInfoView::UpdateIcon(const gfx::Image& image) {
+ if (!image.IsEmpty())
+ icon_->SetImage(image.ToSkBitmap());
}
void AppInfoView::OnPaint(gfx::Canvas* canvas) {
@@ -469,7 +470,7 @@ void CreateUrlApplicationShortcutView::OnIconDownloaded(bool errored,
pending_download_ = NULL;
if (!errored && !image.isNull()) {
- shortcut_info_.favicon = image;
+ shortcut_info_.favicon = gfx::Image(image);
static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
} else {
FetchIcon();
@@ -524,11 +525,16 @@ CreateChromeApplicationShortcutView::~CreateChromeApplicationShortcutView() {}
// Called by tracker_ when the app's icon is loaded.
void CreateChromeApplicationShortcutView::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
- if (!image || image->isNull())
- image = ExtensionIconSource::LoadImageByResourceId(IDR_APP_DEFAULT_ICON);
+ const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
+ if (image.IsEmpty()) {
+ shortcut_info_.favicon = ui::ResourceBundle::GetSharedInstance().
+ GetImageNamed(IDR_APP_DEFAULT_ICON);
+ } else {
+ shortcut_info_.favicon = image;
+ }
- shortcut_info_.favicon = *image;
CHECK(app_info_);
static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
}
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.h b/chrome/browser/ui/views/create_application_shortcut_view.h
index 0602628..8a49f9b 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.h
+++ b/chrome/browser/ui/views/create_application_shortcut_view.h
@@ -116,8 +116,8 @@ class CreateChromeApplicationShortcutView
// Implement ImageLoadingTracker::Observer. |tracker_| is used to
// load the app's icon. This method recieves the icon, and adds
// it to the "Create Shortcut" dailog box.
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
private:
diff --git a/chrome/browser/ui/views/infobars/extension_infobar.cc b/chrome/browser/ui/views/infobars/extension_infobar.cc
index db272a9..1e47b89 100644
--- a/chrome/browser/ui/views/infobars/extension_infobar.cc
+++ b/chrome/browser/ui/views/infobars/extension_infobar.cc
@@ -16,6 +16,7 @@
#include "ui/base/animation/slide_animation.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/image/image.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/widget/widget.h"
@@ -93,29 +94,27 @@ void ExtensionInfoBar::ViewHierarchyChanged(bool is_add,
ExtensionIconSet::Icons image_size = ExtensionIconSet::EXTENSION_ICON_BITTY;
ExtensionResource icon_resource = extension->GetIconResource(
image_size, ExtensionIconSet::MATCH_EXACTLY);
- if (!icon_resource.relative_path().empty()) {
- tracker_.LoadImage(extension, icon_resource,
- gfx::Size(image_size, image_size), ImageLoadingTracker::DONT_CACHE);
- } else {
- OnImageLoaded(NULL, icon_resource, 0);
- }
+ tracker_.LoadImage(extension, icon_resource,
+ gfx::Size(image_size, image_size), ImageLoadingTracker::DONT_CACHE);
}
int ExtensionInfoBar::ContentMinimumWidth() const {
return menu_->GetPreferredSize().width() + kMenuHorizontalMargin;
}
-void ExtensionInfoBar::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void ExtensionInfoBar::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
if (!GetDelegate())
return; // The delegate can go away while we asynchronously load images.
- SkBitmap* icon = image;
+ const SkBitmap* icon = NULL;
// Fall back on the default extension icon on failure.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- if (!image || image->empty())
+ if (image.IsEmpty())
icon = rb.GetBitmapNamed(IDR_EXTENSIONS_SECTION);
+ else
+ icon = image.ToSkBitmap();
SkBitmap* drop_image = rb.GetBitmapNamed(IDR_APP_DROPARROW);
diff --git a/chrome/browser/ui/views/infobars/extension_infobar.h b/chrome/browser/ui/views/infobars/extension_infobar.h
index 07d347a..dc9b0c6 100644
--- a/chrome/browser/ui/views/infobars/extension_infobar.h
+++ b/chrome/browser/ui/views/infobars/extension_infobar.h
@@ -37,8 +37,8 @@ class ExtensionInfoBar : public InfoBarView,
virtual int ContentMinimumWidth() const OVERRIDE;
// ImageLoadingTracker::Observer:
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
// ExtensionInfoBarDelegate::DelegateObserver:
diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.cc b/chrome/browser/ui/views/location_bar/page_action_image_view.cc
index ed0f8f6..f275df8 100644
--- a/chrome/browser/ui/views/location_bar/page_action_image_view.cc
+++ b/chrome/browser/ui/views/location_bar/page_action_image_view.cc
@@ -177,8 +177,9 @@ void PageActionImageView::ShowContextMenu(const gfx::Point& p,
return;
}
-void PageActionImageView::OnImageLoaded(
- SkBitmap* image, const ExtensionResource& resource, int index) {
+void PageActionImageView::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
+ int index) {
// We loaded icons()->size() icons, plus one extra if the page action had
// a default icon.
int total_icons = static_cast<int>(page_action_->icon_paths()->size());
@@ -188,11 +189,12 @@ void PageActionImageView::OnImageLoaded(
// Map the index of the loaded image back to its name. If we ever get an
// index greater than the number of icons, it must be the default icon.
- if (image) {
+ if (!image.IsEmpty()) {
+ const SkBitmap* bitmap = image.ToSkBitmap();
if (index < static_cast<int>(page_action_->icon_paths()->size()))
- page_action_icons_[page_action_->icon_paths()->at(index)] = *image;
+ page_action_icons_[page_action_->icon_paths()->at(index)] = *bitmap;
else
- page_action_icons_[page_action_->default_icon_path()] = *image;
+ page_action_icons_[page_action_->default_icon_path()] = *bitmap;
}
// During object construction (before the parent has been set) we are already
diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.h b/chrome/browser/ui/views/location_bar/page_action_image_view.h
index 98b824b..1390189 100644
--- a/chrome/browser/ui/views/location_bar/page_action_image_view.h
+++ b/chrome/browser/ui/views/location_bar/page_action_image_view.h
@@ -53,8 +53,8 @@ class PageActionImageView : public views::ImageView,
bool is_mouse_gesture) OVERRIDE;
// Overridden from ImageLoadingTracker.
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE;
// Overridden from ExtensionContextMenuModelModel::Delegate
diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc
index 1d3103a..c408987 100644
--- a/chrome/browser/ui/web_applications/web_app_ui.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui.cc
@@ -162,7 +162,7 @@ void UpdateShortcutWorker::OnIconDownloaded(int download_id,
if (!errored && !image.isNull()) {
// Update icon with download image and update shortcut.
- shortcut_info_.favicon = image;
+ shortcut_info_.favicon = gfx::Image(image);
tab_contents_->extension_tab_helper()->SetAppIcon(image);
UpdateShortcuts();
} else {
@@ -309,7 +309,8 @@ void GetShortcutInfoForTab(TabContentsWrapper* tab_contents_wrapper,
web_contents->GetTitle()) :
app_info.title;
info->description = app_info.description;
- info->favicon = tab_contents_wrapper->favicon_tab_helper()->GetFavicon();
+ info->favicon =
+ gfx::Image(tab_contents_wrapper->favicon_tab_helper()->GetFavicon());
}
void UpdateShortcutForTabContents(TabContentsWrapper* tab_contents) {
diff --git a/chrome/browser/ui/webui/extensions/extension_icon_source.cc b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
index 0aa3066..ca34c99 100644
--- a/chrome/browser/ui/webui/extensions/extension_icon_source.cc
+++ b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
@@ -37,9 +37,9 @@ scoped_refptr<RefCountedMemory> BitmapToMemory(const SkBitmap* image) {
return image_bytes;
}
-void DesaturateImage(SkBitmap* image) {
+SkBitmap DesaturateImage(const SkBitmap* image) {
color_utils::HSL shift = {-1, 0, 0.6};
- *image = SkBitmapOperations::CreateHSLShiftedBitmap(*image, shift);
+ return SkBitmapOperations::CreateHSLShiftedBitmap(*image, shift);
}
SkBitmap* ToBitmap(const unsigned char* data, size_t size) {
@@ -168,13 +168,16 @@ const SkBitmap* ExtensionIconSource::GetDefaultExtensionImage() {
return default_extension_data_.get();
}
-void ExtensionIconSource::FinalizeImage(SkBitmap* image,
+void ExtensionIconSource::FinalizeImage(const SkBitmap* image,
int request_id) {
+ SkBitmap bitmap;
if (GetData(request_id)->grayscale)
- DesaturateImage(image);
+ bitmap = DesaturateImage(image);
+ else
+ bitmap = *image;
ClearData(request_id);
- SendResponse(request_id, BitmapToMemory(image));
+ SendResponse(request_id, BitmapToMemory(&bitmap));
}
void ExtensionIconSource::LoadDefaultImage(int request_id) {
@@ -274,16 +277,16 @@ void ExtensionIconSource::OnFaviconDataAvailable(
}
}
-void ExtensionIconSource::OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+void ExtensionIconSource::OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) {
int request_id = tracker_map_[index];
tracker_map_.erase(tracker_map_.find(index));
- if (!image || image->empty())
+ if (image.IsEmpty())
LoadIconFailed(request_id);
else
- FinalizeImage(image, request_id);
+ FinalizeImage(image.ToSkBitmap(), request_id);
}
bool ExtensionIconSource::ParseData(const std::string& path,
diff --git a/chrome/browser/ui/webui/extensions/extension_icon_source.h b/chrome/browser/ui/webui/extensions/extension_icon_source.h
index d790748c..4ea40fe 100644
--- a/chrome/browser/ui/webui/extensions/extension_icon_source.h
+++ b/chrome/browser/ui/webui/extensions/extension_icon_source.h
@@ -90,7 +90,7 @@ class ExtensionIconSource : public ChromeURLDataManager::DataSource,
// Performs any remaining transformations (like desaturating the |image|),
// then returns the |image| to the client and clears up any temporary data
// associated with the |request_id|.
- void FinalizeImage(SkBitmap* image, int request_id);
+ void FinalizeImage(const SkBitmap* image, int request_id);
// Loads the default image for |request_id| and returns to the client.
void LoadDefaultImage(int request_id);
@@ -114,8 +114,8 @@ class ExtensionIconSource : public ChromeURLDataManager::DataSource,
history::FaviconData favicon);
// ImageLoadingTracker::Observer
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int id) OVERRIDE;
// Called when the extension doesn't have an icon. We fall back to multiple
diff --git a/chrome/browser/ui/webui/ntp/favicon_webui_handler.cc b/chrome/browser/ui/webui/ntp/favicon_webui_handler.cc
index d4e9d5f..c10c14a 100644
--- a/chrome/browser/ui/webui/ntp/favicon_webui_handler.cc
+++ b/chrome/browser/ui/webui/ntp/favicon_webui_handler.cc
@@ -50,11 +50,11 @@ class ExtensionIconColorManager : public ExtensionIconManager {
handler_(handler) {}
virtual ~ExtensionIconColorManager() {}
- virtual void OnImageLoaded(SkBitmap* image,
- const ExtensionResource& resource,
+ virtual void OnImageLoaded(const gfx::Image& image,
+ const std::string& extension_id,
int index) OVERRIDE {
- ExtensionIconManager::OnImageLoaded(image, resource, index);
- handler_->NotifyAppIconReady(resource.extension_id());
+ ExtensionIconManager::OnImageLoaded(image, extension_id, index);
+ handler_->NotifyAppIconReady(extension_id);
}
private:
diff --git a/chrome/browser/web_applications/web_app_mac.mm b/chrome/browser/web_applications/web_app_mac.mm
index 004f8d4..9cc1931 100644
--- a/chrome/browser/web_applications/web_app_mac.mm
+++ b/chrome/browser/web_applications/web_app_mac.mm
@@ -35,6 +35,48 @@ NSBitmapImageRep* SkBitmapToImageRep(const SkBitmap& bitmap) {
[[image representations] lastObject]);
}
+// Adds |image_rep| to |icon_family|. Returns true on success, false on failure.
+bool AddBitmapImageRepToIconFamily(IconFamily* icon_family,
+ NSBitmapImageRep* image_rep) {
+ NSSize size = [image_rep size];
+ if (size.width != size.height)
+ return false;
+
+ switch (static_cast<int>(size.width)) {
+ case 512:
+ return [icon_family setIconFamilyElement:kIconServices512PixelDataARGB
+ fromBitmapImageRep:image_rep];
+ case 256:
+ return [icon_family setIconFamilyElement:kIconServices256PixelDataARGB
+ fromBitmapImageRep:image_rep];
+ case 128:
+ return [icon_family setIconFamilyElement:kThumbnail32BitData
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kThumbnail8BitMask
+ fromBitmapImageRep:image_rep];
+ case 32:
+ return [icon_family setIconFamilyElement:kLarge32BitData
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kLarge8BitData
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kLarge8BitMask
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kLarge1BitMask
+ fromBitmapImageRep:image_rep];
+ case 16:
+ return [icon_family setIconFamilyElement:kSmall32BitData
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kSmall8BitData
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kSmall8BitMask
+ fromBitmapImageRep:image_rep] &&
+ [icon_family setIconFamilyElement:kSmall1BitMask
+ fromBitmapImageRep:image_rep];
+ default:
+ return false;
+ }
+}
+
} // namespace
@@ -150,26 +192,26 @@ bool WebAppShortcutCreator::UpdatePlist(const FilePath& app_path) const {
}
bool WebAppShortcutCreator::UpdateIcon(const FilePath& app_path) const {
- // TODO(sail): Add support for multiple icon sizes.
- if (info_.favicon.empty() || info_.favicon.width() != 32 ||
- info_.favicon.height() != 32) {
+ if (info_.favicon.IsEmpty())
return true;
- }
-
- NSBitmapImageRep* image_rep = SkBitmapToImageRep(info_.favicon);
- if (!image_rep)
- return false;
scoped_nsobject<IconFamily> icon_family([[IconFamily alloc] init]);
- bool success = [icon_family setIconFamilyElement:kLarge32BitData
- fromBitmapImageRep:image_rep] &&
- [icon_family setIconFamilyElement:kLarge8BitData
- fromBitmapImageRep:image_rep] &&
- [icon_family setIconFamilyElement:kLarge8BitMask
- fromBitmapImageRep:image_rep] &&
- [icon_family setIconFamilyElement:kLarge1BitMask
- fromBitmapImageRep:image_rep];
- if (!success)
+ bool image_added = false;
+ for (size_t i = 0; i < info_.favicon.GetNumberOfSkBitmaps(); ++i) {
+ NSBitmapImageRep* image_rep =
+ SkBitmapToImageRep(*info_.favicon.GetSkBitmapAtIndex(i));
+ if (!image_rep)
+ continue;
+
+ // Missing an icon size is not fatal so don't fail if adding the bitmap
+ // doesn't work.
+ if (!AddBitmapImageRepToIconFamily(icon_family, image_rep))
+ continue;
+
+ image_added = true;
+ }
+
+ if (!image_added)
return false;
FilePath resources_path = app_path.Append("Contents").Append("Resources");
diff --git a/chrome/browser/web_applications/web_app_mac_unittest.mm b/chrome/browser/web_applications/web_app_mac_unittest.mm
index a2b78dc..f98757a 100644
--- a/chrome/browser/web_applications/web_app_mac_unittest.mm
+++ b/chrome/browser/web_applications/web_app_mac_unittest.mm
@@ -103,8 +103,8 @@ TEST(WebAppShortcutCreatorTest, UpdateIcon) {
FilePath dst_path = scoped_temp_dir.path();
ShellIntegration::ShortcutInfo info = GetShortcutInfo();
- info.favicon = *ui::ResourceBundle::GetSharedInstance().GetImageNamed(
- IDR_PRODUCT_LOGO_32).ToSkBitmap();
+ info.favicon = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+ IDR_PRODUCT_LOGO_32);
WebAppShortcutCreatorMock shortcut_creator(info);
shortcut_creator.UpdateIcon(dst_path);
@@ -114,8 +114,8 @@ TEST(WebAppShortcutCreatorTest, UpdateIcon) {
scoped_nsobject<NSImage> image([[NSImage alloc] initWithContentsOfFile:
base::mac::FilePathToNSString(icon_path)]);
EXPECT_TRUE(image);
- EXPECT_EQ(info.favicon.width(), [image size].width);
- EXPECT_EQ(info.favicon.height(), [image size].height);
+ EXPECT_EQ(info.favicon.ToSkBitmap()->width(), [image size].width);
+ EXPECT_EQ(info.favicon.ToSkBitmap()->height(), [image size].height);
}
} // namespace web_app