OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "modules/notifications/NotificationResourcesLoader.h" |
| 6 |
| 7 #include "core/dom/ExecutionContext.h" |
| 8 #include "public/platform/modules/notifications/WebNotificationData.h" |
| 9 #include "public/platform/modules/notifications/WebNotificationResources.h" |
| 10 #include "skia/ext/image_operations.h" |
| 11 #include "third_party/skia/include/core/SkBitmap.h" |
| 12 |
| 13 namespace blink { |
| 14 |
| 15 namespace { |
| 16 |
| 17 // TODO(mvanouwerkerk): Get icon dimensions from the embedder. |
| 18 |
| 19 // The maximum reasonable notification icon size, scaled from dip units to |
| 20 // pixels using the largest supported scaling factor. |
| 21 static const int kMaxIconSizePx = 320; // 80 dip * 4 |
| 22 |
| 23 // The maximum reasonable badge size, scaled from dip units to pixels using the |
| 24 // largest supported scaling factor. |
| 25 static const int kMaxBadgeSizePx = 96; // 24 dip * 4 |
| 26 |
| 27 // The maximum reasonable action icon size, scaled from dip units to pixels |
| 28 // using the largest supported scaling factor. |
| 29 static const int kMaxActionIconSizePx = 128; // 32 dip * 4 |
| 30 |
| 31 // Scales down |image| to fit within |maxSizePx| if its width or height is |
| 32 // larger than |maxSizePx| and returns the result. Otherwise does nothing and |
| 33 // returns |image| unchanged. |
| 34 // TODO(mvanouwerkerk): Explore doing the scaling on a background thread. |
| 35 SkBitmap scaleDownIfNeeded(const SkBitmap& image, int maxSizePx) |
| 36 { |
| 37 if (image.width() > maxSizePx || image.height() > maxSizePx) { |
| 38 return skia::ImageOperations::Resize(image, |
| 39 skia::ImageOperations::RESIZE_BEST, |
| 40 std::min(image.width(), maxSizePx), |
| 41 std::min(image.height(), maxSizePx)); |
| 42 } |
| 43 return image; |
| 44 } |
| 45 |
| 46 } // namespace |
| 47 |
| 48 NotificationResourcesLoader::NotificationResourcesLoader( |
| 49 ExecutionContext* executionContext, |
| 50 PassOwnPtr<CompletionCallback> completionCallback) |
| 51 : ContextLifecycleObserver(executionContext) |
| 52 , m_started(false) |
| 53 , m_completionCallback(completionCallback) |
| 54 , m_pendingRequestCount(0) |
| 55 { |
| 56 LOG(WARNING) << __FUNCTION__; |
| 57 ThreadState::current()->registerPreFinalizer(this); |
| 58 DCHECK(m_completionCallback); |
| 59 } |
| 60 |
| 61 NotificationResourcesLoader::~NotificationResourcesLoader() |
| 62 { |
| 63 LOG(WARNING) << __FUNCTION__; |
| 64 } |
| 65 |
| 66 void NotificationResourcesLoader::start(const WebNotificationData& notificationD
ata) |
| 67 { |
| 68 LOG(WARNING) << __FUNCTION__; |
| 69 DCHECK(!m_started); |
| 70 m_started = true; |
| 71 |
| 72 size_t numActions = notificationData.actions.size(); |
| 73 m_pendingRequestCount = 2 /* icon and badge */ + numActions; |
| 74 |
| 75 loadImage(notificationData.icon, |
| 76 bind<const SkBitmap&>(&NotificationResourcesLoader::didLoadIcon, |
| 77 WeakPersistentThisPointer<NotificationResourcesLoader>(this))); |
| 78 loadImage(notificationData.badge, |
| 79 bind<const SkBitmap&>(&NotificationResourcesLoader::didLoadBadge, |
| 80 WeakPersistentThisPointer<NotificationResourcesLoader>(this))); |
| 81 |
| 82 m_actionIcons.resize(numActions); |
| 83 for (size_t i = 0; i < numActions; i++) { |
| 84 loadImage(notificationData.actions[i].icon, |
| 85 bind<const SkBitmap&>( |
| 86 &NotificationResourcesLoader::didLoadActionIcon, |
| 87 WeakPersistentThisPointer<NotificationResourcesLoader>(this), |
| 88 i)); |
| 89 } |
| 90 } |
| 91 |
| 92 std::unique_ptr<WebNotificationResources> |
| 93 NotificationResourcesLoader::getResources() const |
| 94 { |
| 95 LOG(WARNING) << __FUNCTION__; |
| 96 std::unique_ptr<WebNotificationResources> resources(new WebNotificationResou
rces()); |
| 97 resources->icon = m_icon; |
| 98 resources->badge = m_badge; |
| 99 resources->actionIcons = m_actionIcons; |
| 100 return resources; |
| 101 } |
| 102 |
| 103 void NotificationResourcesLoader::contextDestroyed() |
| 104 { |
| 105 LOG(WARNING) << __FUNCTION__; |
| 106 stop(); |
| 107 } |
| 108 |
| 109 void NotificationResourcesLoader::stop() |
| 110 { |
| 111 LOG(WARNING) << __FUNCTION__; |
| 112 for (auto imageLoader : m_imageLoaders) |
| 113 imageLoader->stop(); |
| 114 } |
| 115 |
| 116 DEFINE_TRACE(NotificationResourcesLoader) |
| 117 { |
| 118 LOG(WARNING) << __FUNCTION__; |
| 119 visitor->trace(m_imageLoaders); |
| 120 ContextLifecycleObserver::trace(visitor); |
| 121 } |
| 122 |
| 123 void NotificationResourcesLoader::loadImage( |
| 124 const KURL& url, |
| 125 PassOwnPtr<NotificationImageLoader::ImageCallback> imageCallback) |
| 126 { |
| 127 if (url.isNull() || url.isEmpty() || !url.isValid()) { |
| 128 didFinishRequest(); |
| 129 return; |
| 130 } |
| 131 |
| 132 NotificationImageLoader* imageLoader = new NotificationImageLoader(); |
| 133 m_imageLoaders.append(imageLoader); |
| 134 imageLoader->start(getExecutionContext(), url, imageCallback); |
| 135 } |
| 136 |
| 137 void NotificationResourcesLoader::didLoadIcon(const SkBitmap& image) |
| 138 { |
| 139 m_icon = scaleDownIfNeeded(image, kMaxIconSizePx); |
| 140 didFinishRequest(); |
| 141 } |
| 142 |
| 143 void NotificationResourcesLoader::didLoadBadge(const SkBitmap& image) |
| 144 { |
| 145 m_badge = scaleDownIfNeeded(image, kMaxBadgeSizePx); |
| 146 didFinishRequest(); |
| 147 } |
| 148 |
| 149 void NotificationResourcesLoader::didLoadActionIcon(size_t actionIndex, const Sk
Bitmap& image) |
| 150 { |
| 151 DCHECK_LT(actionIndex, m_actionIcons.size()); |
| 152 |
| 153 m_actionIcons[actionIndex] = scaleDownIfNeeded(image, kMaxActionIconSizePx); |
| 154 didFinishRequest(); |
| 155 } |
| 156 |
| 157 void NotificationResourcesLoader::didFinishRequest() |
| 158 { |
| 159 LOG(WARNING) << __FUNCTION__ << " m_pendingRequestCount: " << m_pendingReque
stCount; |
| 160 DCHECK_GT(m_pendingRequestCount, 0); |
| 161 m_pendingRequestCount--; |
| 162 if (!m_pendingRequestCount) { |
| 163 stop(); |
| 164 (*m_completionCallback)(this); |
| 165 // The |this| pointer may have been deleted now. |
| 166 } |
| 167 } |
| 168 |
| 169 } // namespace blink |
OLD | NEW |