| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 "content/child/notifications/notification_image_loader.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/location.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/metrics/histogram_macros.h" | |
| 11 #include "base/single_thread_task_runner.h" | |
| 12 #include "content/child/image_decoder.h" | |
| 13 #include "third_party/WebKit/public/platform/Platform.h" | |
| 14 #include "third_party/WebKit/public/platform/WebURL.h" | |
| 15 #include "third_party/WebKit/public/platform/WebURLLoader.h" | |
| 16 #include "third_party/WebKit/public/platform/WebURLRequest.h" | |
| 17 #include "third_party/skia/include/core/SkBitmap.h" | |
| 18 | |
| 19 using blink::WebURL; | |
| 20 using blink::WebURLError; | |
| 21 using blink::WebURLLoader; | |
| 22 using blink::WebURLRequest; | |
| 23 | |
| 24 namespace content { | |
| 25 | |
| 26 NotificationImageLoader::NotificationImageLoader( | |
| 27 const ImageLoadCompletedCallback& callback, | |
| 28 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, | |
| 29 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) | |
| 30 : callback_(callback), | |
| 31 worker_task_runner_(worker_task_runner), | |
| 32 main_task_runner_(main_task_runner), | |
| 33 completed_(false) {} | |
| 34 | |
| 35 NotificationImageLoader::~NotificationImageLoader() { | |
| 36 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
| 37 } | |
| 38 | |
| 39 void NotificationImageLoader::StartOnMainThread(const GURL& image_url) { | |
| 40 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
| 41 DCHECK(!url_loader_); | |
| 42 | |
| 43 start_time_ = base::TimeTicks::Now(); | |
| 44 | |
| 45 WebURL image_web_url(image_url); | |
| 46 WebURLRequest request(image_web_url); | |
| 47 request.setRequestContext(WebURLRequest::RequestContextImage); | |
| 48 | |
| 49 url_loader_.reset(blink::Platform::current()->createURLLoader()); | |
| 50 url_loader_->loadAsynchronously(request, this); | |
| 51 } | |
| 52 | |
| 53 void NotificationImageLoader::didReceiveData(WebURLLoader* loader, | |
| 54 const char* data, | |
| 55 int data_length, | |
| 56 int encoded_data_length) { | |
| 57 DCHECK(!completed_); | |
| 58 DCHECK_GT(data_length, 0); | |
| 59 | |
| 60 buffer_.insert(buffer_.end(), data, data + data_length); | |
| 61 } | |
| 62 | |
| 63 void NotificationImageLoader::didFinishLoading( | |
| 64 WebURLLoader* loader, | |
| 65 double finish_time, | |
| 66 int64_t total_encoded_data_length) { | |
| 67 DCHECK(!completed_); | |
| 68 | |
| 69 UMA_HISTOGRAM_LONG_TIMES("Notifications.Icon.LoadFinishTime", | |
| 70 base::TimeTicks::Now() - start_time_); | |
| 71 | |
| 72 RunCallbackOnWorkerThread(); | |
| 73 } | |
| 74 | |
| 75 void NotificationImageLoader::didFail(WebURLLoader* loader, | |
| 76 const WebURLError& error) { | |
| 77 if (completed_) | |
| 78 return; | |
| 79 | |
| 80 UMA_HISTOGRAM_LONG_TIMES("Notifications.Icon.LoadFailTime", | |
| 81 base::TimeTicks::Now() - start_time_); | |
| 82 | |
| 83 RunCallbackOnWorkerThread(); | |
| 84 } | |
| 85 | |
| 86 void NotificationImageLoader::RunCallbackOnWorkerThread() { | |
| 87 url_loader_.reset(); | |
| 88 | |
| 89 completed_ = true; | |
| 90 SkBitmap icon = GetDecodedImage(); | |
| 91 | |
| 92 if (worker_task_runner_->BelongsToCurrentThread()) { | |
| 93 callback_.Run(icon); | |
| 94 } else { | |
| 95 worker_task_runner_->PostTask(FROM_HERE, base::Bind(callback_, icon)); | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 SkBitmap NotificationImageLoader::GetDecodedImage() const { | |
| 100 DCHECK(completed_); | |
| 101 | |
| 102 UMA_HISTOGRAM_CUSTOM_COUNTS("Notifications.Icon.FileSize", buffer_.size(), 1, | |
| 103 10000000 /* ~10mb */, 50); | |
| 104 | |
| 105 if (buffer_.empty()) | |
| 106 return SkBitmap(); | |
| 107 | |
| 108 ImageDecoder decoder; | |
| 109 return decoder.Decode(&buffer_[0], buffer_.size()); | |
| 110 } | |
| 111 | |
| 112 void NotificationImageLoader::DeleteOnCorrectThread() const { | |
| 113 if (!main_task_runner_->BelongsToCurrentThread()) { | |
| 114 main_task_runner_->DeleteSoon(FROM_HERE, this); | |
| 115 return; | |
| 116 } | |
| 117 | |
| 118 delete this; | |
| 119 } | |
| 120 | |
| 121 } // namespace content | |
| OLD | NEW |