Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Unified Diff: chrome/browser/notifications/notification_platform_bridge_linux.cc

Issue 2872053002: Linux native notifications: Support image notifications (Closed)
Patch Set: Resize on task runner Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 6bcf7a2f34ecdf5bcddd159f33669ebb6a253429..6b42d0e158f33af7ba3313020519f059662ebbd1 100644
--- a/chrome/browser/notifications/notification_platform_bridge_linux.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -35,6 +35,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 {
@@ -45,6 +46,10 @@ const char kFreedesktopNotificationsPath[] = "/org/freedesktop/Notifications";
const char kDefaultButtonId[] = "default";
const char kSettingsButtonId[] = "settings";
+// Max image size; specified in the FDO notification specification.
+const int kMaxImageWidth = 200;
+const int kMaxImageHeight = 100;
+
// 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
@@ -58,6 +63,14 @@ enum class ConnectionInitializationStatusCode {
NUM_ITEMS
};
+int ClampInt(int v, int lo, int hi) {
Lei Zhang 2017/05/11 00:54:56 return std::max(std::min(value, hi), low);
Lei Zhang 2017/05/11 00:54:56 BTW, std::clamp() will be in C++17, so we'll have
Tom (Use chromium acct) 2017/05/11 01:28:22 Done.
+ if (v < lo)
+ return lo;
+ if (v > hi)
+ return hi;
+ return v;
+}
+
base::string16 CreateNotificationTitle(const Notification& notification) {
base::string16 title;
if (notification.type() == message_center::NOTIFICATION_TYPE_PROGRESS) {
@@ -95,6 +108,29 @@ int NotificationPriorityToFdoUrgency(int priority) {
}
}
+// Constrain |image|'s size to |kMaxImageWidth|x|kMaxImageHeight|. If
+// the image does not need to be resized, or the image is empty,
+// returns |image| directly.
+gfx::Image ResizeImageToFdoMaxSize(const gfx::Image& image) {
+ if (image.IsEmpty())
+ return image;
+ int width = image.Width();
+ int height = image.Height();
+ if (width <= kMaxImageWidth && height <= kMaxImageHeight) {
+ return image;
+ } else {
Lei Zhang 2017/05/11 00:54:56 No else after return.
Tom (Use chromium acct) 2017/05/11 01:28:22 Done.
+ const SkBitmap* image_bitmap = 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);
+ return gfx::Image(
+ gfx::ImageSkia::CreateFrom1xBitmap(skia::ImageOperations::Resize(
+ *image_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, width,
+ height)));
+ }
+}
+
// Runs once the profile has been loaded in order to perform a given
// |operation| on a notification.
void ProfileLoadedCallback(NotificationCommon::Operation operation,
@@ -209,7 +245,9 @@ 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());
+ notification_copy->set_image(body_images_supported_
+ ? DeepCopyImage(notification_copy->image())
+ : gfx::Image());
notification_copy->set_small_image(gfx::Image());
for (size_t i = 0; i < notification_copy->buttons().size(); i++)
notification_copy->SetButtonIcon(i, gfx::Image());
@@ -311,6 +349,11 @@ class NotificationPlatformBridgeLinuxImpl
CleanUp();
}
+ void SetBodyImagesSupported(bool body_images_supported) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ body_images_supported_ = body_images_supported;
+ }
+
void PostTaskToUiThread(base::OnceClosure closure) const {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
bool success = content::BrowserThread::PostTask(
@@ -360,6 +403,9 @@ class NotificationPlatformBridgeLinuxImpl
capabilities_.insert(capability);
}
RecordMetricsForCapabilities();
+ PostTaskToUiThread(base::BindOnce(
+ &NotificationPlatformBridgeLinuxImpl::SetBodyImagesSupported, this,
+ base::ContainsKey(capabilities_, "body-images")));
dbus::MethodCall get_server_information_call(kFreedesktopNotificationsName,
"GetServerInformation");
@@ -468,6 +514,18 @@ class NotificationPlatformBridgeLinuxImpl
else
body += title + " - " + message;
}
+ } else if (notification->type() ==
+ message_center::NOTIFICATION_TYPE_IMAGE &&
+ base::ContainsKey(capabilities_, "body-images")) {
+ std::unique_ptr<ResourceFile> image_file = WriteDataToTmpFile(
+ ResizeImageToFdoMaxSize(notification->image()).As1xPNGBytes());
+ if (image_file) {
+ if (!body.empty())
+ body += "\n";
+ body +=
+ "<img src=\"" + image_file->file_path().value() + "\" alt=\"\"/>";
+ data->resource_files.push_back(std::move(image_file));
+ }
}
}
writer.AppendString(body);
@@ -750,6 +808,12 @@ class NotificationPlatformBridgeLinuxImpl
base::Optional<bool> connected_;
std::vector<NotificationBridgeReadyCallback> on_connected_callbacks_;
+ // Notification servers very rarely have the 'body-images'
+ // capability, so try to avoid an image copy if possible. It is
+ // intialized to true so that the UI thread will conservatively copy
+ // the image before the GetCapabilities message completes.
+ bool body_images_supported_ = true;
+
//////////////////////////////////////////////////////////////////////////////
// Members used only on the task runner thread.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698