| OLD | NEW | 
|    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/NotificationImageLoader.h" |    5 #include "modules/notifications/NotificationImageLoader.h" | 
|    6  |    6  | 
|    7 #include "core/dom/ExecutionContext.h" |    7 #include "core/dom/ExecutionContext.h" | 
|    8 #include "core/fetch/ResourceLoaderOptions.h" |    8 #include "core/fetch/ResourceLoaderOptions.h" | 
|    9 #include "platform/Histogram.h" |    9 #include "platform/Histogram.h" | 
|   10 #include "platform/image-decoders/ImageDecoder.h" |   10 #include "platform/image-decoders/ImageDecoder.h" | 
|   11 #include "platform/image-decoders/ImageFrame.h" |   11 #include "platform/image-decoders/ImageFrame.h" | 
|   12 #include "platform/network/ResourceError.h" |   12 #include "platform/network/ResourceError.h" | 
|   13 #include "platform/network/ResourceLoadPriority.h" |   13 #include "platform/network/ResourceLoadPriority.h" | 
|   14 #include "platform/network/ResourceRequest.h" |   14 #include "platform/network/ResourceRequest.h" | 
|   15 #include "platform/weborigin/KURL.h" |   15 #include "platform/weborigin/KURL.h" | 
|   16 #include "public/platform/WebURLRequest.h" |   16 #include "public/platform/WebURLRequest.h" | 
|   17 #include "third_party/skia/include/core/SkBitmap.h" |   17 #include "public/platform/modules/notifications/WebNotificationConstants.h" | 
 |   18 #include "skia/ext/image_operations.h" | 
|   18 #include "wtf/CurrentTime.h" |   19 #include "wtf/CurrentTime.h" | 
|   19 #include "wtf/Threading.h" |   20 #include "wtf/Threading.h" | 
|   20 #include <memory> |   21 #include <memory> | 
|   21  |   22  | 
 |   23 #define NOTIFICATION_PER_TYPE_HISTOGRAM_COUNTS(metric, type_name, value, max) \ | 
 |   24   case NotificationImageLoader::Type::type_name: {                            \ | 
 |   25     DEFINE_THREAD_SAFE_STATIC_LOCAL(                                          \ | 
 |   26         CustomCountHistogram, metric##type_name##Histogram,                   \ | 
 |   27         new CustomCountHistogram("Notifications." #metric "." #type_name,     \ | 
 |   28                                  1 /* min */, max, 50 /* buckets */));        \ | 
 |   29     metric##type_name##Histogram.count(value);                                \ | 
 |   30     break;                                                                    \ | 
 |   31   } | 
 |   32  | 
 |   33 #define NOTIFICATION_HISTOGRAM_COUNTS(metric, type, value, max)            \ | 
 |   34   switch (type) {                                                          \ | 
 |   35     NOTIFICATION_PER_TYPE_HISTOGRAM_COUNTS(metric, Image, value, max)      \ | 
 |   36     NOTIFICATION_PER_TYPE_HISTOGRAM_COUNTS(metric, Icon, value, max)       \ | 
 |   37     NOTIFICATION_PER_TYPE_HISTOGRAM_COUNTS(metric, Badge, value, max)      \ | 
 |   38     NOTIFICATION_PER_TYPE_HISTOGRAM_COUNTS(metric, ActionIcon, value, max) \ | 
 |   39   } | 
 |   40  | 
|   22 namespace { |   41 namespace { | 
|   23  |   42  | 
|   24 // 99.9% of all images were fetched successfully in 90 seconds. |   43 // 99.9% of all images were fetched successfully in 90 seconds. | 
|   25 const unsigned long kImageFetchTimeoutInMs = 90000; |   44 const unsigned long kImageFetchTimeoutInMs = 90000; | 
|   26  |   45  | 
|   27 }  // namespace |   46 }  // namespace | 
|   28  |   47  | 
|   29 namespace blink { |   48 namespace blink { | 
|   30  |   49  | 
|   31 NotificationImageLoader::NotificationImageLoader() |   50 NotificationImageLoader::NotificationImageLoader(Type type) | 
|   32     : m_stopped(false), m_startTime(0.0) {} |   51     : m_type(type), m_stopped(false), m_startTime(0.0) {} | 
|   33  |   52  | 
|   34 NotificationImageLoader::~NotificationImageLoader() {} |   53 NotificationImageLoader::~NotificationImageLoader() {} | 
|   35  |   54  | 
 |   55 // static | 
 |   56 SkBitmap NotificationImageLoader::scaleDownIfNeeded(const SkBitmap& image, | 
 |   57                                                     Type type) { | 
 |   58   int maxWidthPx = 0, maxHeightPx = 0; | 
 |   59   switch (type) { | 
 |   60     case Type::Image: | 
 |   61       maxWidthPx = kWebNotificationMaxImageWidthPx; | 
 |   62       maxHeightPx = kWebNotificationMaxImageHeightPx; | 
 |   63       break; | 
 |   64     case Type::Icon: | 
 |   65       maxWidthPx = kWebNotificationMaxIconSizePx; | 
 |   66       maxHeightPx = kWebNotificationMaxIconSizePx; | 
 |   67       break; | 
 |   68     case Type::Badge: | 
 |   69       maxWidthPx = kWebNotificationMaxBadgeSizePx; | 
 |   70       maxHeightPx = kWebNotificationMaxBadgeSizePx; | 
 |   71       break; | 
 |   72     case Type::ActionIcon: | 
 |   73       maxWidthPx = kWebNotificationMaxActionIconSizePx; | 
 |   74       maxHeightPx = kWebNotificationMaxActionIconSizePx; | 
 |   75       break; | 
 |   76   } | 
 |   77   DCHECK_GT(maxWidthPx, 0); | 
 |   78   DCHECK_GT(maxHeightPx, 0); | 
 |   79   // TODO(peter): Explore doing the scaling on a background thread. | 
 |   80   if (image.width() > maxWidthPx || image.height() > maxHeightPx) { | 
 |   81     double scale = std::min(static_cast<double>(maxWidthPx) / image.width(), | 
 |   82                             static_cast<double>(maxHeightPx) / image.height()); | 
 |   83     double startTime = monotonicallyIncreasingTimeMS(); | 
 |   84     // TODO(peter): Try using RESIZE_BETTER for large images. | 
 |   85     SkBitmap scaledImage = | 
 |   86         skia::ImageOperations::Resize(image, skia::ImageOperations::RESIZE_BEST, | 
 |   87                                       std::lround(scale * image.width()), | 
 |   88                                       std::lround(scale * image.height())); | 
 |   89     NOTIFICATION_HISTOGRAM_COUNTS(LoadScaleDownTime, type, | 
 |   90                                   monotonicallyIncreasingTimeMS() - startTime, | 
 |   91                                   1000 * 10 /* 10 seconds max */); | 
 |   92     return scaledImage; | 
 |   93   } | 
 |   94   return image; | 
 |   95 } | 
 |   96  | 
|   36 void NotificationImageLoader::start( |   97 void NotificationImageLoader::start( | 
|   37     ExecutionContext* executionContext, |   98     ExecutionContext* executionContext, | 
|   38     const KURL& url, |   99     const KURL& url, | 
|   39     std::unique_ptr<ImageCallback> imageCallback) { |  100     std::unique_ptr<ImageCallback> imageCallback) { | 
|   40   DCHECK(!m_stopped); |  101   DCHECK(!m_stopped); | 
|   41  |  102  | 
|   42   m_startTime = monotonicallyIncreasingTimeMS(); |  103   m_startTime = monotonicallyIncreasingTimeMS(); | 
|   43   m_imageCallback = std::move(imageCallback); |  104   m_imageCallback = std::move(imageCallback); | 
|   44  |  105  | 
|   45   ThreadableLoaderOptions threadableLoaderOptions; |  106   ThreadableLoaderOptions threadableLoaderOptions; | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   82   m_data->append(data, length); |  143   m_data->append(data, length); | 
|   83 } |  144 } | 
|   84  |  145  | 
|   85 void NotificationImageLoader::didFinishLoading(unsigned long resourceIdentifier, |  146 void NotificationImageLoader::didFinishLoading(unsigned long resourceIdentifier, | 
|   86                                                double finishTime) { |  147                                                double finishTime) { | 
|   87   // If this has been stopped it is not desirable to trigger further work, |  148   // If this has been stopped it is not desirable to trigger further work, | 
|   88   // there is a shutdown of some sort in progress. |  149   // there is a shutdown of some sort in progress. | 
|   89   if (m_stopped) |  150   if (m_stopped) | 
|   90     return; |  151     return; | 
|   91  |  152  | 
|   92   DEFINE_THREAD_SAFE_STATIC_LOCAL( |  153   NOTIFICATION_HISTOGRAM_COUNTS(LoadFinishTime, m_type, | 
|   93       CustomCountHistogram, finishedTimeHistogram, |  154                                 monotonicallyIncreasingTimeMS() - m_startTime, | 
|   94       new CustomCountHistogram("Notifications.Icon.LoadFinishTime", 1, |  155                                 1000 * 60 * 60 /* 1 hour max */); | 
|   95                                1000 * 60 * 60 /* 1 hour max */, |  | 
|   96                                50 /* buckets */)); |  | 
|   97   finishedTimeHistogram.count(monotonicallyIncreasingTimeMS() - m_startTime); |  | 
|   98  |  156  | 
|   99   if (m_data) { |  157   if (m_data) { | 
|  100     DEFINE_THREAD_SAFE_STATIC_LOCAL( |  158     NOTIFICATION_HISTOGRAM_COUNTS(LoadFileSize, m_type, m_data->size(), | 
|  101         CustomCountHistogram, fileSizeHistogram, |  159                                   10000000 /* ~10mb max */); | 
|  102         new CustomCountHistogram("Notifications.Icon.FileSize", 1, |  | 
|  103                                  10000000 /* ~10mb max */, 50 /* buckets */)); |  | 
|  104     fileSizeHistogram.count(m_data->size()); |  | 
|  105  |  160  | 
|  106     std::unique_ptr<ImageDecoder> decoder = ImageDecoder::create( |  161     std::unique_ptr<ImageDecoder> decoder = ImageDecoder::create( | 
|  107         m_data, true /* dataComplete */, ImageDecoder::AlphaPremultiplied, |  162         m_data, true /* dataComplete */, ImageDecoder::AlphaPremultiplied, | 
|  108         ImageDecoder::ColorSpaceApplied); |  163         ImageDecoder::ColorSpaceApplied); | 
|  109     if (decoder) { |  164     if (decoder) { | 
|  110       // The |ImageFrame*| is owned by the decoder. |  165       // The |ImageFrame*| is owned by the decoder. | 
|  111       ImageFrame* imageFrame = decoder->frameBufferAtIndex(0); |  166       ImageFrame* imageFrame = decoder->frameBufferAtIndex(0); | 
|  112       if (imageFrame) { |  167       if (imageFrame) { | 
|  113         (*m_imageCallback)(imageFrame->bitmap()); |  168         (*m_imageCallback)(imageFrame->bitmap()); | 
|  114         return; |  169         return; | 
|  115       } |  170       } | 
|  116     } |  171     } | 
|  117   } |  172   } | 
|  118   runCallbackWithEmptyBitmap(); |  173   runCallbackWithEmptyBitmap(); | 
|  119 } |  174 } | 
|  120  |  175  | 
|  121 void NotificationImageLoader::didFail(const ResourceError& error) { |  176 void NotificationImageLoader::didFail(const ResourceError& error) { | 
|  122   DEFINE_THREAD_SAFE_STATIC_LOCAL( |  177   NOTIFICATION_HISTOGRAM_COUNTS(LoadFailTime, m_type, | 
|  123       CustomCountHistogram, failedTimeHistogram, |  178                                 monotonicallyIncreasingTimeMS() - m_startTime, | 
|  124       new CustomCountHistogram("Notifications.Icon.LoadFailTime", 1, |  179                                 1000 * 60 * 60 /* 1 hour max */); | 
|  125                                1000 * 60 * 60 /* 1 hour max */, |  | 
|  126                                50 /* buckets */)); |  | 
|  127   failedTimeHistogram.count(monotonicallyIncreasingTimeMS() - m_startTime); |  | 
|  128  |  180  | 
|  129   runCallbackWithEmptyBitmap(); |  181   runCallbackWithEmptyBitmap(); | 
|  130 } |  182 } | 
|  131  |  183  | 
|  132 void NotificationImageLoader::didFailRedirectCheck() { |  184 void NotificationImageLoader::didFailRedirectCheck() { | 
|  133   runCallbackWithEmptyBitmap(); |  185   runCallbackWithEmptyBitmap(); | 
|  134 } |  186 } | 
|  135  |  187  | 
|  136 void NotificationImageLoader::runCallbackWithEmptyBitmap() { |  188 void NotificationImageLoader::runCallbackWithEmptyBitmap() { | 
|  137   // If this has been stopped it is not desirable to trigger further work, |  189   // If this has been stopped it is not desirable to trigger further work, | 
|  138   // there is a shutdown of some sort in progress. |  190   // there is a shutdown of some sort in progress. | 
|  139   if (m_stopped) |  191   if (m_stopped) | 
|  140     return; |  192     return; | 
|  141  |  193  | 
|  142   (*m_imageCallback)(SkBitmap()); |  194   (*m_imageCallback)(SkBitmap()); | 
|  143 } |  195 } | 
|  144  |  196  | 
|  145 }  // namespace blink |  197 }  // namespace blink | 
| OLD | NEW |