Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |