| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/message_center/public/cpp/notification.h" |
| |
| #include <map> |
| #include <memory> |
| |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/image/image_skia_operations.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| #include "ui/gfx/vector_icon_types.h" |
| #include "ui/message_center/public/cpp/message_center_constants.h" |
| #include "ui/message_center/public/cpp/notification_delegate.h" |
| #include "ui/message_center/public/cpp/notification_types.h" |
| |
| namespace message_center { |
| |
| namespace { |
| |
| unsigned g_next_serial_number = 0; |
| |
| base::LazyInstance<std::map<std::string, const gfx::VectorIcon&>>::Leaky |
| g_vector_icon_registry = LAZY_INSTANCE_INITIALIZER; |
| |
| const gfx::ImageSkia CreateSolidColorImage(int width, |
| int height, |
| SkColor color) { |
| SkBitmap bitmap; |
| bitmap.allocN32Pixels(width, height); |
| bitmap.eraseColor(color); |
| return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
| } |
| |
| gfx::Image DeepCopyImage(const gfx::Image& image) { |
| if (image.IsEmpty()) |
| return gfx::Image(); |
| std::unique_ptr<gfx::ImageSkia> image_skia( |
| new gfx::ImageSkia(*image.ToImageSkia())); |
| return gfx::Image(*image_skia); |
| } |
| |
| } // namespace |
| |
| ButtonInfo::ButtonInfo(const base::string16& title) : title(title) {} |
| |
| ButtonInfo::ButtonInfo(const ButtonInfo& other) = default; |
| |
| ButtonInfo::ButtonInfo() = default; |
| |
| ButtonInfo::~ButtonInfo() = default; |
| |
| ButtonInfo& ButtonInfo::operator=(const ButtonInfo& other) = default; |
| |
| RichNotificationData::RichNotificationData() : timestamp(base::Time::Now()) {} |
| |
| RichNotificationData::RichNotificationData(const RichNotificationData& other) = |
| default; |
| |
| RichNotificationData::~RichNotificationData() = default; |
| |
| Notification::Notification() : serial_number_(g_next_serial_number++) {} |
| |
| Notification::Notification(NotificationType type, |
| const std::string& id, |
| const base::string16& title, |
| const base::string16& message, |
| const gfx::Image& icon, |
| const base::string16& display_source, |
| const GURL& origin_url, |
| const NotifierId& notifier_id, |
| const RichNotificationData& optional_fields, |
| scoped_refptr<NotificationDelegate> delegate) |
| : type_(type), |
| id_(id), |
| title_(title), |
| message_(message), |
| icon_(icon), |
| display_source_(display_source), |
| origin_url_(origin_url), |
| notifier_id_(notifier_id), |
| optional_fields_(optional_fields), |
| serial_number_(g_next_serial_number++), |
| delegate_(std::move(delegate)) {} |
| |
| Notification::Notification(const std::string& id, const Notification& other) |
| : Notification(other) { |
| id_ = id; |
| } |
| |
| Notification::Notification(const Notification& other) = default; |
| |
| Notification& Notification::operator=(const Notification& other) = default; |
| |
| Notification::~Notification() = default; |
| |
| // static |
| std::unique_ptr<Notification> Notification::DeepCopy( |
| const Notification& notification, |
| bool include_body_image, |
| bool include_small_image, |
| bool include_icon_images) { |
| std::unique_ptr<Notification> notification_copy = |
| std::make_unique<Notification>(notification); |
| notification_copy->set_icon(DeepCopyImage(notification_copy->icon())); |
| notification_copy->set_image(include_body_image |
| ? DeepCopyImage(notification_copy->image()) |
| : gfx::Image()); |
| notification_copy->set_small_image( |
| include_small_image ? notification_copy->small_image() : gfx::Image()); |
| for (size_t i = 0; i < notification_copy->buttons().size(); i++) { |
| notification_copy->SetButtonIcon( |
| i, include_icon_images |
| ? DeepCopyImage(notification_copy->buttons()[i].icon) |
| : gfx::Image()); |
| } |
| return notification_copy; |
| } |
| |
| void Notification::SetButtonIcon(size_t index, const gfx::Image& icon) { |
| if (index >= optional_fields_.buttons.size()) |
| return; |
| optional_fields_.buttons[index].icon = icon; |
| } |
| |
| void Notification::SetSystemPriority() { |
| optional_fields_.priority = SYSTEM_PRIORITY; |
| optional_fields_.never_timeout = true; |
| } |
| |
| bool Notification::UseOriginAsContextMessage() const { |
| return optional_fields_.context_message.empty() && origin_url_.is_valid() && |
| origin_url_.SchemeIsHTTPOrHTTPS(); |
| } |
| |
| gfx::Image Notification::GenerateMaskedSmallIcon(int dip_size, |
| SkColor color) const { |
| if (!vector_small_image().is_empty()) |
| return gfx::Image( |
| gfx::CreateVectorIcon(vector_small_image(), dip_size, color)); |
| |
| if (small_image().IsEmpty()) |
| return gfx::Image(); |
| |
| // If |vector_small_image| is not available, fallback to raster based |
| // masking and resizing. |
| gfx::ImageSkia image = small_image().AsImageSkia(); |
| gfx::ImageSkia masked = gfx::ImageSkiaOperations::CreateMaskedImage( |
| CreateSolidColorImage(image.width(), image.height(), color), image); |
| gfx::ImageSkia resized = gfx::ImageSkiaOperations::CreateResizedImage( |
| masked, skia::ImageOperations::ResizeMethod::RESIZE_BEST, |
| gfx::Size(dip_size, dip_size)); |
| return gfx::Image(resized); |
| } |
| |
| // static |
| void RegisterVectorIcons( |
| const std::vector<const gfx::VectorIcon*>& vector_icons) { |
| for (const gfx::VectorIcon* icon : vector_icons) { |
| g_vector_icon_registry.Get().insert( |
| std::pair<std::string, const gfx::VectorIcon&>(icon->name, *icon)); |
| } |
| } |
| |
| // static |
| const gfx::VectorIcon* GetRegisteredVectorIcon(const std::string& id) { |
| auto iter = g_vector_icon_registry.Get().find(id); |
| return iter != g_vector_icon_registry.Get().end() ? &iter->second : nullptr; |
| } |
| |
| } // namespace message_center |