Index: chrome/browser/notifications/notification_platform_bridge_linux.cc |
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.cc b/chrome/browser/notifications/notification_platform_bridge_linux.cc |
index 79ae1651465dda83865f2b41dd0974b01ced8478..9e6e0739d61f2ab1708a7d1ecea093931052581a 100644 |
--- a/chrome/browser/notifications/notification_platform_bridge_linux.cc |
+++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc |
@@ -34,6 +34,7 @@ |
#include "dbus/bus.h" |
#include "dbus/message.h" |
#include "dbus/object_proxy.h" |
+#include "skia/ext/image_operations.h" |
#include "ui/gfx/image/image_skia.h" |
namespace { |
@@ -44,6 +45,10 @@ const char kFreedesktopNotificationsPath[] = "/org/freedesktop/Notifications"; |
const char kDefaultButtonId[] = "default"; |
const char kSettingsButtonId[] = "settings"; |
+// Specified in FDO notification specification. |
+const int kMaxImageWidth = 200; |
+const int kMaxImageHeight = 100; |
Peter Beverloo
2017/05/10 12:54:40
This is tiny! Developers have to provide images wi
Tom (Use chromium acct)
2017/05/11 00:07:04
Yeah, but the only notification server that actual
|
+ |
// The values in this enumeration correspond to those of the |
// Linux.NotificationPlatformBridge.InitializationStatus histogram, so |
// the ordering should not be changed. New error codes should be |
@@ -57,6 +62,14 @@ enum class ConnectionInitializationStatusCode { |
NUM_ITEMS |
}; |
+int ClampInt(int v, int lo, int hi) { |
+ if (v < lo) |
+ return lo; |
+ if (v > hi) |
+ return hi; |
+ return v; |
+} |
+ |
gfx::Image DeepCopyImage(const gfx::Image& image) { |
if (image.IsEmpty()) |
return gfx::Image(); |
@@ -198,7 +211,24 @@ class NotificationPlatformBridgeLinuxImpl |
// non-thread-safe reference counts) to the task runner thread. |
auto notification_copy = base::MakeUnique<Notification>(notification); |
notification_copy->set_icon(DeepCopyImage(notification_copy->icon())); |
- notification_copy->set_image(gfx::Image()); |
+ if (body_images_supported_ != BODY_IMAGES_NOT_SUPPORTED && |
+ !notification_copy->image().IsEmpty()) { |
+ int width = notification_copy->image().Width(); |
+ int height = notification_copy->image().Height(); |
+ if (width <= kMaxImageWidth && height <= kMaxImageHeight) { |
+ notification_copy->set_image(DeepCopyImage(notification_copy->image())); |
+ } else { |
+ const SkBitmap* image_bitmap = notification_copy->image().ToSkBitmap(); |
+ double scale = std::min(static_cast<double>(kMaxImageWidth) / width, |
+ static_cast<double>(kMaxImageHeight) / height); |
+ width = ClampInt(scale * width, 1, kMaxImageWidth); |
+ height = ClampInt(scale * height, 1, kMaxImageHeight); |
+ notification_copy->set_image(gfx::Image( |
+ gfx::ImageSkia::CreateFrom1xBitmap(skia::ImageOperations::Resize( |
+ *image_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, width, |
+ height)))); |
Peter Beverloo
2017/05/10 12:54:40
Since these images potentially can be huge, we sho
Tom (Use chromium acct)
2017/05/11 00:07:04
Done.
|
+ } |
+ } |
notification_copy->set_small_image(gfx::Image()); |
for (size_t i = 0; i < notification_copy->buttons().size(); i++) |
notification_copy->SetButtonIcon(i, gfx::Image()); |
@@ -349,6 +379,9 @@ class NotificationPlatformBridgeLinuxImpl |
capabilities_.insert(capability); |
} |
RecordMetricsForCapabilities(); |
+ body_images_supported_ = base::ContainsKey(capabilities_, "body-images") |
+ ? BODY_IMAGES_SUPPORTED |
+ : BODY_IMAGES_NOT_SUPPORTED; |
dbus::MethodCall get_server_information_call(kFreedesktopNotificationsName, |
"GetServerInformation"); |
@@ -457,6 +490,17 @@ class NotificationPlatformBridgeLinuxImpl |
else |
body += title + " - " + message; |
} |
+ } else if (notification->type() == |
+ message_center::NOTIFICATION_TYPE_IMAGE) { |
+ std::unique_ptr<ResourceFile> image_file = |
+ WriteDataToTmpFile(notification->image().As1xPNGBytes()); |
+ if (image_file) { |
+ if (!body.empty()) |
+ body += "\n"; |
+ body += |
+ "<img src=\"" + image_file->file_path().value() + "\" alt=\"\"/>"; |
Peter Beverloo
2017/05/10 12:54:40
Is a data: URL an option here? If the toast requir
Tom (Use chromium acct)
2017/05/11 00:07:04
No, the spec says "Images referenced must always b
|
+ data->resource_files.push_back(std::move(image_file)); |
+ } |
} |
} |
writer.AppendString(body); |
@@ -768,6 +812,19 @@ class NotificationPlatformBridgeLinuxImpl |
UnorderedUniqueSet<NotificationData> notifications_; |
+ ////////////////////////////////////////////////////////////////////////////// |
+ // Members used on both the UI thread and the task runner thread. |
+ |
+ // Notification servers very rarely have the 'body-images' |
+ // capability, so try to avoid an image copy/resize if possible. |
+ // Reads and writes to |body_images_supported_| should be atomic, so |
+ // no locking is necessary. |
+ enum { |
+ BODY_IMAGES_UNKNOWN, |
+ BODY_IMAGES_SUPPORTED, |
+ BODY_IMAGES_NOT_SUPPORTED, |
+ } body_images_supported_ = BODY_IMAGES_UNKNOWN; |
Peter Beverloo
2017/05/10 12:54:40
It looks like you're considering base::Optional<bo
Tom (Use chromium acct)
2017/05/11 00:07:04
Done.
|
+ |
DISALLOW_COPY_AND_ASSIGN(NotificationPlatformBridgeLinuxImpl); |
}; |