Index: chrome/browser/extensions/api/notifications/notifications_api.cc |
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc |
index 2e6d46f6a35c6c78d411888a2b758d96f582e3d8..0fa6ec482abf62b65613447eeb340862e0674e55 100644 |
--- a/chrome/browser/extensions/api/notifications/notifications_api.cc |
+++ b/chrome/browser/extensions/api/notifications/notifications_api.cc |
@@ -53,34 +53,42 @@ const char kExtraListItemsProvided[] = |
const char kExtraImageProvided[] = |
"Image resource provided for notification type != image"; |
-// Converts an object with width, height, and data in RGBA format into an |
-// gfx::Image (in ARGB format). |
-bool NotificationBitmapToGfxImage( |
- float max_scale, |
- const gfx::Size& target_size_dips, |
- api::notifications::NotificationBitmap* notification_bitmap, |
- gfx::Image* return_image) { |
- if (!notification_bitmap) |
+typedef std::vector<linked_ptr<notifications::ImageRepresentation> > |
+ ImageRepresentationList; |
+ |
+bool ImageRepresentationToImageSkiaRep(float max_scale, |
+ const gfx::Size& target_size_dips, |
+ notifications::BitmapData* bitmap_data, |
+ float configured_scale, |
+ gfx::ImageSkiaRep* return_rep) { |
+ if (!bitmap_data || !return_rep) { |
+ LOG(WARNING) << "Bitmap data: " << bitmap_data; |
+ LOG(WARNING) << "return_rep: " << return_rep; |
+ |
return false; |
+ } |
const int max_device_pixel_width = target_size_dips.width() * max_scale; |
const int max_device_pixel_height = target_size_dips.height() * max_scale; |
const int BYTES_PER_PIXEL = 4; |
- const int width = notification_bitmap->width; |
- const int height = notification_bitmap->height; |
+ const int width = bitmap_data->width; |
+ const int height = bitmap_data->height; |
- if (width < 0 || height < 0 || width > max_device_pixel_width || |
- height > max_device_pixel_height) |
+ if (configured_scale < 1.0f || width < 0 || height < 0 || |
+ width > max_device_pixel_width || height > max_device_pixel_height) { |
+ LOG(WARNING) << "Configured scale: " << configured_scale; |
+ LOG(WARNING) << "width: " << width; |
+ LOG(WARNING) << "height: " << height; |
return false; |
+ } |
// Ensure we have rgba data. |
- std::string* rgba_data = notification_bitmap->data.get(); |
- if (!rgba_data) |
+ if (!bitmap_data->data.length()) |
return false; |
- const size_t rgba_data_length = rgba_data->length(); |
+ const size_t rgba_data_length = bitmap_data->data.length(); |
const size_t rgba_area = width * height; |
if (rgba_data_length != rgba_area * BYTES_PER_PIXEL) |
@@ -99,7 +107,7 @@ bool NotificationBitmapToGfxImage( |
return false; |
uint32_t* pixels = bitmap.getAddr32(0, 0); |
- const char* c_rgba_data = rgba_data->data(); |
+ const char* c_rgba_data = bitmap_data->data.data(); |
for (size_t t = 0; t < rgba_area; ++t) { |
// |c_rgba_data| is RGBA, pixels is ARGB. |
@@ -113,8 +121,37 @@ bool NotificationBitmapToGfxImage( |
// TODO(dewittj): Handle HiDPI images with more than one scale factor |
// representation. |
- gfx::ImageSkia skia(gfx::ImageSkiaRep(bitmap, 1.0f)); |
- *return_image = gfx::Image(skia); |
+ *return_rep = gfx::ImageSkiaRep(bitmap, configured_scale); |
+ return true; |
+} |
+ |
+// Converts an object with width, height, and data in RGBA format into an |
+// gfx::Image (in ARGB format). |
+bool ImageRepresentationListToGfxImage(float max_scale, |
+ const gfx::Size& target_size_dips, |
+ ImageRepresentationList* bitmap_list, |
+ gfx::Image* return_image) { |
+ if (!bitmap_list || bitmap_list->size() == 0) |
+ return false; |
+ |
+ gfx::ImageSkia out; |
+ ImageRepresentationList::iterator iter = bitmap_list->begin(); |
+ while (iter != bitmap_list->end()) { |
+ notifications::ImageRepresentation* rep = (*iter).get(); |
+ if (rep->scale > max_scale) |
+ return false; |
+ |
+ notifications::BitmapData* bitmap = rep->data.as_bitmap_data.get(); |
+ gfx::ImageSkiaRep skia_rep; |
+ if (!ImageRepresentationToImageSkiaRep( |
+ max_scale, target_size_dips, bitmap, rep->scale, &skia_rep)) |
+ return false; |
+ |
+ out.AddRepresentation(skia_rep); |
+ |
+ ++iter; |
+ } |
+ *return_image = gfx::Image(out); |
return true; |
} |
@@ -260,8 +297,12 @@ bool NotificationsApiFunction::CreateNotification( |
// These fields are defined as optional in IDL such that they can be used as |
// optional for notification updates. But for notification creations, they |
// should be present. |
+ if (options->icons == NULL || options->icons->size() < 1) { |
+ SetError(kMissingRequiredPropertiesForCreateNotification); |
+ return false; |
+ } |
if (options->type == api::notifications::TEMPLATE_TYPE_NONE || |
- !options->icon_url || !options->title || !options->message) { |
+ !options->title || !options->message) { |
SetError(kMissingRequiredPropertiesForCreateNotification); |
return false; |
} |
@@ -278,10 +319,8 @@ bool NotificationsApiFunction::CreateNotification( |
const base::string16 message(base::UTF8ToUTF16(*options->message)); |
gfx::Image icon; |
- if (!NotificationBitmapToGfxImage(image_scale, |
- bitmap_sizes.icon_size, |
- options->icon_bitmap.get(), |
- &icon)) { |
+ if (!ImageRepresentationListToGfxImage( |
+ image_scale, bitmap_sizes.icon_size, options->icons.get(), &icon)) { |
SetError(kUnableToDecodeIconError); |
return false; |
} |
@@ -302,10 +341,10 @@ bool NotificationsApiFunction::CreateNotification( |
for (size_t i = 0; i < number_of_buttons; i++) { |
message_center::ButtonInfo info( |
base::UTF8ToUTF16((*options->buttons)[i]->title)); |
- NotificationBitmapToGfxImage(image_scale, |
- bitmap_sizes.button_icon_size, |
- (*options->buttons)[i]->icon_bitmap.get(), |
- &info.icon); |
+ ImageRepresentationListToGfxImage(image_scale, |
+ bitmap_sizes.button_icon_size, |
+ (*options->buttons)[i]->icons.get(), |
+ &info.icon); |
optional_fields.buttons.push_back(info); |
} |
} |
@@ -315,10 +354,10 @@ bool NotificationsApiFunction::CreateNotification( |
base::UTF8ToUTF16(*options->context_message); |
} |
- bool has_image = NotificationBitmapToGfxImage(image_scale, |
- bitmap_sizes.image_size, |
- options->image_bitmap.get(), |
- &optional_fields.image); |
+ bool has_image = ImageRepresentationListToGfxImage(image_scale, |
+ bitmap_sizes.image_size, |
+ options->images.get(), |
+ &optional_fields.image); |
// We should have an image if and only if the type is an image type. |
if (has_image != (type == message_center::NOTIFICATION_TYPE_IMAGE)) { |
SetError(kExtraImageProvided); |
@@ -398,10 +437,10 @@ bool NotificationsApiFunction::UpdateNotification( |
notification->set_message(base::UTF8ToUTF16(*options->message)); |
// TODO(dewittj): Return error if this fails. |
- if (options->icon_bitmap) { |
+ if (options->icons) { |
gfx::Image icon; |
- NotificationBitmapToGfxImage( |
- image_scale, bitmap_sizes.icon_size, options->icon_bitmap.get(), &icon); |
+ ImageRepresentationListToGfxImage( |
+ image_scale, bitmap_sizes.icon_size, options->icons.get(), &icon); |
notification->set_icon(icon); |
} |
@@ -420,10 +459,10 @@ bool NotificationsApiFunction::UpdateNotification( |
for (size_t i = 0; i < number_of_buttons; i++) { |
message_center::ButtonInfo button( |
base::UTF8ToUTF16((*options->buttons)[i]->title)); |
- NotificationBitmapToGfxImage(image_scale, |
- bitmap_sizes.button_icon_size, |
- (*options->buttons)[i]->icon_bitmap.get(), |
- &button.icon); |
+ ImageRepresentationListToGfxImage(image_scale, |
+ bitmap_sizes.button_icon_size, |
+ (*options->buttons)[i]->icons.get(), |
+ &button.icon); |
buttons.push_back(button); |
} |
notification->set_buttons(buttons); |
@@ -435,10 +474,8 @@ bool NotificationsApiFunction::UpdateNotification( |
} |
gfx::Image image; |
- bool has_image = NotificationBitmapToGfxImage(image_scale, |
- bitmap_sizes.image_size, |
- options->image_bitmap.get(), |
- &image); |
+ bool has_image = ImageRepresentationListToGfxImage( |
+ image_scale, bitmap_sizes.image_size, options->images.get(), &image); |
if (has_image) { |
// We should have an image if and only if the type is an image type. |
if (notification->type() != message_center::NOTIFICATION_TYPE_IMAGE) { |