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

Side by Side Diff: components/webp_transcode/webp_network_client.mm

Issue 1860003003: Remove the WebPNetworkClient* from iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Build fix No. 2 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
(Empty)
1 // Copyright 2013 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 #import "components/webp_transcode/webp_network_client.h"
6
7 #include <stddef.h>
8
9 #include "base/bind.h"
10 #include "base/compiler_specific.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/mac/bind_objc_block.h"
14 #include "base/mac/scoped_nsobject.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/sys_string_conversions.h"
19 #include "base/thread_task_runner_handle.h"
20 #include "components/webp_transcode/webp_decoder.h"
21 #include "net/base/net_errors.h"
22 #include "net/http/http_request_headers.h"
23 #include "net/url_request/url_request.h"
24
25 namespace net {
26 class URLRequest;
27 }
28
29 using namespace webp_transcode;
30
31 namespace {
32
33 // MIME type for WebP images.
34 const char kWebPMimeType[] = "image/webp";
35 NSString* const kNSWebPMimeType = @"image/webp";
36
37 NSURLResponse* NewImageResponse(NSURLResponse* webp_response,
38 size_t content_length,
39 WebpDecoder::DecodedImageFormat format) {
40 DCHECK(webp_response);
41
42 NSString* mime_type = nil;
43 switch (format) {
44 case WebpDecoder::JPEG:
45 mime_type = @"image/jpeg";
46 break;
47 case WebpDecoder::PNG:
48 mime_type = @"image/png";
49 break;
50 case WebpDecoder::TIFF:
51 mime_type = @"image/tiff";
52 break;
53 case WebpDecoder::DECODED_FORMAT_COUNT:
54 NOTREACHED();
55 break;
56 }
57 DCHECK(mime_type);
58
59 if ([webp_response isKindOfClass:[NSHTTPURLResponse class]]) {
60 NSHTTPURLResponse* http_response =
61 static_cast<NSHTTPURLResponse*>(webp_response);
62 NSMutableDictionary* header_fields = [NSMutableDictionary
63 dictionaryWithDictionary:[http_response allHeaderFields]];
64 [header_fields setObject:[NSString stringWithFormat:@"%zu", content_length]
65 forKey:@"Content-Length"];
66 [header_fields setObject:mime_type forKey:@"Content-Type"];
67 return [[NSHTTPURLResponse alloc] initWithURL:[http_response URL]
68 statusCode:[http_response statusCode]
69 HTTPVersion:@"HTTP/1.1"
70 headerFields:header_fields];
71 } else {
72 return [[NSURLResponse alloc] initWithURL:[webp_response URL]
73 MIMEType:mime_type
74 expectedContentLength:content_length
75 textEncodingName:[webp_response textEncodingName]];
76 }
77 }
78
79 class WebpDecoderDelegate : public WebpDecoder::Delegate {
80 public:
81 WebpDecoderDelegate(id<CRNNetworkClientProtocol> client,
82 const base::Time& request_creation_time,
83 const scoped_refptr<base::TaskRunner>& callback_runner)
84 : underlying_client_([client retain]),
85 callback_task_runner_(callback_runner),
86 request_creation_time_(request_creation_time) {
87 DCHECK(underlying_client_.get());
88 }
89
90 void SetOriginalResponse(
91 const base::scoped_nsobject<NSURLResponse>& response) {
92 original_response_.reset([response retain]);
93 }
94
95 // WebpDecoder::Delegate methods.
96 void OnFinishedDecoding(bool success) override {
97 base::scoped_nsprotocol<id<CRNNetworkClientProtocol>> block_client(
98 [underlying_client_ retain]);
99 if (success) {
100 callback_task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
101 [block_client didFinishLoading];
102 }));
103 } else {
104 DLOG(WARNING) << "WebP decoding failed "
105 << base::SysNSStringToUTF8(
106 [[original_response_ URL] absoluteString]);
107 void (^errorBlock)(void) = ^{
108 [block_client didFailWithNSErrorCode:NSURLErrorCannotDecodeContentData
109 netErrorCode:net::ERR_CONTENT_DECODING_FAILED];
110 };
111 callback_task_runner_->PostTask(FROM_HERE, base::BindBlock(errorBlock));
112 }
113 }
114
115 void SetImageFeatures(size_t total_size,
116 WebpDecoder::DecodedImageFormat format) override {
117 base::scoped_nsobject<NSURLResponse> imageResponse(
118 NewImageResponse(original_response_, total_size, format));
119 DCHECK(imageResponse);
120 base::scoped_nsprotocol<id<CRNNetworkClientProtocol>> block_client(
121 [underlying_client_ retain]);
122 callback_task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
123 [block_client didReceiveResponse:imageResponse];
124 }));
125 }
126
127 void OnDataDecoded(NSData* data) override {
128 base::scoped_nsprotocol<id<CRNNetworkClientProtocol>> block_client(
129 [underlying_client_ retain]);
130 callback_task_runner_->PostTask(FROM_HERE, base::BindBlock(^{
131 [block_client didLoadData:data];
132 }));
133 }
134
135 private:
136 ~WebpDecoderDelegate() override {}
137
138 base::scoped_nsprotocol<id<CRNNetworkClientProtocol>> underlying_client_;
139 base::scoped_nsobject<NSURLResponse> original_response_;
140 scoped_refptr<base::TaskRunner> callback_task_runner_;
141 base::Time request_creation_time_;
142 };
143
144 } // namespace
145
146 @interface WebPNetworkClient () {
147 scoped_refptr<webp_transcode::WebpDecoder> _webpDecoder;
148 scoped_refptr<WebpDecoderDelegate> _webpDecoderDelegate;
149 scoped_refptr<base::SequencedTaskRunner> _taskRunner;
150 base::Time _requestCreationTime;
151 }
152 @end
153
154 @implementation WebPNetworkClient
155
156 - (instancetype)init {
157 NOTREACHED() << "Use |-initWithTaskRunner:| instead";
158 return nil;
159 }
160
161 - (instancetype)initWithTaskRunner:
162 (const scoped_refptr<base::SequencedTaskRunner>&)runner {
163 if (self = [super init]) {
164 DCHECK(runner);
165 _taskRunner = runner;
166 }
167 return self;
168 }
169
170 - (void)didCreateNativeRequest:(net::URLRequest*)nativeRequest {
171 // Append 'image/webp' to the outgoing 'Accept' header.
172 const net::HttpRequestHeaders& headers =
173 nativeRequest->extra_request_headers();
174 std::string acceptHeader;
175 if (headers.GetHeader("Accept", &acceptHeader)) {
176 // Add 'image/webp' if it isn't in the Accept header yet.
177 if (acceptHeader.find(kWebPMimeType) == std::string::npos) {
178 acceptHeader += std::string(",") + kWebPMimeType;
179 nativeRequest->SetExtraRequestHeaderByName("Accept", acceptHeader, true);
180 }
181 } else {
182 // All requests should already have an Accept: header, so this case
183 // should never happen outside of unit tests.
184 nativeRequest->SetExtraRequestHeaderByName("Accept", kWebPMimeType, false);
185 }
186 [super didCreateNativeRequest:nativeRequest];
187 }
188
189 - (void)didLoadData:(NSData*)data {
190 if (_webpDecoder.get()) {
191 // |data| is assumed to be immutable.
192 base::scoped_nsobject<NSData> scopedData([data retain]);
193 _taskRunner->PostTask(FROM_HERE, base::Bind(&WebpDecoder::OnDataReceived,
194 _webpDecoder, scopedData));
195 } else {
196 [super didLoadData:data];
197 }
198 }
199
200 - (void)didReceiveResponse:(NSURLResponse*)response {
201 DCHECK(self.underlyingClient);
202 NSString* responseMimeType = [response MIMEType];
203 if (responseMimeType &&
204 [responseMimeType caseInsensitiveCompare:kNSWebPMimeType] ==
205 NSOrderedSame) {
206 _webpDecoderDelegate =
207 new WebpDecoderDelegate(self.underlyingClient, _requestCreationTime,
208 base::ThreadTaskRunnerHandle::Get());
209 _webpDecoder = new webp_transcode::WebpDecoder(_webpDecoderDelegate.get());
210 base::scoped_nsobject<NSURLResponse> scoped_response([response copy]);
211 _taskRunner->PostTask(FROM_HERE,
212 base::Bind(&WebpDecoderDelegate::SetOriginalResponse,
213 _webpDecoderDelegate, scoped_response));
214 // Do not call super here, the WebpDecoderDelegate will update the mime type
215 // and call |-didReceiveResponse:|.
216 } else {
217 // If this isn't a WebP, pass the call up the chain.
218 [super didReceiveResponse:response];
219 }
220 }
221
222 - (void)didFinishLoading {
223 if (_webpDecoder.get()) {
224 _taskRunner->PostTask(FROM_HERE,
225 base::Bind(&WebpDecoder::Stop, _webpDecoder));
226 } else {
227 [super didFinishLoading];
228 }
229 }
230
231 @end
OLDNEW
« no previous file with comments | « components/webp_transcode/webp_network_client.h ('k') | components/webp_transcode/webp_network_client_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698