diff options
author | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-13 17:18:01 +0000 |
---|---|---|
committer | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-13 17:18:01 +0000 |
commit | 8b50bd202626cf978685197adee0d8f32161443b (patch) | |
tree | fe543b2bba72103859baefb8e149814e3e35e2ee /chrome/browser/printing | |
parent | d94ccedd108876d5be652dfa8129df54cab555e9 (diff) | |
download | chromium_src-8b50bd202626cf978685197adee0d8f32161443b.zip chromium_src-8b50bd202626cf978685197adee0d8f32161443b.tar.gz chromium_src-8b50bd202626cf978685197adee0d8f32161443b.tar.bz2 |
Moved cloud print code from the chrome/browser/printing/cloud_print to chrome/service/cloud_print
BUG=None.
TEST=None.
Review URL: http://codereview.chromium.org/2007012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47155 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/printing')
16 files changed, 7 insertions, 2691 deletions
diff --git a/chrome/browser/printing/cloud_print/cloud_print_consts.cc b/chrome/browser/printing/cloud_print/cloud_print_consts.cc deleted file mode 100644 index d1c4685..0000000 --- a/chrome/browser/printing/cloud_print/cloud_print_consts.cc +++ /dev/null @@ -1,30 +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. - -// Constant defines used in the cloud print proxy code - -#include "chrome/browser/printing/cloud_print/cloud_print_consts.h" - -const char kProxyIdValue[] = "proxy"; -const char kPrinterNameValue[] = "printer"; -const char kPrinterDescValue[] = "description"; -const char kPrinterCapsValue[] = "capabilities"; -const char kPrinterDefaultsValue[] = "defaults"; -const char kPrinterStatusValue[] = "status"; - -// Values in the respone JSON from the cloud print server -const wchar_t kPrinterListValue[] = L"printers"; -const wchar_t kSuccessValue[] = L"success"; -const wchar_t kNameValue[] = L"name"; -const wchar_t kIdValue[] = L"id"; -const wchar_t kTicketUrlValue[] = L"ticketUrl"; -const wchar_t kFileUrlValue[] = L"fileUrl"; -const wchar_t kJobListValue[] = L"jobs"; -const wchar_t kTitleValue[] = L"title"; -const wchar_t kPrinterCapsHashValue[] = L"capsHash"; - -// TODO(sanjeevr): Change this to a real one. Also read this from prefs instead -// of hardcoding. -const char kCloudPrintServerUrl[] = "https://<TBD>"; - diff --git a/chrome/browser/printing/cloud_print/cloud_print_consts.h b/chrome/browser/printing/cloud_print/cloud_print_consts.h deleted file mode 100644 index 13a091f..0000000 --- a/chrome/browser/printing/cloud_print/cloud_print_consts.h +++ /dev/null @@ -1,37 +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_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_CONSTS_H_ -#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_CONSTS_H_ - -#include "base/basictypes.h" - -// Constant defines used in the cloud print proxy code -extern const char kProxyIdValue[]; -extern const char kPrinterNameValue[]; -extern const char kPrinterDescValue[]; -extern const char kPrinterCapsValue[]; -extern const char kPrinterDefaultsValue[]; -extern const char kPrinterStatusValue[]; -// Values in the respone JSON from the cloud print server -extern const wchar_t kPrinterListValue[]; -extern const wchar_t kSuccessValue[]; -extern const wchar_t kNameValue[]; -extern const wchar_t kIdValue[]; -extern const wchar_t kTicketUrlValue[]; -extern const wchar_t kFileUrlValue[]; -extern const wchar_t kJobListValue[]; -extern const wchar_t kTitleValue[]; -extern const wchar_t kPrinterCapsHashValue[]; - -extern const char kCloudPrintServerUrl[]; - -// Max interval between retrying connection to the server -const int64 kMaxRetryInterval = 5*60*1000; // 5 minutes in millseconds -const int64 kBaseRetryInterval = 5*1000; // 5 seconds -const int kMaxRetryCount = 5; -const int64 kJobStatusUpdateInterval = 10*1000; // 10 seconds - -#endif // CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_CONSTS_H_ - diff --git a/chrome/browser/printing/cloud_print/cloud_print_helpers.cc b/chrome/browser/printing/cloud_print/cloud_print_helpers.cc deleted file mode 100644 index 3f0871f..0000000 --- a/chrome/browser/printing/cloud_print/cloud_print_helpers.cc +++ /dev/null @@ -1,158 +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. - -#include "chrome/browser/printing/cloud_print/cloud_print_helpers.h" - -#include "base/json/json_reader.h" -#include "base/rand_util.h" -#include "base/scoped_ptr.h" -#include "base/string_util.h" -#include "base/task.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/printing/cloud_print/cloud_print_consts.h" -#include "chrome/browser/profile.h" -#include "chrome/common/net/url_fetcher.h" - -std::string StringFromJobStatus(cloud_print::PrintJobStatus status) { - std::string ret; - switch (status) { - case cloud_print::PRINT_JOB_STATUS_IN_PROGRESS: - ret = "in_progress"; - break; - case cloud_print::PRINT_JOB_STATUS_ERROR: - ret = "error"; - break; - case cloud_print::PRINT_JOB_STATUS_COMPLETED: - ret = "done"; - break; - default: - ret = "unknown"; - NOTREACHED(); - break; - } - return ret; -} - -GURL CloudPrintHelpers::GetUrlForPrinterRegistration() { - return GURL(StringPrintf("%s/printing/register", kCloudPrintServerUrl)); -} - -GURL CloudPrintHelpers::GetUrlForPrinterUpdate(const std::string& printer_id) { - return GURL(StringPrintf("%s/printing/update?printerid=%s", - kCloudPrintServerUrl, printer_id.c_str())); -} - -GURL CloudPrintHelpers::GetUrlForPrinterDelete(const std::string& printer_id) { - return GURL(StringPrintf("%s/printing/delete?printerid=%s", - kCloudPrintServerUrl, printer_id.c_str())); -} - -GURL CloudPrintHelpers::GetUrlForPrinterList(const std::string& proxy_id) { - return GURL(StringPrintf( - "%s/printing/list?proxy=%s", - kCloudPrintServerUrl, proxy_id.c_str())); -} - -GURL CloudPrintHelpers::GetUrlForJobFetch(const std::string& printer_id) { - return GURL(StringPrintf( - "%s/printing/fetch?printerid=%s", - kCloudPrintServerUrl, printer_id.c_str())); -} - -GURL CloudPrintHelpers::GetUrlForJobStatusUpdate( - const std::string& job_id, cloud_print::PrintJobStatus status) { - std::string status_string = StringFromJobStatus(status); - return GURL(StringPrintf( - "%s/printing/control?jobid=%s&status=%s", - kCloudPrintServerUrl, job_id.c_str(), status_string.c_str())); -} - -GURL CloudPrintHelpers::GetUrlForJobStatusUpdate( - const std::string& job_id, const cloud_print::PrintJobDetails& details) { - std::string status_string = StringFromJobStatus(details.status); - return GURL(StringPrintf( - "%s/printing/control?jobid=%s&status=%s&code=%d&message=%s" - "&numpages=%d&pagesprinted=%d", - kCloudPrintServerUrl, job_id.c_str(), status_string.c_str(), - details.platform_status_flags, details.status_message.c_str(), - details.total_pages, details.pages_printed)); -} - -bool CloudPrintHelpers::ParseResponseJSON( - const std::string& response_data, bool* succeeded, - DictionaryValue** response_dict) { - scoped_ptr<Value> message_value(base::JSONReader::Read(response_data, false)); - if (!message_value.get()) { - NOTREACHED(); - return false; - } - if (!message_value->IsType(Value::TYPE_DICTIONARY)) { - NOTREACHED(); - return false; - } - scoped_ptr<DictionaryValue> response_dict_local( - static_cast<DictionaryValue*>(message_value.release())); - if (succeeded) - response_dict_local->GetBoolean(kSuccessValue, succeeded); - if (response_dict) - *response_dict = response_dict_local.release(); - return true; -} - -void CloudPrintHelpers::PrepCloudPrintRequest(URLFetcher* request, - const std::string& auth_token) { - request->set_request_context( - Profile::GetDefaultRequestContext()); - std::string headers = "Authorization: GoogleLogin auth="; - headers += auth_token; - request->set_extra_request_headers(headers); -} - -void CloudPrintHelpers::HandleServerError(int* error_count, int max_retry_count, - int64 max_retry_interval, - int64 base_retry_interval, - Task* task_to_retry, - Task* task_on_give_up) { - (*error_count)++; - if ((-1 != max_retry_count) && (*error_count > max_retry_count)) { - if (task_on_give_up) { - MessageLoop::current()->PostTask(FROM_HERE, task_on_give_up); - } - } else { - int64 retry_interval = base_retry_interval * (*error_count); - if ((-1 != max_retry_interval) && (retry_interval > max_retry_interval)) { - retry_interval = max_retry_interval; - } - MessageLoop::current()->PostDelayedTask(FROM_HERE, task_to_retry, - retry_interval); - } -} - -void CloudPrintHelpers::AddMultipartValueForUpload( - const std::string& value_name, const std::string& value, - const std::string& mime_boundary, const std::string& content_type, - std::string* post_data) { - DCHECK(post_data); - // First line is the boundary - post_data->append("--" + mime_boundary + "\r\n"); - // Next line is the Content-disposition - post_data->append(StringPrintf("Content-Disposition: form-data; " - "name=\"%s\"\r\n", value_name.c_str())); - if (!content_type.empty()) { - // If Content-type is specified, the next line is that - post_data->append(StringPrintf("Content-Type: %s\r\n", - content_type.c_str())); - } - // Leave an empty line and append the value. - post_data->append(StringPrintf("\r\n%s\r\n", value.c_str())); -} - -// Create a MIME boundary marker (27 '-' characters followed by 16 hex digits). -void CloudPrintHelpers::CreateMimeBoundaryForUpload(std::string* out) { - int r1 = base::RandInt(0, kint32max); - int r2 = base::RandInt(0, kint32max); - SStringPrintf(out, "---------------------------%08X%08X", r1, r2); -} - diff --git a/chrome/browser/printing/cloud_print/cloud_print_helpers.h b/chrome/browser/printing/cloud_print/cloud_print_helpers.h deleted file mode 100644 index 46f0e5b..0000000 --- a/chrome/browser/printing/cloud_print/cloud_print_helpers.h +++ /dev/null @@ -1,71 +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_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_HELPERS_H_ -#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_HELPERS_H_ - -#include <string> - -#include "chrome/browser/printing/cloud_print/printer_info.h" -#include "googleurl/src/gurl.h" - -class DictionaryValue; -class Task; -class URLFetcher; - -// Helper methods for the cloud print proxy code. -class CloudPrintHelpers { - public: - static GURL GetUrlForPrinterRegistration(); - static GURL GetUrlForPrinterUpdate(const std::string& printer_id); - static GURL GetUrlForPrinterDelete(const std::string& printer_id); - static GURL GetUrlForPrinterList(const std::string& proxy_id); - static GURL GetUrlForJobFetch(const std::string& printer_id); - static GURL GetUrlForJobStatusUpdate(const std::string& job_id, - cloud_print::PrintJobStatus status); - static GURL GetUrlForJobStatusUpdate( - const std::string& job_id, const cloud_print::PrintJobDetails& details); - // Parses the response data for any cloud print server request. The method - // returns false if there was an error in parsing the JSON. The succeeded - // value returns the value of the "success" value in the response JSON. - // Returns the response as a dictionary value. - static bool ParseResponseJSON(const std::string& response_data, - bool* succeeded, DictionaryValue** response_dict); - // Sets up common parameters for a cloud print request - // (such as the GAIA auth token in the request headers, the request context - // etc). - static void PrepCloudPrintRequest(URLFetcher* request, - const std::string& auth_token); - // Strictly speaking, this helper method is not specific to cloud printing. - // It handles the logic to retry tasks when the server returns an error. - // The parameters are as below: - // |error_count| Contains the current number of consecutive failed attempts. - // This method increments it (in/out) - // |max_retry_count| Number of retries before giving up. -1 implies no limit. - // |max_retry_interval| Maximum amount of time (in ms) we are willing to - // wait between retries. -1 implies no limit. - // |base_retry_interval| Starting value of the retry interval. This - // method progressively increases the interval on each retry. - // |task_to_retry| The task to be retried. - // |task_on_give_up| Task to be performed when we give up. This is only - // valid when max_retry_count is not -1. It can be NULL. - static void HandleServerError(int* error_count, int max_retry_count, - int64 max_retry_interval, - int64 base_retry_interval, - Task* task_to_retry, Task* task_on_give_up); - // Prepares one value as part of a multi-part upload request. - static void AddMultipartValueForUpload( - const std::string& value_name, const std::string& value, - const std::string& mime_boundary, const std::string& content_type, - std::string* post_data); -// Create a MIME boundary marker (27 '-' characters followed by 16 hex digits). - static void CreateMimeBoundaryForUpload(std::string *out); - - private: - CloudPrintHelpers() { - } -}; - -#endif // CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_HELPERS_H_ - diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_backend.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_backend.cc deleted file mode 100644 index dbc6640..0000000 --- a/chrome/browser/printing/cloud_print/cloud_print_proxy_backend.cc +++ /dev/null @@ -1,496 +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. - -#include "chrome/browser/printing/cloud_print/cloud_print_proxy_backend.h" - -#include "base/file_util.h" -#include "base/md5.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/printing/cloud_print/cloud_print_consts.h" -#include "chrome/browser/printing/cloud_print/cloud_print_helpers.h" -#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" -#include "chrome/browser/printing/cloud_print/printer_job_handler.h" -#include "googleurl/src/gurl.h" -#include "net/url_request/url_request_status.h" - -// The real guts of SyncBackendHost, to keep the public client API clean. -class CloudPrintProxyBackend::Core - : public base::RefCountedThreadSafe<CloudPrintProxyBackend::Core>, - public URLFetcherDelegate, - public cloud_print::PrinterChangeNotifierDelegate, - public PrinterJobHandlerDelegate { - public: - explicit Core(CloudPrintProxyBackend* backend); - // Note: - // - // The Do* methods are the various entry points from CloudPrintProxyBackend - // It calls us on a dedicated thread to actually perform synchronous - // (and potentially blocking) syncapi operations. - // - // Called on the CloudPrintProxyBackend core_thread_ to perform - // initialization - void DoInitialize(const std::string& auth_token, - const std::string& proxy_id); - // Called on the CloudPrintProxyBackend core_thread_ to perform - // shutdown. - void DoShutdown(); - void DoRegisterSelectedPrinters( - const cloud_print::PrinterList& printer_list); - void DoHandlePrinterNotification(const std::string& printer_id); - - // URLFetcher::Delegate implementation. - virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); -// 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); - - protected: - // FrontendNotification defines parameters for NotifyFrontend. Each enum - // value corresponds to the one CloudPrintProcyService method that - // NotifyFrontend should invoke. - enum FrontendNotification { - PRINTER_LIST_AVAILABLE, // OnPrinterListAvailable - }; - // Prototype for a response handler. - typedef void (CloudPrintProxyBackend::Core::*ResponseHandler)( - const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, int response_code, - const ResponseCookies& cookies, const std::string& data); - // Begin response handlers - void HandlePrinterListResponse(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - void HandleRegisterPrinterResponse(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - // End response handlers - - // NotifyFrontend is how the Core communicates with the frontend across - // threads. - void NotifyFrontend(FrontendNotification notification); - // Starts a new printer registration process. - void StartRegistration(); - // Ends the printer registration process. - void EndRegistration(); - // Registers printer capabilities and defaults for the next printer in the - // list with the cloud print server. - void RegisterNextPrinter(); - // Retrieves the list of registered printers for this user/proxy combination - // from the cloud print server. - void GetRegisteredPrinters(); - void HandleServerError(Task* task_to_retry); - // Removes the given printer from the list. Returns false if the printer - // did not exist in the list. - bool RemovePrinterFromList(const std::string& printer_name); - // Initializes a job handler object for the specified printer. The job - // handler is responsible for checking for pending print jobs for this - // printer and print them. - void InitJobHandlerForPrinter(DictionaryValue* printer_data); - - // Our parent CloudPrintProxyBackend - CloudPrintProxyBackend* backend_; - // 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 - // already registered. We trim this list to remove the printers already - // registered. We then pass a copy of this list to the frontend to give the - // user a chance to further trim the list. When the frontend gives us the - // final list we make a copy into this so that we can start registering. - cloud_print::PrinterList printer_list_; - // The URLFetcher instance for the current request - scoped_ptr<URLFetcher> request_; - // The index of the nex printer to be uploaded. - size_t next_upload_index_; - // The unique id for this proxy - std::string proxy_id_; - // The GAIA auth token - std::string auth_token_; - // The number of consecutive times that connecting to the server failed. - int server_error_count_; - // Cached info about the last printer that we tried to upload. We cache this - // so we won't have to requery the printer if the upload fails and we need - // to retry. - std::string last_uploaded_printer_name_; - cloud_print::PrinterCapsAndDefaults last_uploaded_printer_info_; - // A map of printer id to job handler. - typedef std::map<std::string, scoped_refptr<PrinterJobHandler> > - JobHandlerMap; - JobHandlerMap job_handler_map_; - ResponseHandler next_response_handler_; - cloud_print::PrinterChangeNotifier printer_change_notifier_; - bool new_printers_available_; - - DISALLOW_COPY_AND_ASSIGN(Core); -}; - -CloudPrintProxyBackend::CloudPrintProxyBackend( - CloudPrintProxyFrontend* frontend) - : core_thread_("Chrome_CloudPrintProxyCoreThread"), - frontend_loop_(MessageLoop::current()), - frontend_(frontend) { - DCHECK(frontend_); - core_ = new Core(this); -} - -CloudPrintProxyBackend::~CloudPrintProxyBackend() { - DCHECK(!core_); -} - -bool CloudPrintProxyBackend::Initialize(const std::string& auth_token, - const std::string& proxy_id) { - if (!core_thread_.Start()) - return false; - core_thread_.message_loop()->PostTask(FROM_HERE, - NewRunnableMethod( - core_.get(), &CloudPrintProxyBackend::Core::DoInitialize, auth_token, - proxy_id)); - return true; -} - -void CloudPrintProxyBackend::Shutdown() { - core_thread_.message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(core_.get(), - &CloudPrintProxyBackend::Core::DoShutdown)); - core_thread_.Stop(); - core_ = NULL; // Releases reference to core_. -} - -void CloudPrintProxyBackend::RegisterPrinters( - const cloud_print::PrinterList& printer_list) { - core_thread_.message_loop()->PostTask(FROM_HERE, - NewRunnableMethod( - core_.get(), - &CloudPrintProxyBackend::Core::DoRegisterSelectedPrinters, - printer_list)); -} - -void CloudPrintProxyBackend::HandlePrinterNotification( - const std::string& printer_id) { - core_thread_.message_loop()->PostTask(FROM_HERE, - NewRunnableMethod( - core_.get(), - &CloudPrintProxyBackend::Core::DoHandlePrinterNotification, - printer_id)); -} - -CloudPrintProxyBackend::Core::Core(CloudPrintProxyBackend* backend) - : backend_(backend), next_upload_index_(0), server_error_count_(0), - next_response_handler_(NULL), new_printers_available_(false) { -} - -void CloudPrintProxyBackend::Core::DoInitialize(const std::string& auth_token, - const std::string& proxy_id) { - DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); - printer_change_notifier_.StartWatching(std::string(), this); - proxy_id_ = proxy_id; - auth_token_ = auth_token; - StartRegistration(); -} - -void CloudPrintProxyBackend::Core::StartRegistration() { - printer_list_.clear(); - 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. - GetRegisteredPrinters(); -} - -void CloudPrintProxyBackend::Core::EndRegistration() { - request_.reset(); - if (new_printers_available_) { - new_printers_available_ = false; - StartRegistration(); - } -} - -void CloudPrintProxyBackend::Core::DoShutdown() { - // Need to kill all running jobs. - while (!job_handler_map_.empty()) { - JobHandlerMap::iterator index = job_handler_map_.begin(); - // Shutdown will call our OnPrinterJobHandlerShutdown method which will - // remove this from the map. - index->second->Shutdown(); - } -} - -void CloudPrintProxyBackend::Core::DoRegisterSelectedPrinters( - const cloud_print::PrinterList& printer_list) { - server_error_count_ = 0; - printer_list_.assign(printer_list.begin(), printer_list.end()); - DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); - next_upload_index_ = 0; - RegisterNextPrinter(); -} - -void CloudPrintProxyBackend::Core::DoHandlePrinterNotification( - const std::string& printer_id) { - JobHandlerMap::iterator index = job_handler_map_.find(printer_id); - if (index != job_handler_map_.end()) - index->second->NotifyJobAvailable(); -} - -void CloudPrintProxyBackend::Core::GetRegisteredPrinters() { - request_.reset( - new URLFetcher(CloudPrintHelpers::GetUrlForPrinterList(proxy_id_), - URLFetcher::GET, this)); - CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_); - next_response_handler_ = - &CloudPrintProxyBackend::Core::HandlePrinterListResponse; - request_->Start(); -} - -void CloudPrintProxyBackend::Core::RegisterNextPrinter() { - // For the next printer to be uploaded, create a multi-part post request to - // upload the printer capabilities and the printer defaults. - if (next_upload_index_ < printer_list_.size()) { - const cloud_print::PrinterBasicInfo& info = - printer_list_.at(next_upload_index_); - bool have_printer_info = true; - // 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 = cloud_print::GetPrinterCapsAndDefaults( - info.printer_name.c_str(), &last_uploaded_printer_info_); - } - if (have_printer_info) { - last_uploaded_printer_name_ = info.printer_name; - std::string mime_boundary; - CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary); - std::string post_data; - CloudPrintHelpers::AddMultipartValueForUpload(kProxyIdValue, proxy_id_, - mime_boundary, - std::string(), &post_data); - CloudPrintHelpers::AddMultipartValueForUpload(kPrinterNameValue, - info.printer_name, - mime_boundary, - std::string(), &post_data); - CloudPrintHelpers::AddMultipartValueForUpload(kPrinterDescValue, - info.printer_description, - mime_boundary, - std::string() , &post_data); - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterStatusValue, StringPrintf("%d", info.printer_status), - mime_boundary, std::string(), &post_data); - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterCapsValue, last_uploaded_printer_info_.printer_capabilities, - mime_boundary, last_uploaded_printer_info_.caps_mime_type, - &post_data); - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterDefaultsValue, last_uploaded_printer_info_.printer_defaults, - mime_boundary, last_uploaded_printer_info_.defaults_mime_type, - &post_data); - // Send a hash of the printer capabilities to the server. We will use this - // later to check if the capabilities have changed - CloudPrintHelpers::AddMultipartValueForUpload( - WideToUTF8(kPrinterCapsHashValue).c_str(), - MD5String(last_uploaded_printer_info_.printer_capabilities), - mime_boundary, std::string(), &post_data); - // Terminate the request body - post_data.append("--" + mime_boundary + "--\r\n"); - std::string mime_type("multipart/form-data; boundary="); - mime_type += mime_boundary; - request_.reset( - new URLFetcher(CloudPrintHelpers::GetUrlForPrinterRegistration(), - URLFetcher::POST, this)); - CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_); - request_->set_upload_data(mime_type, post_data); - next_response_handler_ = - &CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse; - request_->Start(); - } else { - NOTREACHED(); - } - } else { - EndRegistration(); - } -} - -// URLFetcher::Delegate implementation. -void CloudPrintProxyBackend::Core::OnURLFetchComplete( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - DCHECK(source == request_.get()); - // We need a next response handler - DCHECK(next_response_handler_); - (this->*next_response_handler_)(source, url, status, response_code, - cookies, data); -} - -void CloudPrintProxyBackend::Core::NotifyFrontend( - FrontendNotification notification) { - switch (notification) { - case PRINTER_LIST_AVAILABLE: - backend_->frontend_->OnPrinterListAvailable(printer_list_); - break; - default: - NOTREACHED(); - break; - } -} - -void CloudPrintProxyBackend::Core::HandlePrinterListResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - if (status.is_success()) { - server_error_count_ = 0; - if (response_code == 200) { - // Parse the response JSON for the list of printers already registered. - bool succeeded = false; - DictionaryValue* response_dict_temp = NULL; - CloudPrintHelpers::ParseResponseJSON(data, &succeeded, - &response_dict_temp); - scoped_ptr<DictionaryValue> response_dict; - response_dict.reset(response_dict_temp); - if (succeeded) { - DCHECK(response_dict.get()); - ListValue* printer_list = NULL; - response_dict->GetList(kPrinterListValue, &printer_list); - // There may be no "printers" value in the JSON - if (printer_list) { - for (size_t index = 0; index < printer_list->GetSize(); index++) { - DictionaryValue* printer_data = NULL; - if (printer_list->GetDictionary(index, &printer_data)) { - std::string printer_name; - printer_data->GetString(kNameValue, &printer_name); - RemovePrinterFromList(printer_name); - InitJobHandlerForPrinter(printer_data); - } else { - NOTREACHED(); - } - } - } - } - } - MessageLoop::current()->DeleteSoon(FROM_HERE, request_.release()); - if (!printer_list_.empty()) { - // Let the frontend know that we have a list of printers available. - backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, - &Core::NotifyFrontend, PRINTER_LIST_AVAILABLE)); - } else { - // No more work to be done here. - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &Core::EndRegistration)); - } - } else { - HandleServerError(NewRunnableMethod(this, &Core::GetRegisteredPrinters)); - } -} - -void CloudPrintProxyBackend::Core::InitJobHandlerForPrinter( - DictionaryValue* printer_data) { - DCHECK(printer_data); - std::string printer_id; - printer_data->GetString(kIdValue, &printer_id); - DCHECK(!printer_id.empty()); - JobHandlerMap::iterator index = job_handler_map_.find(printer_id); - // We might already have a job handler for this printer - if (index == job_handler_map_.end()) { - cloud_print::PrinterBasicInfo printer_info; - printer_data->GetString(kNameValue, &printer_info.printer_name); - DCHECK(!printer_info.printer_name.empty()); - printer_data->GetString(UTF8ToWide(kPrinterDescValue), - &printer_info.printer_description); - printer_data->GetInteger(UTF8ToWide(kPrinterStatusValue), - &printer_info.printer_status); - std::string caps_hash; - printer_data->GetString(kPrinterCapsHashValue, &caps_hash); - scoped_refptr<PrinterJobHandler> job_handler; - job_handler = new PrinterJobHandler(printer_info, printer_id, caps_hash, - auth_token_, this); - job_handler_map_[printer_id] = job_handler; - job_handler->Initialize(); - } -} - -void CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - Task* next_task = - NewRunnableMethod(this, - &CloudPrintProxyBackend::Core::RegisterNextPrinter); - if (status.is_success() && (response_code == 200)) { - bool succeeded = false; - DictionaryValue* response_dict = NULL; - CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict); - if (succeeded) { - DCHECK(response_dict); - ListValue* printer_list = NULL; - response_dict->GetList(kPrinterListValue, &printer_list); - // There should be a "printers" value in the JSON - DCHECK(printer_list); - if (printer_list) { - DictionaryValue* printer_data = NULL; - if (printer_list->GetDictionary(0, &printer_data)) { - InitJobHandlerForPrinter(printer_data); - } - } - } - server_error_count_ = 0; - next_upload_index_++; - MessageLoop::current()->PostTask(FROM_HERE, next_task); - } else { - HandleServerError(next_task); - } -} - -void CloudPrintProxyBackend::Core::HandleServerError(Task* task_to_retry) { - CloudPrintHelpers::HandleServerError( - &server_error_count_, -1, kMaxRetryInterval, kBaseRetryInterval, - task_to_retry, NULL); -} - -bool CloudPrintProxyBackend::Core::RemovePrinterFromList( - const std::string& printer_name) { - bool ret = false; - for (cloud_print::PrinterList::iterator index = printer_list_.begin(); - index != printer_list_.end(); index++) { - if (0 == base::strcasecmp(index->printer_name.c_str(), - printer_name.c_str())) { - index = printer_list_.erase(index); - ret = true; - break; - } - } - return ret; -} - -// cloud_print::PrinterChangeNotifier::Delegate implementation -void CloudPrintProxyBackend::Core::OnPrinterAdded() { - if (request_.get()) { - new_printers_available_ = true; - } else { - StartRegistration(); - } -} - -// PrinterJobHandler::Delegate implementation -void CloudPrintProxyBackend::Core::OnPrinterJobHandlerShutdown( - PrinterJobHandler* job_handler, const std::string& printer_id) { - job_handler_map_.erase(printer_id); -} - diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_backend.h b/chrome/browser/printing/cloud_print/cloud_print_proxy_backend.h deleted file mode 100644 index acced9a..0000000 --- a/chrome/browser/printing/cloud_print/cloud_print_proxy_backend.h +++ /dev/null @@ -1,70 +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_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_PROXY_BACKEND_H_ -#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_PROXY_BACKEND_H_ - -#include <map> -#include <string> - -#include "base/thread.h" -#include "chrome/browser/printing/cloud_print/printer_info.h" -#include "chrome/common/net/url_fetcher.h" - -class CloudPrintProxyService; -class DictionaryValue; - -// CloudPrintProxyFrontend is the interface used by CloudPrintProxyBackend to -// communicate with the entity that created it and, presumably, is interested in -// cloud print proxy related activity. -// NOTE: All methods will be invoked by a CloudPrintProxyBackend on the same -// thread used to create that CloudPrintProxyBackend. -class CloudPrintProxyFrontend { - public: - CloudPrintProxyFrontend() {} - - // There is a list of printers available that can be registered. - virtual void OnPrinterListAvailable( - const cloud_print::PrinterList& printer_list) = 0; - - protected: - // Don't delete through SyncFrontend interface. - virtual ~CloudPrintProxyFrontend() { - } - private: - DISALLOW_COPY_AND_ASSIGN(CloudPrintProxyFrontend); -}; - -class CloudPrintProxyBackend { - public: - explicit CloudPrintProxyBackend(CloudPrintProxyFrontend* frontend); - ~CloudPrintProxyBackend(); - - bool Initialize(const std::string& auth_token, const std::string& proxy_id); - void Shutdown(); - void RegisterPrinters(const cloud_print::PrinterList& printer_list); - void HandlePrinterNotification(const std::string& printer_id); - - private: - // The real guts of SyncBackendHost, to keep the public client API clean. - class Core; - // A thread we dedicate for use to perform initialization and - // authentication. - base::Thread core_thread_; - // Our core, which communicates with AuthWatcher for GAIA authentication and - // which contains printer registration code. - scoped_refptr<Core> core_; - // A reference to the MessageLoop used to construct |this|, so we know how - // to safely talk back to the SyncFrontend. - MessageLoop* const frontend_loop_; - // The frontend which is responsible for displaying UI and updating Prefs - CloudPrintProxyFrontend* frontend_; - - friend class base::RefCountedThreadSafe<CloudPrintProxyBackend::Core>; - - DISALLOW_COPY_AND_ASSIGN(CloudPrintProxyBackend); -}; - -#endif // CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_PROXY_BACKEND_H_ - diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc index 75ec15c..87b4450 100644 --- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc +++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc @@ -26,78 +26,20 @@ CloudPrintProxyService::~CloudPrintProxyService() { } void CloudPrintProxyService::Initialize() { - PrefService* prefs = g_browser_process->local_state(); - DCHECK(prefs); - prefs->RegisterStringPref(prefs::kCloudPrintProxyId, L""); - prefs->RegisterStringPref(prefs::kCloudPrintProxyName, L""); - prefs->RegisterStringPref(prefs::kCloudPrintAuthToken, L""); } void CloudPrintProxyService::EnableForUser(const std::string& auth_token) { - if (backend_.get()) - return; - - PrefService* prefs = g_browser_process->local_state(); - DCHECK(prefs); - std::string proxy_id = - WideToUTF8(prefs->GetString(prefs::kCloudPrintProxyId)); - if (proxy_id.empty()) { - // TODO(sanjeevr): Determine whether the proxy id should be server generated - proxy_id = cloud_print::GenerateProxyId(); - prefs->SetString(prefs::kCloudPrintProxyId, UTF8ToWide(proxy_id)); - } - std::string token_to_use = auth_token; - if (token_to_use.empty()) { - token_to_use = WideToUTF8(prefs->GetString(prefs::kCloudPrintAuthToken)); - } else { - prefs->SetString(prefs::kCloudPrintAuthToken, UTF8ToWide(token_to_use)); - } - - backend_.reset(new CloudPrintProxyBackend(this)); - backend_->Initialize(token_to_use, proxy_id); + // TODO(sanjeevr): Add code to communicate with the cloud print proxy code + // running in the service process here. } void CloudPrintProxyService::DisableForUser() { - PrefService* prefs = g_browser_process->local_state(); - DCHECK(prefs); - prefs->ClearPref(prefs::kCloudPrintAuthToken); Shutdown(); } -void CloudPrintProxyService::HandlePrinterNotification( - const std::string& printer_id) { - if (backend_.get()) - backend_->HandlePrinterNotification(printer_id); -} - void CloudPrintProxyService::Shutdown() { - if (backend_.get()) - backend_->Shutdown(); - backend_.reset(); -} - -// Notification methods from the backend. Called on UI thread. -void CloudPrintProxyService::OnPrinterListAvailable( - const cloud_print::PrinterList& printer_list) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - // Here we will trim the list to eliminate printers already registered. - // If there are any more printers left in the list after trimming, we will - // show the print selection UI. Any printers left in the list after the user - // selection process will then be registered. - backend_->RegisterPrinters(printer_list); -} - -// Called when authentication is done. Called on UI thread. -// Note that sid can be empty. This is a temp function to steal the sid -// from the Bookmarks Sync code. When the common GAIA signin code is done, -// The CloudPrintProxyService will simply get a notification when authentication -// done with an lsid and a sid. -void CloudPrintProxyService::OnAuthenticated(const std::string& sid) { - FilePath user_data_dir; - PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); - ProfileManager* profile_manager = g_browser_process->profile_manager(); - Profile* profile = profile_manager->GetDefaultProfile(user_data_dir); - profile->GetCloudPrintProxyService()->EnableForUser(sid); + // TODO(sanjeevr): Add code to communicate with the cloud print proxy code + // running in the service process here. } diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h index 92985e2..a3795b0 100644 --- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h +++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h @@ -15,12 +15,12 @@ #include "base/scoped_ptr.h" #include "chrome/browser/profile.h" -#include "chrome/browser/printing/cloud_print/cloud_print_proxy_backend.h" class Profile; -// Layer between the browser user interface and the cloud print proxy backend. -class CloudPrintProxyService : public CloudPrintProxyFrontend { +// Layer between the browser user interface and the cloud print proxy code +// running in the service process. +class CloudPrintProxyService { public: explicit CloudPrintProxyService(Profile* profile); virtual ~CloudPrintProxyService(); @@ -32,26 +32,10 @@ class CloudPrintProxyService : public CloudPrintProxyFrontend { // Enables/disables cloud printing for the user virtual void EnableForUser(const std::string& auth_token); virtual void DisableForUser(); - // Notification received from the server for a particular printer. - // We need to inform the backend to look for jobs for this printer. - void HandlePrinterNotification(const std::string& printer_id); - - // Notification methods from the backend. Called on UI thread. - void OnPrinterListAvailable(const cloud_print::PrinterList& printer_list); - - // Called when authentication is done. Called on UI thread. - // Note that sid can be empty. This is placeholder code until we can get - // common GAIA signin code in place. - // TODO(sanjeevr): Remove this. - static void OnAuthenticated(const std::string& auth_token); protected: void Shutdown(); - // Our asynchronous backend to communicate with sync components living on - // other threads. - scoped_ptr<CloudPrintProxyBackend> backend_; - DISALLOW_COPY_AND_ASSIGN(CloudPrintProxyService); }; diff --git a/chrome/browser/printing/cloud_print/job_status_updater.cc b/chrome/browser/printing/cloud_print/job_status_updater.cc deleted file mode 100644 index a17c451..0000000 --- a/chrome/browser/printing/cloud_print/job_status_updater.cc +++ /dev/null @@ -1,90 +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. - -#include "chrome/browser/printing/cloud_print/job_status_updater.h" - -#include "base/json/json_reader.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/printing/cloud_print/cloud_print_consts.h" -#include "chrome/browser/printing/cloud_print/cloud_print_helpers.h" -#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, - Delegate* delegate) - : printer_name_(printer_name), job_id_(job_id), - local_job_id_(local_job_id), auth_token_(auth_token), - delegate_(delegate), stopped_(false) { - DCHECK(delegate_); -} - -// Start checking the status of the local print job. -void JobStatusUpdater::UpdateStatus() { - // It does not matter if we had already sent out an update and are waiting for - // a response. This is a new update and we will simply cancel the old request - // and send a new one. - if (!stopped_) { - bool need_update = false; - // If the job has already been completed, we just need to update the server - // with that status. The *only* reason we would come back here in that case - // is if our last server update attempt failed. - if (last_job_details_.status == cloud_print::PRINT_JOB_STATUS_COMPLETED) { - need_update = true; - } else { - cloud_print::PrintJobDetails details; - if (cloud_print::GetJobDetails(printer_name_, local_job_id_, &details)) { - if (details != last_job_details_) { - last_job_details_ = details; - need_update = true; - } - } else { - // If GetJobDetails failed, the most likely case is that the job no - // longer exists in the OS queue. We are going to assume it is done in - // this case. - last_job_details_.Clear(); - last_job_details_.status = cloud_print::PRINT_JOB_STATUS_COMPLETED; - need_update = true; - } - } - if (need_update) { - GURL update_url = CloudPrintHelpers::GetUrlForJobStatusUpdate( - job_id_, last_job_details_); - request_.reset(new URLFetcher(update_url, URLFetcher::GET, this)); - CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_); - request_->Start(); - } - } -} - -void JobStatusUpdater::Stop() { - request_.reset(); - DCHECK(delegate_); - stopped_ = true; - delegate_->OnJobCompleted(this); -} - -// URLFetcher::Delegate implementation. -void JobStatusUpdater::OnURLFetchComplete(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data) { - int64 next_update_interval = kJobStatusUpdateInterval; - if (!status.is_success() || (response_code != 200)) { - next_update_interval *= 10; - MessageLoop::current()->PostDelayedTask( - FROM_HERE, NewRunnableMethod(this, &JobStatusUpdater::UpdateStatus), - next_update_interval); - } else if (last_job_details_.status == - cloud_print::PRINT_JOB_STATUS_COMPLETED) { - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &JobStatusUpdater::Stop)); - } -} - diff --git a/chrome/browser/printing/cloud_print/job_status_updater.h b/chrome/browser/printing/cloud_print/job_status_updater.h deleted file mode 100644 index a951084..0000000 --- a/chrome/browser/printing/cloud_print/job_status_updater.h +++ /dev/null @@ -1,64 +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_BROWSER_PRINTING_CLOUD_PRINT_JOB_STATUS_UPDATER_H_ -#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_JOB_STATUS_UPDATER_H_ - -#include <string> - -#include "base/file_path.h" -#include "base/ref_counted.h" -#include "base/thread.h" -#include "chrome/browser/printing/cloud_print/printer_info.h" -#include "chrome/common/net/url_fetcher.h" -#include "net/url_request/url_request_status.h" - -// Periodically monitors the status of a local print job and updates the -// cloud print server accordingly. When the job has been completed this -// object releases the reference to itself which should cause it to -// self-destruct. -class JobStatusUpdater : public base::RefCountedThreadSafe<JobStatusUpdater>, - public URLFetcher::Delegate { - public: - class Delegate { - public: - virtual bool OnJobCompleted(JobStatusUpdater* updater) = 0; - }; - - JobStatusUpdater(const std::string& printer_name, - const std::string& job_id, - cloud_print::PlatformJobId& local_job_id, - const std::string& auth_token, - Delegate* delegate); - // Checks the status of the local print job and sends an update. - void UpdateStatus(); - void Stop(); - // URLFetcher::Delegate implementation. - virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - private: - std::string printer_name_; - std::string job_id_; - cloud_print::PlatformJobId local_job_id_; - cloud_print::PrintJobDetails last_job_details_; - scoped_ptr<URLFetcher> request_; - std::string auth_token_; - Delegate* delegate_; - // A flag that is set to true in Stop() and will ensure the next scheduled - // task will do nothing. - bool stopped_; - DISALLOW_COPY_AND_ASSIGN(JobStatusUpdater); -}; - -// 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 JobStatusUpdater::Delegate JobStatusUpdaterDelegate; - -#endif // CHROME_BROWSER_PRINTING_CLOUD_PRINT_JOB_STATUS_UPDATER_H_ - diff --git a/chrome/browser/printing/cloud_print/printer_info.h b/chrome/browser/printing/cloud_print/printer_info.h deleted file mode 100644 index 1bb1746..0000000 --- a/chrome/browser/printing/cloud_print/printer_info.h +++ /dev/null @@ -1,125 +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_BROWSER_PRINTING_CLOUD_PRINT_PRINTER_INFO_H_ -#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRINTER_INFO_H_ - -#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; - 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_BROWSER_PRINTING_CLOUD_PRINT_PRINTER_INFO_H_ - diff --git a/chrome/browser/printing/cloud_print/printer_info_linux.cc b/chrome/browser/printing/cloud_print/printer_info_linux.cc deleted file mode 100644 index 0715bb8..0000000 --- a/chrome/browser/printing/cloud_print/printer_info_linux.cc +++ /dev/null @@ -1,80 +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. - -#include "chrome/browser/printing/cloud_print/printer_info.h" - -#include "base/logging.h" - -// TODO(sanjeevr): Implement the Linux interfaces. -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 - diff --git a/chrome/browser/printing/cloud_print/printer_info_mac.cc b/chrome/browser/printing/cloud_print/printer_info_mac.cc deleted file mode 100644 index dd0dbad..0000000 --- a/chrome/browser/printing/cloud_print/printer_info_mac.cc +++ /dev/null @@ -1,80 +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. - -#include "chrome/browser/printing/cloud_print/printer_info.h" - -#include "base/logging.h" - -// TODO(sanjeevr): Implement the Mac interfaces. -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 - diff --git a/chrome/browser/printing/cloud_print/printer_info_win.cc b/chrome/browser/printing/cloud_print/printer_info_win.cc deleted file mode 100644 index b1ec208..0000000 --- a/chrome/browser/printing/cloud_print/printer_info_win.cc +++ /dev/null @@ -1,509 +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. - -#include "chrome/browser/printing/cloud_print/printer_info.h" - -#include <windows.h> -#include <objidl.h> -#include <ocidl.h> -#include <olectl.h> -#include <prntvpt.h> -#include <winspool.h> - -#include "base/lock.h" -#include "base/object_watcher.h" -#include "base/scoped_bstr_win.h" -#include "base/scoped_comptr_win.h" -#include "base/scoped_handle_win.h" -#include "base/scoped_ptr.h" -#include "base/utf_string_conversions.h" - -#pragma comment(lib, "prntvpt.lib") -#pragma comment(lib, "rpcrt4.lib") - -namespace { - -class DevMode { - public: - DevMode() : dm_(NULL) {} - ~DevMode() { Free(); } - - void Allocate(int size) { - Free(); - dm_ = reinterpret_cast<DEVMODE*>(new char[size]); - } - - void Free() { - if (dm_) - delete dm_; - dm_ = NULL; - } - - DEVMODE* dm_; - - private: - DISALLOW_COPY_AND_ASSIGN(DevMode); -}; - -bool InitXPSModule() { - HMODULE prntvpt_module = LoadLibrary(L"prntvpt.dll"); - return (NULL != prntvpt_module); -} - -inline HRESULT GetLastErrorHR() { - LONG error = GetLastError(); - return HRESULT_FROM_WIN32(error); -} - -HRESULT StreamFromPrintTicket(const std::string& print_ticket, - IStream** stream) { - DCHECK(stream); - HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, stream); - if (FAILED(hr)) { - return hr; - } - ULONG bytes_written = 0; - (*stream)->Write(print_ticket.c_str(), print_ticket.length(), &bytes_written); - DCHECK(bytes_written == print_ticket.length()); - LARGE_INTEGER pos = {0}; - ULARGE_INTEGER new_pos = {0}; - (*stream)->Seek(pos, STREAM_SEEK_SET, &new_pos); - return S_OK; -} - -HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { - DCHECK(stream); - DCHECK(out); - HGLOBAL hdata = NULL; - HRESULT hr = GetHGlobalFromStream(stream, &hdata); - if (SUCCEEDED(hr)) { - DCHECK(hdata); - ScopedHGlobal<char> locked_data(hdata); - out->assign(locked_data.release(), locked_data.Size()); - } - return hr; -} - -HRESULT PrintTicketToDevMode(const std::string& printer_name, - const std::string& print_ticket, - DevMode* dev_mode) { - DCHECK(dev_mode); - - ScopedComPtr<IStream> pt_stream; - HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); - if (FAILED(hr)) - return hr; - - HPTPROVIDER provider = NULL; - hr = PTOpenProvider(UTF8ToWide(printer_name).c_str(), 1, &provider); - if (SUCCEEDED(hr)) { - ULONG size = 0; - DEVMODE* dm = NULL; - hr = PTConvertPrintTicketToDevMode(provider, - pt_stream, - kUserDefaultDevmode, - kPTDocumentScope, - &size, - &dm, - NULL); - if (SUCCEEDED(hr)) { - dev_mode->Allocate(size); - memcpy(dev_mode->dm_, dm, size); - PTReleaseMemory(dm); - } - PTCloseProvider(provider); - } - return hr; -} - -HRESULT PrintPdf2DC(HDC dc, const FilePath& pdf_filename) { - HRESULT hr = E_NOTIMPL; - // TODO(sanjeevr): Implement this. - NOTIMPLEMENTED(); - return hr; -} - -} // namespace - -namespace cloud_print { - -void EnumeratePrinters(PrinterList* printer_list) { - DCHECK(printer_list); - DWORD bytes_needed = 0; - DWORD count_returned = 0; - BOOL ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, - NULL, 0, &bytes_needed, &count_returned); - if (0 != bytes_needed) { - scoped_ptr<BYTE> printer_info_buffer(new BYTE[bytes_needed]); - ret = EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, - printer_info_buffer.get(), bytes_needed, &bytes_needed, - &count_returned); - DCHECK(ret); - PRINTER_INFO_2* printer_info = - reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); - for (DWORD index = 0; index < count_returned; index++) { - PrinterBasicInfo info; - info.printer_name = WideToUTF8(printer_info[index].pPrinterName); - if (printer_info[index].pComment) - info.printer_description = WideToUTF8(printer_info[index].pComment); - info.printer_status = printer_info[index].Status; - printer_list->push_back(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; - } - if (!IsValidPrinter(printer_name)) { - return false; - } - DCHECK(printer_info); - HPTPROVIDER provider = NULL; - std::wstring printer_name_wide = UTF8ToWide(printer_name); - HRESULT hr = PTOpenProvider(printer_name_wide.c_str(), 1, &provider); - DCHECK(SUCCEEDED(hr)); - if (provider) { - ScopedComPtr<IStream> print_capabilities_stream; - hr = CreateStreamOnHGlobal(NULL, TRUE, - print_capabilities_stream.Receive()); - DCHECK(SUCCEEDED(hr)); - if (print_capabilities_stream) { - ScopedBstr error; - hr = PTGetPrintCapabilities(provider, NULL, print_capabilities_stream, - error.Receive()); - DCHECK(SUCCEEDED(hr)); - if (FAILED(hr)) { - return false; - } - hr = StreamOnHGlobalToString(print_capabilities_stream.get(), - &printer_info->printer_capabilities); - DCHECK(SUCCEEDED(hr)); - printer_info->caps_mime_type = "text/xml"; - } - // TODO(sanjeevr): Add ScopedPrinterHandle - HANDLE printer_handle = NULL; - OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), &printer_handle, - NULL); - DCHECK(printer_handle); - if (printer_handle) { - DWORD devmode_size = DocumentProperties( - NULL, printer_handle, const_cast<LPTSTR>(printer_name_wide.c_str()), - NULL, NULL, 0); - DCHECK(0 != devmode_size); - scoped_ptr<BYTE> devmode_out_buffer(new BYTE[devmode_size]); - DEVMODE* devmode_out = - reinterpret_cast<DEVMODE*>(devmode_out_buffer.get()); - DocumentProperties( - NULL, printer_handle, const_cast<LPTSTR>(printer_name_wide.c_str()), - devmode_out, NULL, DM_OUT_BUFFER); - ScopedComPtr<IStream> printer_defaults_stream; - hr = CreateStreamOnHGlobal(NULL, TRUE, - printer_defaults_stream.Receive()); - DCHECK(SUCCEEDED(hr)); - if (printer_defaults_stream) { - hr = PTConvertDevModeToPrintTicket(provider, devmode_size, - devmode_out, kPTJobScope, - printer_defaults_stream); - DCHECK(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) { - hr = StreamOnHGlobalToString(printer_defaults_stream.get(), - &printer_info->printer_defaults); - DCHECK(SUCCEEDED(hr)); - printer_info->defaults_mime_type = "text/xml"; - } - } - ClosePrinter(printer_handle); - } - PTCloseProvider(provider); - } - return true; -} - -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; - } - bool ret = false; - HPTPROVIDER provider = NULL; - PTOpenProvider(UTF8ToWide(printer_name.c_str()).c_str(), 1, &provider); - if (provider) { - ScopedComPtr<IStream> print_ticket_stream; - CreateStreamOnHGlobal(NULL, TRUE, print_ticket_stream.Receive()); - ULONG bytes_written = 0; - print_ticket_stream->Write(print_ticket_data.c_str(), - print_ticket_data.length(), - &bytes_written); - DCHECK(bytes_written == print_ticket_data.length()); - LARGE_INTEGER pos = {0}; - ULARGE_INTEGER new_pos = {0}; - print_ticket_stream->Seek(pos, STREAM_SEEK_SET, &new_pos); - ScopedBstr error; - ScopedComPtr<IStream> result_ticket_stream; - CreateStreamOnHGlobal(NULL, TRUE, result_ticket_stream.Receive()); - ret = SUCCEEDED(PTMergeAndValidatePrintTicket(provider, - print_ticket_stream.get(), - NULL, - kPTJobScope, - result_ticket_stream.get(), - error.Receive())); - PTCloseProvider(provider); - } - 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) { - if (!InitXPSModule()) { - // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) - return false; - } - DevMode pt_dev_mode; - HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket, &pt_dev_mode); - if (FAILED(hr)) { - NOTREACHED(); - return false; - } - ScopedHDC dc(CreateDC(L"WINSPOOL", UTF8ToWide(printer_name).c_str(), NULL, - pt_dev_mode.dm_)); - if (!dc.Get()) { - NOTREACHED(); - return false; - } - hr = E_FAIL; - DOCINFO di = {0}; - di.cbSize = sizeof(DOCINFO); - std::wstring doc_name = UTF8ToWide(job_title); - di.lpszDocName = doc_name.c_str(); - int job_id = StartDoc(dc.Get(), &di); - if (SP_ERROR != job_id) { - if (print_data_mime_type == "application/pdf") { - hr = PrintPdf2DC(dc.Get(), print_data_file_path); - } else { - NOTREACHED(); - } - EndDoc(dc.Get()); - if (SUCCEEDED(hr) && job_id_ret) { - *job_id_ret = job_id; - } - } - return SUCCEEDED(hr); -} - -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); - OpenPrinter(const_cast<LPTSTR>(printer_name_wide.c_str()), &printer_handle, - NULL); - DCHECK(printer_handle); - bool ret = false; - if (printer_handle) { - DWORD bytes_needed = 0; - GetJob(printer_handle, job_id, 1, NULL, 0, &bytes_needed); - DWORD last_error = GetLastError(); - if (ERROR_INVALID_PARAMETER != last_error) { - // ERROR_INVALID_PARAMETER normally means that the job id is not valid. - DCHECK(last_error == ERROR_INSUFFICIENT_BUFFER); - scoped_ptr<BYTE> job_info_buffer(new BYTE[bytes_needed]); - if (GetJob(printer_handle, job_id, 1, job_info_buffer.get(), bytes_needed, - &bytes_needed)) { - JOB_INFO_1 *job_info = - reinterpret_cast<JOB_INFO_1 *>(job_info_buffer.get()); - if (job_info->pStatus) { - WideToUTF8(job_info->pStatus, wcslen(job_info->pStatus), - &job_details->status_message); - } - job_details->platform_status_flags = job_info->Status; - if ((job_info->Status & JOB_STATUS_COMPLETE) || - (job_info->Status & JOB_STATUS_PRINTED)) { - job_details->status = PRINT_JOB_STATUS_COMPLETED; - } else if (job_info->Status & JOB_STATUS_ERROR) { - job_details->status = PRINT_JOB_STATUS_ERROR; - } else { - job_details->status = PRINT_JOB_STATUS_IN_PROGRESS; - } - job_details->total_pages = job_info->TotalPages; - job_details->pages_printed = job_info->PagesPrinted; - ret = true; - } - } - ClosePrinter(printer_handle); - } - return ret; -} - -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, - NULL); - bool ret = false; - if (printer_handle) { - ret = true; - ClosePrinter(printer_handle); - } - 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) { -} - -PrinterChangeNotifier::~PrinterChangeNotifier() { - StopWatching(); -} - -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; -} - -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/browser/printing/cloud_print/printer_job_handler.cc b/chrome/browser/printing/cloud_print/printer_job_handler.cc deleted file mode 100644 index a27fdf0..0000000 --- a/chrome/browser/printing/cloud_print/printer_job_handler.cc +++ /dev/null @@ -1,560 +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. - -#include "chrome/browser/printing/cloud_print/printer_job_handler.h" - -#include "base/file_util.h" -#include "base/json/json_reader.h" -#include "base/md5.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/printing/cloud_print/cloud_print_consts.h" -#include "chrome/browser/printing/cloud_print/cloud_print_helpers.h" -#include "chrome/browser/printing/cloud_print/job_status_updater.h" -#include "googleurl/src/gurl.h" -#include "net/http/http_response_headers.h" - -PrinterJobHandler::PrinterJobHandler( - const cloud_print::PrinterBasicInfo& printer_info, - const std::string& printer_id, - const std::string& caps_hash, - const std::string& auth_token, - Delegate* delegate) - : printer_info_(printer_info), - printer_id_(printer_id), - auth_token_(auth_token), - last_caps_hash_(caps_hash), - delegate_(delegate), - local_job_id_(-1), - next_response_handler_(NULL), - server_error_count_(0), - print_thread_("Chrome_CloudPrintJobPrintThread"), - shutting_down_(false), - server_job_available_(false), - printer_update_pending_(true), - printer_delete_pending_(false), - task_in_progress_(false) { -} - -bool PrinterJobHandler::Initialize() { - 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. - OnPrinterDeleted(); - } - return true; -} - -PrinterJobHandler::~PrinterJobHandler() { - printer_change_notifier_.StopWatching(); -} - -void PrinterJobHandler::Reset() { - print_data_url_.clear(); - job_details_.Clear(); - request_.reset(); - print_thread_.Stop(); -} - -void PrinterJobHandler::Start() { - if (task_in_progress_) { - // Multiple Starts can get posted because of multiple notifications - // We want to ignore the other ones that happen when a task is in progress. - return; - } - Reset(); - if (!shutting_down_) { - // Check if we have work to do. - if (HavePendingTasks()) { - if (printer_delete_pending_) { - printer_delete_pending_ = false; - task_in_progress_ = true; - MakeServerRequest( - CloudPrintHelpers::GetUrlForPrinterDelete(printer_id_), - &PrinterJobHandler::HandlePrinterDeleteResponse); - } - if (!task_in_progress_ && printer_update_pending_) { - printer_update_pending_ = false; - task_in_progress_ = UpdatePrinterInfo(); - } - if (!task_in_progress_ && server_job_available_) { - task_in_progress_ = true; - server_job_available_ = false; - // We need to fetch any pending jobs for this printer - MakeServerRequest(CloudPrintHelpers::GetUrlForJobFetch(printer_id_), - &PrinterJobHandler::HandleJobMetadataResponse); - } - } - } -} - -void PrinterJobHandler::Stop() { - task_in_progress_ = false; - Reset(); - if (HavePendingTasks()) { - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); - } -} - -void PrinterJobHandler::NotifyJobAvailable() { - server_job_available_ = true; - if (!task_in_progress_) { - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); - } -} - -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_change_notifier_.GetCurrentPrinterInfo(&printer_info); - cloud_print::PrinterCapsAndDefaults printer_caps; - std::string post_data; - std::string mime_boundary; - 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_) { - // Hashes don't match, we need to upload new capabilities (the defaults - // go for free along with the capabilities) - last_caps_hash_ = caps_hash; - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterCapsValue, printer_caps.printer_capabilities, - mime_boundary, printer_caps.caps_mime_type, &post_data); - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterDefaultsValue, printer_caps.printer_defaults, - mime_boundary, printer_caps.defaults_mime_type, - &post_data); - CloudPrintHelpers::AddMultipartValueForUpload( - WideToUTF8(kPrinterCapsHashValue).c_str(), caps_hash, mime_boundary, - std::string(), &post_data); - } - } - if (printer_info.printer_name != printer_info_.printer_name) { - CloudPrintHelpers::AddMultipartValueForUpload(kPrinterNameValue, - printer_info.printer_name, - mime_boundary, - std::string(), &post_data); - } - if (printer_info.printer_description != printer_info_.printer_description) { - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterDescValue, printer_info.printer_description, mime_boundary, - std::string() , &post_data); - } - if (printer_info.printer_status != printer_info_.printer_status) { - CloudPrintHelpers::AddMultipartValueForUpload( - kPrinterStatusValue, StringPrintf("%d", printer_info.printer_status), - mime_boundary, std::string(), &post_data); - } - printer_info_ = printer_info; - bool ret = false; - if (!post_data.empty()) { - // Terminate the request body - post_data.append("--" + mime_boundary + "--\r\n"); - std::string mime_type("multipart/form-data; boundary="); - mime_type += mime_boundary; - request_.reset( - new URLFetcher(CloudPrintHelpers::GetUrlForPrinterUpdate(printer_id_), - URLFetcher::POST, this)); - CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_); - request_->set_upload_data(mime_type, post_data); - next_response_handler_ = &PrinterJobHandler::HandlePrinterUpdateResponse; - request_->Start(); - ret = true; - } - return ret; -} - -// URLFetcher::Delegate implementation. -void PrinterJobHandler::OnURLFetchComplete( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - if (!shutting_down_) { - DCHECK(source == request_.get()); - // We need a next response handler because we are strictly a sequential - // state machine. We need each response handler to tell us which state to - // advance to next. - DCHECK(next_response_handler_); - if (!(this->*next_response_handler_)(source, url, status, - response_code, cookies, data)) { - // By contract, if the response handler returns false, it wants us to - // retry the request (upto the usual limit after which we give up and - // send the state machine to the Stop state); - HandleServerError(url); - } - } -} - -// JobStatusUpdater::Delegate implementation -bool PrinterJobHandler::OnJobCompleted(JobStatusUpdater* updater) { - bool ret = false; - for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); - index != job_status_updater_list_.end(); index++) { - if (index->get() == updater) { - job_status_updater_list_.erase(index); - ret = true; - break; - } - } - 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_) { - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); - } -} - -void PrinterJobHandler::OnPrinterChanged() { - printer_update_pending_ = true; - if (!task_in_progress_) { - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start)); - } -} - -void PrinterJobHandler::OnJobChanged() { - // Some job on the printer changed. Loop through all our JobStatusUpdaters - // and have them check for updates. - for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); - index != job_status_updater_list_.end(); index++) { - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(index->get(), - &JobStatusUpdater::UpdateStatus)); - } -} - -bool PrinterJobHandler::HandlePrinterUpdateResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - bool ret = false; - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (status.is_success() && (response_code == 200)) { - bool succeeded = false; - DictionaryValue* response_dict = NULL; - CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict); - // If we get valid JSON back, we are done. - if (NULL != response_dict) { - ret = true; - } - } - if (ret) { - // We are done here. Go to the Stop state - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); - } else { - // Since we failed to update the server, set the flag again. - printer_update_pending_ = true; - } - return ret; -} - -bool PrinterJobHandler::HandlePrinterDeleteResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - bool ret = false; - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (status.is_success() && (response_code == 200)) { - bool succeeded = false; - DictionaryValue* response_dict = NULL; - CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict); - // If we get valid JSON back, we are done. - if (NULL != response_dict) { - ret = true; - } - } - if (ret) { - // The printer has been deleted. Shutdown the handler class. - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Shutdown)); - } else { - // Since we failed to update the server, set the flag again. - printer_delete_pending_ = true; - } - return ret; -} - -bool PrinterJobHandler::HandleJobMetadataResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (!status.is_success() || (response_code != 200)) { - return false; - } - bool succeeded = false; - DictionaryValue* response_dict = NULL; - CloudPrintHelpers::ParseResponseJSON(data, &succeeded, &response_dict); - if (NULL == response_dict) { - // If we did not get a valid JSON response, we need to retry. - return false; - } - Task* next_task = NULL; - if (succeeded) { - ListValue* job_list = NULL; - response_dict->GetList(kJobListValue, &job_list); - if (job_list) { - // Even though it is a job list, for now we are only interested in the - // first job - DictionaryValue* job_data = NULL; - if (job_list->GetDictionary(0, &job_data)) { - job_data->GetString(kIdValue, &job_details_.job_id_); - job_data->GetString(kTitleValue, &job_details_.job_title_); - std::string print_ticket_url; - job_data->GetString(kTicketUrlValue, &print_ticket_url); - job_data->GetString(kFileUrlValue, &print_data_url_); - next_task = NewRunnableMethod( - this, &PrinterJobHandler::MakeServerRequest, - GURL(print_ticket_url.c_str()), - &PrinterJobHandler::HandlePrintTicketResponse); - } - } - } - if (!next_task) { - // If we got a valid JSON but there were no jobs, we are done - next_task = NewRunnableMethod(this, &PrinterJobHandler::Stop); - } - delete response_dict; - DCHECK(next_task); - MessageLoop::current()->PostTask(FROM_HERE, next_task); - return true; -} - -bool PrinterJobHandler::HandlePrintTicketResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (!status.is_success() || (response_code != 200)) { - return false; - } - if (cloud_print::ValidatePrintTicket(printer_info_.printer_name, data)) { - job_details_.print_ticket_ = data; - MessageLoop::current()->PostTask( - FROM_HERE, - NewRunnableMethod(this, - &PrinterJobHandler::MakeServerRequest, - GURL(print_data_url_.c_str()), - &PrinterJobHandler::HandlePrintDataResponse)); - } else { - // The print ticket was not valid. We are done here. - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::JobFailed, - INVALID_JOB_DATA)); - } - return true; -} - -bool PrinterJobHandler::HandlePrintDataResponse(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data) { - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (!status.is_success() || (response_code != 200)) { - return false; - } - Task* next_task = NULL; - if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) { - int ret = file_util::WriteFile(job_details_.print_data_file_path_, - data.c_str(), - data.length()); - source->response_headers()->GetMimeType( - &job_details_.print_data_mime_type_); - DCHECK(ret == static_cast<int>(data.length())); - if (ret == static_cast<int>(data.length())) { - next_task = NewRunnableMethod(this, &PrinterJobHandler::StartPrinting); - } - } - // If there was no task allocated above, then there was an error in - // saving the print data, bail out here. - if (!next_task) { - next_task = NewRunnableMethod(this, &PrinterJobHandler::JobFailed, - JOB_DOWNLOAD_FAILED); - } - MessageLoop::current()->PostTask(FROM_HERE, next_task); - return true; -} - -void PrinterJobHandler::StartPrinting() { - // We are done with the request object for now. - request_.reset(); - if (!shutting_down_) { - if (!print_thread_.Start()) { - JobFailed(PRINT_FAILED); - } else { - print_thread_.message_loop()->PostTask( - FROM_HERE, NewRunnableFunction(&PrinterJobHandler::DoPrint, - job_details_, - printer_info_.printer_name, this, - MessageLoop::current())); - } - } -} - -void PrinterJobHandler::JobFailed(PrintJobError error) { - if (!shutting_down_) { - UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error); - } -} - -void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) { - if (!shutting_down_) { - local_job_id_ = local_job_id; - UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); - print_thread_.Stop(); - } -} - -void PrinterJobHandler::Shutdown() { - Reset(); - shutting_down_ = true; - while (!job_status_updater_list_.empty()) { - // Calling Stop() will cause the OnJobCompleted to be called which will - // remove the updater object from the list. - job_status_updater_list_.front()->Stop(); - } - if (delegate_) { - delegate_->OnPrinterJobHandlerShutdown(this, printer_id_); - } -} - -void PrinterJobHandler::HandleServerError(const GURL& url) { - Task* task_to_retry = NewRunnableMethod(this, - &PrinterJobHandler::MakeServerRequest, - url, next_response_handler_); - Task* task_on_give_up = NewRunnableMethod(this, &PrinterJobHandler::Stop); - CloudPrintHelpers::HandleServerError(&server_error_count_, kMaxRetryCount, - -1, kBaseRetryInterval, task_to_retry, - task_on_give_up); -} - -void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status, - PrintJobError error) { - if (!shutting_down_) { - if (!job_details_.job_id_.empty()) { - ResponseHandler response_handler = NULL; - if (error == SUCCESS) { - response_handler = - &PrinterJobHandler::HandleSuccessStatusUpdateResponse; - } else { - response_handler = - &PrinterJobHandler::HandleFailureStatusUpdateResponse; - } - MakeServerRequest( - CloudPrintHelpers::GetUrlForJobStatusUpdate(job_details_.job_id_, - status), - response_handler); - } - } -} - -bool PrinterJobHandler::HandleSuccessStatusUpdateResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (!status.is_success() || (response_code != 200)) { - return false; - } - // The print job has been spooled locally. We now need to create an object - // that monitors the status of the job and updates the server. - scoped_refptr<JobStatusUpdater> job_status_updater = - new JobStatusUpdater(printer_info_.printer_name, job_details_.job_id_, - local_job_id_, auth_token_, this); - job_status_updater_list_.push_back(job_status_updater); - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(job_status_updater.get(), - &JobStatusUpdater::UpdateStatus)); - bool succeeded = false; - CloudPrintHelpers::ParseResponseJSON(data, &succeeded, NULL); - if (succeeded) { - // Since we just printed successfully, we want to look for more jobs. - server_job_available_ = true; - } - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); - return true; -} - -bool PrinterJobHandler::HandleFailureStatusUpdateResponse( - const URLFetcher* source, const GURL& url, const URLRequestStatus& status, - int response_code, const ResponseCookies& cookies, - const std::string& data) { - // If there was a network error or a non-200 response (which, for our purposes - // is the same as a network error), we want to retry. - if (!status.is_success() || (response_code != 200)) { - return false; - } - MessageLoop::current()->PostTask( - FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop)); - return true; -} - -void PrinterJobHandler::MakeServerRequest(const GURL& url, - ResponseHandler response_handler) { - if (!shutting_down_) { - request_.reset(new URLFetcher(url, URLFetcher::GET, this)); - server_error_count_ = 0; - CloudPrintHelpers::PrepCloudPrintRequest(request_.get(), auth_token_); - // Set up the next response handler - next_response_handler_ = response_handler; - request_->Start(); - } -} - -bool PrinterJobHandler::HavePendingTasks() { - return server_job_available_ || printer_update_pending_ || - printer_delete_pending_; -} - - -void PrinterJobHandler::DoPrint(const JobDetails& job_details, - 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 (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, - job_id)); - } else { - job_message_loop->PostTask(FROM_HERE, - NewRunnableMethod(job_handler, - &PrinterJobHandler::JobFailed, - PRINT_FAILED)); - } -} - diff --git a/chrome/browser/printing/cloud_print/printer_job_handler.h b/chrome/browser/printing/cloud_print/printer_job_handler.h deleted file mode 100644 index 4e8d61c..0000000 --- a/chrome/browser/printing/cloud_print/printer_job_handler.h +++ /dev/null @@ -1,240 +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_BROWSER_PRINTING_CLOUD_PRINT_PRINTER_JOB_HANDLER_H_ -#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRINTER_JOB_HANDLER_H_ - -#include <list> -#include <string> - -#include "base/file_path.h" -#include "base/ref_counted.h" -#include "base/thread.h" -#include "chrome/browser/printing/cloud_print/job_status_updater.h" -#include "chrome/browser/printing/cloud_print/printer_info.h" -#include "chrome/common/net/url_fetcher.h" -#include "net/url_request/url_request_status.h" - -// A class that handles cloud print jobs for a particular printer. This class -// imlements a state machine that transitions from Start to various states. The -// various states are shown in the below diagram. -// the status on the server. - -// Start --> No pending tasks --> Done -// | -// | -// | Have Pending tasks -// | -// | -// <----Delete Pending -- | ---Update Pending-----> -// | | | -// | | | -// | | | -// Delete Printer from server | Update Printer info on server -// Shutdown | Go to Stop -// | -// | Job Available -// | -// | -// Fetch Next Job Metadata -// Fetch Print Ticket -// Fetch Print Data -// Spool Print Job -// Create Job StatusUpdater for job -// Mark job as "in progress" on server -// (On any unrecoverable error in any of the above steps go to Stop) -// Go to Stop -// | -// | -// | -// | -// | -// | -// | -// Stop -// (If there are pending tasks go back to Start) - -typedef URLFetcher::Delegate URLFetcherDelegate; - -class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, - public URLFetcherDelegate, - public JobStatusUpdaterDelegate, - public cloud_print::PrinterChangeNotifierDelegate { - enum PrintJobError { - SUCCESS, - JOB_DOWNLOAD_FAILED, - INVALID_JOB_DATA, - PRINT_FAILED, - }; - struct JobDetails { - std::string job_id_; - std::string job_title_; - std::string print_ticket_; - FilePath print_data_file_path_; - std::string print_data_mime_type_; - void Clear() { - job_id_.clear(); - job_title_.clear(); - print_ticket_.clear(); - print_data_mime_type_.clear(); - print_data_file_path_ = FilePath(); - } - }; - - public: - class Delegate { - public: - virtual void OnPrinterJobHandlerShutdown( - PrinterJobHandler* job_handler, const std::string& printer_id) = 0; - }; - - // 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, - Delegate* delegate); - ~PrinterJobHandler(); - bool Initialize(); - // Notifies the JobHandler that a job is available - void NotifyJobAvailable(); - // Shutdown everything (the process is exiting). - void Shutdown(); - // End public interface - - // Begin Delegate implementations - - // URLFetcher::Delegate implementation. - virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - // JobStatusUpdater::Delegate implementation - virtual bool OnJobCompleted(JobStatusUpdater* updater); - // cloud_print::PrinterChangeNotifier::Delegate implementation - virtual void OnPrinterAdded(); - virtual void OnPrinterDeleted(); - virtual void OnPrinterChanged(); - virtual void OnJobChanged(); - - // End Delegate implementations - - private: - // Prototype for a response handler. The return value indicates whether the - // request should be retried, false means "retry", true means "do not retry" - typedef bool (PrinterJobHandler::*ResponseHandler)( - const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, int response_code, - const ResponseCookies& cookies, const std::string& data); - // Begin request handlers for each state in the state machine - bool HandlePrinterUpdateResponse(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - bool HandlePrinterDeleteResponse(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - bool HandleJobMetadataResponse(const URLFetcher* source, const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - bool HandlePrintTicketResponse(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - bool HandlePrintDataResponse(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - bool HandleSuccessStatusUpdateResponse(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - bool HandleFailureStatusUpdateResponse(const URLFetcher* source, - const GURL& url, - const URLRequestStatus& status, - int response_code, - const ResponseCookies& cookies, - const std::string& data); - // End request handlers for each state in the state machine - - // Start the state machine. Based on the flags set this could mean updating - // printer information, deleting the printer from the server or looking for - // new print jobs - void Start(); - - // End the state machine. If there are pending tasks, we will post a Start - // again. - void Stop(); - - void StartPrinting(); - void HandleServerError(const GURL& url); - void Reset(); - void UpdateJobStatus(cloud_print::PrintJobStatus status, PrintJobError error); - void MakeServerRequest(const GURL& url, ResponseHandler response_handler); - void JobFailed(PrintJobError error); - void JobSpooled(cloud_print::PlatformJobId local_job_id); - // Returns false if printer info is up to date and no updating is needed. - bool UpdatePrinterInfo(); - bool HavePendingTasks(); - - static void DoPrint(const JobDetails& job_details, - const std::string& printer_name, - PrinterJobHandler* job_handler, - MessageLoop* job_message_loop); - - - scoped_ptr<URLFetcher> request_; - cloud_print::PrinterBasicInfo printer_info_; - std::string printer_id_; - std::string auth_token_; - std::string last_caps_hash_; - std::string print_data_url_; - JobDetails job_details_; - Delegate* delegate_; - // Once the job has been spooled to the local spooler, this specifies the - // job id of the job on the local spooler. - cloud_print::PlatformJobId local_job_id_; - ResponseHandler next_response_handler_; - // The number of consecutive times that connecting to the server failed. - int server_error_count_; - // The thread on which the actual print operation happens - base::Thread print_thread_; - // There may be pending tasks in the message queue when Shutdown is called. - // We set this flag so as to do nothing in those tasks. - bool shutting_down_; - - // Flags that specify various pending server updates - bool server_job_available_; - bool printer_update_pending_; - bool printer_delete_pending_; - - // Some task in the state machine is in progress. - bool task_in_progress_; - cloud_print::PrinterChangeNotifier printer_change_notifier_; - typedef std::list< scoped_refptr<JobStatusUpdater> > JobStatusUpdaterList; - JobStatusUpdaterList job_status_updater_list_; - - DISALLOW_COPY_AND_ASSIGN(PrinterJobHandler); -}; - -// 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 PrinterJobHandler::Delegate PrinterJobHandlerDelegate; - -#endif // CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRINTER_JOB_HANDLER_H_ - |