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

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

Issue 2763103002: Move ImageDecoder to components/image_fetcher/content (Closed)
Patch Set: Rebased. Created 3 years, 9 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
« no previous file with comments | « chrome/browser/image_decoder.h ('k') | chrome/browser/image_decoder_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/image_decoder.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/threading/thread_task_runner_handle.h"
12 #include "build/build_config.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/common/service_manager_connection.h"
15 #include "ipc/ipc_channel.h"
16 #include "services/data_decoder/public/cpp/decode_image.h"
17 #include "services/service_manager/public/cpp/connector.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/gfx/geometry/size.h"
20
21 namespace {
22
23 const int64_t kMaxImageSizeInBytes =
24 static_cast<int64_t>(IPC::Channel::kMaximumMessageSize);
25
26 // Note that this is always called on the thread which initiated the
27 // corresponding data_decoder::DecodeImage request.
28 void OnDecodeImageDone(
29 base::Callback<void(int)> fail_callback,
30 base::Callback<void(const SkBitmap&, int)> success_callback,
31 int request_id,
32 const SkBitmap& image) {
33 if (!image.isNull() && !image.empty())
34 success_callback.Run(image, request_id);
35 else
36 fail_callback.Run(request_id);
37 }
38
39 void BindToBrowserConnector(service_manager::mojom::ConnectorRequest request) {
40 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
41 content::BrowserThread::PostTask(
42 content::BrowserThread::UI, FROM_HERE,
43 base::Bind(&BindToBrowserConnector, base::Passed(&request)));
44 return;
45 }
46
47 content::ServiceManagerConnection::GetForProcess()->GetConnector()
48 ->BindConnectorRequest(std::move(request));
49 }
50
51 void RunDecodeCallbackOnTaskRunner(
52 const data_decoder::mojom::ImageDecoder::DecodeImageCallback& callback,
53 scoped_refptr<base::SequencedTaskRunner> task_runner,
54 const SkBitmap& image) {
55 task_runner->PostTask(FROM_HERE, base::Bind(callback, image));
56 }
57
58 void DecodeImage(
59 std::vector<uint8_t> image_data,
60 data_decoder::mojom::ImageCodec codec,
61 bool shrink_to_fit,
62 const gfx::Size& desired_image_frame_size,
63 const data_decoder::mojom::ImageDecoder::DecodeImageCallback& callback,
64 scoped_refptr<base::SequencedTaskRunner> callback_task_runner) {
65 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
66
67 service_manager::mojom::ConnectorRequest connector_request;
68 std::unique_ptr<service_manager::Connector> connector =
69 service_manager::Connector::Create(&connector_request);
70 BindToBrowserConnector(std::move(connector_request));
71
72 data_decoder::DecodeImage(connector.get(), image_data, codec, shrink_to_fit,
73 kMaxImageSizeInBytes, desired_image_frame_size,
74 base::Bind(&RunDecodeCallbackOnTaskRunner, callback,
75 callback_task_runner));
76 }
77
78 } // namespace
79
80 ImageDecoder::ImageRequest::ImageRequest()
81 : task_runner_(base::ThreadTaskRunnerHandle::Get()) {
82 DCHECK(sequence_checker_.CalledOnValidSequence());
83 }
84
85 ImageDecoder::ImageRequest::ImageRequest(
86 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
87 : task_runner_(task_runner) {
88 DCHECK(sequence_checker_.CalledOnValidSequence());
89 }
90
91 ImageDecoder::ImageRequest::~ImageRequest() {
92 DCHECK(sequence_checker_.CalledOnValidSequence());
93 ImageDecoder::Cancel(this);
94 }
95
96 // static
97 ImageDecoder* ImageDecoder::GetInstance() {
98 static auto* image_decoder = new ImageDecoder();
99 return image_decoder;
100 }
101
102 // static
103 void ImageDecoder::Start(ImageRequest* image_request,
104 std::vector<uint8_t> image_data) {
105 StartWithOptions(image_request, std::move(image_data), DEFAULT_CODEC, false,
106 gfx::Size());
107 }
108
109 // static
110 void ImageDecoder::Start(ImageRequest* image_request,
111 const std::string& image_data) {
112 Start(image_request,
113 std::vector<uint8_t>(image_data.begin(), image_data.end()));
114 }
115
116 // static
117 void ImageDecoder::StartWithOptions(ImageRequest* image_request,
118 std::vector<uint8_t> image_data,
119 ImageCodec image_codec,
120 bool shrink_to_fit,
121 const gfx::Size& desired_image_frame_size) {
122 ImageDecoder::GetInstance()->StartWithOptionsImpl(
123 image_request, std::move(image_data), image_codec, shrink_to_fit,
124 desired_image_frame_size);
125 }
126
127 // static
128 void ImageDecoder::StartWithOptions(ImageRequest* image_request,
129 const std::string& image_data,
130 ImageCodec image_codec,
131 bool shrink_to_fit) {
132 StartWithOptions(image_request,
133 std::vector<uint8_t>(image_data.begin(), image_data.end()),
134 image_codec, shrink_to_fit, gfx::Size());
135 }
136
137 ImageDecoder::ImageDecoder() : image_request_id_counter_(0) {}
138
139 void ImageDecoder::StartWithOptionsImpl(
140 ImageRequest* image_request,
141 std::vector<uint8_t> image_data,
142 ImageCodec image_codec,
143 bool shrink_to_fit,
144 const gfx::Size& desired_image_frame_size) {
145 DCHECK(image_request);
146 DCHECK(image_request->task_runner());
147
148 int request_id;
149 {
150 base::AutoLock lock(map_lock_);
151 request_id = image_request_id_counter_++;
152 image_request_id_map_.insert(std::make_pair(request_id, image_request));
153 }
154
155 data_decoder::mojom::ImageCodec codec =
156 data_decoder::mojom::ImageCodec::DEFAULT;
157 #if defined(OS_CHROMEOS)
158 if (image_codec == ROBUST_JPEG_CODEC)
159 codec = data_decoder::mojom::ImageCodec::ROBUST_JPEG;
160 if (image_codec == ROBUST_PNG_CODEC)
161 codec = data_decoder::mojom::ImageCodec::ROBUST_PNG;
162 #endif // defined(OS_CHROMEOS)
163
164 auto callback = base::Bind(
165 &OnDecodeImageDone,
166 base::Bind(&ImageDecoder::OnDecodeImageFailed, base::Unretained(this)),
167 base::Bind(&ImageDecoder::OnDecodeImageSucceeded, base::Unretained(this)),
168 request_id);
169
170 // NOTE: There exist ImageDecoder consumers which implicitly rely on this
171 // operation happening on a thread which always has a ThreadTaskRunnerHandle.
172 // We arbitrarily use the IO thread here to match details of the legacy
173 // implementation.
174 content::BrowserThread::PostTask(
175 content::BrowserThread::IO, FROM_HERE,
176 base::Bind(&DecodeImage, base::Passed(&image_data), codec, shrink_to_fit,
177 desired_image_frame_size, callback,
178 make_scoped_refptr(image_request->task_runner())));
179 }
180
181 // static
182 void ImageDecoder::Cancel(ImageRequest* image_request) {
183 DCHECK(image_request);
184 ImageDecoder::GetInstance()->CancelImpl(image_request);
185 }
186
187 void ImageDecoder::CancelImpl(ImageRequest* image_request) {
188 base::AutoLock lock(map_lock_);
189 for (auto it = image_request_id_map_.begin();
190 it != image_request_id_map_.end();) {
191 if (it->second == image_request) {
192 image_request_id_map_.erase(it++);
193 } else {
194 ++it;
195 }
196 }
197 }
198
199 void ImageDecoder::OnDecodeImageSucceeded(
200 const SkBitmap& decoded_image,
201 int request_id) {
202 ImageRequest* image_request;
203 {
204 base::AutoLock lock(map_lock_);
205 auto it = image_request_id_map_.find(request_id);
206 if (it == image_request_id_map_.end())
207 return;
208 image_request = it->second;
209 image_request_id_map_.erase(it);
210 }
211
212 DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread());
213 image_request->OnImageDecoded(decoded_image);
214 }
215
216 void ImageDecoder::OnDecodeImageFailed(int request_id) {
217 ImageRequest* image_request;
218 {
219 base::AutoLock lock(map_lock_);
220 auto it = image_request_id_map_.find(request_id);
221 if (it == image_request_id_map_.end())
222 return;
223 image_request = it->second;
224 image_request_id_map_.erase(it);
225 }
226
227 DCHECK(image_request->task_runner()->RunsTasksOnCurrentThread());
228 image_request->OnDecodeImageFailed();
229 }
OLDNEW
« no previous file with comments | « chrome/browser/image_decoder.h ('k') | chrome/browser/image_decoder_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698