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

Side by Side Diff: ios/chrome/browser/net/image_fetcher.mm

Issue 805713004: Cleanup image_fetcher::ImageFetcher (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 6 years 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 #import "ios/chrome/browser/net/image_fetcher.h" 5 #import "ios/chrome/browser/net/image_fetcher.h"
6 6
7 #import <Foundation/Foundation.h> 7 #import <Foundation/Foundation.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h"
11 #include "base/location.h" 10 #include "base/location.h"
12 #include "base/logging.h" 11 #include "base/mac/scoped_nsobject.h"
13 #include "base/mac/scoped_block.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/task_runner_util.h"
16 #include "base/threading/sequenced_worker_pool.h" 12 #include "base/threading/sequenced_worker_pool.h"
13 #include "ios/web/public/web_thread.h"
17 #include "ios/web/public/webp_decoder.h" 14 #include "ios/web/public/webp_decoder.h"
18 #include "net/base/load_flags.h" 15 #include "net/base/load_flags.h"
19 #include "net/http/http_response_headers.h" 16 #include "net/http/http_response_headers.h"
20 #include "net/url_request/url_fetcher.h" 17 #include "net/url_request/url_fetcher.h"
21 #include "url/gurl.h" 18 #include "net/url_request/url_request_context_getter.h"
22 19
23 namespace { 20 namespace {
24 21
25 class WebpDecoderDelegate : public web::WebpDecoder::Delegate { 22 class WebpDecoderDelegate : public web::WebpDecoder::Delegate {
26 public: 23 public:
27 NSData* data() const { return decoded_image_; } 24 NSData* data() const { return decoded_image_; }
28 25
29 // WebpDecoder::Delegate methods 26 // WebpDecoder::Delegate methods
30 void OnFinishedDecoding(bool success) override { 27 void OnFinishedDecoding(bool success) override {
31 if (!success) 28 if (!success)
32 decoded_image_.reset(); 29 decoded_image_.reset();
33 } 30 }
34 void SetImageFeatures( 31 void SetImageFeatures(
35 size_t total_size, 32 size_t total_size,
36 web::WebpDecoder::DecodedImageFormat format) override { 33 web::WebpDecoder::DecodedImageFormat format) override {
37 decoded_image_.reset([[NSMutableData alloc] initWithCapacity:total_size]); 34 decoded_image_.reset([[NSMutableData alloc] initWithCapacity:total_size]);
38 } 35 }
39 void OnDataDecoded(NSData* data) override { 36 void OnDataDecoded(NSData* data) override {
40 DCHECK(decoded_image_); 37 DCHECK(decoded_image_);
41 [decoded_image_ appendData:data]; 38 [decoded_image_ appendData:data];
42 } 39 }
43 private: 40 private:
44 ~WebpDecoderDelegate() override {} 41 ~WebpDecoderDelegate() override {}
45 base::scoped_nsobject<NSMutableData> decoded_image_; 42 base::scoped_nsobject<NSMutableData> decoded_image_;
46 }; 43 };
47 44
45 // Content-type header for WebP images.
46 static const char kWEBPMimeType[] = "image/webp";
47
48 // Returns a NSData object containing the decoded image. 48 // Returns a NSData object containing the decoded image.
49 // Returns nil in case of failure. 49 // Returns nil in case of failure.
50 base::scoped_nsobject<NSData> DecodeWebpImage( 50 base::scoped_nsobject<NSData> DecodeWebpImage(
51 const base::scoped_nsobject<NSData>& webp_image) { 51 const base::scoped_nsobject<NSData>& webp_image) {
52 scoped_refptr<WebpDecoderDelegate> delegate(new WebpDecoderDelegate); 52 scoped_refptr<WebpDecoderDelegate> delegate(new WebpDecoderDelegate);
53 scoped_refptr<web::WebpDecoder> decoder(new web::WebpDecoder(delegate.get())); 53 scoped_refptr<web::WebpDecoder> decoder(new web::WebpDecoder(delegate.get()));
54 decoder->OnDataReceived(webp_image); 54 decoder->OnDataReceived(webp_image);
55 DLOG_IF(ERROR, !delegate->data()) << "WebP image decoding failed."; 55 DLOG_IF(ERROR, !delegate->data()) << "WebP image decoding failed.";
56 return base::scoped_nsobject<NSData>([delegate->data() retain]); 56 return base::scoped_nsobject<NSData>([delegate->data() retain]);
57 } 57 }
58 58
59 } // namespace 59 } // namespace
60 60
61 namespace image_fetcher { 61 namespace image_fetcher {
62 62
63 ImageFetcher::ImageFetcher( 63 ImageFetcher::ImageFetcher(
64 const scoped_refptr<base::SequencedWorkerPool> decoding_pool) 64 const scoped_refptr<base::SequencedWorkerPool>& decoding_pool)
65 : request_context_getter_(nullptr), 65 : request_context_getter_(nullptr),
66 weak_factory_(this), 66 weak_factory_(this),
67 decoding_pool_(decoding_pool) { 67 decoding_pool_(decoding_pool) {
68 DCHECK(decoding_pool_.get()); 68 DCHECK(decoding_pool_.get());
69 } 69 }
70 70
71 ImageFetcher::~ImageFetcher() { 71 ImageFetcher::~ImageFetcher() {
72 // Delete all the entries in the |downloads_in_progress_| map. This will in 72 // Delete all the entries in the |downloads_in_progress_| map. This will in
73 // turn cancel all of the requests. 73 // turn cancel all of the requests.
74 for (std::map<const net::URLFetcher*, Callback>::iterator it = 74 for (const auto& pair : downloads_in_progress_) {
75 downloads_in_progress_.begin(); 75 [pair.second release];
76 it != downloads_in_progress_.end(); ++it) { 76 delete pair.first;
77 [it->second release];
78 delete it->first;
79 } 77 }
80 } 78 }
81 79
82 void ImageFetcher::StartDownload( 80 void ImageFetcher::StartDownload(
83 const GURL& url, 81 const GURL& url,
84 Callback callback, 82 ImageFetchedCallback callback,
85 const std::string& referrer, 83 const std::string& referrer,
86 net::URLRequest::ReferrerPolicy referrer_policy) { 84 net::URLRequest::ReferrerPolicy referrer_policy) {
87 DCHECK(request_context_getter_.get()); 85 DCHECK(request_context_getter_.get());
88 net::URLFetcher* fetcher = net::URLFetcher::Create(url, 86 net::URLFetcher* fetcher = net::URLFetcher::Create(url,
89 net::URLFetcher::GET, 87 net::URLFetcher::GET,
90 this); 88 this);
91 downloads_in_progress_[fetcher] = [callback copy]; 89 downloads_in_progress_[fetcher] = [callback copy];
92 fetcher->SetLoadFlags( 90 fetcher->SetLoadFlags(
93 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); 91 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES |
92 net::LOAD_DO_NOT_SEND_AUTH_DATA | net::LOAD_DO_NOT_PROMPT_FOR_LOGIN);
94 fetcher->SetRequestContext(request_context_getter_.get()); 93 fetcher->SetRequestContext(request_context_getter_.get());
95 fetcher->SetReferrer(referrer); 94 fetcher->SetReferrer(referrer);
96 fetcher->SetReferrerPolicy(referrer_policy); 95 fetcher->SetReferrerPolicy(referrer_policy);
97 fetcher->Start(); 96 fetcher->Start();
98 } 97 }
99 98
100 void ImageFetcher::StartDownload(const GURL& url, Callback callback) { 99 void ImageFetcher::StartDownload(
100 const GURL& url, ImageFetchedCallback callback) {
101 ImageFetcher::StartDownload( 101 ImageFetcher::StartDownload(
102 url, callback, "", net::URLRequest::NEVER_CLEAR_REFERRER); 102 url, callback, std::string(), net::URLRequest::NEVER_CLEAR_REFERRER);
103 } 103 }
104 104
105 // Delegate callback that is called when URLFetcher completes. If the image 105 // Delegate callback that is called when URLFetcher completes. If the image
106 // was fetched successfully, creates a new NSData and returns it to the 106 // was fetched successfully, creates a new NSData and returns it to the
107 // callback, otherwise returns nil to the callback. 107 // callback, otherwise returns nil to the callback.
108 void ImageFetcher::OnURLFetchComplete(const net::URLFetcher* fetcher) { 108 void ImageFetcher::OnURLFetchComplete(const net::URLFetcher* fetcher) {
109 if (downloads_in_progress_.find(fetcher) == downloads_in_progress_.end()) { 109 if (downloads_in_progress_.find(fetcher) == downloads_in_progress_.end()) {
110 LOG(ERROR) << "Received callback for unknown URLFetcher " << fetcher; 110 LOG(ERROR) << "Received callback for unknown URLFetcher " << fetcher;
111 return; 111 return;
112 } 112 }
113 113
114 // Ensures that |fetcher| will be deleted even if we return early. 114 // Ensures that |fetcher| will be deleted in the event of early return.
115 scoped_ptr<const net::URLFetcher> fetcher_deleter(fetcher); 115 scoped_ptr<const net::URLFetcher> fetcher_deleter(fetcher);
116 116
117 // Retrieves the callback and ensures that it will be deleted even if we 117 // Retrieves the callback and ensures that it will be deleted in the event
118 // return early. 118 // of early return.
119 base::mac::ScopedBlock<Callback> callback(downloads_in_progress_[fetcher]); 119 base::mac::ScopedBlock<ImageFetchedCallback> callback(
120 downloads_in_progress_[fetcher]);
120 121
121 // Remove |fetcher| from the map. 122 // Remove |fetcher| from the map.
122 downloads_in_progress_.erase(fetcher); 123 downloads_in_progress_.erase(fetcher);
123 124
124 // Make sure the request was successful. For "data" requests, the response 125 // Make sure the request was successful. For "data" requests, the response
125 // code has no meaning, because there is no actual server (data is encoded 126 // code has no meaning, because there is no actual server (data is encoded
126 // directly in the URL). In that case, we set the response code to 200. 127 // directly in the URL). In that case, set the response code to 200 (OK).
127 const GURL& original_url = fetcher->GetOriginalURL(); 128 const GURL& original_url = fetcher->GetOriginalURL();
128 const int http_response_code = original_url.SchemeIs("data") ? 129 const int http_response_code = original_url.SchemeIs("data") ?
129 200 : fetcher->GetResponseCode(); 130 200 : fetcher->GetResponseCode();
130 if (http_response_code != 200) { 131 if (http_response_code != 200) {
131 (callback.get())(original_url, http_response_code, nil); 132 (callback.get())(original_url, http_response_code, nil);
132 return; 133 return;
133 } 134 }
134 135
135 std::string response; 136 std::string response;
136 if (!fetcher->GetResponseAsString(&response)) { 137 if (!fetcher->GetResponseAsString(&response)) {
137 (callback.get())(original_url, http_response_code, nil); 138 (callback.get())(original_url, http_response_code, nil);
138 return; 139 return;
139 } 140 }
140 141
141 // Create a NSData from the returned data and notify the callback. 142 // Create a NSData from the returned data and notify the callback.
142 base::scoped_nsobject<NSData> data([[NSData alloc] 143 base::scoped_nsobject<NSData> data([[NSData alloc]
143 initWithBytes:reinterpret_cast<const unsigned char*>(response.data()) 144 initWithBytes:reinterpret_cast<const unsigned char*>(response.data())
144 length:response.size()]); 145 length:response.size()]);
145 146
146 if (fetcher->GetResponseHeaders()) { 147 if (fetcher->GetResponseHeaders()) {
147 std::string mime_type; 148 std::string mime_type;
148 fetcher->GetResponseHeaders()->GetMimeType(&mime_type); 149 fetcher->GetResponseHeaders()->GetMimeType(&mime_type);
149 if (mime_type == "image/webp") { 150 if (mime_type == kWEBPMimeType) {
150 base::PostTaskAndReplyWithResult(decoding_pool_.get(), 151 base::PostTaskAndReplyWithResult(decoding_pool_.get(),
151 FROM_HERE, 152 FROM_HERE,
152 base::Bind(&DecodeWebpImage, data), 153 base::Bind(&DecodeWebpImage, data),
153 base::Bind(&ImageFetcher::RunCallback, 154 base::Bind(&ImageFetcher::RunCallback,
154 weak_factory_.GetWeakPtr(), 155 weak_factory_.GetWeakPtr(),
155 callback, 156 callback,
156 original_url, 157 original_url,
157 http_response_code)); 158 http_response_code));
158 return; 159 return;
159 } 160 }
160 } 161 }
161 (callback.get())(original_url, http_response_code, data); 162 (callback.get())(original_url, http_response_code, data);
162 } 163 }
163 164
164 void ImageFetcher::RunCallback(const base::mac::ScopedBlock<Callback>& callback, 165 void ImageFetcher::RunCallback(
165 const GURL& url, 166 const base::mac::ScopedBlock<ImageFetchedCallback>& callback,
166 int http_response_code, 167 const GURL& url,
167 NSData* data) { 168 int http_response_code,
169 NSData* data) {
168 (callback.get())(url, http_response_code, data); 170 (callback.get())(url, http_response_code, data);
169 } 171 }
170 172
171 void ImageFetcher::SetRequestContextGetter( 173 void ImageFetcher::SetRequestContextGetter(
172 net::URLRequestContextGetter* request_context_getter) { 174 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter) {
173 request_context_getter_ = request_context_getter; 175 request_context_getter_ = request_context_getter;
174 } 176 }
175 177
176 } // namespace image_fetcher 178 } // namespace image_fetcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698