Commit 8fabb768 authored by Luum Habtemariam's avatar Luum Habtemariam Committed by Commit Bot

Migrate to metadata v2 and support PPD Restrictions

Update the GetPrintersURL call to utilize metadata_v2. This allows for certain
restrictions to be placed on the model to determine whether or not the printer should be displayed

Bug: chromium:773766
Change-Id: Iaade00489a066340a095b3b07bbd853f13f8e35a
Reviewed-on: https://chromium-review.googlesource.com/797476
Commit-Queue: Luum Habtemariam <luum@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521064}
parent 76107e3c
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chromeos/printing/ppd_cache.h" #include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_provider.h" #include "chromeos/printing/ppd_provider.h"
#include "components/version_info/version_info.h"
#include "google_apis/google_api_keys.h" #include "google_apis/google_api_keys.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
...@@ -22,7 +23,8 @@ scoped_refptr<PpdProvider> CreatePpdProvider(Profile* profile) { ...@@ -22,7 +23,8 @@ scoped_refptr<PpdProvider> CreatePpdProvider(Profile* profile) {
return PpdProvider::Create(g_browser_process->GetApplicationLocale(), return PpdProvider::Create(g_browser_process->GetApplicationLocale(),
g_browser_process->system_request_context(), g_browser_process->system_request_context(),
PpdCache::Create(ppd_cache_path)); PpdCache::Create(ppd_cache_path),
base::Version(version_info::GetVersionNumber()));
} }
} // namespace chromeos } // namespace chromeos
...@@ -567,8 +567,8 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) { ...@@ -567,8 +567,8 @@ void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
// model. // model.
bool found = false; bool found = false;
for (const auto& resolved_printer : resolved_printers_[ppd_manufacturer]) { for (const auto& resolved_printer : resolved_printers_[ppd_manufacturer]) {
if (resolved_printer.first == ppd_model) { if (resolved_printer.name == ppd_model) {
*printer->mutable_ppd_reference() = resolved_printer.second; *(printer->mutable_ppd_reference()) = resolved_printer.ppd_ref;
found = true; found = true;
break; break;
} }
...@@ -745,7 +745,7 @@ void CupsPrintersHandler::ResolvePrintersDone( ...@@ -745,7 +745,7 @@ void CupsPrintersHandler::ResolvePrintersDone(
if (result_code == PpdProvider::SUCCESS) { if (result_code == PpdProvider::SUCCESS) {
resolved_printers_[manufacturer] = printers; resolved_printers_[manufacturer] = printers;
for (const auto& printer : printers) { for (const auto& printer : printers) {
printers_value->AppendString(printer.first); printers_value->AppendString(printer.name);
} }
} }
base::DictionaryValue response; base::DictionaryValue response;
......
...@@ -173,6 +173,69 @@ bool FetchFile(const GURL& url, std::string* file_contents) { ...@@ -173,6 +173,69 @@ bool FetchFile(const GURL& url, std::string* file_contents) {
return base::ReadFileToString(path, file_contents); return base::ReadFileToString(path, file_contents);
} }
// Constructs and returns a printers' restrictions parsed form |dict|.
PpdProvider::Restrictions ComputeRestrictions(const base::Value& dict) {
PpdProvider::Restrictions restrictions;
const base::Value* min_milestone =
dict.FindKeyOfType({"min_milestone"}, base::Value::Type::DOUBLE);
const base::Value* max_milestone =
dict.FindKeyOfType({"max_milestone"}, base::Value::Type::DOUBLE);
if (min_milestone)
restrictions.min_milestone =
base::Version(base::NumberToString(min_milestone->GetDouble()));
if (max_milestone)
restrictions.max_milestone =
base::Version(base::NumberToString(max_milestone->GetDouble()));
return restrictions;
}
// Returns true if this printer with these |restrictions| is permitted in the
// |current_version|.
bool IsPrinterPermitted(const PpdProvider::Restrictions& restrictions,
const base::Version& current_version) {
if (restrictions.min_milestone != base::Version("0.0") &&
restrictions.min_milestone > current_version)
return false;
if (restrictions.max_milestone != base::Version("0.0") &&
restrictions.max_milestone < current_version)
return false;
return true;
}
// Modifies |printers| by removing any restricted printers excluded from the
// current |version|, as judged by IsPrinterPermitted.
void FilterRestrictedPpdReferences(PpdProvider::ResolvedPrintersList& printers,
const base::Version& version) {
auto it = std::partition(
printers.begin(), printers.end(),
[&version](const PpdProvider::ResolvedPpdReference& printer) -> bool {
return IsPrinterPermitted(printer.restrictions, version);
});
for (auto ij = it; ij != printers.end(); ++ij) {
VLOG(1) << "Limitations exclude this model: " << ij->name;
}
printers.erase(it, printers.end());
}
// The result fields from a metadata_v2 resolve printers request
struct ResolvePrintersResponse {
// The name of the model of printer or printer line
std::string name;
// Cannonical name of this printer
std::string effective_make_and_model;
// The limitations on this model
PpdProvider::Restrictions restrictions;
};
struct ManufacturerMetadata { struct ManufacturerMetadata {
// Key used to look up the printer list on the server. This is initially // Key used to look up the printer list on the server. This is initially
// populated. // populated.
...@@ -180,7 +243,8 @@ struct ManufacturerMetadata { ...@@ -180,7 +243,8 @@ struct ManufacturerMetadata {
// Map from localized printer name to canonical-make-and-model string for // Map from localized printer name to canonical-make-and-model string for
// the given printer. Populated on demand. // the given printer. Populated on demand.
std::unique_ptr<std::unordered_map<std::string, std::string>> printers; std::unique_ptr<std::unordered_map<std::string, ResolvePrintersResponse>>
printers;
}; };
// A queued request to download printer information for a manufacturer. // A queued request to download printer information for a manufacturer.
...@@ -237,6 +301,7 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -237,6 +301,7 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
const std::string& browser_locale, const std::string& browser_locale,
scoped_refptr<net::URLRequestContextGetter> url_context_getter, scoped_refptr<net::URLRequestContextGetter> url_context_getter,
scoped_refptr<PpdCache> ppd_cache, scoped_refptr<PpdCache> ppd_cache,
const base::Version& current_version,
const PpdProvider::Options& options) const PpdProvider::Options& options)
: browser_locale_(browser_locale), : browser_locale_(browser_locale),
url_context_getter_(url_context_getter), url_context_getter_(url_context_getter),
...@@ -244,6 +309,7 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -244,6 +309,7 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
disk_task_runner_(base::CreateSequencedTaskRunnerWithTraits( disk_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
{base::TaskPriority::USER_VISIBLE, base::MayBlock(), {base::TaskPriority::USER_VISIBLE, base::MayBlock(),
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
version_(current_version),
options_(options), options_(options),
weak_factory_(this) {} weak_factory_(this) {}
...@@ -529,7 +595,7 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -529,7 +595,7 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
// Return the URL used to get a list of printers from the manufacturer |ref|. // Return the URL used to get a list of printers from the manufacturer |ref|.
GURL GetPrintersURL(const std::string& ref) { GURL GetPrintersURL(const std::string& ref) {
return GURL(base::StringPrintf( return GURL(base::StringPrintf(
"%s/metadata/%s", options_.ppd_server_root.c_str(), ref.c_str())); "%s/metadata_v2/%s", options_.ppd_server_root.c_str(), ref.c_str()));
} }
// Return the URL used to get a ppd with the given filename. // Return the URL used to get a ppd with the given filename.
...@@ -701,9 +767,11 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -701,9 +767,11 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
void OnPrintersFetchComplete() { void OnPrintersFetchComplete() {
CHECK(cached_metadata_.get() != nullptr); CHECK(cached_metadata_.get() != nullptr);
DCHECK(!printers_resolution_queue_.empty()); DCHECK(!printers_resolution_queue_.empty());
std::vector<std::pair<std::string, std::string>> contents; std::vector<ResolvePrintersResponse> contents;
PpdProvider::CallbackResultCode code = PpdProvider::CallbackResultCode code =
ValidateAndParseJSONResponse(&contents); ValidateAndParsePrintersJSON(&contents);
if (code != PpdProvider::SUCCESS) { if (code != PpdProvider::SUCCESS) {
base::SequencedTaskRunnerHandle::Get()->PostTask( base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(printers_resolution_queue_.front().cb, code, FROM_HERE, base::Bind(printers_resolution_queue_.front().cb, code,
...@@ -723,12 +791,15 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -723,12 +791,15 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
// Create the printer map in the cache, and populate it. // Create the printer map in the cache, and populate it.
auto& manufacturer_metadata = it->second; auto& manufacturer_metadata = it->second;
CHECK(manufacturer_metadata.printers.get() == nullptr); CHECK(manufacturer_metadata.printers.get() == nullptr);
manufacturer_metadata.printers = manufacturer_metadata.printers = base::MakeUnique<
std::make_unique<std::unordered_map<std::string, std::string>>(); std::unordered_map<std::string, ResolvePrintersResponse>>();
for (const auto& entry : contents) { for (const auto& entry : contents) {
manufacturer_metadata.printers->insert({entry.first, entry.second}); manufacturer_metadata.printers->insert(
{entry.name,
{entry.name, entry.effective_make_and_model, entry.restrictions}});
} }
base::SequencedTaskRunnerHandle::Get()->PostTask( base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(printers_resolution_queue_.front().cb, base::Bind(printers_resolution_queue_.front().cb,
...@@ -1081,8 +1152,8 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -1081,8 +1152,8 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
// [manufacturer], [model], [dictionary of metadata]} // [manufacturer], [model], [dictionary of metadata]}
for (const auto& entry : *top_list) { for (const auto& entry : *top_list) {
if (!entry.is_list()) { if (!entry.is_list()) {
LOG(WARNING) << "Retrieved data in unexpected format. Data should be " LOG(ERROR) << "Retrieved data in unexpected format. Data should be "
"in list format"; "in list format";
return PpdProvider::INTERNAL_ERROR; return PpdProvider::INTERNAL_ERROR;
} }
...@@ -1105,6 +1176,65 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -1105,6 +1176,65 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
return PpdProvider::SUCCESS; return PpdProvider::SUCCESS;
} }
// For the metadata fetches that happens to be in the form of a JSON
// list-of-lists-of-2-strings and a dictionary of metadata (where the
// restrictions will be specified). This method attempts to parse a JSON
// reply from |fetcher| into |contents|.
// If parsed correctly, returns CallbackResultCode::SUCCESS. Else returns
// CallbackResultCode::FAILURE and clears |contents|.
PpdProvider::CallbackResultCode ValidateAndParsePrintersJSON(
std::vector<ResolvePrintersResponse>* contents) {
DCHECK(contents != NULL);
contents->clear();
std::string buffer;
auto fetch_result = ValidateAndGetResponseAsString(&buffer);
if (fetch_result != PpdProvider::SUCCESS) {
return fetch_result;
}
auto top_list = base::ListValue::From(base::JSONReader::Read(buffer));
if (top_list.get() == nullptr) {
return PpdProvider::INTERNAL_ERROR;
}
// Fetched data should be in form [[name], [canonical name],
// {restrictions}]
for (const auto& entry : *top_list) {
if (!entry.is_list()) {
LOG(ERROR) << "Retrieved data in unexpected format. Data should be "
"in list format";
return PpdProvider::INTERNAL_ERROR;
}
const base::Value::ListStorage& list = entry.GetList();
if (list.size() < 2 || !list[0].is_string() || !list[1].is_string()) {
LOG(ERROR) << "Retrived data in unexpected format. Expecting List of "
"2 strings, optionally followed by a dictionary";
return PpdProvider::INTERNAL_ERROR;
}
ResolvePrintersResponse rpr_entry;
rpr_entry.name = list[0].GetString();
rpr_entry.effective_make_and_model = list[1].GetString();
// Populate restrictions, if possible
if (list.size() >= 3) {
if (!list[2].is_dict()) {
LOG(ERROR) << "Retrived data in unexpected format. Expecting List of "
"2 strings, optionally followed by a dictionary";
return PpdProvider::INTERNAL_ERROR;
}
rpr_entry.restrictions = ComputeRestrictions(list[2]);
}
contents->push_back(rpr_entry);
}
return PpdProvider::SUCCESS;
}
// Create the list of manufacturers from |cached_metadata_|. Requires that // Create the list of manufacturers from |cached_metadata_|. Requires that
// the manufacturer list has already been resolved. // the manufacturer list has already been resolved.
std::vector<std::string> GetManufacturerList() const { std::vector<std::string> GetManufacturerList() const {
...@@ -1128,15 +1258,15 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -1128,15 +1258,15 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
ret.reserve(meta.printers->size()); ret.reserve(meta.printers->size());
for (const auto& entry : *meta.printers) { for (const auto& entry : *meta.printers) {
Printer::PpdReference ppd_ref; Printer::PpdReference ppd_ref;
ppd_ref.effective_make_and_model = entry.second; ppd_ref.effective_make_and_model = entry.second.effective_make_and_model;
ret.push_back({entry.first, ppd_ref}); ret.push_back({entry.first, entry.second.restrictions, ppd_ref});
} }
// TODO(justincarlson) -- this should be a localization-aware sort. // TODO(justincarlson) -- this should be a localization-aware sort.
sort(ret.begin(), ret.end(), sort(ret.begin(), ret.end(),
[](const std::pair<std::string, Printer::PpdReference>& a, [](const ResolvedPpdReference& a,
const std::pair<std::string, Printer::PpdReference>& b) -> bool { const ResolvedPpdReference& b) -> bool { return a.name < b.name; });
return a.first < b.first;
}); FilterRestrictedPpdReferences(ret, version_);
return ret; return ret;
} }
...@@ -1221,6 +1351,9 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate { ...@@ -1221,6 +1351,9 @@ class PpdProviderImpl : public PpdProvider, public net::URLFetcherDelegate {
// Where to run disk operations. // Where to run disk operations.
scoped_refptr<base::SequencedTaskRunner> disk_task_runner_; scoped_refptr<base::SequencedTaskRunner> disk_task_runner_;
// Current version used to filter restricted ppds
base::Version version_;
// Construction-time options, immutable. // Construction-time options, immutable.
const PpdProvider::Options options_; const PpdProvider::Options options_;
...@@ -1242,8 +1375,9 @@ scoped_refptr<PpdProvider> PpdProvider::Create( ...@@ -1242,8 +1375,9 @@ scoped_refptr<PpdProvider> PpdProvider::Create(
const std::string& browser_locale, const std::string& browser_locale,
scoped_refptr<net::URLRequestContextGetter> url_context_getter, scoped_refptr<net::URLRequestContextGetter> url_context_getter,
scoped_refptr<PpdCache> ppd_cache, scoped_refptr<PpdCache> ppd_cache,
const base::Version& current_version,
const PpdProvider::Options& options) { const PpdProvider::Options& options) {
return scoped_refptr<PpdProvider>(new PpdProviderImpl( return scoped_refptr<PpdProvider>(new PpdProviderImpl(
browser_locale, url_context_getter, ppd_cache, options)); browser_locale, url_context_getter, ppd_cache, current_version, options));
} }
} // namespace chromeos } // namespace chromeos
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/version.h"
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_configuration.h"
...@@ -78,6 +79,26 @@ class CHROMEOS_EXPORT PpdProvider : public base::RefCounted<PpdProvider> { ...@@ -78,6 +79,26 @@ class CHROMEOS_EXPORT PpdProvider : public base::RefCounted<PpdProvider> {
int usb_product_id = 0; int usb_product_id = 0;
}; };
// Defines the limitations on when we show a particular PPD
struct Restrictions {
// Minimum milestone for ChromeOS build
base::Version min_milestone = base::Version("0.0");
// Maximum milestone for ChomeOS build
base::Version max_milestone = base::Version("0.0");
};
struct ResolvedPpdReference {
// The name of the model of printer or printer line
std::string name;
// The limitations on this model
Restrictions restrictions;
// Correct PpdReferece to be used with this printer
Printer::PpdReference ppd_ref;
};
// Result of a ResolvePpd() call. // Result of a ResolvePpd() call.
// If the result code is SUCCESS, then: // If the result code is SUCCESS, then:
// string holds the contents of a PPD (that may or may not be gzipped). // string holds the contents of a PPD (that may or may not be gzipped).
...@@ -96,8 +117,7 @@ class CHROMEOS_EXPORT PpdProvider : public base::RefCounted<PpdProvider> { ...@@ -96,8 +117,7 @@ class CHROMEOS_EXPORT PpdProvider : public base::RefCounted<PpdProvider> {
// A list of printer names paired with the PpdReference that should be used // A list of printer names paired with the PpdReference that should be used
// for that printer. // for that printer.
using ResolvedPrintersList = using ResolvedPrintersList = std::vector<ResolvedPpdReference>;
std::vector<std::pair<std::string, Printer::PpdReference>>;
// Result of a ResolvePrinters() call. If the result code is SUCCESS, then // Result of a ResolvePrinters() call. If the result code is SUCCESS, then
// the vector contains a sorted list <model_name, PpdReference> tuples of all // the vector contains a sorted list <model_name, PpdReference> tuples of all
...@@ -128,6 +148,7 @@ class CHROMEOS_EXPORT PpdProvider : public base::RefCounted<PpdProvider> { ...@@ -128,6 +148,7 @@ class CHROMEOS_EXPORT PpdProvider : public base::RefCounted<PpdProvider> {
const std::string& browser_locale, const std::string& browser_locale,
scoped_refptr<net::URLRequestContextGetter> url_context_getter, scoped_refptr<net::URLRequestContextGetter> url_context_getter,
scoped_refptr<PpdCache> cache, scoped_refptr<PpdCache> cache,
const base::Version& current_version,
const Options& options = Options()); const Options& options = Options());
// Get all manufacturers for which we have drivers. Keys of the map will be // Get all manufacturers for which we have drivers. Keys of the map will be
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/test/test_message_loop.h" #include "base/test/test_message_loop.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "chromeos/chromeos_paths.h" #include "chromeos/chromeos_paths.h"
#include "chromeos/printing/ppd_cache.h" #include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_provider.h" #include "chromeos/printing/ppd_provider.h"
...@@ -80,7 +81,7 @@ class PpdProviderTest : public ::testing::Test { ...@@ -80,7 +81,7 @@ class PpdProviderTest : public ::testing::Test {
return PpdProvider::Create(locale, request_context_getter_.get(), return PpdProvider::Create(locale, request_context_getter_.get(),
PpdCache::Create(ppd_cache_temp_dir_.GetPath()), PpdCache::Create(ppd_cache_temp_dir_.GetPath()),
provider_options); base::Version("40.8.6753.09"), provider_options);
} }
// Create an interceptor that serves a small fileset of ppd server files. // Create an interceptor that serves a small fileset of ppd server files.
...@@ -100,7 +101,9 @@ class PpdProviderTest : public ::testing::Test { ...@@ -100,7 +101,9 @@ class PpdProviderTest : public ::testing::Test {
R"([ R"([
["printer_a_ref", "printer_a.ppd"], ["printer_a_ref", "printer_a.ppd"],
["printer_b_ref", "printer_b.ppd"], ["printer_b_ref", "printer_b.ppd"],
["printer_c_ref", "printer_c.ppd"] ["printer_c_ref", "printer_c.ppd"],
["printer_d_ref", "printer_d.ppd"],
["printer_e_ref", "printer_e.ppd"]
])"}, ])"},
{"metadata/usb-031f.json", {"metadata/usb-031f.json",
R"([ R"([
...@@ -126,10 +129,21 @@ class PpdProviderTest : public ::testing::Test { ...@@ -126,10 +129,21 @@ class PpdProviderTest : public ::testing::Test {
R"([ R"([
["printer_a", "printer_a_ref"], ["printer_a", "printer_a_ref"],
["printer_b", "printer_b_ref"] ["printer_b", "printer_b_ref"]
["printer_d", "printer_d_ref"]
])"},
{"metadata_v2/manufacturer_a.json",
R"([
["printer_a", "printer_a_ref",
{"min_milestone":25.0000}],
["printer_b", "printer_b_ref",
{"min_milestone":30.0000, "max_milestone":45.0000}],
["printer_d", "printer_d_ref",
{"min_milestone":60.0000, "max_milestone":75.0000}]
])"}, ])"},
{"metadata/manufacturer_b.json", {"metadata/manufacturer_b.json",
R"([ R"([
["printer_c", "printer_c_ref"] ["printer_c", "printer_c_ref"],
["printer_e", "printer_e_ref"]
])"}, ])"},
{"metadata_v2/reverse_index-en-01.json", {"metadata_v2/reverse_index-en-01.json",
R"([ R"([
...@@ -138,9 +152,18 @@ class PpdProviderTest : public ::testing::Test { ...@@ -138,9 +152,18 @@ class PpdProviderTest : public ::testing::Test {
{"metadata_v2/reverse_index-en-19.json", {"metadata_v2/reverse_index-en-19.json",
R"([ R"([
])"}, ])"},
{"metadata_v2/manufacturer_b.json",
R"([
["printer_c", "printer_c_ref",
{"max_milestone":55.0000}],
["printer_e", "printer_e_ref",
{"min_milestone":17.0000, "max_milestone":33.0000}]
])"},
{"ppds/printer_a.ppd", kCupsFilterPpdContents}, {"ppds/printer_a.ppd", kCupsFilterPpdContents},
{"ppds/printer_b.ppd", kCupsFilter2PpdContents}, {"ppds/printer_b.ppd", kCupsFilter2PpdContents},
{"ppds/printer_c.ppd", "c"}, {"ppds/printer_c.ppd", "c"},
{"ppds/printer_d.ppd", "d"},
{"ppds/printer_e.ppd", "e"},
{"user_supplied_ppd_directory/user_supplied.ppd", "u"}}; {"user_supplied_ppd_directory/user_supplied.ppd", "u"}};
int next_file_num = 0; int next_file_num = 0;
for (const auto& entry : server_contents) { for (const auto& entry : server_contents) {
...@@ -434,6 +457,7 @@ TEST_F(PpdProviderTest, ResolvePrinters) { ...@@ -434,6 +457,7 @@ TEST_F(PpdProviderTest, ResolvePrinters) {
provider->ResolvePrinters("manufacturer_b_en", provider->ResolvePrinters("manufacturer_b_en",
base::Bind(&PpdProviderTest::CaptureResolvePrinters, base::Bind(&PpdProviderTest::CaptureResolvePrinters,
base::Unretained(this))); base::Unretained(this)));
scoped_task_environment_.RunUntilIdle(); scoped_task_environment_.RunUntilIdle();
ASSERT_EQ(2UL, captured_resolve_printers_.size()); ASSERT_EQ(2UL, captured_resolve_printers_.size());
EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_printers_[0].first); EXPECT_EQ(PpdProvider::SUCCESS, captured_resolve_printers_[0].first);
...@@ -444,18 +468,22 @@ TEST_F(PpdProviderTest, ResolvePrinters) { ...@@ -444,18 +468,22 @@ TEST_F(PpdProviderTest, ResolvePrinters) {
// reference effective make and models of printer_a_ref and printer_b_ref. // reference effective make and models of printer_a_ref and printer_b_ref.
const auto& capture0 = captured_resolve_printers_[0].second; const auto& capture0 = captured_resolve_printers_[0].second;
ASSERT_EQ(2UL, capture0.size()); ASSERT_EQ(2UL, capture0.size());
EXPECT_EQ("printer_a", capture0[0].first); EXPECT_EQ("printer_a", capture0[0].name);
EXPECT_EQ("printer_a_ref", capture0[0].second.effective_make_and_model); EXPECT_EQ("printer_a_ref", capture0[0].ppd_ref.effective_make_and_model);
EXPECT_EQ(base::Version("25"), capture0[0].restrictions.min_milestone);
EXPECT_EQ("printer_b", capture0[1].first); EXPECT_EQ("printer_b", capture0[1].name);
EXPECT_EQ("printer_b_ref", capture0[1].second.effective_make_and_model); EXPECT_EQ("printer_b_ref", capture0[1].ppd_ref.effective_make_and_model);
EXPECT_EQ(base::Version("30"), capture0[1].restrictions.min_milestone);
EXPECT_EQ(base::Version("45"), capture0[1].restrictions.max_milestone);
// Second capture should get back printer_c with effective make and model of // Second capture should get back printer_c with effective make and model of
// printer_c_ref // printer_c_ref
const auto& capture1 = captured_resolve_printers_[1].second; const auto& capture1 = captured_resolve_printers_[1].second;
ASSERT_EQ(1UL, capture1.size()); ASSERT_EQ(1UL, capture1.size());
EXPECT_EQ("printer_c", capture1[0].first); EXPECT_EQ("printer_c", capture1[0].name);
EXPECT_EQ("printer_c_ref", capture1[0].second.effective_make_and_model); EXPECT_EQ("printer_c_ref", capture1[0].ppd_ref.effective_make_and_model);
EXPECT_EQ(base::Version("55"), capture1[0].restrictions.max_milestone);
} }
// Test that if we give a bad reference to ResolvePrinters(), we get an // Test that if we give a bad reference to ResolvePrinters(), we get an
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment