Index: third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.cpp |
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.cpp b/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.cpp |
index fcf1e910a021523870f1bac101ab4c9813de34b2..fdb019561f8a15899bc003a268acf028a9f4e3d2 100644 |
--- a/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.cpp |
+++ b/third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.cpp |
@@ -13,21 +13,25 @@ |
#include "third_party/skia/include/core/SkBitmap.h" |
#include "wtf/CurrentTime.h" |
#include "wtf/Threading.h" |
+#include <cmath> |
namespace blink { |
namespace { |
-// Scales down |image| to fit within |maxSizePx| if its width or height is |
-// larger than |maxSizePx| and returns the result. Otherwise does nothing and |
-// returns |image| unchanged. |
+// Scales down |image| to fit within |maxWidthPx|x|maxHeightPx| if it is larger |
+// and returns the result. Otherwise does nothing and returns |image| unchanged. |
// TODO(mvanouwerkerk): Explore doing the scaling on a background thread. |
-SkBitmap scaleDownIfNeeded(const SkBitmap& image, int maxSizePx) |
+SkBitmap scaleDownIfNeeded(const SkBitmap& image, int maxWidthPx, int maxHeightPx) |
{ |
- if (image.width() > maxSizePx || image.height() > maxSizePx) { |
+ if (image.width() > maxWidthPx || image.height() > maxHeightPx) { |
+ double scale = std::min( |
+ static_cast<double>(maxWidthPx) / image.width(), |
+ static_cast<double>(maxHeightPx) / image.height()); |
DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scaleTimeHistogram, new CustomCountHistogram("Notifications.Icon.ScaleDownTime", 1, 1000 * 10 /* 10 seconds max */, 50 /* buckets */)); |
double startTime = monotonicallyIncreasingTimeMS(); |
- SkBitmap scaledImage = skia::ImageOperations::Resize(image, skia::ImageOperations::RESIZE_BEST, std::min(image.width(), maxSizePx), std::min(image.height(), maxSizePx)); |
+ // TODO(peter): Try using RESIZE_BETTER for large images. |
+ SkBitmap scaledImage = skia::ImageOperations::Resize(image, skia::ImageOperations::RESIZE_BEST, std::lround(scale * image.width()), std::lround(scale * image.height())); |
scaleTimeHistogram.count(monotonicallyIncreasingTimeMS() - startTime); |
return scaledImage; |
} |
@@ -53,8 +57,11 @@ void NotificationResourcesLoader::start(ExecutionContext* executionContext, cons |
m_started = true; |
size_t numActions = notificationData.actions.size(); |
- m_pendingRequestCount = 2 /* icon and badge */ + numActions; |
+ m_pendingRequestCount = 3 /* image, icon, badge */ + numActions; |
+ // TODO(johnme): ensure image is not loaded when it will not be used. |
+ // TODO(mvanouwerkerk): ensure no badge is loaded when it will not be used. |
+ loadImage(executionContext, notificationData.image, WTF::bind(&NotificationResourcesLoader::didLoadImage, wrapWeakPersistent(this))); |
loadImage(executionContext, notificationData.icon, WTF::bind(&NotificationResourcesLoader::didLoadIcon, wrapWeakPersistent(this))); |
loadImage(executionContext, notificationData.badge, WTF::bind(&NotificationResourcesLoader::didLoadBadge, wrapWeakPersistent(this))); |
@@ -66,6 +73,7 @@ void NotificationResourcesLoader::start(ExecutionContext* executionContext, cons |
std::unique_ptr<WebNotificationResources> NotificationResourcesLoader::getResources() const |
{ |
std::unique_ptr<WebNotificationResources> resources(new WebNotificationResources()); |
+ resources->image = m_image; |
resources->icon = m_icon; |
resources->badge = m_badge; |
resources->actionIcons = m_actionIcons; |
@@ -95,15 +103,21 @@ void NotificationResourcesLoader::loadImage(ExecutionContext* executionContext, |
imageLoader->start(executionContext, url, std::move(imageCallback)); |
} |
+void NotificationResourcesLoader::didLoadImage(const SkBitmap& image) |
+{ |
+ m_image = scaleDownIfNeeded(image, kWebNotificationMaxImageWidthPx, kWebNotificationMaxImageHeightPx); |
+ didFinishRequest(); |
+} |
+ |
void NotificationResourcesLoader::didLoadIcon(const SkBitmap& image) |
{ |
- m_icon = scaleDownIfNeeded(image, kWebNotificationMaxIconSizePx); |
+ m_icon = scaleDownIfNeeded(image, kWebNotificationMaxIconSizePx, kWebNotificationMaxIconSizePx); |
didFinishRequest(); |
} |
void NotificationResourcesLoader::didLoadBadge(const SkBitmap& image) |
{ |
- m_badge = scaleDownIfNeeded(image, kWebNotificationMaxBadgeSizePx); |
+ m_badge = scaleDownIfNeeded(image, kWebNotificationMaxBadgeSizePx, kWebNotificationMaxBadgeSizePx); |
didFinishRequest(); |
} |
@@ -111,7 +125,7 @@ void NotificationResourcesLoader::didLoadActionIcon(size_t actionIndex, const Sk |
{ |
DCHECK_LT(actionIndex, m_actionIcons.size()); |
- m_actionIcons[actionIndex] = scaleDownIfNeeded(image, kWebNotificationMaxActionIconSizePx); |
+ m_actionIcons[actionIndex] = scaleDownIfNeeded(image, kWebNotificationMaxActionIconSizePx, kWebNotificationMaxActionIconSizePx); |
didFinishRequest(); |
} |