| 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_cache.h" | 5 #include "chromeos/printing/ppd_cache.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 ret = contents_path; | 61 ret = contents_path; |
| 62 break; | 62 break; |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 return ret; | 65 return ret; |
| 66 } | 66 } |
| 67 | 67 |
| 68 base::Optional<base::FilePath> Store( | 68 base::Optional<base::FilePath> Store( |
| 69 const Printer::PpdReference& reference, | 69 const Printer::PpdReference& reference, |
| 70 const std::string& ppd_contents) override { | 70 const std::string& ppd_contents) override { |
| 71 base::ThreadRestrictions::AssertIOAllowed(); |
| 72 if (!EnsureCacheDirectoryExists()) { |
| 73 return base::nullopt; |
| 74 } |
| 71 base::Optional<base::FilePath> ret; | 75 base::Optional<base::FilePath> ret; |
| 72 base::FilePath contents_path = | 76 base::FilePath contents_path = |
| 73 GetCachePathBase(reference).AddExtension(".ppd"); | 77 GetCachePathBase(reference).AddExtension(".ppd"); |
| 74 if (IsGZipped(ppd_contents)) { | 78 if (IsGZipped(ppd_contents)) { |
| 75 contents_path = contents_path.AddExtension(".gz"); | 79 contents_path = contents_path.AddExtension(".gz"); |
| 76 } | 80 } |
| 77 if (base::WriteFile(contents_path, ppd_contents.data(), | 81 if (base::WriteFile(contents_path, ppd_contents.data(), |
| 78 ppd_contents.size()) == | 82 ppd_contents.size()) == |
| 79 static_cast<int>(ppd_contents.size())) { | 83 static_cast<int>(ppd_contents.size())) { |
| 80 ret = contents_path; | 84 ret = contents_path; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } | 138 } |
| 135 return available_printers_.get(); | 139 return available_printers_.get(); |
| 136 } | 140 } |
| 137 | 141 |
| 138 // Note we throw up our hands and fail (gracefully) to store if we encounter | 142 // Note we throw up our hands and fail (gracefully) to store if we encounter |
| 139 // non-unicode things in the strings of |available_printers|. Since these | 143 // non-unicode things in the strings of |available_printers|. Since these |
| 140 // strings come from a source we control, being less paranoid about these | 144 // strings come from a source we control, being less paranoid about these |
| 141 // values seems reasonable. | 145 // values seems reasonable. |
| 142 void StoreAvailablePrinters(std::unique_ptr<PpdProvider::AvailablePrintersMap> | 146 void StoreAvailablePrinters(std::unique_ptr<PpdProvider::AvailablePrintersMap> |
| 143 available_printers) override { | 147 available_printers) override { |
| 148 base::ThreadRestrictions::AssertIOAllowed(); |
| 149 if (!EnsureCacheDirectoryExists()) { |
| 150 return; |
| 151 } |
| 144 available_printers_ = std::move(available_printers); | 152 available_printers_ = std::move(available_printers); |
| 145 available_printers_timestamp_ = base::Time::Now(); | 153 available_printers_timestamp_ = base::Time::Now(); |
| 146 // Convert the map to Values, in preparation for jsonification. | 154 // Convert the map to Values, in preparation for jsonification. |
| 147 base::DictionaryValue top_level; | 155 base::DictionaryValue top_level; |
| 148 for (const auto& entry : *available_printers_) { | 156 for (const auto& entry : *available_printers_) { |
| 149 auto printers = base::MakeUnique<base::ListValue>(); | 157 auto printers = base::MakeUnique<base::ListValue>(); |
| 150 printers->AppendStrings(entry.second); | 158 printers->AppendStrings(entry.second); |
| 151 top_level.Set(entry.first, std::move(printers)); | 159 top_level.Set(entry.first, std::move(printers)); |
| 152 } | 160 } |
| 153 std::string contents; | 161 std::string contents; |
| 154 if (!base::JSONWriter::Write(top_level, &contents)) { | 162 if (!base::JSONWriter::Write(top_level, &contents)) { |
| 155 LOG(ERROR) << "Failed to generate JSON"; | 163 LOG(ERROR) << "Failed to generate JSON"; |
| 156 return; | 164 return; |
| 157 } | 165 } |
| 158 if (contents.size() > options_.max_available_list_cached_size) { | 166 if (contents.size() > options_.max_available_list_cached_size) { |
| 159 LOG(ERROR) << "Serialized available printers list too large (size is " | 167 LOG(ERROR) << "Serialized available printers list too large (size is " |
| 160 << contents.size() << " bytes)"; | 168 << contents.size() << " bytes)"; |
| 161 return; | 169 return; |
| 162 } | 170 } |
| 163 if (base::WriteFile(available_printers_file_, contents.data(), | 171 if (base::WriteFile(available_printers_file_, contents.data(), |
| 164 contents.size()) != static_cast<int>(contents.size())) { | 172 contents.size()) != static_cast<int>(contents.size())) { |
| 165 LOG(ERROR) << "Failed to write available printers cache to " | 173 LOG(ERROR) << "Failed to write available printers cache to " |
| 166 << available_printers_file_.MaybeAsASCII(); | 174 << available_printers_file_.MaybeAsASCII(); |
| 167 } | 175 } |
| 168 } | 176 } |
| 169 | 177 |
| 170 private: | 178 private: |
| 179 // Create the cache directory if it doesn't already exist. Returns true |
| 180 // on success. |
| 181 bool EnsureCacheDirectoryExists() { |
| 182 if (base::PathExists(cache_base_dir_) || |
| 183 base::CreateDirectory(cache_base_dir_)) { |
| 184 return true; |
| 185 } |
| 186 LOG(ERROR) << "Failed to create ppd cache directory " |
| 187 << cache_base_dir_.MaybeAsASCII(); |
| 188 return false; |
| 189 } |
| 190 |
| 171 // Get the file path at which we expect to find a PPD if it's cached. | 191 // Get the file path at which we expect to find a PPD if it's cached. |
| 172 // | 192 // |
| 173 // This is, ultimately, just a hash function. It's extremely infrequently | 193 // This is, ultimately, just a hash function. It's extremely infrequently |
| 174 // used (called once when trying to look up information on a printer or store | 194 // used (called once when trying to look up information on a printer or store |
| 175 // a PPD), and should be stable, as changing the function will make previously | 195 // a PPD), and should be stable, as changing the function will make previously |
| 176 // cached entries unfindable, causing resolve logic to be reinvoked | 196 // cached entries unfindable, causing resolve logic to be reinvoked |
| 177 // unnecessarily. | 197 // unnecessarily. |
| 178 // | 198 // |
| 179 // There's also a faint possibility that a bad actor might try to do something | 199 // There's also a faint possibility that a bad actor might try to do something |
| 180 // nefarious by intentionally causing a cache collision that makes the wrong | 200 // nefarious by intentionally causing a cache collision that makes the wrong |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 } // namespace | 292 } // namespace |
| 273 | 293 |
| 274 // static | 294 // static |
| 275 std::unique_ptr<PpdCache> PpdCache::Create(const base::FilePath& cache_base_dir, | 295 std::unique_ptr<PpdCache> PpdCache::Create(const base::FilePath& cache_base_dir, |
| 276 const PpdCache::Options& options) { | 296 const PpdCache::Options& options) { |
| 277 return base::MakeUnique<PpdCacheImpl>(cache_base_dir, options); | 297 return base::MakeUnique<PpdCacheImpl>(cache_base_dir, options); |
| 278 } | 298 } |
| 279 | 299 |
| 280 } // namespace printing | 300 } // namespace printing |
| 281 } // namespace chromeos | 301 } // namespace chromeos |
| OLD | NEW |