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

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

Issue 2540763002: Notifications: Split up image loading histograms by image type (Closed)
Patch Set: Use histogram_suffixes Created 4 years 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"
10 #include "public/platform/modules/notifications/WebNotificationData.h" 9 #include "public/platform/modules/notifications/WebNotificationData.h"
11 #include "public/platform/modules/notifications/WebNotificationResources.h" 10 #include "public/platform/modules/notifications/WebNotificationResources.h"
12 #include "skia/ext/image_operations.h"
13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "wtf/CurrentTime.h" 11 #include "wtf/CurrentTime.h"
15 #include "wtf/Threading.h" 12 #include "wtf/Threading.h"
16 #include <cmath> 13 #include <cmath>
17 14
18 namespace blink { 15 namespace blink {
19 16
20 namespace {
21
22 // Scales down |image| to fit within |maxWidthPx|x|maxHeightPx| if it is larger
23 // and returns the result. Otherwise does nothing and returns |image| unchanged.
24 // TODO(mvanouwerkerk): Explore doing the scaling on a background thread.
25 SkBitmap scaleDownIfNeeded(const SkBitmap& image,
26 int maxWidthPx,
27 int maxHeightPx) {
28 if (image.width() > maxWidthPx || image.height() > maxHeightPx) {
29 double scale = std::min(static_cast<double>(maxWidthPx) / image.width(),
30 static_cast<double>(maxHeightPx) / image.height());
31 DEFINE_THREAD_SAFE_STATIC_LOCAL(
32 CustomCountHistogram, scaleTimeHistogram,
33 new CustomCountHistogram("Notifications.Icon.ScaleDownTime", 1,
34 1000 * 10 /* 10 seconds max */,
35 50 /* buckets */));
36 double startTime = monotonicallyIncreasingTimeMS();
37 // TODO(peter): Try using RESIZE_BETTER for large images.
38 SkBitmap scaledImage =
39 skia::ImageOperations::Resize(image, skia::ImageOperations::RESIZE_BEST,
40 std::lround(scale * image.width()),
41 std::lround(scale * image.height()));
42 scaleTimeHistogram.count(monotonicallyIncreasingTimeMS() - startTime);
43 return scaledImage;
44 }
45 return image;
46 }
47
48 } // namespace
49
50 NotificationResourcesLoader::NotificationResourcesLoader( 17 NotificationResourcesLoader::NotificationResourcesLoader(
51 std::unique_ptr<CompletionCallback> completionCallback) 18 std::unique_ptr<CompletionCallback> completionCallback)
52 : m_started(false), 19 : m_started(false),
53 m_completionCallback(std::move(completionCallback)), 20 m_completionCallback(std::move(completionCallback)),
54 m_pendingRequestCount(0) { 21 m_pendingRequestCount(0) {
55 ThreadState::current()->registerPreFinalizer(this); 22 ThreadState::current()->registerPreFinalizer(this);
56 DCHECK(m_completionCallback); 23 DCHECK(m_completionCallback);
57 } 24 }
58 25
59 NotificationResourcesLoader::~NotificationResourcesLoader() {} 26 NotificationResourcesLoader::~NotificationResourcesLoader() {}
60 27
61 void NotificationResourcesLoader::start( 28 void NotificationResourcesLoader::start(
62 ExecutionContext* executionContext, 29 ExecutionContext* executionContext,
63 const WebNotificationData& notificationData) { 30 const WebNotificationData& notificationData) {
64 DCHECK(!m_started); 31 DCHECK(!m_started);
65 m_started = true; 32 m_started = true;
66 33
67 size_t numActions = notificationData.actions.size(); 34 size_t numActions = notificationData.actions.size();
68 m_pendingRequestCount = 3 /* image, icon, badge */ + numActions; 35 m_pendingRequestCount = 3 /* image, icon, badge */ + numActions;
69 36
70 // TODO(johnme): ensure image is not loaded when it will not be used. 37 // TODO(johnme): ensure image is not loaded when it will not be used.
71 // TODO(mvanouwerkerk): ensure no badge is loaded when it will not be used. 38 // TODO(mvanouwerkerk): ensure no badge is loaded when it will not be used.
72 loadImage(executionContext, notificationData.image, 39 loadImage(executionContext, NotificationImageLoader::Type::Image,
40 notificationData.image,
73 WTF::bind(&NotificationResourcesLoader::didLoadImage, 41 WTF::bind(&NotificationResourcesLoader::didLoadImage,
74 wrapWeakPersistent(this))); 42 wrapWeakPersistent(this)));
75 loadImage(executionContext, notificationData.icon, 43 loadImage(executionContext, NotificationImageLoader::Type::Icon,
44 notificationData.icon,
76 WTF::bind(&NotificationResourcesLoader::didLoadIcon, 45 WTF::bind(&NotificationResourcesLoader::didLoadIcon,
77 wrapWeakPersistent(this))); 46 wrapWeakPersistent(this)));
78 loadImage(executionContext, notificationData.badge, 47 loadImage(executionContext, NotificationImageLoader::Type::Badge,
48 notificationData.badge,
79 WTF::bind(&NotificationResourcesLoader::didLoadBadge, 49 WTF::bind(&NotificationResourcesLoader::didLoadBadge,
80 wrapWeakPersistent(this))); 50 wrapWeakPersistent(this)));
81 51
82 m_actionIcons.resize(numActions); 52 m_actionIcons.resize(numActions);
83 for (size_t i = 0; i < numActions; i++) 53 for (size_t i = 0; i < numActions; i++)
84 loadImage(executionContext, notificationData.actions[i].icon, 54 loadImage(executionContext, NotificationImageLoader::Type::ActionIcon,
55 notificationData.actions[i].icon,
85 WTF::bind(&NotificationResourcesLoader::didLoadActionIcon, 56 WTF::bind(&NotificationResourcesLoader::didLoadActionIcon,
86 wrapWeakPersistent(this), i)); 57 wrapWeakPersistent(this), i));
87 } 58 }
88 59
89 std::unique_ptr<WebNotificationResources> 60 std::unique_ptr<WebNotificationResources>
90 NotificationResourcesLoader::getResources() const { 61 NotificationResourcesLoader::getResources() const {
91 std::unique_ptr<WebNotificationResources> resources( 62 std::unique_ptr<WebNotificationResources> resources(
92 new WebNotificationResources()); 63 new WebNotificationResources());
93 resources->image = m_image; 64 resources->image = m_image;
94 resources->icon = m_icon; 65 resources->icon = m_icon;
95 resources->badge = m_badge; 66 resources->badge = m_badge;
96 resources->actionIcons = m_actionIcons; 67 resources->actionIcons = m_actionIcons;
97 return resources; 68 return resources;
98 } 69 }
99 70
100 void NotificationResourcesLoader::stop() { 71 void NotificationResourcesLoader::stop() {
101 for (auto imageLoader : m_imageLoaders) 72 for (auto imageLoader : m_imageLoaders)
102 imageLoader->stop(); 73 imageLoader->stop();
103 } 74 }
104 75
105 DEFINE_TRACE(NotificationResourcesLoader) { 76 DEFINE_TRACE(NotificationResourcesLoader) {
106 visitor->trace(m_imageLoaders); 77 visitor->trace(m_imageLoaders);
107 } 78 }
108 79
109 void NotificationResourcesLoader::loadImage( 80 void NotificationResourcesLoader::loadImage(
110 ExecutionContext* executionContext, 81 ExecutionContext* executionContext,
82 NotificationImageLoader::Type type,
111 const KURL& url, 83 const KURL& url,
112 std::unique_ptr<NotificationImageLoader::ImageCallback> imageCallback) { 84 std::unique_ptr<NotificationImageLoader::ImageCallback> imageCallback) {
113 if (url.isNull() || url.isEmpty() || !url.isValid()) { 85 if (url.isNull() || url.isEmpty() || !url.isValid()) {
114 didFinishRequest(); 86 didFinishRequest();
115 return; 87 return;
116 } 88 }
117 89
118 NotificationImageLoader* imageLoader = new NotificationImageLoader(); 90 NotificationImageLoader* imageLoader = new NotificationImageLoader(type);
119 m_imageLoaders.append(imageLoader); 91 m_imageLoaders.append(imageLoader);
120 imageLoader->start(executionContext, url, std::move(imageCallback)); 92 imageLoader->start(executionContext, url, std::move(imageCallback));
121 } 93 }
122 94
123 void NotificationResourcesLoader::didLoadImage(const SkBitmap& image) { 95 void NotificationResourcesLoader::didLoadImage(const SkBitmap& image) {
124 m_image = scaleDownIfNeeded(image, kWebNotificationMaxImageWidthPx, 96 m_image = NotificationImageLoader::scaleDownIfNeeded(
125 kWebNotificationMaxImageHeightPx); 97 image, NotificationImageLoader::Type::Image);
126 didFinishRequest(); 98 didFinishRequest();
127 } 99 }
128 100
129 void NotificationResourcesLoader::didLoadIcon(const SkBitmap& image) { 101 void NotificationResourcesLoader::didLoadIcon(const SkBitmap& image) {
130 m_icon = scaleDownIfNeeded(image, kWebNotificationMaxIconSizePx, 102 m_icon = NotificationImageLoader::scaleDownIfNeeded(
131 kWebNotificationMaxIconSizePx); 103 image, NotificationImageLoader::Type::Icon);
132 didFinishRequest(); 104 didFinishRequest();
133 } 105 }
134 106
135 void NotificationResourcesLoader::didLoadBadge(const SkBitmap& image) { 107 void NotificationResourcesLoader::didLoadBadge(const SkBitmap& image) {
136 m_badge = scaleDownIfNeeded(image, kWebNotificationMaxBadgeSizePx, 108 m_badge = NotificationImageLoader::scaleDownIfNeeded(
137 kWebNotificationMaxBadgeSizePx); 109 image, NotificationImageLoader::Type::Badge);
138 didFinishRequest(); 110 didFinishRequest();
139 } 111 }
140 112
141 void NotificationResourcesLoader::didLoadActionIcon(size_t actionIndex, 113 void NotificationResourcesLoader::didLoadActionIcon(size_t actionIndex,
142 const SkBitmap& image) { 114 const SkBitmap& image) {
143 DCHECK_LT(actionIndex, m_actionIcons.size()); 115 DCHECK_LT(actionIndex, m_actionIcons.size());
144 116
145 m_actionIcons[actionIndex] = 117 m_actionIcons[actionIndex] = NotificationImageLoader::scaleDownIfNeeded(
146 scaleDownIfNeeded(image, kWebNotificationMaxActionIconSizePx, 118 image, NotificationImageLoader::Type::ActionIcon);
147 kWebNotificationMaxActionIconSizePx);
148 didFinishRequest(); 119 didFinishRequest();
149 } 120 }
150 121
151 void NotificationResourcesLoader::didFinishRequest() { 122 void NotificationResourcesLoader::didFinishRequest() {
152 DCHECK_GT(m_pendingRequestCount, 0); 123 DCHECK_GT(m_pendingRequestCount, 0);
153 m_pendingRequestCount--; 124 m_pendingRequestCount--;
154 if (!m_pendingRequestCount) { 125 if (!m_pendingRequestCount) {
155 stop(); 126 stop();
156 (*m_completionCallback)(this); 127 (*m_completionCallback)(this);
157 // The |this| pointer may have been deleted now. 128 // The |this| pointer may have been deleted now.
158 } 129 }
159 } 130 }
160 131
161 } // namespace blink 132 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/notifications/NotificationResourcesLoader.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698