OLD | NEW |
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 "chrome/browser/browser_process.h" | 9 #include "chrome/browser/browser_process.h" |
10 #include "chrome/common/chrome_utility_messages.h" | 10 #include "chrome/common/chrome_utility_messages.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 // static, Leaky to allow access from any thread. | 21 // static, Leaky to allow access from any thread. |
22 base::LazyInstance<ImageDecoder>::Leaky g_decoder = LAZY_INSTANCE_INITIALIZER; | 22 base::LazyInstance<ImageDecoder>::Leaky g_decoder = LAZY_INSTANCE_INITIALIZER; |
23 | 23 |
24 // How long to wait after the last request has been received before ending | 24 // How long to wait after the last request has been received before ending |
25 // batch mode. | 25 // batch mode. |
26 const int kBatchModeTimeoutSeconds = 5; | 26 const int kBatchModeTimeoutSeconds = 5; |
27 | 27 |
28 } // namespace | 28 } // namespace |
29 | 29 |
30 ImageDecoder::ImageDecoder() | 30 ImageDecoder::ImageDecoder() |
31 : image_request_id_counter_(0), last_request_(base::TimeTicks::Now()) { | 31 : image_request_id_counter_(0) { |
32 // A single ImageDecoder instance should live for the life of the program. | 32 // A single ImageDecoder instance should live for the life of the program. |
33 // Explicitly add a reference so the object isn't deleted. | 33 // Explicitly add a reference so the object isn't deleted. |
34 AddRef(); | 34 AddRef(); |
35 } | 35 } |
36 | 36 |
37 ImageDecoder::~ImageDecoder() { | 37 ImageDecoder::~ImageDecoder() { |
38 } | 38 } |
39 | 39 |
40 ImageDecoder::ImageRequest::ImageRequest() | 40 ImageDecoder::ImageRequest::ImageRequest() |
41 : task_runner_(base::ThreadTaskRunnerHandle::Get()) { | 41 : task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // Utility process failed to start; notify delegate and return. | 116 // Utility process failed to start; notify delegate and return. |
117 // Without this check, we were seeing crashes on startup. Further | 117 // Without this check, we were seeing crashes on startup. Further |
118 // investigation is needed to determine why the utility process | 118 // investigation is needed to determine why the utility process |
119 // is failing to start. See crbug.com/472272 | 119 // is failing to start. See crbug.com/472272 |
120 image_request->task_runner()->PostTask( | 120 image_request->task_runner()->PostTask( |
121 FROM_HERE, | 121 FROM_HERE, |
122 base::Bind(&ImageDecoder::RunOnDecodeImageFailed, this, request_id)); | 122 base::Bind(&ImageDecoder::RunOnDecodeImageFailed, this, request_id)); |
123 return; | 123 return; |
124 } | 124 } |
125 | 125 |
126 last_request_ = base::TimeTicks::Now(); | 126 if (!batch_mode_timer_) { |
| 127 // Created here so it will call StopBatchMode() on the right thread. |
| 128 batch_mode_timer_.reset(new base::DelayTimer<ImageDecoder>( |
| 129 FROM_HERE, |
| 130 base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds), |
| 131 this, |
| 132 &ImageDecoder::StopBatchMode)); |
| 133 } |
| 134 batch_mode_timer_->Reset(); |
127 | 135 |
128 switch (image_codec) { | 136 switch (image_codec) { |
129 case ROBUST_JPEG_CODEC: | 137 case ROBUST_JPEG_CODEC: |
130 utility_process_host_->Send(new ChromeUtilityMsg_RobustJPEGDecodeImage( | 138 utility_process_host_->Send(new ChromeUtilityMsg_RobustJPEGDecodeImage( |
131 image_data, request_id)); | 139 image_data, request_id)); |
132 break; | 140 break; |
133 case DEFAULT_CODEC: | 141 case DEFAULT_CODEC: |
134 utility_process_host_->Send(new ChromeUtilityMsg_DecodeImage( | 142 utility_process_host_->Send(new ChromeUtilityMsg_DecodeImage( |
135 image_data, shrink_to_fit, request_id)); | 143 image_data, shrink_to_fit, request_id)); |
136 break; | 144 break; |
(...skipping 16 matching lines...) Expand all Loading... |
153 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 161 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
154 utility_process_host_ = | 162 utility_process_host_ = |
155 UtilityProcessHost::Create(this, base::MessageLoopProxy::current().get()) | 163 UtilityProcessHost::Create(this, base::MessageLoopProxy::current().get()) |
156 ->AsWeakPtr(); | 164 ->AsWeakPtr(); |
157 utility_process_host_->SetName(l10n_util::GetStringUTF16( | 165 utility_process_host_->SetName(l10n_util::GetStringUTF16( |
158 IDS_UTILITY_PROCESS_IMAGE_DECODER_NAME)); | 166 IDS_UTILITY_PROCESS_IMAGE_DECODER_NAME)); |
159 if (!utility_process_host_->StartBatchMode()) { | 167 if (!utility_process_host_->StartBatchMode()) { |
160 utility_process_host_.reset(); | 168 utility_process_host_.reset(); |
161 return; | 169 return; |
162 } | 170 } |
163 batch_mode_timer_.Start( | |
164 FROM_HERE, base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds), | |
165 this, &ImageDecoder::StopBatchMode); | |
166 } | 171 } |
167 | 172 |
168 void ImageDecoder::StopBatchMode() { | 173 void ImageDecoder::StopBatchMode() { |
169 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 174 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
170 if ((base::TimeTicks::Now() - last_request_) | |
171 < base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds)) { | |
172 return; | |
173 } | |
174 | |
175 if (utility_process_host_) { | 175 if (utility_process_host_) { |
176 utility_process_host_->EndBatchMode(); | 176 utility_process_host_->EndBatchMode(); |
177 utility_process_host_.reset(); | 177 utility_process_host_.reset(); |
178 } | 178 } |
179 batch_mode_timer_.Stop(); | |
180 } | 179 } |
181 | 180 |
182 bool ImageDecoder::OnMessageReceived( | 181 bool ImageDecoder::OnMessageReceived( |
183 const IPC::Message& message) { | 182 const IPC::Message& message) { |
184 bool handled = true; | 183 bool handled = true; |
185 IPC_BEGIN_MESSAGE_MAP(ImageDecoder, message) | 184 IPC_BEGIN_MESSAGE_MAP(ImageDecoder, message) |
186 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded, | 185 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded, |
187 OnDecodeImageSucceeded) | 186 OnDecodeImageSucceeded) |
188 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed, | 187 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed, |
189 OnDecodeImageFailed) | 188 OnDecodeImageFailed) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 auto it = image_request_id_map_.find(request_id); | 245 auto it = image_request_id_map_.find(request_id); |
247 if (it == image_request_id_map_.end()) | 246 if (it == image_request_id_map_.end()) |
248 return; | 247 return; |
249 image_request = it->second; | 248 image_request = it->second; |
250 image_request_id_map_.erase(it); | 249 image_request_id_map_.erase(it); |
251 } | 250 } |
252 | 251 |
253 DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread()); | 252 DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread()); |
254 image_request->OnDecodeImageFailed(); | 253 image_request->OnDecodeImageFailed(); |
255 } | 254 } |
OLD | NEW |