| 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/bind_helpers.h" |
| 9 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 10 #include "base/json/json_parser.h" | 11 #include "base/json/json_parser.h" |
| 11 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 12 #include "base/sequence_checker.h" | 13 #include "base/sequence_checker.h" |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 16 #include "base/task_runner_util.h" | 17 #include "base/task_runner_util.h" |
| 17 #include "base/threading/sequenced_task_runner_handle.h" | 18 #include "base/threading/sequenced_task_runner_handle.h" |
| 18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 << "Can't have concurrent PpdProvider Resolve calls"; | 86 << "Can't have concurrent PpdProvider Resolve calls"; |
| 86 resolve_inflight_ = true; | 87 resolve_inflight_ = true; |
| 87 auto cache_result = base::MakeUnique<base::Optional<base::FilePath>>(); | 88 auto cache_result = base::MakeUnique<base::Optional<base::FilePath>>(); |
| 88 auto* raw_cache_result_ptr = cache_result.get(); | 89 auto* raw_cache_result_ptr = cache_result.get(); |
| 89 bool post_result = io_task_runner_->PostTaskAndReply( | 90 bool post_result = io_task_runner_->PostTaskAndReply( |
| 90 FROM_HERE, base::Bind(&PpdProviderImpl::ResolveDoCacheLookup, | 91 FROM_HERE, base::Bind(&PpdProviderImpl::ResolveDoCacheLookup, |
| 91 weak_factory_.GetWeakPtr(), ppd_reference, | 92 weak_factory_.GetWeakPtr(), ppd_reference, |
| 92 raw_cache_result_ptr), | 93 raw_cache_result_ptr), |
| 93 base::Bind(&PpdProviderImpl::ResolveCacheLookupDone, | 94 base::Bind(&PpdProviderImpl::ResolveCacheLookupDone, |
| 94 weak_factory_.GetWeakPtr(), ppd_reference, cb, | 95 weak_factory_.GetWeakPtr(), ppd_reference, cb, |
| 95 std::move(cache_result))); | 96 base::Passed(&cache_result))); |
| 96 DCHECK(post_result); | 97 DCHECK(post_result); |
| 97 } | 98 } |
| 98 | 99 |
| 99 void QueryAvailable(const QueryAvailableCallback& cb) override { | 100 void QueryAvailable(const QueryAvailableCallback& cb) override { |
| 100 CHECK(!cb.is_null()); | 101 CHECK(!cb.is_null()); |
| 101 CHECK(base::SequencedTaskRunnerHandle::IsSet()) | 102 CHECK(base::SequencedTaskRunnerHandle::IsSet()) |
| 102 << "QueryAvailable() must be called from a SequencedTaskRunner context"; | 103 << "QueryAvailable() must be called from a SequencedTaskRunner context"; |
| 103 auto cache_result = base::MakeUnique< | 104 auto cache_result = base::MakeUnique< |
| 104 base::Optional<const PpdProvider::AvailablePrintersMap*>>(); | 105 base::Optional<const PpdProvider::AvailablePrintersMap*>>(); |
| 105 CHECK(!query_inflight_) | 106 CHECK(!query_inflight_) |
| 106 << "Can't have concurrent PpdProvider QueryAvailable calls"; | 107 << "Can't have concurrent PpdProvider QueryAvailable calls"; |
| 107 query_inflight_ = true; | 108 query_inflight_ = true; |
| 108 auto* raw_cache_result_ptr = cache_result.get(); | 109 auto* raw_cache_result_ptr = cache_result.get(); |
| 109 CHECK(io_task_runner_->PostTaskAndReply( | 110 CHECK(io_task_runner_->PostTaskAndReply( |
| 110 FROM_HERE, base::Bind(&PpdProviderImpl::QueryAvailableDoCacheLookup, | 111 FROM_HERE, base::Bind(&PpdProviderImpl::QueryAvailableDoCacheLookup, |
| 111 weak_factory_.GetWeakPtr(), raw_cache_result_ptr), | 112 weak_factory_.GetWeakPtr(), raw_cache_result_ptr), |
| 112 base::Bind(&PpdProviderImpl::QueryAvailableCacheLookupDone, | 113 base::Bind(&PpdProviderImpl::QueryAvailableCacheLookupDone, |
| 113 weak_factory_.GetWeakPtr(), cb, std::move(cache_result)))); | 114 weak_factory_.GetWeakPtr(), cb, std::move(cache_result)))); |
| 114 } | 115 } |
| 115 | 116 |
| 116 bool CachePpd(const Printer::PpdReference& ppd_reference, | 117 bool CachePpd(const Printer::PpdReference& ppd_reference, |
| 117 const base::FilePath& ppd_path) override { | 118 const base::FilePath& ppd_path) override { |
| 119 VLOG(1) << "Caching PPD"; |
| 118 std::string buf; | 120 std::string buf; |
| 119 if (!base::ReadFileToStringWithMaxSize(ppd_path, &buf, | 121 if (!base::ReadFileToStringWithMaxSize(ppd_path, &buf, |
| 120 options_.max_ppd_contents_size_)) { | 122 options_.max_ppd_contents_size_)) { |
| 123 VLOG(1) << "Read bytes: " << buf.size() |
| 124 << " max: " << options_.max_ppd_contents_size_; |
| 125 LOG(WARNING) << "Failed to read ppd file " << ppd_path.value(); |
| 121 return false; | 126 return false; |
| 122 } | 127 } |
| 123 return static_cast<bool>(cache_->Store(ppd_reference, buf)); | 128 return static_cast<bool>(cache_->Store(ppd_reference, buf)); |
| 124 } | 129 } |
| 125 | 130 |
| 126 private: | 131 private: |
| 127 // Trivial wrappers around PpdCache::Find() and | 132 // Trivial wrappers around PpdCache::Find() and |
| 128 // PpdCache::FindAvailablePrinters(). We need these wrappers both because we | 133 // PpdCache::FindAvailablePrinters(). We need these wrappers both because we |
| 129 // use weak_ptrs to manage lifetime, and so we need to bind callbacks to | 134 // use weak_ptrs to manage lifetime, and so we need to bind callbacks to |
| 130 // *this*, and because weak_ptr's preclude return values in posted tasks, so | 135 // *this*, and because weak_ptr's preclude return values in posted tasks, so |
| 131 // we have to use a parameter to return state. | 136 // we have to use a parameter to return state. |
| 132 void ResolveDoCacheLookup( | 137 void ResolveDoCacheLookup( |
| 133 const Printer::PpdReference& reference, | 138 const Printer::PpdReference& reference, |
| 134 base::Optional<base::FilePath>* cache_result) const { | 139 base::Optional<base::FilePath>* cache_result) const { |
| 140 VLOG(1) << "Checking cache for result"; |
| 135 *cache_result = cache_->Find(reference); | 141 *cache_result = cache_->Find(reference); |
| 142 VLOG(1) << "result found? " << cache_result->has_value(); |
| 136 } | 143 } |
| 137 | 144 |
| 138 void QueryAvailableDoCacheLookup( | 145 void QueryAvailableDoCacheLookup( |
| 139 base::Optional<const PpdProvider::AvailablePrintersMap*>* cache_result) | 146 base::Optional<const PpdProvider::AvailablePrintersMap*>* cache_result) |
| 140 const { | 147 const { |
| 141 DCHECK(cache_result); | 148 DCHECK(cache_result); |
| 142 auto tmp = cache_->FindAvailablePrinters(); | 149 auto tmp = cache_->FindAvailablePrinters(); |
| 143 if (tmp != nullptr) { | 150 if (tmp != nullptr) { |
| 144 *cache_result = tmp; | 151 *cache_result = tmp; |
| 145 } else { | 152 } else { |
| 146 *cache_result = base::nullopt; | 153 *cache_result = base::nullopt; |
| 147 } | 154 } |
| 148 } | 155 } |
| 149 | 156 |
| 150 // Callback that happens when the Resolve() cache lookup completes. If the | 157 // Callback that happens when the Resolve() cache lookup completes. If the |
| 151 // cache satisfied the request, finish the Resolve, otherwise start a URL | 158 // cache satisfied the request, finish the Resolve, otherwise start a URL |
| 152 // request to satisfy the request. This runs on the same thread as Resolve() | 159 // request to satisfy the request. This runs on the same thread as Resolve() |
| 153 // was invoked on. | 160 // was invoked on. |
| 154 void ResolveCacheLookupDone( | 161 void ResolveCacheLookupDone( |
| 155 const Printer::PpdReference& ppd_reference, | 162 const Printer::PpdReference& ppd_reference, |
| 156 const PpdProvider::ResolveCallback& done_callback, | 163 const PpdProvider::ResolveCallback& done_callback, |
| 157 const std::unique_ptr<base::Optional<base::FilePath>>& cache_result) { | 164 const std::unique_ptr<base::Optional<base::FilePath>>& cache_result) { |
| 158 CHECK(resolve_sequence_checker_.CalledOnValidSequence()); | 165 CHECK(resolve_sequence_checker_.CalledOnValidSequence()); |
| 159 if (*cache_result) { | 166 if (*cache_result) { |
| 167 VLOG(1) << "Cache hit!"; |
| 160 // Cache hit. Schedule the callback now and return. | 168 // Cache hit. Schedule the callback now and return. |
| 161 resolve_inflight_ = false; | 169 resolve_inflight_ = false; |
| 162 done_callback.Run(PpdProvider::SUCCESS, cache_result->value()); | 170 done_callback.Run(PpdProvider::SUCCESS, cache_result->value()); |
| 163 return; | 171 return; |
| 164 } | 172 } |
| 165 | 173 |
| 166 // We don't have a way to automatically resolve user-supplied PPDs yet. So | 174 // We don't have a way to automatically resolve user-supplied PPDs yet. So |
| 167 // if we have one specified, and it's not cached, we fail out rather than | 175 // if we have one specified, and it's not cached, we fail out rather than |
| 168 // fall back to quirks-server based resolution. The reasoning here is that | 176 // fall back to quirks-server based resolution. The reasoning here is that |
| 169 // if the user has specified a PPD when a quirks-server one exists, it | 177 // if the user has specified a PPD when a quirks-server one exists, it |
| 170 // probably means the quirks server one doesn't work for some reason, so we | 178 // probably means the quirks server one doesn't work for some reason, so we |
| 171 // shouldn't silently use it. | 179 // shouldn't silently use it. |
| 172 if (!ppd_reference.user_supplied_ppd_url.empty()) { | 180 if (!ppd_reference.user_supplied_ppd_url.empty()) { |
| 181 VLOG(1) << "Input error"; |
| 173 resolve_inflight_ = false; | 182 resolve_inflight_ = false; |
| 174 done_callback.Run(PpdProvider::NOT_FOUND, base::FilePath()); | 183 done_callback.Run(PpdProvider::NOT_FOUND, base::FilePath()); |
| 175 return; | 184 return; |
| 176 } | 185 } |
| 177 | 186 |
| 187 VLOG(1) << "Perform PPD download"; |
| 178 // Missed in the cache, so start a URLRequest to resolve the request. | 188 // Missed in the cache, so start a URLRequest to resolve the request. |
| 179 resolve_fetcher_delegate_ = base::MakeUnique<ForwardingURLFetcherDelegate>( | 189 resolve_fetcher_delegate_ = base::MakeUnique<ForwardingURLFetcherDelegate>( |
| 180 base::Bind(&PpdProviderImpl::OnResolveFetchComplete, | 190 base::Bind(&PpdProviderImpl::OnResolveFetchComplete, |
| 181 weak_factory_.GetWeakPtr(), ppd_reference, done_callback)); | 191 weak_factory_.GetWeakPtr(), ppd_reference, done_callback)); |
| 182 | 192 |
| 183 resolve_fetcher_ = net::URLFetcher::Create( | 193 resolve_fetcher_ = net::URLFetcher::Create( |
| 184 GetQuirksServerPpdLookupURL(ppd_reference), net::URLFetcher::GET, | 194 GetQuirksServerPpdLookupURL(ppd_reference), net::URLFetcher::GET, |
| 185 resolve_fetcher_delegate_.get()); | 195 resolve_fetcher_delegate_.get()); |
| 186 | 196 |
| 187 resolve_fetcher_->SetRequestContext(url_context_getter_.get()); | 197 resolve_fetcher_->SetRequestContext(url_context_getter_.get()); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 scoped_refptr<net::URLRequestContextGetter> url_context_getter, | 429 scoped_refptr<net::URLRequestContextGetter> url_context_getter, |
| 420 scoped_refptr<base::SequencedTaskRunner> io_task_runner, | 430 scoped_refptr<base::SequencedTaskRunner> io_task_runner, |
| 421 std::unique_ptr<PpdCache> cache, | 431 std::unique_ptr<PpdCache> cache, |
| 422 const PpdProvider::Options& options) { | 432 const PpdProvider::Options& options) { |
| 423 return base::MakeUnique<PpdProviderImpl>( | 433 return base::MakeUnique<PpdProviderImpl>( |
| 424 api_key, url_context_getter, io_task_runner, std::move(cache), options); | 434 api_key, url_context_getter, io_task_runner, std::move(cache), options); |
| 425 } | 435 } |
| 426 | 436 |
| 427 } // namespace printing | 437 } // namespace printing |
| 428 } // namespace chromeos | 438 } // namespace chromeos |
| OLD | NEW |