Commit 4969d273 authored by liyanhou@chromium.org's avatar liyanhou@chromium.org

Add app icon masp to notification API

Add an app icon mask (16*16, or 32*32 for retina display) on the bottom right corner of notifications to indicate source of the notification. The app icon is displayed in a way that takes only the alpha channel of the image passed in, masks it with white foreground and grey background.

BUG=284592

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284586 0039d316-1c4b-4281-b951-d872f2087c98
parent b4cb55bb
......@@ -285,6 +285,16 @@ bool NotificationsApiFunction::CreateNotification(
// Then, handle any optional data that's been provided.
message_center::RichNotificationData optional_fields;
if (options->app_icon_mask_url.get()) {
if (!NotificationBitmapToGfxImage(image_scale,
bitmap_sizes.app_icon_mask_size,
options->app_icon_mask_bitmap.get(),
&optional_fields.small_image)) {
SetError(kUnableToDecodeIconError);
return false;
}
}
if (options->priority.get())
optional_fields.priority = *options->priority;
......@@ -402,6 +412,14 @@ bool NotificationsApiFunction::UpdateNotification(
notification->set_icon(icon);
}
gfx::Image app_icon_mask;
if (NotificationBitmapToGfxImage(image_scale,
bitmap_sizes.app_icon_mask_size,
options->app_icon_mask_bitmap.get(),
&app_icon_mask)) {
notification->set_small_image(app_icon_mask);
}
if (options->priority)
notification->set_priority(*options->priority);
......
......@@ -53,11 +53,23 @@ namespace notifications {
// <em>Required for $(ref:notifications.create)</em> method.
TemplateType? type;
// Sender's avatar, app icon, or a thumbnail for image notifications.
// A URL to the sender's avatar, app icon, or a thumbnail for image
// notifications.
//
// URLs can be a data URL, a blob URL, or a URL relative to a resource
// within this extension's .crx file
// <em>Required for $(ref:notifications.create)</em> method.
DOMString? iconUrl;
[nodoc] NotificationBitmap? iconBitmap;
// A URL to the app icon mask. URLs have the same restrictions as
// $(ref:notifications.NotificationOptions.iconUrl iconUrl).
//
// The app icon mask should be in alpha channel, as only the alpha channel
// of the image will be considered.
DOMString? appIconMaskUrl;
[nodoc] NotificationBitmap? appIconMaskBitmap;
// Title of the notification (e.g. sender name for email).
// <em>Required for $(ref:notifications.create)</em> method.
DOMString? title;
......@@ -83,7 +95,9 @@ namespace notifications {
// Secondary notification content.
[nodoc] DOMString? expandedMessage;
// Image thumbnail for image-type notifications.
// A URL to the image thumbnail for image-type notifications.
// URLs have the same restrictions as
// $(ref:notifications.NotificationOptions.iconUrl iconUrl).
DOMString? imageUrl;
[nodoc] NotificationBitmap? imageBitmap;
......
......@@ -6,6 +6,11 @@
#include "ui/message_center/message_center_style.h"
NotificationBitmapSizes::NotificationBitmapSizes() {
}
NotificationBitmapSizes::~NotificationBitmapSizes() {
}
NotificationBitmapSizes GetNotificationBitmapSizes() {
NotificationBitmapSizes sizes;
sizes.image_size =
......@@ -16,5 +21,8 @@ NotificationBitmapSizes GetNotificationBitmapSizes() {
sizes.button_icon_size =
gfx::Size(message_center::kNotificationButtonIconSize,
message_center::kNotificationButtonIconSize);
sizes.app_icon_mask_size = gfx::Size(message_center::kSmallImageSize,
message_center::kSmallImageSize);
return sizes;
}
......@@ -10,9 +10,13 @@
// This structure describes the size in DIPs of each type of image rendered
// by the notification center within a notification.
struct NotificationBitmapSizes {
NotificationBitmapSizes();
~NotificationBitmapSizes();
gfx::Size image_size;
gfx::Size icon_size;
gfx::Size button_icon_size;
gfx::Size app_icon_mask_size;
};
NotificationBitmapSizes GetNotificationBitmapSizes();
......
......@@ -38,6 +38,10 @@ void NotificationsNativeHandler::GetNotificationImageSizes(
dict->SetInteger("image.height", bitmap_sizes.image_size.height());
dict->SetInteger("buttonIcon.width", bitmap_sizes.button_icon_size.width());
dict->SetInteger("buttonIcon.height", bitmap_sizes.button_icon_size.height());
dict->SetInteger("appIconMask.width",
bitmap_sizes.app_icon_mask_size.width());
dict->SetInteger("appIconMask.height",
bitmap_sizes.app_icon_mask_size.height());
scoped_ptr<content::V8ValueConverter> converter(
content::V8ValueConverter::create());
......
......@@ -40,6 +40,16 @@ function getUrlSpecs(imageSizes, notificationDetails) {
});
}
// |appIconMaskUrl| is optional.
if (notificationDetails.appIconMaskUrl) {
$Array.push(urlSpecs, {
path: notificationDetails.appIconMaskUrl,
width: imageSizes.appIconMask.width * imageSizes.scaleFactor,
height: imageSizes.appIconMask.height * imageSizes.scaleFactor,
callback: imageDataSetter(notificationDetails, 'appIconMaskBitmap')
});
}
// |imageUrl| is optional.
if (notificationDetails.imageUrl) {
$Array.push(urlSpecs, {
......
......@@ -23,6 +23,8 @@ const SkColor kImageBackgroundColor = SkColorSetRGB(0x22, 0x22, 0x22);
const SkColor kRegularTextColor = SkColorSetRGB(0x33, 0x33, 0x33);
const SkColor kDimTextColor = SkColorSetRGB(0x7f, 0x7f, 0x7f);
const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
const SkColor kSmallImageMaskForegroundColor = SK_ColorWHITE;
const SkColor kSmallImageMaskBackgroundColor = SkColorSetRGB(0xa3, 0xa3, 0xa3);
// Limits.
......
......@@ -77,6 +77,10 @@ extern const SkColor kIconBackgroundColor; // Used behind icons smaller
extern const SkColor kRegularTextColor; // Title, message, ...
extern const SkColor kDimTextColor;
extern const SkColor kFocusBorderColor; // The focus border.
extern const SkColor
kSmallImageMaskForegroundColor; // Foreground of small icon image.
extern const SkColor
kSmallImageMaskBackgroundColor; // Background of small icon image.
// Limits.
......
......@@ -12,6 +12,7 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/views/padded_button.h"
......@@ -31,6 +32,31 @@ const int kCloseIconRightPadding = 5;
const int kShadowOffset = 1;
const int kShadowBlur = 4;
const gfx::ImageSkia CreateImage(int width, int height, SkColor color) {
SkBitmap bitmap;
bitmap.allocN32Pixels(width, height);
bitmap.eraseColor(color);
return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
}
// Take the alpha channel of small_image, mask it with the foreground,
// then add the masked foreground on top of the background
const gfx::ImageSkia GetMaskedSmallImage(const gfx::ImageSkia& small_image) {
int width = small_image.width();
int height = small_image.height();
// Background color grey
const gfx::ImageSkia background = CreateImage(
width, height, message_center::kSmallImageMaskBackgroundColor);
// Foreground color white
const gfx::ImageSkia foreground = CreateImage(
width, height, message_center::kSmallImageMaskForegroundColor);
const gfx::ImageSkia masked_small_image =
gfx::ImageSkiaOperations::CreateMaskedImage(foreground, small_image);
return gfx::ImageSkiaOperations::CreateSuperimposedImage(background,
masked_small_image);
}
} // namespace
namespace message_center {
......@@ -54,8 +80,9 @@ MessageView::MessageView(MessageViewController* controller,
views::Background::CreateSolidBackground(kNotificationBackgroundColor));
AddChildView(background_view_);
const gfx::ImageSkia masked_small_image = GetMaskedSmallImage(small_image);
views::ImageView* small_image_view = new views::ImageView();
small_image_view->SetImage(small_image);
small_image_view->SetImage(masked_small_image);
small_image_view->SetImageSize(gfx::Size(kSmallImageSize, kSmallImageSize));
// The small image view should be added to view hierarchy by the derived
// class. This ensures that it is on top of other views.
......@@ -84,7 +111,9 @@ MessageView::~MessageView() {
}
void MessageView::UpdateWithNotification(const Notification& notification) {
small_image_view_->SetImage(notification.small_image().AsImageSkia());
const gfx::ImageSkia masked_small_image =
GetMaskedSmallImage(notification.small_image().AsImageSkia());
small_image_view_->SetImage(masked_small_image);
display_source_ = notification.display_source();
}
......
......@@ -7,6 +7,10 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/insets.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/notification.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment