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

Side by Side Diff: chrome/browser/image_decoder.cc

Issue 1844103004: Convert the utility process image decoder into a Mojo service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/image_decoder.h" 5 #include "chrome/browser/image_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/thread_task_runner_handle.h" 8 #include "base/thread_task_runner_handle.h"
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/common/chrome_utility_messages.h" 11 #include "chrome/common/chrome_utility_messages.h"
12 #include "chrome/common/image_decoder.mojom.h"
12 #include "chrome/grit/generated_resources.h" 13 #include "chrome/grit/generated_resources.h"
13 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/utility_process_host.h" 15 #include "content/public/browser/utility_process_host.h"
16 #include "content/public/common/service_registry.h"
17 #include "skia/public/type_converters.h"
15 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
16 19
17 using content::BrowserThread; 20 using content::BrowserThread;
18 using content::UtilityProcessHost; 21 using content::UtilityProcessHost;
19 22
20 namespace { 23 namespace {
21 24
22 // static, Leaky to allow access from any thread. 25 // static, Leaky to allow access from any thread.
23 base::LazyInstance<ImageDecoder>::Leaky g_decoder = LAZY_INSTANCE_INITIALIZER; 26 base::LazyInstance<ImageDecoder>::Leaky g_decoder = LAZY_INSTANCE_INITIALIZER;
24 27
25 // How long to wait after the last request has been received before ending 28 // How long to wait after the last request has been received before ending
26 // batch mode. 29 // batch mode.
27 const int kBatchModeTimeoutSeconds = 5; 30 const int kBatchModeTimeoutSeconds = 5;
28 31
32 void OnDecodeImageDone(
33 base::Callback<void(int)> fail_callback,
34 base::Callback<void(const SkBitmap&, int)> success_callback,
35 int request_id, skia::mojom::BitmapPtr image) {
36 DCHECK_CURRENTLY_ON(BrowserThread::IO);
37 if (image) {
38 SkBitmap bitmap = image.To<SkBitmap>();
39 if (!bitmap.empty()) {
40 success_callback.Run(bitmap, request_id);
41 return;
42 }
43 }
44 fail_callback.Run(request_id);
45 }
46
29 } // namespace 47 } // namespace
30 48
31 ImageDecoder::ImageDecoder() 49 ImageDecoder::ImageDecoder()
32 : image_request_id_counter_(0) { 50 : image_request_id_counter_(0) {
33 // A single ImageDecoder instance should live for the life of the program. 51 // A single ImageDecoder instance should live for the life of the program.
34 // Explicitly add a reference so the object isn't deleted. 52 // Explicitly add a reference so the object isn't deleted.
35 AddRef(); 53 AddRef();
36 } 54 }
37 55
38 ImageDecoder::~ImageDecoder() { 56 ImageDecoder::~ImageDecoder() {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 143 }
126 144
127 if (!batch_mode_timer_) { 145 if (!batch_mode_timer_) {
128 // Created here so it will call StopBatchMode() on the right thread. 146 // Created here so it will call StopBatchMode() on the right thread.
129 batch_mode_timer_.reset(new base::DelayTimer( 147 batch_mode_timer_.reset(new base::DelayTimer(
130 FROM_HERE, base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds), this, 148 FROM_HERE, base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds), this,
131 &ImageDecoder::StopBatchMode)); 149 &ImageDecoder::StopBatchMode));
132 } 150 }
133 batch_mode_timer_->Reset(); 151 batch_mode_timer_->Reset();
134 152
135 switch (image_codec) { 153 mojom::ImageCodec mojo_codec = mojom::ImageCodec::DEFAULT;
136 #if defined(OS_CHROMEOS) 154 #if defined(OS_CHROMEOS)
137 case ROBUST_JPEG_CODEC: 155 if (image_codec == ROBUST_JPEG_CODEC)
138 utility_process_host_->Send(new ChromeUtilityMsg_RobustJPEGDecodeImage( 156 mojo_codec = mojom::ImageCodec::ROBUST_JPEG;
139 image_data, request_id)); 157 if (image_codec == ROBUST_PNG_CODEC)
140 break; 158 mojo_codec = mojom::ImageCodec::ROBUST_PNG;
141 case ROBUST_PNG_CODEC:
142 utility_process_host_->Send(new ChromeUtilityMsg_RobustPNGDecodeImage(
143 image_data, request_id));
144 break;
145 #endif // defined(OS_CHROMEOS) 159 #endif // defined(OS_CHROMEOS)
146 case DEFAULT_CODEC: 160 (*decoder_)->DecodeImage(
147 utility_process_host_->Send(new ChromeUtilityMsg_DecodeImage( 161 mojo::Array<uint8_t>::From(image_data),
148 image_data, shrink_to_fit, request_id)); 162 mojo_codec,
149 break; 163 shrink_to_fit,
150 } 164 base::Bind(&OnDecodeImageDone,
165 base::Bind(&ImageDecoder::OnDecodeImageFailed, this),
166 base::Bind(&ImageDecoder::OnDecodeImageSucceeded, this),
167 request_id));
151 } 168 }
152 169
153 void ImageDecoder::CancelImpl(ImageRequest* image_request) { 170 void ImageDecoder::CancelImpl(ImageRequest* image_request) {
154 base::AutoLock lock(map_lock_); 171 base::AutoLock lock(map_lock_);
155 for (auto it = image_request_id_map_.begin(); 172 for (auto it = image_request_id_map_.begin();
156 it != image_request_id_map_.end();) { 173 it != image_request_id_map_.end();) {
157 if (it->second == image_request) { 174 if (it->second == image_request) {
158 image_request_id_map_.erase(it++); 175 image_request_id_map_.erase(it++);
159 } else { 176 } else {
160 ++it; 177 ++it;
161 } 178 }
162 } 179 }
163 } 180 }
164 181
165 void ImageDecoder::StartBatchMode() { 182 void ImageDecoder::StartBatchMode() {
166 DCHECK_CURRENTLY_ON(BrowserThread::IO); 183 DCHECK_CURRENTLY_ON(BrowserThread::IO);
167 utility_process_host_ = 184 utility_process_host_ =
168 UtilityProcessHost::Create( 185 UtilityProcessHost::Create(
169 this, base::ThreadTaskRunnerHandle::Get().get())->AsWeakPtr(); 186 this, base::ThreadTaskRunnerHandle::Get().get())->AsWeakPtr();
170 utility_process_host_->SetName(l10n_util::GetStringUTF16( 187 utility_process_host_->SetName(l10n_util::GetStringUTF16(
171 IDS_UTILITY_PROCESS_IMAGE_DECODER_NAME)); 188 IDS_UTILITY_PROCESS_IMAGE_DECODER_NAME));
172 if (!utility_process_host_->StartBatchMode()) { 189 decoder_.reset(new mojom::ImageDecoderPtr);
173 utility_process_host_.reset(); 190 if (!utility_process_host_->StartMojoMode()) {
174 return; 191 utility_process_host_.reset();
jam 2016/03/31 17:46:33 (this already existed) should also delete utility_
Anand Mistry (off Chromium) 2016/04/01 05:35:11 Oops, yeah, this should be a delete (the reset wou
192 return;
175 } 193 }
194 content::ServiceRegistry* service_registry =
195 utility_process_host_->GetServiceRegistry();
196 service_registry->ConnectToRemoteService(mojo::GetProxy(decoder_.get()));
176 } 197 }
177 198
178 void ImageDecoder::StopBatchMode() { 199 void ImageDecoder::StopBatchMode() {
179 DCHECK_CURRENTLY_ON(BrowserThread::IO); 200 DCHECK_CURRENTLY_ON(BrowserThread::IO);
180 { 201 {
181 // Check for outstanding requests and wait for them to finish. 202 // Check for outstanding requests and wait for them to finish.
182 base::AutoLock lock(map_lock_); 203 base::AutoLock lock(map_lock_);
183 if (!image_request_id_map_.empty()) { 204 if (!image_request_id_map_.empty()) {
184 batch_mode_timer_->Reset(); 205 batch_mode_timer_->Reset();
185 return; 206 return;
186 } 207 }
187 } 208 }
188 209
189 if (utility_process_host_) { 210 if (utility_process_host_) {
190 utility_process_host_->EndBatchMode(); 211 // With Mojo, the utility process needs to be explicitly shut down by
212 // deleting the host.
213 delete utility_process_host_.get();
214 decoder_.reset();
191 utility_process_host_.reset(); 215 utility_process_host_.reset();
192 } 216 }
193 } 217 }
194 218
195 void ImageDecoder::FailAllRequests() { 219 void ImageDecoder::FailAllRequests() {
196 RequestMap requests; 220 RequestMap requests;
197 { 221 {
198 base::AutoLock lock(map_lock_); 222 base::AutoLock lock(map_lock_);
199 requests = image_request_id_map_; 223 requests = image_request_id_map_;
200 } 224 }
(...skipping 11 matching lines...) Expand all
212 void ImageDecoder::OnProcessCrashed(int exit_code) { 236 void ImageDecoder::OnProcessCrashed(int exit_code) {
213 DCHECK_CURRENTLY_ON(BrowserThread::IO); 237 DCHECK_CURRENTLY_ON(BrowserThread::IO);
214 FailAllRequests(); 238 FailAllRequests();
215 } 239 }
216 240
217 void ImageDecoder::OnProcessLaunchFailed() { 241 void ImageDecoder::OnProcessLaunchFailed() {
218 DCHECK_CURRENTLY_ON(BrowserThread::IO); 242 DCHECK_CURRENTLY_ON(BrowserThread::IO);
219 FailAllRequests(); 243 FailAllRequests();
220 } 244 }
221 245
222 bool ImageDecoder::OnMessageReceived( 246 bool ImageDecoder::OnMessageReceived(const IPC::Message& message) {
223 const IPC::Message& message) { 247 return false;
224 bool handled = true;
225 IPC_BEGIN_MESSAGE_MAP(ImageDecoder, message)
226 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded,
227 OnDecodeImageSucceeded)
228 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed,
229 OnDecodeImageFailed)
230 IPC_MESSAGE_UNHANDLED(handled = false)
231 IPC_END_MESSAGE_MAP()
232 return handled;
233 } 248 }
234 249
235 void ImageDecoder::OnDecodeImageSucceeded( 250 void ImageDecoder::OnDecodeImageSucceeded(
236 const SkBitmap& decoded_image, 251 const SkBitmap& decoded_image,
237 int request_id) { 252 int request_id) {
238 DCHECK_CURRENTLY_ON(BrowserThread::IO); 253 DCHECK_CURRENTLY_ON(BrowserThread::IO);
239 base::AutoLock lock(map_lock_); 254 base::AutoLock lock(map_lock_);
240 auto it = image_request_id_map_.find(request_id); 255 auto it = image_request_id_map_.find(request_id);
241 if (it == image_request_id_map_.end()) 256 if (it == image_request_id_map_.end())
242 return; 257 return;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 auto it = image_request_id_map_.find(request_id); 301 auto it = image_request_id_map_.find(request_id);
287 if (it == image_request_id_map_.end()) 302 if (it == image_request_id_map_.end())
288 return; 303 return;
289 image_request = it->second; 304 image_request = it->second;
290 image_request_id_map_.erase(it); 305 image_request_id_map_.erase(it);
291 } 306 }
292 307
293 DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread()); 308 DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread());
294 image_request->OnDecodeImageFailed(); 309 image_request->OnDecodeImageFailed();
295 } 310 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698