summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/chrome.gyp8
-rw-r--r--chrome/service/cloud_print/cloud_print_helpers.h2
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy.cc2
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy_backend.cc46
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy_backend.h2
-rw-r--r--chrome/service/cloud_print/job_status_updater.cc16
-rw-r--r--chrome/service/cloud_print/job_status_updater.h4
-rw-r--r--chrome/service/cloud_print/print_system.h168
-rw-r--r--chrome/service/cloud_print/print_system_dummy.cc27
-rw-r--r--chrome/service/cloud_print/printer_info.h127
-rw-r--r--chrome/service/cloud_print/printer_info_cups.cc (renamed from chrome/service/cloud_print/print_system_cups.cc)268
-rw-r--r--chrome/service/cloud_print/printer_info_dummy.cc85
-rw-r--r--chrome/service/cloud_print/printer_info_win.cc (renamed from chrome/service/cloud_print/print_system_win.cc)410
-rw-r--r--chrome/service/cloud_print/printer_job_handler.cc48
-rw-r--r--chrome/service/cloud_print/printer_job_handler.h23
15 files changed, 547 insertions, 689 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index ccb858e..a1800d3f 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -980,8 +980,8 @@
'service/cloud_print/cloud_print_proxy_backend.h',
'service/cloud_print/job_status_updater.cc',
'service/cloud_print/job_status_updater.h',
- 'service/cloud_print/print_system_dummy.cc',
- 'service/cloud_print/print_system.h',
+ 'service/cloud_print/printer_info_dummy.cc',
+ 'service/cloud_print/printer_info.h',
'service/cloud_print/printer_job_handler.cc',
'service/cloud_print/printer_job_handler.h',
'service/gaia/service_gaia_authenticator.cc',
@@ -1002,7 +1002,7 @@
'CP_PRINT_SYSTEM_AVAILABLE',
],
'sources': [
- 'service/cloud_print/print_system_win.cc',
+ 'service/cloud_print/printer_info_win.cc',
],
}],
['OS=="linux"', {
@@ -1022,7 +1022,7 @@
'CP_PRINT_SYSTEM_AVAILABLE',
],
'sources': [
- 'service/cloud_print/print_system_cups.cc',
+ 'service/cloud_print/printer_info_cups.cc',
],
}],
],
diff --git a/chrome/service/cloud_print/cloud_print_helpers.h b/chrome/service/cloud_print/cloud_print_helpers.h
index 5c79b6e..55fd601 100644
--- a/chrome/service/cloud_print/cloud_print_helpers.h
+++ b/chrome/service/cloud_print/cloud_print_helpers.h
@@ -7,7 +7,7 @@
#include <string>
-#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_info.h"
#include "googleurl/src/gurl.h"
class DictionaryValue;
diff --git a/chrome/service/cloud_print/cloud_print_proxy.cc b/chrome/service/cloud_print/cloud_print_proxy.cc
index 3be2f49..c006e12 100644
--- a/chrome/service/cloud_print/cloud_print_proxy.cc
+++ b/chrome/service/cloud_print/cloud_print_proxy.cc
@@ -30,7 +30,7 @@ void CloudPrintProxy::EnableForUser(const std::string& lsid) {
std::string proxy_id;
service_prefs_->prefs()->GetString(prefs::kCloudPrintProxyId, &proxy_id);
if (proxy_id.empty()) {
- proxy_id = cloud_print::PrintSystem::GenerateProxyId();
+ proxy_id = cloud_print::GenerateProxyId();
service_prefs_->prefs()->SetString(prefs::kCloudPrintProxyId, proxy_id);
service_prefs_->WritePrefs();
}
diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc
index 719ecb5..cad6f38 100644
--- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc
+++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc
@@ -24,13 +24,12 @@
class CloudPrintProxyBackend::Core
: public base::RefCountedThreadSafe<CloudPrintProxyBackend::Core>,
public URLFetcherDelegate,
- public cloud_print::PrintServerWatcherDelegate,
+ public cloud_print::PrinterChangeNotifierDelegate,
public PrinterJobHandlerDelegate,
public notifier::TalkMediator::Delegate {
public:
explicit Core(CloudPrintProxyBackend* backend,
const GURL& cloud_print_server_url);
-
// Note:
//
// The Do* methods are the various entry points from CloudPrintProxyBackend
@@ -60,8 +59,14 @@ class CloudPrintProxyBackend::Core
int response_code,
const ResponseCookies& cookies,
const std::string& data);
- // cloud_print::PrintServerWatcherDelegate implementation
+// cloud_print::PrinterChangeNotifier::Delegate implementation
virtual void OnPrinterAdded();
+ virtual void OnPrinterDeleted() {
+ }
+ virtual void OnPrinterChanged() {
+ }
+ virtual void OnJobChanged() {
+ }
// PrinterJobHandler::Delegate implementation
void OnPrinterJobHandlerShutdown(PrinterJobHandler* job_handler,
const std::string& printer_id);
@@ -126,8 +131,6 @@ class CloudPrintProxyBackend::Core
CloudPrintProxyBackend* backend_;
GURL cloud_print_server_url_;
- // Pointer to current print system.
- scoped_refptr<cloud_print::PrintSystem> print_system_;
// The list of printers to be registered with the cloud print server.
// To begin with,this list is initialized with the list of local and network
// printers available. Then we query the server for the list of printers
@@ -156,8 +159,7 @@ class CloudPrintProxyBackend::Core
JobHandlerMap;
JobHandlerMap job_handler_map_;
ResponseHandler next_response_handler_;
- scoped_refptr<cloud_print::PrintSystem::PrintServerWatcher>
- print_server_watcher_;
+ cloud_print::PrinterChangeNotifier printer_change_notifier_;
bool new_printers_available_;
// Notification (xmpp) handler.
scoped_ptr<notifier::TalkMediator> talk_mediator_;
@@ -233,7 +235,7 @@ CloudPrintProxyBackend::Core::Core(CloudPrintProxyBackend* backend,
const GURL& cloud_print_server_url)
: backend_(backend), cloud_print_server_url_(cloud_print_server_url),
next_upload_index_(0), server_error_count_(0),
- next_response_handler_(NULL), new_printers_available_(false) {
+ next_response_handler_(NULL), new_printers_available_(false) {
}
void CloudPrintProxyBackend::Core::DoInitializeWithLsid(
@@ -277,13 +279,6 @@ void CloudPrintProxyBackend::Core::DoInitializeWithToken(
const std::string cloud_print_xmpp_token,
const std::string email, const std::string& proxy_id) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
-
- print_system_ = cloud_print::PrintSystem::CreateInstance();
- if (!print_system_.get()) {
- NOTREACHED();
- return; // No print system available, fail initalization.
- }
-
// TODO(sanjeevr): Validate the tokens.
auth_token_ = cloud_print_token;
talk_mediator_.reset(new notifier::TalkMediatorImpl(
@@ -293,17 +288,14 @@ void CloudPrintProxyBackend::Core::DoInitializeWithToken(
talk_mediator_->SetAuthToken(email, cloud_print_xmpp_token,
kSyncGaiaServiceId);
talk_mediator_->Login();
-
- print_server_watcher_ = print_system_->CreatePrintServerWatcher();
- print_server_watcher_->StartWatching(this);
-
+ printer_change_notifier_.StartWatching(std::string(), this);
proxy_id_ = proxy_id;
StartRegistration();
}
void CloudPrintProxyBackend::Core::StartRegistration() {
printer_list_.clear();
- print_system_->EnumeratePrinters(&printer_list_);
+ cloud_print::EnumeratePrinters(&printer_list_);
server_error_count_ = 0;
// Now we need to ask the server about printers that were registered on the
// server so that we can trim this list.
@@ -319,9 +311,6 @@ void CloudPrintProxyBackend::Core::EndRegistration() {
}
void CloudPrintProxyBackend::Core::DoShutdown() {
- if (print_server_watcher_ != NULL)
- print_server_watcher_->StopWatching();
-
// Need to kill all running jobs.
while (!job_handler_map_.empty()) {
JobHandlerMap::iterator index = job_handler_map_.begin();
@@ -333,8 +322,6 @@ void CloudPrintProxyBackend::Core::DoShutdown() {
void CloudPrintProxyBackend::Core::DoRegisterSelectedPrinters(
const cloud_print::PrinterList& printer_list) {
- if (!print_system_.get())
- return; // No print system available.
server_error_count_ = 0;
printer_list_.assign(printer_list.begin(), printer_list.end());
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
@@ -371,7 +358,7 @@ void CloudPrintProxyBackend::Core::RegisterNextPrinter() {
// If we are retrying a previous upload, we don't need to fetch the caps
// and defaults again.
if (info.printer_name != last_uploaded_printer_name_) {
- have_printer_info = print_system_->GetPrinterCapsAndDefaults(
+ have_printer_info = cloud_print::GetPrinterCapsAndDefaults(
info.printer_name.c_str(), &last_uploaded_printer_info_);
}
if (have_printer_info) {
@@ -436,10 +423,7 @@ void CloudPrintProxyBackend::Core::RegisterNextPrinter() {
&CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse;
request_->Start();
} else {
- LOG(ERROR) << "CP: Failed to get printer info for: " << info.printer_name;
- next_upload_index_++;
- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &CloudPrintProxyBackend::Core::RegisterNextPrinter));
+ NOTREACHED();
}
} else {
EndRegistration();
@@ -541,7 +525,7 @@ void CloudPrintProxyBackend::Core::InitJobHandlerForPrinter(
scoped_refptr<PrinterJobHandler> job_handler;
job_handler = new PrinterJobHandler(printer_info, printer_id, caps_hash,
auth_token_, cloud_print_server_url_,
- print_system_.get(), this);
+ this);
job_handler_map_[printer_id] = job_handler;
job_handler->Initialize();
}
diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.h b/chrome/service/cloud_print/cloud_print_proxy_backend.h
index bc7da23..7464aba 100644
--- a/chrome/service/cloud_print/cloud_print_proxy_backend.h
+++ b/chrome/service/cloud_print/cloud_print_proxy_backend.h
@@ -9,7 +9,7 @@
#include <string>
#include "base/thread.h"
-#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_info.h"
#include "chrome/common/net/url_fetcher.h"
#include "googleurl/src/gurl.h"
diff --git a/chrome/service/cloud_print/job_status_updater.cc b/chrome/service/cloud_print/job_status_updater.cc
index 808b209..9c22f56 100644
--- a/chrome/service/cloud_print/job_status_updater.cc
+++ b/chrome/service/cloud_print/job_status_updater.cc
@@ -13,16 +13,15 @@
#include "googleurl/src/gurl.h"
JobStatusUpdater::JobStatusUpdater(const std::string& printer_name,
- const std::string& job_id,
- cloud_print::PlatformJobId& local_job_id,
- const std::string& auth_token,
- const GURL& cloud_print_server_url,
- cloud_print::PrintSystem* print_system,
- Delegate* delegate)
+ const std::string& job_id,
+ cloud_print::PlatformJobId& local_job_id,
+ const std::string& auth_token,
+ const GURL& cloud_print_server_url,
+ Delegate* delegate)
: printer_name_(printer_name), job_id_(job_id),
local_job_id_(local_job_id), auth_token_(auth_token),
cloud_print_server_url_(cloud_print_server_url),
- print_system_(print_system), delegate_(delegate), stopped_(false) {
+ delegate_(delegate), stopped_(false) {
DCHECK(delegate_);
}
@@ -40,8 +39,7 @@ void JobStatusUpdater::UpdateStatus() {
need_update = true;
} else {
cloud_print::PrintJobDetails details;
- if (print_system_->GetJobDetails(printer_name_, local_job_id_,
- &details)) {
+ if (cloud_print::GetJobDetails(printer_name_, local_job_id_, &details)) {
if (details != last_job_details_) {
last_job_details_ = details;
need_update = true;
diff --git a/chrome/service/cloud_print/job_status_updater.h b/chrome/service/cloud_print/job_status_updater.h
index ed4ab21..870869b 100644
--- a/chrome/service/cloud_print/job_status_updater.h
+++ b/chrome/service/cloud_print/job_status_updater.h
@@ -10,7 +10,7 @@
#include "base/file_path.h"
#include "base/ref_counted.h"
#include "base/thread.h"
-#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_info.h"
#include "chrome/common/net/url_fetcher.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_status.h"
@@ -32,7 +32,6 @@ class JobStatusUpdater : public base::RefCountedThreadSafe<JobStatusUpdater>,
cloud_print::PlatformJobId& local_job_id,
const std::string& auth_token,
const GURL& cloud_print_server_url,
- cloud_print::PrintSystem* print_system,
Delegate* delegate);
// Checks the status of the local print job and sends an update.
void UpdateStatus();
@@ -51,7 +50,6 @@ class JobStatusUpdater : public base::RefCountedThreadSafe<JobStatusUpdater>,
scoped_ptr<URLFetcher> request_;
std::string auth_token_;
GURL cloud_print_server_url_;
- scoped_refptr<cloud_print::PrintSystem> print_system_;
Delegate* delegate_;
// A flag that is set to true in Stop() and will ensure the next scheduled
// task will do nothing.
diff --git a/chrome/service/cloud_print/print_system.h b/chrome/service/cloud_print/print_system.h
deleted file mode 100644
index 579026c..0000000
--- a/chrome/service/cloud_print/print_system.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_SERVICE_CLOUD_PRINT_PRINT_SYSTEM_H_
-#define CHROME_SERVICE_CLOUD_PRINT_PRINT_SYSTEM_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/file_path.h"
-#include "base/ref_counted.h"
-
-// This is the interface for platform-specific code for cloud print
-namespace cloud_print {
-
-typedef int PlatformJobId;
-
-struct PrinterBasicInfo {
- std::string printer_name;
- std::string printer_description;
- int printer_status;
- std::map<std::string, std::string> options;
- PrinterBasicInfo() : printer_status(0) {
- }
-};
-
-typedef std::vector<PrinterBasicInfo> PrinterList;
-
-struct PrinterCapsAndDefaults {
- std::string printer_capabilities;
- std::string caps_mime_type;
- std::string printer_defaults;
- std::string defaults_mime_type;
-};
-
-enum PrintJobStatus {
- PRINT_JOB_STATUS_INVALID,
- PRINT_JOB_STATUS_IN_PROGRESS,
- PRINT_JOB_STATUS_ERROR,
- PRINT_JOB_STATUS_COMPLETED
-};
-
-struct PrintJobDetails {
- PrintJobStatus status;
- int platform_status_flags;
- std::string status_message;
- int total_pages;
- int pages_printed;
- PrintJobDetails() : status(PRINT_JOB_STATUS_INVALID),
- platform_status_flags(0), total_pages(0),
- pages_printed(0) {
- }
- void Clear() {
- status = PRINT_JOB_STATUS_INVALID;
- platform_status_flags = 0;
- status_message.clear();
- total_pages = 0;
- pages_printed = 0;
- }
- bool operator ==(const PrintJobDetails& other) const {
- return (status == other.status) &&
- (platform_status_flags == other.platform_status_flags) &&
- (status_message == other.status_message) &&
- (total_pages == other.total_pages) &&
- (pages_printed == other.pages_printed);
- }
- bool operator !=(const PrintJobDetails& other) const {
- return !(*this == other);
- }
-};
-
-// PrintSystem class will provide interface for different printing systems
-// (Windows, CUPS) to implement. User will call CreateInstance() to
-// obtain available printing system.
-// Please note, that PrintSystem is not platform specific, but rather
-// print system specific. For example, CUPS is available on both Linux and Mac,
-// but not avaialble on ChromeOS, etc. This design allows us to add more
-// functionality on some platforms, while reusing core (CUPS) functions.
-class PrintSystem : public base::RefCountedThreadSafe<PrintSystem> {
- public:
- virtual ~PrintSystem() {}
-
- // Enumerates the list of installed local and network printers.
- virtual void EnumeratePrinters(PrinterList* printer_list) = 0;
-
- // Gets the capabilities and defaults for a specific printer.
- virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name,
- PrinterCapsAndDefaults* printer_info) = 0;
-
- // Returns true if ticket is valid.
- virtual bool ValidatePrintTicket(const std::string& printer_name,
- const std::string& print_ticket_data) = 0;
-
- // Send job to the printer.
- virtual bool SpoolPrintJob(const std::string& print_ticket,
- const FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- PlatformJobId* job_id_ret) = 0;
-
- // Get details for already spooled job.
- virtual bool GetJobDetails(const std::string& printer_name,
- PlatformJobId job_id,
- PrintJobDetails *job_details) = 0;
-
- // Returns true if printer_name points to a valid printer.
- virtual bool IsValidPrinter(const std::string& printer_name) = 0;
-
- class PrintServerWatcher
- : public base::RefCountedThreadSafe<PrintServerWatcher> {
- public:
- // Callback interface for new printer notifications.
- class Delegate {
- public:
- virtual void OnPrinterAdded() = 0;
- // TODO(gene): Do we need OnPrinterDeleted notification here?
- };
-
- virtual ~PrintServerWatcher() {}
- virtual bool StartWatching(PrintServerWatcher::Delegate* delegate) = 0;
- virtual bool StopWatching() = 0;
- };
-
- class PrinterWatcher : public base::RefCountedThreadSafe<PrinterWatcher> {
- public:
- // Callback interface for printer updates notifications.
- class Delegate {
- public:
- virtual void OnPrinterDeleted() = 0;
- virtual void OnPrinterChanged() = 0;
- virtual void OnJobChanged() = 0;
- };
-
- virtual ~PrinterWatcher() {}
- virtual bool StartWatching(PrinterWatcher::Delegate* delegate) = 0;
- virtual bool StopWatching() = 0;
- virtual bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info) = 0;
- };
-
- // Factory methods to create corresponding watcher. Callee is responsible
- // for deleting objects. Return NULL if failed.
- virtual PrintServerWatcher* CreatePrintServerWatcher() = 0;
- virtual PrinterWatcher* CreatePrinterWatcher(
- const std::string& printer_name) = 0;
-
- // Generate unique for proxy.
- static std::string GenerateProxyId();
-
- // Call this function to obtain current printing system. Return NULL if no
- // print system available. Delete returned PrintSystem pointer using delete.
- static scoped_refptr<PrintSystem> CreateInstance();
-};
-
-
-// This typedef is to workaround the issue with certain versions of
-// Visual Studio where it gets confused between multiple Delegate
-// classes and gives a C2500 error. (I saw this error on the try bots -
-// the workaround was not needed for my machine).
-typedef PrintSystem::PrintServerWatcher::Delegate PrintServerWatcherDelegate;
-typedef PrintSystem::PrinterWatcher::Delegate PrinterWatcherDelegate;
-
-} // namespace cloud_print
-
-#endif // CHROME_SERVICE_CLOUD_PRINT_PRINT_SYSTEM_H_
-
diff --git a/chrome/service/cloud_print/print_system_dummy.cc b/chrome/service/cloud_print/print_system_dummy.cc
deleted file mode 100644
index 49e481d..0000000
--- a/chrome/service/cloud_print/print_system_dummy.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is dummy implementation for all configurations where print system
-// for cloud print is not available.
-#if !defined(CP_PRINT_SYSTEM_AVAILABLE)
-
-#include "chrome/service/cloud_print/print_system.h"
-
-#include "base/logging.h"
-
-namespace cloud_print {
-
-std::string PrintSystem::GenerateProxyId() {
- NOTREACHED();
- return std::string();
-}
-
-scoped_refptr<PrintSystem> PrintSystem::CreateInstance() {
- NOTREACHED();
- return NULL;
-}
-} // namespace cloud_print
-
-#endif // CP_PRINT_SYSTEM_AVAILABLE
-
diff --git a/chrome/service/cloud_print/printer_info.h b/chrome/service/cloud_print/printer_info.h
new file mode 100644
index 0000000..4823037
--- /dev/null
+++ b/chrome/service/cloud_print/printer_info.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_SERVICE_CLOUD_PRINT_PRINTER_INFO_H_
+#define CHROME_SERVICE_CLOUD_PRINT_PRINTER_INFO_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/file_path.h"
+
+// This is the interface for platform-specific code for cloud print
+namespace cloud_print {
+
+typedef int PlatformJobId;
+
+struct PrinterBasicInfo {
+ std::string printer_name;
+ std::string printer_description;
+ int printer_status;
+ std::map<std::string, std::string> options;
+ PrinterBasicInfo() : printer_status(0) {
+ }
+};
+
+typedef std::vector<PrinterBasicInfo> PrinterList;
+
+struct PrinterCapsAndDefaults {
+ std::string printer_capabilities;
+ std::string caps_mime_type;
+ std::string printer_defaults;
+ std::string defaults_mime_type;
+};
+
+enum PrintJobStatus {
+ PRINT_JOB_STATUS_INVALID,
+ PRINT_JOB_STATUS_IN_PROGRESS,
+ PRINT_JOB_STATUS_ERROR,
+ PRINT_JOB_STATUS_COMPLETED
+};
+
+struct PrintJobDetails {
+ PrintJobStatus status;
+ int platform_status_flags;
+ std::string status_message;
+ int total_pages;
+ int pages_printed;
+ PrintJobDetails() : status(PRINT_JOB_STATUS_INVALID),
+ platform_status_flags(0), total_pages(0),
+ pages_printed(0) {
+ }
+ void Clear() {
+ status = PRINT_JOB_STATUS_INVALID;
+ platform_status_flags = 0;
+ status_message.clear();
+ total_pages = 0;
+ pages_printed = 0;
+ }
+ bool operator ==(const PrintJobDetails& other) const {
+ return (status == other.status) &&
+ (platform_status_flags == other.platform_status_flags) &&
+ (status_message == other.status_message) &&
+ (total_pages == other.total_pages) &&
+ (pages_printed == other.pages_printed);
+ }
+ bool operator !=(const PrintJobDetails& other) const {
+ return !(*this == other);
+ }
+};
+
+// Enumerates the list of installed local and network printers.
+void EnumeratePrinters(PrinterList* printer_list);
+// Gets the capabilities and defaults for a specific printer.
+bool GetPrinterCapsAndDefaults(const std::string& printer_name,
+ PrinterCapsAndDefaults* printer_info);
+bool ValidatePrintTicket(const std::string& printer_name,
+ const std::string& print_ticket_data);
+std::string GenerateProxyId();
+bool SpoolPrintJob(const std::string& print_ticket,
+ const FilePath& print_data_file_path,
+ const std::string& print_data_mime_type,
+ const std::string& printer_name,
+ const std::string& job_title,
+ PlatformJobId* job_id_ret);
+
+bool GetJobDetails(const std::string& printer_name,
+ PlatformJobId job_id,
+ PrintJobDetails *job_details);
+bool IsValidPrinter(const std::string& printer_name);
+
+// A class that watches changes to a printer or a print server.
+// The set of notifications are very coarse-grained (even though the Windows
+// API allows for listening to fine-grained details about a printer, this class
+// does not support that level of fine-grained control.
+class PrinterChangeNotifier {
+ public:
+ class Delegate {
+ public:
+ virtual void OnPrinterAdded() = 0;
+ virtual void OnPrinterDeleted() = 0;
+ virtual void OnPrinterChanged() = 0;
+ virtual void OnJobChanged() = 0;
+ };
+ PrinterChangeNotifier();
+ ~PrinterChangeNotifier();
+ bool StartWatching(const std::string& printer_name, Delegate* delegate);
+ bool StopWatching();
+ bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info);
+ private:
+ // Internal state maintained by the PrinterChangeNotifier class.
+ class NotificationState;
+ NotificationState* state_;
+ DISALLOW_COPY_AND_ASSIGN(PrinterChangeNotifier);
+};
+
+// This typedef is to workaround the issue with certain versions of
+// Visual Studio where it gets confused between multiple Delegate
+// classes and gives a C2500 error. (I saw this error on the try bots -
+// the workaround was not needed for my machine).
+typedef PrinterChangeNotifier::Delegate PrinterChangeNotifierDelegate;
+
+} // namespace cloud_print
+
+#endif // CHROME_SERVICE_CLOUD_PRINT_PRINTER_INFO_H_
+
diff --git a/chrome/service/cloud_print/print_system_cups.cc b/chrome/service/cloud_print/printer_info_cups.cc
index 4e3e324..38be60b 100644
--- a/chrome/service/cloud_print/print_system_cups.cc
+++ b/chrome/service/cloud_print/printer_info_cups.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_info.h"
#include <cups/cups.h>
#include <list>
@@ -25,107 +25,7 @@ namespace cloud_print {
static const char kCUPSPrinterInfoOpt[] = "printer-info";
static const char kCUPSPrinterStateOpt[] = "printer-state";
-class PrintSystemCUPS : public PrintSystem {
- public:
- virtual void EnumeratePrinters(PrinterList* printer_list);
-
- virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name,
- PrinterCapsAndDefaults* printer_info);
-
- virtual bool ValidatePrintTicket(const std::string& printer_name,
- const std::string& print_ticket_data);
-
- virtual bool SpoolPrintJob(const std::string& print_ticket,
- const FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- PlatformJobId* job_id_ret);
-
- virtual bool GetJobDetails(const std::string& printer_name,
- PlatformJobId job_id,
- PrintJobDetails *job_details);
-
- virtual bool IsValidPrinter(const std::string& printer_name);
-
- // TODO(gene): Add implementation for CUPS print server watcher.
- class PrintServerWatcherCUPS
- : public PrintSystem::PrintServerWatcher {
- public:
- PrintServerWatcherCUPS() {}
-
- // PrintSystem::PrintServerWatcher interface
- virtual bool StartWatching(
- PrintSystem::PrintServerWatcher::Delegate* delegate) {
- NOTIMPLEMENTED();
- return true;
- }
- virtual bool StopWatching() {
- NOTIMPLEMENTED();
- return true;
- }
- };
-
- class PrinterWatcherCUPS
- : public PrintSystem::PrinterWatcher {
- public:
- explicit PrinterWatcherCUPS(PrintSystemCUPS* print_system,
- const std::string& printer_name)
- : printer_name_(printer_name), print_system_(print_system) {
- }
-
- // PrintSystem::PrinterWatcher interface
- virtual bool StartWatching(
- PrintSystem::PrinterWatcher::Delegate* delegate) {
- if (delegate_ != NULL)
- StopWatching();
- delegate_ = delegate;
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- NewRunnableMethod(this,
- &PrintSystemCUPS::PrinterWatcherCUPS::Update), 5000);
- return true;
- }
- virtual bool StopWatching() {
- delegate_ = NULL;
- return true;
- }
- bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info) {
- DCHECK(printer_info);
- return print_system_->GetPrinterInfo(printer_name_, printer_info);
- }
-
- void Update() {
- if (delegate_ == NULL)
- return; // Orphan call. We have been stopped already.
- // For CUPS proxy, we are going to fire OnJobChanged notification
- // periodically. Higher level will check if there are any outstanding
- // jobs for this printer and check their status. If printer has no
- // outstanding jobs, OnJobChanged() will do nothing.
- delegate_->OnJobChanged();
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- NewRunnableMethod(this,
- &PrintSystemCUPS::PrinterWatcherCUPS::Update),
- kNotificationTimeout);
- }
- private:
- static const int kNotificationTimeout = 5000; // in ms
- std::string printer_name_;
- PrintSystem::PrinterWatcher::Delegate* delegate_;
- scoped_refptr<PrintSystemCUPS> print_system_;
- DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS);
- };
-
- virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher();
- virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
- const std::string& printer_name);
-
- // Helper functions.
- bool GetPrinterInfo(const std::string& printer_name, PrinterBasicInfo* info);
- bool ParsePrintTicket(const std::string& print_ticket,
- std::map<std::string, std::string>* options);
-};
-
-void PrintSystemCUPS::EnumeratePrinters(PrinterList* printer_list) {
+void EnumeratePrinters(PrinterList* printer_list) {
DCHECK(printer_list);
printer_list->clear();
@@ -159,31 +59,22 @@ void PrintSystemCUPS::EnumeratePrinters(PrinterList* printer_list) {
cupsFreeDests(num_dests, destinations);
- DLOG(INFO) << "CP_CUPS: Enumerated " << printer_list->size() << " printers.";
+ DLOG(INFO) << "Enumerated " << printer_list->size() << " printers.";
}
-bool PrintSystemCUPS::GetPrinterCapsAndDefaults(const std::string& printer_name,
- PrinterCapsAndDefaults* printer_info) {
+bool GetPrinterCapsAndDefaults(const std::string& printer_name,
+ PrinterCapsAndDefaults* printer_info) {
DCHECK(printer_info);
- DLOG(INFO) << "CP_CUPS: Getting Caps and Defaults for: " << printer_name;
+ DLOG(INFO) << "Getting Caps and Defaults for: " << printer_name;
static Lock ppd_lock;
// cupsGetPPD returns a filename stored in a static buffer in CUPS.
// Protect this code with lock.
ppd_lock.Acquire();
- FilePath ppd_path;
- const char* ppd_file_path = cupsGetPPD(printer_name.c_str());
- if (ppd_file_path)
- ppd_path = FilePath(ppd_file_path);
+ FilePath ppd_path(cupsGetPPD(printer_name.c_str()));
ppd_lock.Release();
- // In some cases CUPS failed to get ppd file.
- if (ppd_path.empty()) {
- DLOG(ERROR) << "CP_CUPS: Failed to get PPD for: " << printer_name;
- return false;
- }
-
std::string content;
bool res = file_util::ReadFileToString(ppd_path, &content);
@@ -200,16 +91,25 @@ bool PrintSystemCUPS::GetPrinterCapsAndDefaults(const std::string& printer_name,
return res;
}
-bool PrintSystemCUPS::ValidatePrintTicket(const std::string& printer_name,
- const std::string& print_ticket_data) {
+bool ValidatePrintTicket(const std::string& printer_name,
+ const std::string& print_ticket_data) {
scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket_data,
false));
return ticket_value != NULL && ticket_value->IsType(Value::TYPE_DICTIONARY);
}
+std::string GenerateProxyId() {
+ // TODO(gene): This code should generate a unique id for proxy. ID should be
+ // unique for this user. Rand may return the same number. We'll need to change
+ // this in the future.
+ std::string id("CP_PROXY_");
+ id += Uint64ToString(base::RandUint64());
+ return id;
+}
+
// Print ticket on linux is a JSON string containing only one dictionary.
-bool PrintSystemCUPS::ParsePrintTicket(const std::string& print_ticket,
- std::map<std::string, std::string>* options) {
+bool ParsePrintTicket(const std::string& print_ticket,
+ std::map<std::string, std::string>* options) {
DCHECK(options);
scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket, false));
if (ticket_value == NULL || !ticket_value->IsType(Value::TYPE_DICTIONARY))
@@ -230,15 +130,15 @@ bool PrintSystemCUPS::ParsePrintTicket(const std::string& print_ticket,
return true;
}
-bool PrintSystemCUPS::SpoolPrintJob(const std::string& print_ticket,
- const FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- PlatformJobId* job_id_ret) {
+bool SpoolPrintJob(const std::string& print_ticket,
+ const FilePath& print_data_file_path,
+ const std::string& print_data_mime_type,
+ const std::string& printer_name,
+ const std::string& job_title,
+ PlatformJobId* job_id_ret) {
DCHECK(job_id_ret);
- DLOG(INFO) << "CP_CUPS: Spooling print job for: " << printer_name;
+ DLOG(INFO) << "Spooling print job for: " << printer_name;
// We need to store options as char* string for the duration of the
// cupsPrintFile call. We'll use map here to store options, since
@@ -262,8 +162,6 @@ bool PrintSystemCUPS::SpoolPrintJob(const std::string& print_ticket,
cups_options.size(),
&(cups_options[0]));
- DLOG(INFO) << "CP_CUPS: Job spooled, id: " << job_id;
-
if (job_id == 0)
return false;
@@ -271,12 +169,12 @@ bool PrintSystemCUPS::SpoolPrintJob(const std::string& print_ticket,
return true;
}
-bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name,
- PlatformJobId job_id,
- PrintJobDetails *job_details) {
+bool GetJobDetails(const std::string& printer_name,
+ PlatformJobId job_id,
+ PrintJobDetails *job_details) {
DCHECK(job_details);
- DLOG(INFO) << "CP_CUPS: Getting job details for: " << printer_name <<
+ DLOG(INFO) << "Getting job details for: " << printer_name <<
" job_id: " << job_id;
cups_job_t* jobs = NULL;
@@ -314,11 +212,10 @@ bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name,
return found;
}
-bool PrintSystemCUPS::GetPrinterInfo(const std::string& printer_name,
- PrinterBasicInfo* info) {
+bool GetPrinterInfo(const std::string& printer_name, PrinterBasicInfo* info) {
DCHECK(info);
- DLOG(INFO) << "CP_CUPS: Getting printer info for: " << printer_name;
+ DLOG(INFO) << "Getting printer info for: " << printer_name;
// This is not very efficient way to get specific printer info. CUPS 1.4
// supports cupsGetNamedDest() function. However, CUPS 1.4 is not available
@@ -336,34 +233,99 @@ bool PrintSystemCUPS::GetPrinterInfo(const std::string& printer_name,
return false;
}
-bool PrintSystemCUPS::IsValidPrinter(const std::string& printer_name) {
+bool IsValidPrinter(const std::string& printer_name) {
PrinterBasicInfo info;
return GetPrinterInfo(printer_name, &info);
}
-PrintSystem::PrintServerWatcher*
-PrintSystemCUPS::CreatePrintServerWatcher() {
- return new PrintServerWatcherCUPS();
+class PrinterChangeNotifier::NotificationState
+ : public base::RefCountedThreadSafe<
+ PrinterChangeNotifier::NotificationState> {
+ public:
+ NotificationState() : delegate_(NULL) {}
+ bool Start(const std::string& printer_name,
+ PrinterChangeNotifier::Delegate* delegate) {
+ if (delegate_ != NULL)
+ Stop();
+
+ printer_name_ = printer_name;
+ delegate_ = delegate;
+
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &PrinterChangeNotifier::NotificationState::Update), 5000);
+ return true;
+ }
+ bool Stop() {
+ delegate_ = NULL;
+ return true;
+ }
+ void Update() {
+ if (delegate_ == NULL)
+ return; // Orphan call. We have been stopped already.
+ // For CUPS proxy, we are going to fire OnJobChanged notification
+ // periodically. Higher level will check if there are any outstanding
+ // jobs for this printer and check their status. If printer has no
+ // outstanding jobs, OnJobChanged() will do nothing.
+ delegate_->OnJobChanged();
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &PrinterChangeNotifier::NotificationState::Update),
+ kNotificationTimeout);
+ }
+ std::string printer_name() const {
+ return printer_name_;
+ }
+ private:
+ friend class base::RefCountedThreadSafe<
+ PrinterChangeNotifier::NotificationState>;
+ ~NotificationState() {
+ Stop();
+ }
+ static const int kNotificationTimeout = 5000; // in ms
+ std::string printer_name_; // The printer being watched
+ PrinterChangeNotifier::Delegate* delegate_; // Delegate to notify
+};
+
+PrinterChangeNotifier::PrinterChangeNotifier() : state_(NULL) {
}
-PrintSystem::PrinterWatcher* PrintSystemCUPS::CreatePrinterWatcher(
- const std::string& printer_name) {
- DCHECK(!printer_name.empty());
- return new PrinterWatcherCUPS(this, printer_name);
+PrinterChangeNotifier::~PrinterChangeNotifier() {
+ StopWatching();
}
-std::string PrintSystem::GenerateProxyId() {
- // TODO(gene): This code should generate a unique id for proxy. ID should be
- // unique for this user. Rand may return the same number. We'll need to change
- // this in the future.
- std::string id("CP_PROXY_");
- id += Uint64ToString(base::RandUint64());
- return id;
+bool PrinterChangeNotifier::StartWatching(const std::string& printer_name,
+ Delegate* delegate) {
+ if (state_) {
+ NOTREACHED();
+ return false;
+ }
+ state_ = new NotificationState;
+ state_->AddRef();
+ if (!state_->Start(printer_name, delegate)) {
+ StopWatching();
+ return false;
+ }
+ return true;
}
-scoped_refptr<PrintSystem> PrintSystem::CreateInstance() {
- return new PrintSystemCUPS;
+bool PrinterChangeNotifier::StopWatching() {
+ if (!state_) {
+ return false;
+ }
+ state_->Stop();
+ state_->Release();
+ state_ = NULL;
+ return true;
}
+bool PrinterChangeNotifier::GetCurrentPrinterInfo(
+ PrinterBasicInfo* printer_info) {
+ if (!state_) {
+ return false;
+ }
+ DCHECK(printer_info);
+ return GetPrinterInfo(state_->printer_name(), printer_info);
+}
} // namespace cloud_print
diff --git a/chrome/service/cloud_print/printer_info_dummy.cc b/chrome/service/cloud_print/printer_info_dummy.cc
new file mode 100644
index 0000000..2d2f25a
--- /dev/null
+++ b/chrome/service/cloud_print/printer_info_dummy.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is dummy implementation for all configurations where print system
+// for cloud print is not available.
+#if !defined(CP_PRINT_SYSTEM_AVAILABLE)
+
+#include "chrome/service/cloud_print/printer_info.h"
+
+#include "base/logging.h"
+
+namespace cloud_print {
+
+void EnumeratePrinters(PrinterList* printer_list) {
+ DCHECK(printer_list);
+ NOTIMPLEMENTED();
+}
+
+bool GetPrinterCapsAndDefaults(const std::string& printer_name,
+ PrinterCapsAndDefaults* printer_info) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool ValidatePrintTicket(const std::string& printer_name,
+ const std::string& print_ticket_data) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+std::string GenerateProxyId() {
+ NOTIMPLEMENTED();
+ return std::string();
+}
+
+bool SpoolPrintJob(const std::string& print_ticket,
+ const FilePath& print_data_file_path,
+ const std::string& print_data_mime_type,
+ const std::string& printer_name,
+ const std::string& job_title,
+ PlatformJobId* job_id_ret) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool GetJobDetails(const std::string& printer_name,
+ PlatformJobId job_id,
+ PrintJobDetails *job_details) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool IsValidPrinter(const std::string& printer_name) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+PrinterChangeNotifier::PrinterChangeNotifier() : state_(NULL) {
+}
+
+PrinterChangeNotifier::~PrinterChangeNotifier() {
+ StopWatching();
+}
+
+bool PrinterChangeNotifier::StartWatching(const std::string& printer_name,
+ Delegate* delegate) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool PrinterChangeNotifier::StopWatching() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool PrinterChangeNotifier::GetCurrentPrinterInfo(
+ PrinterBasicInfo* printer_info) {
+ NOTIMPLEMENTED();
+ return false;
+}
+} // namespace cloud_print
+
+#endif // CP_PRINT_SYSTEM_AVAILABLE
+
diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/printer_info_win.cc
index 5f79d9c..4839d60 100644
--- a/chrome/service/cloud_print/print_system_win.cc
+++ b/chrome/service/cloud_print/printer_info_win.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_info.h"
#include <windows.h>
#include <objidl.h>
@@ -128,224 +128,7 @@ HRESULT PrintPdf2DC(HDC dc, const FilePath& pdf_filename) {
namespace cloud_print {
-class PrintSystemWatcherWin
- : public base::ObjectWatcher::Delegate {
- public:
- PrintSystemWatcherWin()
- : printer_(NULL), printer_change_(NULL), delegate_(NULL) {
- }
- ~PrintSystemWatcherWin() {
- Stop();
- }
-
- class Delegate {
- public:
- virtual void OnPrinterAdded() = 0;
- virtual void OnPrinterDeleted() = 0;
- virtual void OnPrinterChanged() = 0;
- virtual void OnJobChanged() = 0;
- };
-
- bool Start(const std::string& printer_name, Delegate* delegate) {
- delegate_ = delegate;
- // An empty printer name means watch the current server, we need to pass
- // NULL to OpenPrinter.
- LPTSTR printer_name_to_use = NULL;
- std::wstring printer_name_wide;
- if (!printer_name.empty()) {
- printer_name_wide = UTF8ToWide(printer_name);
- printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str());
- }
- bool ret = false;
- OpenPrinter(printer_name_to_use, &printer_, NULL);
- if (printer_) {
- printer_change_ = FindFirstPrinterChangeNotification(
- printer_, PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL);
- if (printer_change_) {
- ret = watcher_.StartWatching(printer_change_, this);
- }
- }
- if (!ret) {
- Stop();
- }
- return ret;
- }
- bool Stop() {
- watcher_.StopWatching();
- if (printer_) {
- ClosePrinter(printer_);
- printer_ = NULL;
- }
- if (printer_change_) {
- FindClosePrinterChangeNotification(printer_change_);
- printer_change_ = NULL;
- }
- return true;
- }
-
- void OnObjectSignaled(HANDLE object) {
- DWORD change = 0;
- FindNextPrinterChangeNotification(object, &change, NULL, NULL);
-
- if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) &
- (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) {
- // For printer connections, we get spurious change notifications with
- // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER.
- // Ignore these.
- if (change & PRINTER_CHANGE_ADD_PRINTER) {
- delegate_->OnPrinterAdded();
- } else if (change & PRINTER_CHANGE_DELETE_PRINTER) {
- delegate_->OnPrinterDeleted();
- } else if (change & PRINTER_CHANGE_SET_PRINTER) {
- delegate_->OnPrinterChanged();
- }
- if (change & PRINTER_CHANGE_JOB) {
- delegate_->OnJobChanged();
- }
- }
- watcher_.StartWatching(printer_change_, this);
- }
-
- bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info) {
- DCHECK(printer_info);
- if (!printer_)
- return false;
-
- DWORD bytes_needed = 0;
- bool ret = false;
- GetPrinter(printer_, 2, NULL, 0, &bytes_needed);
- if (0 != bytes_needed) {
- scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]);
- if (GetPrinter(printer_, 2, printer_info_buffer.get(),
- bytes_needed, &bytes_needed)) {
- PRINTER_INFO_2* printer_info_win =
- reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get());
- printer_info->printer_name = WideToUTF8(printer_info_win->pPrinterName);
- printer_info->printer_description =
- WideToUTF8(printer_info_win->pComment);
- printer_info->printer_status = printer_info_win->Status;
- ret = true;
- }
- }
- return ret;
- }
-
- private:
- base::ObjectWatcher watcher_;
- HANDLE printer_; // The printer being watched
- HANDLE printer_change_; // Returned by FindFirstPrinterChangeNotifier
- Delegate* delegate_; // Delegate to notify
- bool did_signal_; // DoneWaiting was called
-};
-
-class PrintSystemWin : public PrintSystem {
- public:
- virtual void EnumeratePrinters(PrinterList* printer_list);
-
- virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name,
- PrinterCapsAndDefaults* printer_info);
-
- virtual bool ValidatePrintTicket(const std::string& printer_name,
- const std::string& print_ticket_data);
-
- virtual bool SpoolPrintJob(const std::string& print_ticket,
- const FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- PlatformJobId* job_id_ret);
-
- virtual bool GetJobDetails(const std::string& printer_name,
- PlatformJobId job_id,
- PrintJobDetails *job_details);
-
- virtual bool IsValidPrinter(const std::string& printer_name);
-
- class PrintServerWatcherWin
- : public PrintSystem::PrintServerWatcher, PrintSystemWatcherWin::Delegate {
- public:
- PrintServerWatcherWin() {}
-
- // PrintSystem::PrintServerWatcher interface
- virtual bool StartWatching(
- PrintSystem::PrintServerWatcher::Delegate* delegate) {
- delegate_ = delegate;
- return watcher_.Start(std::string(), this);
- }
- virtual bool StopWatching() {
- bool ret = watcher_.Stop();
- delegate_ = NULL;
- return ret;
- }
-
- // PrintSystemWatcherWin::Delegate interface
- virtual void OnPrinterAdded() {
- delegate_->OnPrinterAdded();
- }
- virtual void OnPrinterDeleted() {
- NOTREACHED();
- }
- virtual void OnPrinterChanged() {
- NOTREACHED();
- }
- virtual void OnJobChanged() {
- NOTREACHED();
- }
-
- private:
- PrintSystem::PrintServerWatcher::Delegate* delegate_;
- PrintSystemWatcherWin watcher_;
- DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherWin);
- };
-
- class PrinterWatcherWin
- : public PrintSystem::PrinterWatcher, PrintSystemWatcherWin::Delegate {
- public:
- explicit PrinterWatcherWin(const std::string& printer_name)
- : printer_name_(printer_name) {}
-
- // PrintSystem::PrinterWatcher interface
- virtual bool StartWatching(
- PrintSystem::PrinterWatcher::Delegate* delegate) {
- delegate_ = delegate;
- return watcher_.Start(printer_name_, this);
- }
- virtual bool StopWatching() {
- bool ret = watcher_.Stop();
- delegate_ = NULL;
- return ret;
- }
- virtual bool GetCurrentPrinterInfo(PrinterBasicInfo* printer_info) {
- return watcher_.GetCurrentPrinterInfo(printer_info);
- }
-
- // PrintSystemWatcherWin::Delegate interface
- virtual void OnPrinterAdded() {
- NOTREACHED();
- }
- virtual void OnPrinterDeleted() {
- delegate_->OnPrinterDeleted();
- }
- virtual void OnPrinterChanged() {
- delegate_->OnPrinterChanged();
- }
- virtual void OnJobChanged() {
- delegate_->OnJobChanged();
- }
-
- private:
- std::string printer_name_;
- PrintSystem::PrinterWatcher::Delegate* delegate_;
- PrintSystemWatcherWin watcher_;
- DISALLOW_COPY_AND_ASSIGN(PrinterWatcherWin);
- };
-
- virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher();
- virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
- const std::string& printer_name);
-};
-
-void PrintSystemWin::EnumeratePrinters(PrinterList* printer_list) {
+void EnumeratePrinters(PrinterList* printer_list) {
DCHECK(printer_list);
DWORD bytes_needed = 0;
DWORD count_returned = 0;
@@ -370,9 +153,8 @@ void PrintSystemWin::EnumeratePrinters(PrinterList* printer_list) {
}
}
-bool PrintSystemWin::GetPrinterCapsAndDefaults(
- const std::string& printer_name,
- PrinterCapsAndDefaults* printer_info) {
+bool GetPrinterCapsAndDefaults(const std::string& printer_name,
+ PrinterCapsAndDefaults* printer_info) {
if (!InitXPSModule()) {
// TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll)
return false;
@@ -442,9 +224,8 @@ bool PrintSystemWin::GetPrinterCapsAndDefaults(
return true;
}
-bool PrintSystemWin::ValidatePrintTicket(
- const std::string& printer_name,
- const std::string& print_ticket_data) {
+bool ValidatePrintTicket(const std::string& printer_name,
+ const std::string& print_ticket_data) {
if (!InitXPSModule()) {
// TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll)
return false;
@@ -477,12 +258,25 @@ bool PrintSystemWin::ValidatePrintTicket(
return ret;
}
-bool PrintSystemWin::SpoolPrintJob(const std::string& print_ticket,
- const FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- PlatformJobId* job_id_ret) {
+std::string GenerateProxyId() {
+ GUID proxy_id = {0};
+ HRESULT hr = UuidCreate(&proxy_id);
+ DCHECK(SUCCEEDED(hr));
+ wchar_t* proxy_id_as_string = NULL;
+ UuidToString(&proxy_id, reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string));
+ DCHECK(proxy_id_as_string);
+ std::string ret;
+ WideToUTF8(proxy_id_as_string, wcslen(proxy_id_as_string), &ret);
+ RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string));
+ return ret;
+}
+
+bool SpoolPrintJob(const std::string& print_ticket,
+ const FilePath& print_data_file_path,
+ const std::string& print_data_mime_type,
+ const std::string& printer_name,
+ const std::string& job_title,
+ PlatformJobId* job_id_ret) {
if (!InitXPSModule()) {
// TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll)
return false;
@@ -519,9 +313,9 @@ bool PrintSystemWin::SpoolPrintJob(const std::string& print_ticket,
return SUCCEEDED(hr);
}
-bool PrintSystemWin::GetJobDetails(const std::string& printer_name,
- PlatformJobId job_id,
- PrintJobDetails *job_details) {
+bool GetJobDetails(const std::string& printer_name,
+ PlatformJobId job_id,
+ PrintJobDetails *job_details) {
DCHECK(job_details);
HANDLE printer_handle = NULL;
std::wstring printer_name_wide = UTF8ToWide(printer_name);
@@ -564,7 +358,7 @@ bool PrintSystemWin::GetJobDetails(const std::string& printer_name,
return ret;
}
-bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) {
+bool IsValidPrinter(const std::string& printer_name) {
std::wstring printer_name_wide = UTF8ToWide(printer_name);
HANDLE printer_handle = NULL;
OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), &printer_handle,
@@ -577,33 +371,139 @@ bool PrintSystemWin::IsValidPrinter(const std::string& printer_name) {
return ret;
}
-PrintSystem::PrintServerWatcher*
-PrintSystemWin::CreatePrintServerWatcher() {
- return new PrintServerWatcherWin();
+class PrinterChangeNotifier::NotificationState
+ : public base::ObjectWatcher::Delegate {
+ public:
+ NotificationState() : printer_(NULL), printer_change_(NULL), delegate_(NULL) {
+ }
+ ~NotificationState() {
+ Stop();
+ }
+ bool Start(const std::string& printer_name,
+ PrinterChangeNotifier::Delegate* delegate) {
+ delegate_ = delegate;
+ // An empty printer name means watch the current server, we need to pass
+ // NULL to OpenPrinter.
+ LPTSTR printer_name_to_use = NULL;
+ std::wstring printer_name_wide;
+ if (!printer_name.empty()) {
+ printer_name_wide = UTF8ToWide(printer_name);
+ printer_name_to_use = const_cast<LPTSTR>(printer_name_wide.c_str());
+ }
+ bool ret = false;
+ OpenPrinter(printer_name_to_use, &printer_, NULL);
+ if (printer_) {
+ printer_change_ = FindFirstPrinterChangeNotification(
+ printer_, PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB, 0, NULL);
+ if (printer_change_) {
+ ret = watcher_.StartWatching(printer_change_, this);
+ }
+ }
+ if (!ret) {
+ Stop();
+ }
+ return ret;
+ }
+ bool Stop() {
+ watcher_.StopWatching();
+ if (printer_) {
+ ClosePrinter(printer_);
+ printer_ = NULL;
+ }
+ if (printer_change_) {
+ FindClosePrinterChangeNotification(printer_change_);
+ printer_change_ = NULL;
+ }
+ return true;
+ }
+
+ void OnObjectSignaled(HANDLE object) {
+ DWORD change = 0;
+ FindNextPrinterChangeNotification(object, &change, NULL, NULL);
+
+ if (change != ((PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB) &
+ (~PRINTER_CHANGE_FAILED_CONNECTION_PRINTER))) {
+ // For printer connections, we get spurious change notifications with
+ // all flags set except PRINTER_CHANGE_FAILED_CONNECTION_PRINTER.
+ // Ignore these.
+ if (change & PRINTER_CHANGE_ADD_PRINTER) {
+ delegate_->OnPrinterAdded();
+ } else if (change & PRINTER_CHANGE_DELETE_PRINTER) {
+ delegate_->OnPrinterDeleted();
+ } else if (change & PRINTER_CHANGE_SET_PRINTER) {
+ delegate_->OnPrinterChanged();
+ }
+ if (change & PRINTER_CHANGE_JOB) {
+ delegate_->OnJobChanged();
+ }
+ }
+ watcher_.StartWatching(printer_change_, this);
+ }
+ HANDLE printer_handle() const {
+ return printer_;
+ }
+ private:
+ base::ObjectWatcher watcher_;
+ HANDLE printer_; // The printer being watched
+ HANDLE printer_change_; // Returned by FindFirstPrinterChangeNotifier
+ PrinterChangeNotifier::Delegate* delegate_; // Delegate to notify
+ bool did_signal_; // DoneWaiting was called
+};
+
+PrinterChangeNotifier::PrinterChangeNotifier() : state_(NULL) {
}
-PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher(
- const std::string& printer_name) {
- DCHECK(!printer_name.empty());
- return new PrinterWatcherWin(printer_name);
+PrinterChangeNotifier::~PrinterChangeNotifier() {
+ StopWatching();
}
-std::string PrintSystem::GenerateProxyId() {
- GUID proxy_id = {0};
- HRESULT hr = UuidCreate(&proxy_id);
- DCHECK(SUCCEEDED(hr));
- wchar_t* proxy_id_as_string = NULL;
- UuidToString(&proxy_id, reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string));
- DCHECK(proxy_id_as_string);
- std::string ret;
- WideToUTF8(proxy_id_as_string, wcslen(proxy_id_as_string), &ret);
- RpcStringFree(reinterpret_cast<RPC_WSTR *>(&proxy_id_as_string));
- return ret;
+bool PrinterChangeNotifier::StartWatching(const std::string& printer_name,
+ Delegate* delegate) {
+ if (state_) {
+ NOTREACHED();
+ return false;
+ }
+ state_ = new NotificationState;
+ if (!state_->Start(printer_name, delegate)) {
+ StopWatching();
+ return false;
+ }
+ return true;
}
-scoped_refptr<PrintSystem> PrintSystem::CreateInstance() {
- return new PrintSystemWin;
+bool PrinterChangeNotifier::StopWatching() {
+ if (!state_) {
+ return false;
+ }
+ state_->Stop();
+ delete state_;
+ state_ = NULL;
+ return true;
}
+bool PrinterChangeNotifier::GetCurrentPrinterInfo(
+ PrinterBasicInfo* printer_info) {
+ if (!state_) {
+ return false;
+ }
+ DCHECK(printer_info);
+ DWORD bytes_needed = 0;
+ bool ret = false;
+ GetPrinter(state_->printer_handle(), 2, NULL, 0, &bytes_needed);
+ if (0 != bytes_needed) {
+ scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]);
+ if (GetPrinter(state_->printer_handle(), 2, printer_info_buffer.get(),
+ bytes_needed, &bytes_needed)) {
+ PRINTER_INFO_2* printer_info_win =
+ reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get());
+ printer_info->printer_name = WideToUTF8(printer_info_win->pPrinterName);
+ printer_info->printer_description =
+ WideToUTF8(printer_info_win->pComment);
+ printer_info->printer_status = printer_info_win->Status;
+ ret = true;
+ }
+ }
+ return ret;
+}
} // namespace cloud_print
diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc
index 2fbd60b..8ae919b 100644
--- a/chrome/service/cloud_print/printer_job_handler.cc
+++ b/chrome/service/cloud_print/printer_job_handler.cc
@@ -22,10 +22,8 @@ PrinterJobHandler::PrinterJobHandler(
const std::string& caps_hash,
const std::string& auth_token,
const GURL& cloud_print_server_url,
- cloud_print::PrintSystem* print_system,
Delegate* delegate)
- : print_system_(print_system),
- printer_info_(printer_info),
+ : printer_info_(printer_info),
printer_id_(printer_id),
auth_token_(auth_token),
last_caps_hash_(caps_hash),
@@ -43,10 +41,8 @@ PrinterJobHandler::PrinterJobHandler(
}
bool PrinterJobHandler::Initialize() {
- if (print_system_->IsValidPrinter(printer_info_.printer_name)) {
- printer_watcher_ = print_system_->CreatePrinterWatcher(
- printer_info_.printer_name);
- printer_watcher_->StartWatching(this);
+ if (cloud_print::IsValidPrinter(printer_info_.printer_name)) {
+ printer_change_notifier_.StartWatching(printer_info_.printer_name, this);
NotifyJobAvailable();
} else {
// This printer does not exist any more. Delete it from the server.
@@ -56,7 +52,7 @@ bool PrinterJobHandler::Initialize() {
}
PrinterJobHandler::~PrinterJobHandler() {
- printer_watcher_->StopWatching();
+ printer_change_notifier_.StopWatching();
}
void PrinterJobHandler::Reset() {
@@ -122,12 +118,12 @@ bool PrinterJobHandler::UpdatePrinterInfo() {
// We need to update the parts of the printer info that have changed
// (could be printer name, description, status or capabilities).
cloud_print::PrinterBasicInfo printer_info;
- printer_watcher_->GetCurrentPrinterInfo(&printer_info);
+ printer_change_notifier_.GetCurrentPrinterInfo(&printer_info);
cloud_print::PrinterCapsAndDefaults printer_caps;
std::string post_data;
std::string mime_boundary;
- if (print_system_->GetPrinterCapsAndDefaults(printer_info.printer_name,
- &printer_caps)) {
+ if (cloud_print::GetPrinterCapsAndDefaults(printer_info.printer_name,
+ &printer_caps)) {
std::string caps_hash = MD5String(printer_caps.printer_capabilities);
CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary);
if (caps_hash != last_caps_hash_) {
@@ -217,6 +213,12 @@ bool PrinterJobHandler::OnJobCompleted(JobStatusUpdater* updater) {
return ret;
}
+ // cloud_print::PrinterChangeNotifier::Delegate implementation
+void PrinterJobHandler::OnPrinterAdded() {
+ // Should never get this notification for a printer
+ NOTREACHED();
+}
+
void PrinterJobHandler::OnPrinterDeleted() {
printer_delete_pending_ = true;
if (!task_in_progress_) {
@@ -354,7 +356,7 @@ bool PrinterJobHandler::HandlePrintTicketResponse(
if (!status.is_success() || (response_code != 200)) {
return false;
}
- if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) {
+ if (cloud_print::ValidatePrintTicket(printer_info_.printer_name, data)) {
job_details_.print_ticket_ = data;
MessageLoop::current()->PostTask(
FROM_HERE,
@@ -414,8 +416,7 @@ void PrinterJobHandler::StartPrinting() {
print_thread_.message_loop()->PostTask(
FROM_HERE, NewRunnableFunction(&PrinterJobHandler::DoPrint,
job_details_,
- printer_info_.printer_name,
- print_system_, this,
+ printer_info_.printer_name, this,
MessageLoop::current()));
}
}
@@ -493,7 +494,7 @@ bool PrinterJobHandler::HandleSuccessStatusUpdateResponse(
scoped_refptr<JobStatusUpdater> job_status_updater =
new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_,
local_job_id_, auth_token_, cloud_print_server_url_,
- print_system_.get(), this);
+ this);
job_status_updater_list_.push_back(job_status_updater);
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableMethod(job_status_updater.get(),
@@ -542,18 +543,17 @@ bool PrinterJobHandler::HavePendingTasks() {
void PrinterJobHandler::DoPrint(const JobDetails& job_details,
- const std::string& printer_name,
- scoped_refptr<cloud_print::PrintSystem> print_system,
- PrinterJobHandler* job_handler,
- MessageLoop* job_message_loop) {
+ const std::string& printer_name,
+ PrinterJobHandler* job_handler,
+ MessageLoop* job_message_loop) {
DCHECK(job_handler);
DCHECK(job_message_loop);
cloud_print::PlatformJobId job_id = -1;
- if (print_system->SpoolPrintJob(job_details.print_ticket_,
- job_details.print_data_file_path_,
- job_details.print_data_mime_type_,
- printer_name,
- job_details.job_title_, &job_id)) {
+ if (cloud_print::SpoolPrintJob(job_details.print_ticket_,
+ job_details.print_data_file_path_,
+ job_details.print_data_mime_type_,
+ printer_name,
+ job_details.job_title_, &job_id)) {
job_message_loop->PostTask(FROM_HERE,
NewRunnableMethod(job_handler,
&PrinterJobHandler::JobSpooled,
diff --git a/chrome/service/cloud_print/printer_job_handler.h b/chrome/service/cloud_print/printer_job_handler.h
index 948021b..8be2b95 100644
--- a/chrome/service/cloud_print/printer_job_handler.h
+++ b/chrome/service/cloud_print/printer_job_handler.h
@@ -12,7 +12,7 @@
#include "base/ref_counted.h"
#include "base/thread.h"
#include "chrome/service/cloud_print/job_status_updater.h"
-#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_info.h"
#include "chrome/common/net/url_fetcher.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_status.h"
@@ -61,7 +61,7 @@ typedef URLFetcher::Delegate URLFetcherDelegate;
class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
public URLFetcherDelegate,
public JobStatusUpdaterDelegate,
- public cloud_print::PrinterWatcherDelegate {
+ public cloud_print::PrinterChangeNotifierDelegate {
enum PrintJobError {
SUCCESS,
JOB_DOWNLOAD_FAILED,
@@ -92,12 +92,11 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
// Begin public interface
PrinterJobHandler(const cloud_print::PrinterBasicInfo& printer_info,
- const std::string& printer_id,
- const std::string& caps_hash,
- const std::string& auth_token,
- const GURL& cloud_print_server_url,
- cloud_print::PrintSystem* print_system,
- Delegate* delegate);
+ const std::string& printer_id,
+ const std::string& caps_hash,
+ const std::string& auth_token,
+ const GURL& cloud_print_server_url,
+ Delegate* delegate);
~PrinterJobHandler();
bool Initialize();
// Notifies the JobHandler that a job is available
@@ -116,7 +115,8 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
const std::string& data);
// JobStatusUpdater::Delegate implementation
virtual bool OnJobCompleted(JobStatusUpdater* updater);
- // cloud_print::PrinterWatcherDelegate implementation
+ // cloud_print::PrinterChangeNotifier::Delegate implementation
+ virtual void OnPrinterAdded();
virtual void OnPrinterDeleted();
virtual void OnPrinterChanged();
virtual void OnJobChanged();
@@ -194,12 +194,11 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
static void DoPrint(const JobDetails& job_details,
const std::string& printer_name,
- scoped_refptr<cloud_print::PrintSystem> print_system,
PrinterJobHandler* job_handler,
MessageLoop* job_message_loop);
+
scoped_ptr<URLFetcher> request_;
- scoped_refptr<cloud_print::PrintSystem> print_system_;
cloud_print::PrinterBasicInfo printer_info_;
std::string printer_id_;
std::string auth_token_;
@@ -227,7 +226,7 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
// Some task in the state machine is in progress.
bool task_in_progress_;
- scoped_refptr<cloud_print::PrintSystem::PrinterWatcher> printer_watcher_;
+ cloud_print::PrinterChangeNotifier printer_change_notifier_;
typedef std::list< scoped_refptr<JobStatusUpdater> > JobStatusUpdaterList;
JobStatusUpdaterList job_status_updater_list_;