Index: chrome/service/cloud_print/print_system_win.cc |
=================================================================== |
--- chrome/service/cloud_print/print_system_win.cc (revision 48641) |
+++ chrome/service/cloud_print/print_system_win.cc (working copy) |
@@ -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/printer_info.h" |
+#include "chrome/service/cloud_print/print_system.h" |
#include <windows.h> |
#include <objidl.h> |
@@ -128,7 +128,233 @@ |
namespace cloud_print { |
-void EnumeratePrinters(PrinterList* printer_list) { |
+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; |
+ } |
+ |
+ // base::ObjectWatcher::Delegate method |
+ virtual 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 |
+}; |
+ |
+// This typedef is to workaround the issue with certain versions of |
+// Visual Studio where it gets confused between multiple Delegate. |
+// In this case, some compilers get confused and inherit |
+// PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors. |
+typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate; |
+ |
+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, |
+ public PrintSystemWatcherWinDelegate { |
+ 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, |
+ public PrintSystemWatcherWinDelegate { |
+ 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) { |
DCHECK(printer_list); |
DWORD bytes_needed = 0; |
DWORD count_returned = 0; |
@@ -153,8 +379,9 @@ |
} |
} |
-bool GetPrinterCapsAndDefaults(const std::string& printer_name, |
- PrinterCapsAndDefaults* printer_info) { |
+bool PrintSystemWin::GetPrinterCapsAndDefaults( |
+ const std::string& printer_name, |
+ PrinterCapsAndDefaults* printer_info) { |
if (!InitXPSModule()) { |
// TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
return false; |
@@ -224,8 +451,9 @@ |
return true; |
} |
-bool ValidatePrintTicket(const std::string& printer_name, |
- const std::string& print_ticket_data) { |
+bool PrintSystemWin::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; |
@@ -258,25 +486,12 @@ |
return 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) { |
+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) { |
if (!InitXPSModule()) { |
// TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
return false; |
@@ -313,9 +528,9 @@ |
return SUCCEEDED(hr); |
} |
-bool GetJobDetails(const std::string& printer_name, |
- PlatformJobId job_id, |
- PrintJobDetails *job_details) { |
+bool PrintSystemWin::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); |
@@ -358,7 +573,7 @@ |
return ret; |
} |
-bool IsValidPrinter(const std::string& printer_name) { |
+bool PrintSystemWin::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, |
@@ -371,139 +586,33 @@ |
return ret; |
} |
-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::PrintServerWatcher* |
+PrintSystemWin::CreatePrintServerWatcher() { |
+ return new PrintServerWatcherWin(); |
} |
-PrinterChangeNotifier::~PrinterChangeNotifier() { |
- StopWatching(); |
+PrintSystem::PrinterWatcher* PrintSystemWin::CreatePrinterWatcher( |
+ const std::string& printer_name) { |
+ DCHECK(!printer_name.empty()); |
+ return new PrinterWatcherWin(printer_name); |
} |
-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; |
+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::StopWatching() { |
- if (!state_) { |
- return false; |
- } |
- state_->Stop(); |
- delete state_; |
- state_ = NULL; |
- return true; |
+scoped_refptr<PrintSystem> PrintSystem::CreateInstance() { |
+ return new PrintSystemWin; |
} |
-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 |