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

Side by Side Diff: chromeos/printing/ppd_provider.cc

Issue 2476073003: Update PpdProvider threading model. (Closed)
Patch Set: Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chromeos/printing/ppd_provider.h" 5 #include "chromeos/printing/ppd_provider.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/json/json_parser.h" 10 #include "base/json/json_parser.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/sequence_checker.h" 12 #include "base/sequence_checker.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "base/threading/sequenced_task_runner_handle.h" 16 #include "base/threading/sequenced_task_runner_handle.h"
17 #include "base/threading/thread_restrictions.h"
17 #include "base/time/time.h" 18 #include "base/time/time.h"
18 #include "base/values.h" 19 #include "base/values.h"
19 #include "chromeos/printing/ppd_cache.h" 20 #include "chromeos/printing/ppd_cache.h"
20 #include "net/base/load_flags.h" 21 #include "net/base/load_flags.h"
21 #include "net/http/http_status_code.h" 22 #include "net/http/http_status_code.h"
22 #include "net/url_request/url_fetcher.h" 23 #include "net/url_request/url_fetcher.h"
23 #include "net/url_request/url_fetcher_delegate.h" 24 #include "net/url_request/url_fetcher_delegate.h"
24 #include "net/url_request/url_request_context_getter.h" 25 #include "net/url_request/url_request_context_getter.h"
25 #include "url/gurl.h" 26 #include "url/gurl.h"
26 27
(...skipping 22 matching lines...) Expand all
49 // PpdProviderImpl definition first. 50 // PpdProviderImpl definition first.
50 void OnURLFetchComplete(const net::URLFetcher* source) override; 51 void OnURLFetchComplete(const net::URLFetcher* source) override;
51 52
52 private: 53 private:
53 // owner of this delegate. 54 // owner of this delegate.
54 PpdProviderImpl* const owner_; 55 PpdProviderImpl* const owner_;
55 }; 56 };
56 57
57 class PpdProviderImpl : public PpdProvider { 58 class PpdProviderImpl : public PpdProvider {
58 public: 59 public:
59 PpdProviderImpl( 60 PpdProviderImpl(const std::string& api_key,
60 const std::string& api_key, 61 net::URLRequestContextGetter* url_context_getter,
61 scoped_refptr<net::URLRequestContextGetter> url_context_getter, 62 base::SequencedTaskRunner* disk_task_runner,
62 std::unique_ptr<PpdCache> cache, 63 std::unique_ptr<PpdCache> cache,
63 const PpdProvider::Options& options) 64 const PpdProvider::Options& options)
64 : api_key_(api_key), 65 : api_key_(api_key),
65 forwarding_delegate_(this), 66 forwarding_delegate_(this),
66 url_context_getter_(url_context_getter), 67 url_context_getter_(url_context_getter),
68 disk_task_runner_(disk_task_runner),
67 cache_(std::move(cache)), 69 cache_(std::move(cache)),
68 options_(options) { 70 options_(options),
71 weak_factory_(this) {
69 CHECK_GT(options_.max_ppd_contents_size_, 0U); 72 CHECK_GT(options_.max_ppd_contents_size_, 0U);
70 } 73 }
71 ~PpdProviderImpl() override {} 74 ~PpdProviderImpl() override {}
72 75
73 void Resolve(const Printer::PpdReference& ppd_reference, 76 void Resolve(const Printer::PpdReference& ppd_reference,
74 const PpdProvider::ResolveCallback& cb) override { 77 const PpdProvider::ResolveCallback& cb) override {
75 CHECK(!cb.is_null()); 78 CHECK(!cb.is_null());
79 CHECK(base::SequencedTaskRunnerHandle::IsSet())
80 << "Resolve must be called from a SequencedTaskRunner context";
81 CHECK(resolve_fetcher_ == nullptr)
skau 2016/11/09 00:01:09 Can you add that you're using resolve_fetcher_ ==
Carlson 2016/11/10 19:22:50 Done.
82 << "Can't have concurrent PpdProvider Resolve calls";
83 resolve_done_task_runner_ = base::SequencedTaskRunnerHandle::Get();
84 disk_task_runner_->PostTask(
85 FROM_HERE, base::Bind(&PpdProviderImpl::ResolveImpl,
86 weak_factory_.GetWeakPtr(), ppd_reference, cb));
87 }
88
89 // Do the work of Resolve on disk_task_runner
90 void ResolveImpl(const Printer::PpdReference& ppd_reference,
91 const PpdProvider::ResolveCallback& cb) {
92 base::ThreadRestrictions::AssertIOAllowed();
93 CHECK(!cb.is_null());
76 CHECK(resolve_sequence_checker_.CalledOnValidSequence()); 94 CHECK(resolve_sequence_checker_.CalledOnValidSequence());
77 CHECK(base::SequencedTaskRunnerHandle::IsSet()) 95 CHECK(base::SequencedTaskRunnerHandle::IsSet())
78 << "Resolve must be called from a SequencedTaskRunner context"; 96 << "Resolve must be called from a SequencedTaskRunner context";
79 CHECK(resolve_fetcher_ == nullptr) 97 CHECK(resolve_fetcher_ == nullptr)
80 << "Can't have concurrent PpdProvider Resolve calls"; 98 << "Can't have concurrent PpdProvider Resolve calls";
81 99
82 base::Optional<base::FilePath> tmp = cache_->Find(ppd_reference); 100 base::Optional<base::FilePath> tmp = cache_->Find(ppd_reference);
83 if (tmp) { 101 if (tmp) {
84 // Cache hit. Schedule the callback now and return. 102 // Cache hit. Schedule the callback now and return.
85 base::SequencedTaskRunnerHandle::Get()->PostTask( 103 resolve_done_task_runner_->PostTask(
86 FROM_HERE, base::Bind(cb, PpdProvider::SUCCESS, tmp.value())); 104 FROM_HERE, base::Bind(cb, PpdProvider::SUCCESS, tmp.value()));
87 return; 105 return;
88 } 106 }
89 107
90 // We don't have a way to automatically resolve user-supplied PPDs yet. So 108 // We don't have a way to automatically resolve user-supplied PPDs yet. So
91 // if we have one specified, and it's not cached, we fail out rather than 109 // if we have one specified, and it's not cached, we fail out rather than
92 // fall back to quirks-server based resolution. The reasoning here is that 110 // fall back to quirks-server based resolution. The reasoning here is that
93 // if the user has specified a PPD when a quirks-server one exists, it 111 // if the user has specified a PPD when a quirks-server one exists, it
94 // probably means the quirks server one doesn't work for some reason, so we 112 // probably means the quirks server one doesn't work for some reason, so we
95 // shouldn't silently use it. 113 // shouldn't silently use it.
96 if (!ppd_reference.user_supplied_ppd_url.empty()) { 114 if (!ppd_reference.user_supplied_ppd_url.empty()) {
97 base::SequencedTaskRunnerHandle::Get()->PostTask( 115 resolve_done_task_runner_->PostTask(
98 FROM_HERE, base::Bind(cb, PpdProvider::NOT_FOUND, base::FilePath())); 116 FROM_HERE, base::Bind(cb, PpdProvider::NOT_FOUND, base::FilePath()));
99 return; 117 return;
100 } 118 }
101 119
102 resolve_reference_ = ppd_reference; 120 resolve_reference_ = ppd_reference;
103 resolve_done_callback_ = cb; 121 resolve_done_callback_ = cb;
104 122
105 resolve_fetcher_ = 123 resolve_fetcher_ =
106 net::URLFetcher::Create(GetQuirksServerPpdLookupURL(ppd_reference), 124 net::URLFetcher::Create(GetQuirksServerPpdLookupURL(ppd_reference),
107 net::URLFetcher::GET, &forwarding_delegate_); 125 net::URLFetcher::GET, &forwarding_delegate_);
108 resolve_fetcher_->SetRequestContext(url_context_getter_.get()); 126 resolve_fetcher_->SetRequestContext(url_context_getter_.get());
109 resolve_fetcher_->SetLoadFlags( 127 resolve_fetcher_->SetLoadFlags(
110 net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | 128 net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
111 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES | 129 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES |
112 net::LOAD_DO_NOT_SEND_AUTH_DATA); 130 net::LOAD_DO_NOT_SEND_AUTH_DATA);
113 resolve_fetcher_->Start(); 131 resolve_fetcher_->Start();
114 }; 132 }
115 133
116 void AbortResolve() override { 134 void AbortResolve() override {
117 // UrlFetcher guarantees that when the object has been destroyed, no further 135 // UrlFetcher guarantees that when the object has been destroyed, no further
118 // callbacks will occur. 136 // callbacks will occur.
119 resolve_fetcher_.reset(); 137 resolve_fetcher_.reset();
120 } 138 }
121 139
122 void QueryAvailable(const QueryAvailableCallback& cb) override { 140 void QueryAvailable(const QueryAvailableCallback& cb) override {
skau 2016/11/10 02:38:41 It looks like model and manufacturer is being quer
Carlson 2016/11/10 19:22:50 We chatted offline about this. Being fixed not in
123 CHECK(!cb.is_null()); 141 CHECK(!cb.is_null());
124 CHECK(query_sequence_checker_.CalledOnValidSequence()); 142 CHECK(query_fetcher_ == nullptr)
143 << "Can't have concurrent PpdProvider QueryAvailable() calls";
125 CHECK(base::SequencedTaskRunnerHandle::IsSet()) 144 CHECK(base::SequencedTaskRunnerHandle::IsSet())
126 << "QueryAvailable() must be called from a SequencedTaskRunner context"; 145 << "QueryAvailable() must be called from a SequencedTaskRunner context";
127 CHECK(query_fetcher_ == nullptr) 146 query_done_task_runner_ = base::SequencedTaskRunnerHandle::Get();
128 << "Can't have concurrent PpdProvider QueryAvailable() calls"; 147 disk_task_runner_->PostTask(FROM_HERE,
148 base::Bind(&PpdProviderImpl::QueryAvailableImpl,
149 weak_factory_.GetWeakPtr(), cb));
150 }
151
152 void QueryAvailableImpl(const QueryAvailableCallback& cb) {
153 base::ThreadRestrictions::AssertIOAllowed();
154 CHECK(query_sequence_checker_.CalledOnValidSequence());
129 155
130 base::Optional<PpdProvider::AvailablePrintersMap> result = 156 base::Optional<PpdProvider::AvailablePrintersMap> result =
131 cache_->FindAvailablePrinters(); 157 cache_->FindAvailablePrinters();
132 if (result) { 158 if (result) {
133 // Satisfy from cache. 159 // Satisfy from cache.
134 base::SequencedTaskRunnerHandle::Get()->PostTask( 160 query_done_task_runner_->PostTask(
135 FROM_HERE, base::Bind(cb, PpdProvider::SUCCESS, result.value())); 161 FROM_HERE, base::Bind(cb, PpdProvider::SUCCESS, result.value()));
136 return; 162 return;
137 } 163 }
138 // Not in the cache, ask QuirksServer. 164 // Not in the cache, ask QuirksServer.
139 query_done_callback_ = cb; 165 query_done_callback_ = cb;
140 166
141 query_fetcher_ = 167 query_fetcher_ =
142 net::URLFetcher::Create(GetQuirksServerPpdListURL(), 168 net::URLFetcher::Create(GetQuirksServerPpdListURL(),
143 net::URLFetcher::GET, &forwarding_delegate_); 169 net::URLFetcher::GET, &forwarding_delegate_);
144 query_fetcher_->SetRequestContext(url_context_getter_.get()); 170 query_fetcher_->SetRequestContext(url_context_getter_.get());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 // fetch. 208 // fetch.
183 void OnResolveFetchComplete() { 209 void OnResolveFetchComplete() {
184 CHECK(resolve_sequence_checker_.CalledOnValidSequence()); 210 CHECK(resolve_sequence_checker_.CalledOnValidSequence());
185 // Scope the allocated |resolve_fetcher_| into this function so we clean it 211 // Scope the allocated |resolve_fetcher_| into this function so we clean it
186 // up when we're done here instead of leaving it around until the next 212 // up when we're done here instead of leaving it around until the next
187 // Resolve() call. 213 // Resolve() call.
188 auto fetcher = std::move(resolve_fetcher_); 214 auto fetcher = std::move(resolve_fetcher_);
189 std::string contents; 215 std::string contents;
190 if (!ValidateAndGetResponseAsString(*fetcher, &contents)) { 216 if (!ValidateAndGetResponseAsString(*fetcher, &contents)) {
191 // Something went wrong with the fetch. 217 // Something went wrong with the fetch.
192 resolve_done_callback_.Run(PpdProvider::SERVER_ERROR, base::FilePath()); 218 resolve_done_task_runner_->PostTask(
219 FROM_HERE, base::Bind(resolve_done_callback_,
220 PpdProvider::SERVER_ERROR, base::FilePath()));
193 return; 221 return;
194 } 222 }
195 223
196 auto dict = base::DictionaryValue::From(base::JSONReader::Read(contents)); 224 auto dict = base::DictionaryValue::From(base::JSONReader::Read(contents));
197 if (dict == nullptr) { 225 if (dict == nullptr) {
198 resolve_done_callback_.Run(PpdProvider::SERVER_ERROR, base::FilePath()); 226 resolve_done_task_runner_->PostTask(
227 FROM_HERE, base::Bind(resolve_done_callback_,
228 PpdProvider::SERVER_ERROR, base::FilePath()));
199 return; 229 return;
200 } 230 }
201 std::string ppd_contents; 231 std::string ppd_contents;
202 std::string last_updated_time_string; 232 std::string last_updated_time_string;
203 uint64_t last_updated_time; 233 uint64_t last_updated_time;
204 if (!(dict->GetString(kJSONPPDKey, &ppd_contents) && 234 if (!(dict->GetString(kJSONPPDKey, &ppd_contents) &&
205 dict->GetString(kJSONLastUpdatedKey, &last_updated_time_string) && 235 dict->GetString(kJSONLastUpdatedKey, &last_updated_time_string) &&
206 base::StringToUint64(last_updated_time_string, &last_updated_time))) { 236 base::StringToUint64(last_updated_time_string, &last_updated_time))) {
207 // Malformed response. TODO(justincarlson) - LOG something here? 237 // Malformed response. TODO(justincarlson) - LOG something here?
208 resolve_done_callback_.Run(PpdProvider::SERVER_ERROR, base::FilePath()); 238 resolve_done_task_runner_->PostTask(
239 FROM_HERE, base::Bind(resolve_done_callback_,
240 PpdProvider::SERVER_ERROR, base::FilePath()));
209 return; 241 return;
210 } 242 }
211 243
212 if (ppd_contents.size() > options_.max_ppd_contents_size_) { 244 if (ppd_contents.size() > options_.max_ppd_contents_size_) {
213 // PPD is too big. 245 // PPD is too big.
214 // 246 //
215 // Note -- if we ever add shared-ppd-sourcing, e.g. we may serve a ppd to 247 // Note -- if we ever add shared-ppd-sourcing, e.g. we may serve a ppd to
216 // a user that's not from an explicitly trusted source, we should also 248 // a user that's not from an explicitly trusted source, we should also
217 // check *uncompressed* size here to head off zip-bombs (e.g. let's 249 // check *uncompressed* size here to head off zip-bombs (e.g. let's
218 // compress 1GBs of zeros into a 900kb file and see what cups does when it 250 // compress 1GBs of zeros into a 900kb file and see what cups does when it
219 // tries to expand that...) 251 // tries to expand that...)
220 resolve_done_callback_.Run(PpdProvider::SERVER_ERROR, base::FilePath()); 252 resolve_done_callback_.Run(PpdProvider::SERVER_ERROR, base::FilePath());
221 return; 253 return;
222 } 254 }
223 255
224 auto ppd_file = cache_->Store(resolve_reference_, ppd_contents); 256 auto ppd_file = cache_->Store(resolve_reference_, ppd_contents);
225 if (!ppd_file) { 257 if (!ppd_file) {
226 // Failed to store. 258 // Failed to store.
227 resolve_done_callback_.Run(PpdProvider::INTERNAL_ERROR, base::FilePath()); 259 resolve_done_task_runner_->PostTask(
260 FROM_HERE, base::Bind(resolve_done_callback_,
261 PpdProvider::INTERNAL_ERROR, base::FilePath()));
228 return; 262 return;
229 } 263 }
230 resolve_done_callback_.Run(PpdProvider::SUCCESS, ppd_file.value()); 264 resolve_done_task_runner_->PostTask(
265 FROM_HERE, base::Bind(resolve_done_callback_, PpdProvider::SUCCESS,
266 ppd_file.value()));
231 } 267 }
232 268
233 // Called on the same thread as QueryAvailable() when the fetcher completes 269 // Called on the same thread as QueryAvailable() when the fetcher completes
234 // its fetch. 270 // its fetch.
235 void OnQueryAvailableFetchComplete() { 271 void OnQueryAvailableFetchComplete() {
236 CHECK(query_sequence_checker_.CalledOnValidSequence()); 272 CHECK(query_sequence_checker_.CalledOnValidSequence());
237 // Scope the object fetcher into this function so we clean it up when we're 273 // Scope the object fetcher into this function so we clean it up when we're
238 // done here instead of leaving it around until the next QueryAvailable() 274 // done here instead of leaving it around until the next QueryAvailable()
239 // call. 275 // call.
240 auto fetcher = std::move(query_fetcher_); 276 auto fetcher = std::move(query_fetcher_);
241 std::string contents; 277 std::string contents;
242 if (!ValidateAndGetResponseAsString(*fetcher, &contents)) { 278 if (!ValidateAndGetResponseAsString(*fetcher, &contents)) {
243 // Something went wrong with the fetch. 279 // Something went wrong with the fetch.
244 query_done_callback_.Run(PpdProvider::SERVER_ERROR, 280 query_done_task_runner_->PostTask(
245 AvailablePrintersMap()); 281 FROM_HERE, base::Bind(query_done_callback_, PpdProvider::SERVER_ERROR,
282 AvailablePrintersMap()));
246 return; 283 return;
247 } 284 }
248 285
249 // The server gives us JSON in the form of a list of (manufacturer, list of 286 // The server gives us JSON in the form of a list of (manufacturer, list of
250 // models) tuples. 287 // models) tuples.
251 auto top_dict = 288 auto top_dict =
252 base::DictionaryValue::From(base::JSONReader::Read(contents)); 289 base::DictionaryValue::From(base::JSONReader::Read(contents));
253 const base::ListValue* top_list; 290 const base::ListValue* top_list;
254 if (top_dict == nullptr || !top_dict->GetList(kJSONTopListKey, &top_list)) { 291 if (top_dict == nullptr || !top_dict->GetList(kJSONTopListKey, &top_list)) {
255 LOG(ERROR) << "Malformed response from quirks server"; 292 LOG(ERROR) << "Malformed response from quirks server";
256 query_done_callback_.Run(PpdProvider::SERVER_ERROR, 293 query_done_task_runner_->PostTask(
257 PpdProvider::AvailablePrintersMap()); 294 FROM_HERE, base::Bind(query_done_callback_, PpdProvider::SERVER_ERROR,
295 AvailablePrintersMap()));
258 return; 296 return;
259 } 297 }
260 298
261 PpdProvider::AvailablePrintersMap result; 299 PpdProvider::AvailablePrintersMap result;
262 for (const std::unique_ptr<base::Value>& entry : *top_list) { 300 for (const std::unique_ptr<base::Value>& entry : *top_list) {
263 base::DictionaryValue* dict; 301 base::DictionaryValue* dict;
264 std::string manufacturer; 302 std::string manufacturer;
265 std::string model; 303 std::string model;
266 base::ListValue* model_list; 304 base::ListValue* model_list;
267 if (!entry->GetAsDictionary(&dict) || 305 if (!entry->GetAsDictionary(&dict) ||
(...skipping 16 matching lines...) Expand all
284 } 322 }
285 if (!result.empty()) { 323 if (!result.empty()) {
286 cache_->StoreAvailablePrinters(result); 324 cache_->StoreAvailablePrinters(result);
287 } else { 325 } else {
288 // An empty map means something is probably wrong; if we cache this map, 326 // An empty map means something is probably wrong; if we cache this map,
289 // we'll have an empty map until the cache expires. So complain and 327 // we'll have an empty map until the cache expires. So complain and
290 // refuse to cache. 328 // refuse to cache.
291 LOG(ERROR) << "Available printers map is unexpectedly empty. Refusing " 329 LOG(ERROR) << "Available printers map is unexpectedly empty. Refusing "
292 "to cache this."; 330 "to cache this.";
293 } 331 }
294 query_done_callback_.Run(PpdProvider::SUCCESS, result); 332 query_done_task_runner_->PostTask(
333 FROM_HERE,
334 base::Bind(query_done_callback_, PpdProvider::SUCCESS, result));
295 } 335 }
296 336
297 // Generate a url to look up a manufacturer/model from the quirks server 337 // Generate a url to look up a manufacturer/model from the quirks server
298 GURL GetQuirksServerPpdLookupURL( 338 GURL GetQuirksServerPpdLookupURL(
299 const Printer::PpdReference& ppd_reference) const { 339 const Printer::PpdReference& ppd_reference) const {
300 return GURL(base::StringPrintf( 340 return GURL(base::StringPrintf(
301 "https://%s/v2/printer/manufacturers/%s/models/%s?key=%s", 341 "https://%s/v2/printer/manufacturers/%s/models/%s?key=%s",
302 options_.quirks_server.c_str(), 342 options_.quirks_server.c_str(),
303 ppd_reference.effective_manufacturer.c_str(), 343 ppd_reference.effective_manufacturer.c_str(),
304 ppd_reference.effective_model.c_str(), api_key_.c_str())); 344 ppd_reference.effective_model.c_str(), api_key_.c_str()));
(...skipping 14 matching lines...) Expand all
319 return ((fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) && 359 return ((fetcher.GetStatus().status() == net::URLRequestStatus::SUCCESS) &&
320 (fetcher.GetResponseCode() == net::HTTP_OK) && 360 (fetcher.GetResponseCode() == net::HTTP_OK) &&
321 fetcher.GetResponseAsString(contents)); 361 fetcher.GetResponseAsString(contents));
322 } 362 }
323 363
324 // State held across a Resolve() call. 364 // State held across a Resolve() call.
325 365
326 // Reference we're currently trying to resolve. 366 // Reference we're currently trying to resolve.
327 Printer::PpdReference resolve_reference_; 367 Printer::PpdReference resolve_reference_;
328 368
369 // TaskRunner on which to invoke the Resolve callback;
370 scoped_refptr<base::SequencedTaskRunner> resolve_done_task_runner_;
371
329 // Callback to invoke on completion. 372 // Callback to invoke on completion.
330 PpdProvider::ResolveCallback resolve_done_callback_; 373 PpdProvider::ResolveCallback resolve_done_callback_;
331 374
332 // Check that Resolve() and its callback are sequenced appropriately. 375 // Check that Resolve() and its callback are sequenced appropriately.
333 base::SequenceChecker resolve_sequence_checker_; 376 base::SequenceChecker resolve_sequence_checker_;
334 377
335 // Fetcher for the current call, if any. 378 // Fetcher for the current call, if any.
336 std::unique_ptr<net::URLFetcher> resolve_fetcher_; 379 std::unique_ptr<net::URLFetcher> resolve_fetcher_;
337 380
338 // State held across a QueryAvailable() call. 381 // State held across a QueryAvailable() call.
339 382
340 // Callback to invoke on completion. 383 // Callback to invoke on completion.
341 PpdProvider::QueryAvailableCallback query_done_callback_; 384 PpdProvider::QueryAvailableCallback query_done_callback_;
342 385
386 // TaskRunner on which to invoke the Query Available callback;
387 scoped_refptr<base::SequencedTaskRunner> query_done_task_runner_;
388
343 // Check that QueryAvailable() and its callback are sequenced appropriately. 389 // Check that QueryAvailable() and its callback are sequenced appropriately.
344 base::SequenceChecker query_sequence_checker_; 390 base::SequenceChecker query_sequence_checker_;
345 391
346 // Fetcher for the current call, if any. 392 // Fetcher for the current call, if any.
347 std::unique_ptr<net::URLFetcher> query_fetcher_; 393 std::unique_ptr<net::URLFetcher> query_fetcher_;
348 394
349 // Common state. 395 // Common state.
350 396
351 // API key for accessing quirks server. 397 // API key for accessing quirks server.
352 const std::string api_key_; 398 const std::string api_key_;
353 399
354 ForwardingURLFetcherDelegate forwarding_delegate_; 400 ForwardingURLFetcherDelegate forwarding_delegate_;
355 scoped_refptr<net::URLRequestContextGetter> url_context_getter_; 401 scoped_refptr<net::URLRequestContextGetter> url_context_getter_;
402 scoped_refptr<base::SequencedTaskRunner> disk_task_runner_;
356 std::unique_ptr<PpdCache> cache_; 403 std::unique_ptr<PpdCache> cache_;
357 404
358 // Construction-time options, immutable. 405 // Construction-time options, immutable.
359 const PpdProvider::Options options_; 406 const PpdProvider::Options options_;
407
408 base::WeakPtrFactory<PpdProviderImpl> weak_factory_;
360 }; 409 };
361 410
362 void ForwardingURLFetcherDelegate::OnURLFetchComplete( 411 void ForwardingURLFetcherDelegate::OnURLFetchComplete(
363 const net::URLFetcher* source) { 412 const net::URLFetcher* source) {
364 owner_->OnURLFetchComplete(source); 413 owner_->OnURLFetchComplete(source);
365 } 414 }
366 415
367 } // namespace 416 } // namespace
368 417
369 // static 418 // static
370 std::unique_ptr<PpdProvider> PpdProvider::Create( 419 std::unique_ptr<PpdProvider> PpdProvider::Create(
371 const std::string& api_key, 420 const std::string& api_key,
372 scoped_refptr<net::URLRequestContextGetter> url_context_getter, 421 net::URLRequestContextGetter* url_context_getter,
422 base::SequencedTaskRunner* disk_task_runner,
373 std::unique_ptr<PpdCache> cache, 423 std::unique_ptr<PpdCache> cache,
374 const PpdProvider::Options& options) { 424 const PpdProvider::Options& options) {
375 return base::MakeUnique<PpdProviderImpl>(api_key, url_context_getter, 425 return base::MakeUnique<PpdProviderImpl>(
376 std::move(cache), options); 426 api_key, url_context_getter, disk_task_runner, std::move(cache), options);
377 } 427 }
378 428
379 } // namespace printing 429 } // namespace printing
380 } // namespace chromeos 430 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698