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

Side by Side Diff: third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.cpp

Issue 2261283002: Add Notification images (Blink + desktop implementation) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Check IPC drawsNothing rather than isNull Created 4 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/notifications/NotificationResourcesLoader.h" 5 #include "modules/notifications/NotificationResourcesLoader.h"
6 6
7 #include "platform/Histogram.h" 7 #include "platform/Histogram.h"
8 #include "platform/weborigin/KURL.h" 8 #include "platform/weborigin/KURL.h"
9 #include "public/platform/modules/notifications/WebNotificationConstants.h" 9 #include "public/platform/modules/notifications/WebNotificationConstants.h"
10 #include "public/platform/modules/notifications/WebNotificationData.h" 10 #include "public/platform/modules/notifications/WebNotificationData.h"
11 #include "public/platform/modules/notifications/WebNotificationResources.h" 11 #include "public/platform/modules/notifications/WebNotificationResources.h"
12 #include "skia/ext/image_operations.h" 12 #include "skia/ext/image_operations.h"
13 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "wtf/CurrentTime.h" 14 #include "wtf/CurrentTime.h"
15 #include "wtf/Threading.h" 15 #include "wtf/Threading.h"
16 #include <cmath>
16 17
17 namespace blink { 18 namespace blink {
18 19
19 namespace { 20 namespace {
20 21
21 // Scales down |image| to fit within |maxSizePx| if its width or height is 22 // Scales down |image| to fit within |maxWidthPx|x|maxHeightPx| if it is larger
22 // larger than |maxSizePx| and returns the result. Otherwise does nothing and 23 // and returns the result. Otherwise does nothing and returns |image| unchanged.
23 // returns |image| unchanged.
24 // TODO(mvanouwerkerk): Explore doing the scaling on a background thread. 24 // TODO(mvanouwerkerk): Explore doing the scaling on a background thread.
25 SkBitmap scaleDownIfNeeded(const SkBitmap& image, int maxSizePx) 25 SkBitmap scaleDownIfNeeded(const SkBitmap& image, int maxWidthPx, int maxHeightP x)
26 { 26 {
27 if (image.width() > maxSizePx || image.height() > maxSizePx) { 27 if (image.width() > maxWidthPx || image.height() > maxHeightPx) {
28 double scale = std::min(
29 static_cast<double>(maxWidthPx) / image.width(),
30 static_cast<double>(maxHeightPx) / image.height());
28 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scaleTimeHistogram , new CustomCountHistogram("Notifications.Icon.ScaleDownTime", 1, 1000 * 10 /* 1 0 seconds max */, 50 /* buckets */)); 31 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, scaleTimeHistogram , new CustomCountHistogram("Notifications.Icon.ScaleDownTime", 1, 1000 * 10 /* 1 0 seconds max */, 50 /* buckets */));
29 double startTime = monotonicallyIncreasingTimeMS(); 32 double startTime = monotonicallyIncreasingTimeMS();
30 SkBitmap scaledImage = skia::ImageOperations::Resize(image, skia::ImageO perations::RESIZE_BEST, std::min(image.width(), maxSizePx), std::min(image.heigh t(), maxSizePx)); 33 // TODO(peter): Try using RESIZE_BETTER for large images.
34 SkBitmap scaledImage = skia::ImageOperations::Resize(image, skia::ImageO perations::RESIZE_BEST, std::lround(scale * image.width()), std::lround(scale * image.height()));
31 scaleTimeHistogram.count(monotonicallyIncreasingTimeMS() - startTime); 35 scaleTimeHistogram.count(monotonicallyIncreasingTimeMS() - startTime);
32 return scaledImage; 36 return scaledImage;
33 } 37 }
34 return image; 38 return image;
35 } 39 }
36 40
37 } // namespace 41 } // namespace
38 42
39 NotificationResourcesLoader::NotificationResourcesLoader(std::unique_ptr<Complet ionCallback> completionCallback) 43 NotificationResourcesLoader::NotificationResourcesLoader(std::unique_ptr<Complet ionCallback> completionCallback)
40 : m_started(false), m_completionCallback(std::move(completionCallback)), m_p endingRequestCount(0) 44 : m_started(false), m_completionCallback(std::move(completionCallback)), m_p endingRequestCount(0)
41 { 45 {
42 ThreadState::current()->registerPreFinalizer(this); 46 ThreadState::current()->registerPreFinalizer(this);
43 DCHECK(m_completionCallback); 47 DCHECK(m_completionCallback);
44 } 48 }
45 49
46 NotificationResourcesLoader::~NotificationResourcesLoader() 50 NotificationResourcesLoader::~NotificationResourcesLoader()
47 { 51 {
48 } 52 }
49 53
50 void NotificationResourcesLoader::start(ExecutionContext* executionContext, cons t WebNotificationData& notificationData) 54 void NotificationResourcesLoader::start(ExecutionContext* executionContext, cons t WebNotificationData& notificationData)
51 { 55 {
52 DCHECK(!m_started); 56 DCHECK(!m_started);
53 m_started = true; 57 m_started = true;
54 58
55 size_t numActions = notificationData.actions.size(); 59 size_t numActions = notificationData.actions.size();
56 m_pendingRequestCount = 2 /* icon and badge */ + numActions; 60 m_pendingRequestCount = 3 /* image, icon, badge */ + numActions;
57 61
62 // TODO(johnme): ensure image is not loaded when it will not be used.
63 // TODO(mvanouwerkerk): ensure no badge is loaded when it will not be used.
64 loadImage(executionContext, notificationData.image, WTF::bind(&NotificationR esourcesLoader::didLoadImage, wrapWeakPersistent(this)));
58 loadImage(executionContext, notificationData.icon, WTF::bind(&NotificationRe sourcesLoader::didLoadIcon, wrapWeakPersistent(this))); 65 loadImage(executionContext, notificationData.icon, WTF::bind(&NotificationRe sourcesLoader::didLoadIcon, wrapWeakPersistent(this)));
59 loadImage(executionContext, notificationData.badge, WTF::bind(&NotificationR esourcesLoader::didLoadBadge, wrapWeakPersistent(this))); 66 loadImage(executionContext, notificationData.badge, WTF::bind(&NotificationR esourcesLoader::didLoadBadge, wrapWeakPersistent(this)));
60 67
61 m_actionIcons.resize(numActions); 68 m_actionIcons.resize(numActions);
62 for (size_t i = 0; i < numActions; i++) 69 for (size_t i = 0; i < numActions; i++)
63 loadImage(executionContext, notificationData.actions[i].icon, WTF::bind( &NotificationResourcesLoader::didLoadActionIcon, wrapWeakPersistent(this), i)); 70 loadImage(executionContext, notificationData.actions[i].icon, WTF::bind( &NotificationResourcesLoader::didLoadActionIcon, wrapWeakPersistent(this), i));
64 } 71 }
65 72
66 std::unique_ptr<WebNotificationResources> NotificationResourcesLoader::getResour ces() const 73 std::unique_ptr<WebNotificationResources> NotificationResourcesLoader::getResour ces() const
67 { 74 {
68 std::unique_ptr<WebNotificationResources> resources(new WebNotificationResou rces()); 75 std::unique_ptr<WebNotificationResources> resources(new WebNotificationResou rces());
76 resources->image = m_image;
69 resources->icon = m_icon; 77 resources->icon = m_icon;
70 resources->badge = m_badge; 78 resources->badge = m_badge;
71 resources->actionIcons = m_actionIcons; 79 resources->actionIcons = m_actionIcons;
72 return resources; 80 return resources;
73 } 81 }
74 82
75 void NotificationResourcesLoader::stop() 83 void NotificationResourcesLoader::stop()
76 { 84 {
77 for (auto imageLoader : m_imageLoaders) 85 for (auto imageLoader : m_imageLoaders)
78 imageLoader->stop(); 86 imageLoader->stop();
79 } 87 }
80 88
81 DEFINE_TRACE(NotificationResourcesLoader) 89 DEFINE_TRACE(NotificationResourcesLoader)
82 { 90 {
83 visitor->trace(m_imageLoaders); 91 visitor->trace(m_imageLoaders);
84 } 92 }
85 93
86 void NotificationResourcesLoader::loadImage(ExecutionContext* executionContext, const KURL& url, std::unique_ptr<NotificationImageLoader::ImageCallback> imageCa llback) 94 void NotificationResourcesLoader::loadImage(ExecutionContext* executionContext, const KURL& url, std::unique_ptr<NotificationImageLoader::ImageCallback> imageCa llback)
87 { 95 {
88 if (url.isNull() || url.isEmpty() || !url.isValid()) { 96 if (url.isNull() || url.isEmpty() || !url.isValid()) {
89 didFinishRequest(); 97 didFinishRequest();
90 return; 98 return;
91 } 99 }
92 100
93 NotificationImageLoader* imageLoader = new NotificationImageLoader(); 101 NotificationImageLoader* imageLoader = new NotificationImageLoader();
94 m_imageLoaders.append(imageLoader); 102 m_imageLoaders.append(imageLoader);
95 imageLoader->start(executionContext, url, std::move(imageCallback)); 103 imageLoader->start(executionContext, url, std::move(imageCallback));
96 } 104 }
97 105
106 void NotificationResourcesLoader::didLoadImage(const SkBitmap& image)
107 {
108 m_image = scaleDownIfNeeded(image, kWebNotificationMaxImageWidthPx, kWebNoti ficationMaxImageHeightPx);
109 didFinishRequest();
110 }
111
98 void NotificationResourcesLoader::didLoadIcon(const SkBitmap& image) 112 void NotificationResourcesLoader::didLoadIcon(const SkBitmap& image)
99 { 113 {
100 m_icon = scaleDownIfNeeded(image, kWebNotificationMaxIconSizePx); 114 m_icon = scaleDownIfNeeded(image, kWebNotificationMaxIconSizePx, kWebNotific ationMaxIconSizePx);
101 didFinishRequest(); 115 didFinishRequest();
102 } 116 }
103 117
104 void NotificationResourcesLoader::didLoadBadge(const SkBitmap& image) 118 void NotificationResourcesLoader::didLoadBadge(const SkBitmap& image)
105 { 119 {
106 m_badge = scaleDownIfNeeded(image, kWebNotificationMaxBadgeSizePx); 120 m_badge = scaleDownIfNeeded(image, kWebNotificationMaxBadgeSizePx, kWebNotif icationMaxBadgeSizePx);
107 didFinishRequest(); 121 didFinishRequest();
108 } 122 }
109 123
110 void NotificationResourcesLoader::didLoadActionIcon(size_t actionIndex, const Sk Bitmap& image) 124 void NotificationResourcesLoader::didLoadActionIcon(size_t actionIndex, const Sk Bitmap& image)
111 { 125 {
112 DCHECK_LT(actionIndex, m_actionIcons.size()); 126 DCHECK_LT(actionIndex, m_actionIcons.size());
113 127
114 m_actionIcons[actionIndex] = scaleDownIfNeeded(image, kWebNotificationMaxAct ionIconSizePx); 128 m_actionIcons[actionIndex] = scaleDownIfNeeded(image, kWebNotificationMaxAct ionIconSizePx, kWebNotificationMaxActionIconSizePx);
115 didFinishRequest(); 129 didFinishRequest();
116 } 130 }
117 131
118 void NotificationResourcesLoader::didFinishRequest() 132 void NotificationResourcesLoader::didFinishRequest()
119 { 133 {
120 DCHECK_GT(m_pendingRequestCount, 0); 134 DCHECK_GT(m_pendingRequestCount, 0);
121 m_pendingRequestCount--; 135 m_pendingRequestCount--;
122 if (!m_pendingRequestCount) { 136 if (!m_pendingRequestCount) {
123 stop(); 137 stop();
124 (*m_completionCallback)(this); 138 (*m_completionCallback)(this);
125 // The |this| pointer may have been deleted now. 139 // The |this| pointer may have been deleted now.
126 } 140 }
127 } 141 }
128 142
129 } // namespace blink 143 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698