summaryrefslogtreecommitdiffstats
path: root/chrome/service
diff options
context:
space:
mode:
authorgene@chromium.org <gene@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-28 18:21:51 +0000
committergene@chromium.org <gene@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-28 18:21:51 +0000
commitf0cb5b9f307dfaf5e1540fb753e0a41694b97387 (patch)
treedb9185622a9760a80e6f136feb6e1ab282a681b1 /chrome/service
parent121352a9a4a7177af585952ff2f3a1e4ec6619f5 (diff)
downloadchromium_src-f0cb5b9f307dfaf5e1540fb753e0a41694b97387.zip
chromium_src-f0cb5b9f307dfaf5e1540fb753e0a41694b97387.tar.gz
chromium_src-f0cb5b9f307dfaf5e1540fb753e0a41694b97387.tar.bz2
Chrome proxy refactoring.Adding myself to the OWNERS file for handling cloud print proxy issues.Split proxy code from cloud_print_proxy_backend to a separate pieces: - auth code goes to cloud_print_auth.h/cc - connector logic goes to cloud_print_connector.h/cc (printer enumeration, registration and deletion) - wiring backend/frontend threads, notifications with other parts will stay in cloud_print_backend.h/ccMade proxy logic more straightforward.
Review URL: http://codereview.chromium.org/8387011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107758 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/service')
-rw-r--r--chrome/service/OWNERS3
-rw-r--r--chrome/service/cloud_print/cloud_print_auth.cc205
-rw-r--r--chrome/service/cloud_print/cloud_print_auth.h114
-rw-r--r--chrome/service/cloud_print/cloud_print_connector.cc551
-rw-r--r--chrome/service/cloud_print/cloud_print_connector.h187
-rw-r--r--chrome/service/cloud_print/cloud_print_consts.cc1
-rw-r--r--chrome/service/cloud_print/cloud_print_consts.h6
-rw-r--r--chrome/service/cloud_print/cloud_print_helpers.cc18
-rw-r--r--chrome/service/cloud_print/cloud_print_helpers.h2
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy.cc3
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy_backend.cc922
-rw-r--r--chrome/service/cloud_print/cloud_print_proxy_backend.h1
-rw-r--r--chrome/service/cloud_print/cloud_print_token_store.cc5
-rw-r--r--chrome/service/cloud_print/cloud_print_token_store.h7
-rw-r--r--chrome/service/cloud_print/cloud_print_token_store_unittest.cc6
-rw-r--r--chrome/service/cloud_print/cloud_print_url_fetcher.cc36
-rw-r--r--chrome/service/cloud_print/cloud_print_url_fetcher.h13
-rw-r--r--chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc7
-rw-r--r--chrome/service/cloud_print/job_status_updater.cc12
-rw-r--r--chrome/service/cloud_print/job_status_updater.h3
-rw-r--r--chrome/service/cloud_print/printer_job_handler.cc120
-rw-r--r--chrome/service/cloud_print/printer_job_handler.h33
22 files changed, 1333 insertions, 922 deletions
diff --git a/chrome/service/OWNERS b/chrome/service/OWNERS
index f8fa783..4e9f44d 100644
--- a/chrome/service/OWNERS
+++ b/chrome/service/OWNERS
@@ -1,5 +1,6 @@
ajwong@chromium.org
dmaclach@chromium.org
hclam@chromium.org
-sanjeevr@chromium.org
scottbyer@chromium.org
+gene@chromium.org
+abodenha@chromium.org
diff --git a/chrome/service/cloud_print/cloud_print_auth.cc b/chrome/service/cloud_print/cloud_print_auth.cc
new file mode 100644
index 0000000..4e7b056
--- /dev/null
+++ b/chrome/service/cloud_print/cloud_print_auth.cc
@@ -0,0 +1,205 @@
+// Copyright (c) 2011 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/service/cloud_print/cloud_print_auth.h"
+
+#include "base/string_util.h"
+#include "chrome/common/net/gaia/gaia_urls.h"
+#include "chrome/service/cloud_print/cloud_print_consts.h"
+#include "chrome/service/cloud_print/cloud_print_helpers.h"
+#include "chrome/service/cloud_print/cloud_print_token_store.h"
+#include "chrome/service/gaia/service_gaia_authenticator.h"
+#include "chrome/service/net/service_url_request_context.h"
+#include "chrome/service/service_process.h"
+
+CloudPrintAuth::CloudPrintAuth(
+ Client* client,
+ const GURL& cloud_print_server_url,
+ const base::DictionaryValue* print_sys_settings,
+ const gaia::OAuthClientInfo& oauth_client_info,
+ const std::string& proxy_id)
+ : client_(client),
+ oauth_client_info_(oauth_client_info),
+ cloud_print_server_url_(cloud_print_server_url),
+ proxy_id_(proxy_id) {
+ DCHECK(client);
+ if (print_sys_settings) {
+ // It is possible to have no print settings specified.
+ print_system_settings_.reset(print_sys_settings->DeepCopy());
+ }
+}
+
+CloudPrintAuth::~CloudPrintAuth() {
+}
+
+void CloudPrintAuth::AuthenticateWithLsid(
+ const std::string& lsid,
+ const std::string& last_robot_refresh_token,
+ const std::string& last_robot_email,
+ const std::string& last_user_email) {
+ // Keeping VLOGs for Cloud Print proxy logging. It is convinient for finding
+ // issues with GCP in the field, where only release version is avaialble.
+ VLOG(1) << "CP_AUTH: Authenticating with LSID";
+ scoped_refptr<ServiceGaiaAuthenticator> gaia_auth_for_print(
+ new ServiceGaiaAuthenticator(
+ kProxyAuthUserAgent, kCloudPrintGaiaServiceId,
+ GaiaUrls::GetInstance()->client_login_url(),
+ g_service_process->io_thread()->message_loop_proxy()));
+ gaia_auth_for_print->set_message_loop(MessageLoop::current());
+ if (gaia_auth_for_print->AuthenticateWithLsid(lsid)) {
+ // Stash away the user email so we can save it in prefs.
+ user_email_ = gaia_auth_for_print->email();
+ // If the same user is re-enabling Cloud Print and we have stashed robot
+ // credentials, we will use those.
+ if ((0 == base::strcasecmp(user_email_.c_str(), last_user_email.c_str())) &&
+ !last_robot_refresh_token.empty() &&
+ !last_robot_email.empty()) {
+ AuthenticateWithRobotToken(last_robot_refresh_token,
+ last_robot_email);
+ }
+ AuthenticateWithToken(gaia_auth_for_print->auth_token());
+ } else {
+ // Notify client about authentication error.
+ client_->OnInvalidCredentials();
+ }
+}
+
+void CloudPrintAuth::AuthenticateWithToken(
+ const std::string cloud_print_token) {
+ VLOG(1) << "CP_AUTH: Authenticating with token";
+
+ client_login_token_ = cloud_print_token;
+
+ // We need to get the credentials of the robot here.
+ GURL get_authcode_url =
+ CloudPrintHelpers::GetUrlForGetAuthCode(cloud_print_server_url_,
+ oauth_client_info_.client_id,
+ proxy_id_);
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(get_authcode_url,
+ this,
+ kCloudPrintAuthMaxRetryCount,
+ std::string());
+}
+
+void CloudPrintAuth::AuthenticateWithRobotToken(
+ const std::string& robot_oauth_refresh_token,
+ const std::string& robot_email) {
+ VLOG(1) << "CP_AUTH: Authenticating with robot token";
+
+ robot_email_ = robot_email;
+ refresh_token_ = robot_oauth_refresh_token;
+ RefreshAccessToken();
+}
+
+void CloudPrintAuth::AuthenticateWithRobotAuthCode(
+ const std::string& robot_oauth_auth_code,
+ const std::string& robot_email) {
+ VLOG(1) << "CP_AUTH: Authenticating with robot auth code";
+
+ robot_email_ = robot_email;
+ // Now that we have an auth code we need to get the refresh and access tokens.
+ oauth_client_.reset(new gaia::GaiaOAuthClient(
+ gaia::kGaiaOAuth2Url,
+ g_service_process->GetServiceURLRequestContextGetter()));
+ oauth_client_->GetTokensFromAuthCode(oauth_client_info_,
+ robot_oauth_auth_code,
+ kCloudPrintAuthMaxRetryCount,
+ this);
+}
+
+void CloudPrintAuth::RefreshAccessToken() {
+ oauth_client_.reset(new gaia::GaiaOAuthClient(
+ gaia::kGaiaOAuth2Url,
+ g_service_process->GetServiceURLRequestContextGetter()));
+ oauth_client_->RefreshToken(oauth_client_info_,
+ refresh_token_,
+ kCloudPrintAuthMaxRetryCount,
+ this);
+}
+
+void CloudPrintAuth::OnGetTokensResponse(const std::string& refresh_token,
+ const std::string& access_token,
+ int expires_in_seconds) {
+ refresh_token_ = refresh_token;
+ // After saving the refresh token, this is just like having just refreshed
+ // the access token. Just call OnRefreshTokenResponse.
+ OnRefreshTokenResponse(access_token, expires_in_seconds);
+}
+
+void CloudPrintAuth::OnRefreshTokenResponse(const std::string& access_token,
+ int expires_in_seconds) {
+ client_->OnAuthenticationComplete(access_token, refresh_token_,
+ robot_email_, user_email_);
+
+ // Schedule a task to refresh the access token again when it is about to
+ // expire.
+ DCHECK(expires_in_seconds > kTokenRefreshGracePeriodSecs);
+ int64 refresh_delay =
+ (expires_in_seconds - kTokenRefreshGracePeriodSecs)*1000;
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &CloudPrintAuth::RefreshAccessToken),
+ refresh_delay);
+}
+
+void CloudPrintAuth::OnOAuthError() {
+ // Notify client about authentication error.
+ client_->OnInvalidCredentials();
+}
+
+void CloudPrintAuth::OnNetworkError(int response_code) {
+ // Since we specify infinite retries on network errors, this should never
+ // be called.
+ NOTREACHED() <<
+ "OnNetworkError invoked when not expected, response code is " <<
+ response_code;
+}
+
+CloudPrintURLFetcher::ResponseAction CloudPrintAuth::HandleJSONData(
+ const content::URLFetcher* source,
+ const GURL& url,
+ base::DictionaryValue* json_data,
+ bool succeeded) {
+ if (!succeeded) {
+ VLOG(1) << "CP_AUTH: Creating robot account failed";
+ client_->OnInvalidCredentials();
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+ }
+
+ std::string auth_code;
+ if (!json_data->GetString(kOAuthCodeValue, &auth_code)) {
+ VLOG(1) << "CP_AUTH: Creating robot account returned invalid json response";
+ client_->OnInvalidCredentials();
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+ }
+
+ json_data->GetString(kXMPPJidValue, &robot_email_);
+ // Now that we have an auth code we need to get the refresh and access tokens.
+ oauth_client_.reset(new gaia::GaiaOAuthClient(
+ gaia::kGaiaOAuth2Url,
+ g_service_process->GetServiceURLRequestContextGetter()));
+ oauth_client_->GetTokensFromAuthCode(oauth_client_info_,
+ auth_code,
+ kCloudPrintAPIMaxRetryCount,
+ this);
+
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+CloudPrintURLFetcher::ResponseAction CloudPrintAuth::OnRequestAuthError() {
+ VLOG(1) << "CP_AUTH: Creating robot account authentication error";
+ // Notify client about authentication error.
+ client_->OnInvalidCredentials();
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+std::string CloudPrintAuth::GetAuthHeader() {
+ DCHECK(!client_login_token_.empty());
+ std::string header;
+ header = "Authorization: GoogleLogin auth=";
+ header += client_login_token_;
+ return header;
+}
+
diff --git a/chrome/service/cloud_print/cloud_print_auth.h b/chrome/service/cloud_print/cloud_print_auth.h
new file mode 100644
index 0000000..7eea7f4
--- /dev/null
+++ b/chrome/service/cloud_print/cloud_print_auth.h
@@ -0,0 +1,114 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_AUTH_H_
+#define CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_AUTH_H_
+#pragma once
+
+#include <string>
+
+#include "base/values.h"
+#include "chrome/common/net/gaia/gaia_oauth_client.h"
+#include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
+#include "googleurl/src/gurl.h"
+
+// CloudPrintAuth is a class to handle login, token refresh, and other
+// authentication tasks for Cloud Print.
+// CloudPrintAuth will create new robot account for this proxy if needed.
+// CloudPrintAuth will obtain new OAuth token.
+// CloudPrintAuth will schedule periodic OAuth token refresh
+// It is running in the same thread as CloudPrintProxyBackend::Core.
+class CloudPrintAuth
+ : public base::RefCountedThreadSafe<CloudPrintAuth>,
+ public CloudPrintURLFetcherDelegate,
+ public gaia::GaiaOAuthClient::Delegate {
+ public:
+ class Client {
+ public:
+ virtual void OnAuthenticationComplete(
+ const std::string& access_token,
+ const std::string& robot_oauth_refresh_token,
+ const std::string& robot_email,
+ const std::string& user_email) = 0;
+ virtual void OnInvalidCredentials() = 0;
+ protected:
+ virtual ~Client() {}
+ };
+
+ CloudPrintAuth(Client* client,
+ const GURL& cloud_print_server_url,
+ const base::DictionaryValue* print_sys_settings,
+ const gaia::OAuthClientInfo& oauth_client_info,
+ const std::string& proxy_id);
+ virtual ~CloudPrintAuth();
+
+ // Note:
+ //
+ // The Authenticate* methods are the various entry points from
+ // CloudPrintProxyBackend::Core. It calls us on a dedicated thread to
+ // actually perform synchronous (and potentially blocking) operations.
+ //
+ // When we are passed in an LSID we authenticate using that
+ // and retrieve new auth tokens.
+ void AuthenticateWithLsid(const std::string& lsid,
+ const std::string& last_robot_refresh_token,
+ const std::string& last_robot_email,
+ const std::string& last_user_email);
+
+ void AuthenticateWithToken(const std::string cloud_print_token);
+ void AuthenticateWithRobotToken(const std::string& robot_oauth_refresh_token,
+ const std::string& robot_email);
+ void AuthenticateWithRobotAuthCode(const std::string& robot_oauth_auth_code,
+ const std::string& robot_email);
+
+ void RefreshAccessToken();
+
+ // gaia::GaiaOAuthClient::Delegate implementation.
+ virtual void OnGetTokensResponse(const std::string& refresh_token,
+ const std::string& access_token,
+ int expires_in_seconds);
+ virtual void OnRefreshTokenResponse(const std::string& access_token,
+ int expires_in_seconds);
+ virtual void OnOAuthError();
+ virtual void OnNetworkError(int response_code);
+
+ // CloudPrintURLFetcher::Delegate implementation.
+ virtual CloudPrintURLFetcher::ResponseAction HandleJSONData(
+ const content::URLFetcher* source,
+ const GURL& url,
+ base::DictionaryValue* json_data,
+ bool succeeded);
+ virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError();
+ virtual std::string GetAuthHeader();
+
+ private:
+ Client* client_;
+ gaia::OAuthClientInfo oauth_client_info_;
+ scoped_ptr<gaia::GaiaOAuthClient> oauth_client_;
+ scoped_ptr<DictionaryValue> print_system_settings_;
+
+ // The CloudPrintURLFetcher instance for the current request.
+ scoped_refptr<CloudPrintURLFetcher> request_;
+
+ GURL cloud_print_server_url_;
+ // Proxy id, need to send to the cloud print server to find and update
+ // necessary printers during the migration process.
+ const std::string& proxy_id_;
+ // The OAuth2 refresh token for the robot.
+ std::string refresh_token_;
+ // The email address of the user. This is only used during initial
+ // authentication with an LSID. This is only used for storing in prefs for
+ // display purposes.
+ std::string user_email_;
+ // The email address of the robot account.
+ std::string robot_email_;
+ // client login token used to authenticate request to cloud print server to
+ // get the robot account.
+ std::string client_login_token_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPrintAuth);
+};
+
+#endif // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_AUTH_H_
+
diff --git a/chrome/service/cloud_print/cloud_print_connector.cc b/chrome/service/cloud_print/cloud_print_connector.cc
new file mode 100644
index 0000000..5432d32
--- /dev/null
+++ b/chrome/service/cloud_print/cloud_print_connector.cc
@@ -0,0 +1,551 @@
+// Copyright (c) 2011 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/service/cloud_print/cloud_print_connector.h"
+
+#include "base/md5.h"
+#include "base/rand_util.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/service/cloud_print/cloud_print_consts.h"
+#include "chrome/service/cloud_print/cloud_print_helpers.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+CloudPrintConnector::CloudPrintConnector(
+ Client* client,
+ const std::string& proxy_id,
+ const GURL& cloud_print_server_url,
+ const DictionaryValue* print_system_settings)
+ : client_(client),
+ proxy_id_(proxy_id),
+ cloud_print_server_url_(cloud_print_server_url),
+ next_response_handler_(NULL) {
+ if (print_system_settings) {
+ // It is possible to have no print settings specified.
+ print_system_settings_.reset(print_system_settings->DeepCopy());
+ }
+}
+
+CloudPrintConnector::~CloudPrintConnector() {
+}
+
+bool CloudPrintConnector::Start() {
+ DCHECK(!print_system_.get());
+ VLOG(1) << "CP_CONNECTOR: Starting connector, id: " << proxy_id_;
+
+ pending_tasks_.clear();
+
+ print_system_ =
+ cloud_print::PrintSystem::CreateInstance(print_system_settings_.get());
+ if (!print_system_.get()) {
+ NOTREACHED();
+ return false; // No print system available, fail initalization.
+ }
+ cloud_print::PrintSystem::PrintSystemResult result = print_system_->Init();
+ if (!result.succeeded()) {
+ // We could not initialize the print system. We need to notify the server.
+ ReportUserMessage(kPrintSystemFailedMessageId, result.message());
+ print_system_.release();
+ return false;
+ }
+
+ // Start watching for updates from the print system.
+ print_server_watcher_ = print_system_->CreatePrintServerWatcher();
+ print_server_watcher_->StartWatching(this);
+
+ // Get list of registered printers.
+ AddPendingAvailableTask();
+ return true;
+}
+
+void CloudPrintConnector::Stop() {
+ VLOG(1) << "CP_CONNECTOR: Stopping connector, id: " << proxy_id_;
+ DCHECK(print_system_.get());
+ if (print_system_.get()) {
+ // Do uninitialization here.
+ pending_tasks_.clear();
+ print_server_watcher_.release();
+ print_system_.release();
+ }
+}
+
+bool CloudPrintConnector::IsRunning() {
+ return print_system_.get() != NULL;
+}
+
+void CloudPrintConnector::RegisterPrinters(
+ const printing::PrinterList& printers) {
+ if (!IsRunning())
+ return;
+ printing::PrinterList::const_iterator it;
+ for (it = printers.begin(); it != printers.end(); ++it) {
+ AddPendingRegisterTask(*it);
+ }
+}
+
+// Check for jobs for specific printer
+void CloudPrintConnector::CheckForJobs(const std::string& reason,
+ const std::string& printer_id) {
+ if (!IsRunning())
+ return;
+ if (!printer_id.empty()) {
+ JobHandlerMap::iterator index = job_handler_map_.find(printer_id);
+ if (index != job_handler_map_.end())
+ index->second->CheckForJobs(reason);
+ } else {
+ for (JobHandlerMap::iterator index = job_handler_map_.begin();
+ index != job_handler_map_.end(); index++) {
+ index->second->CheckForJobs(reason);
+ }
+ }
+}
+
+void CloudPrintConnector::OnPrinterAdded() {
+ AddPendingAvailableTask();
+}
+
+void CloudPrintConnector::OnPrinterDeleted(const std::string& printer_id) {
+ AddPendingDeleteTask(printer_id);
+}
+
+void CloudPrintConnector::OnAuthError() {
+ client_->OnAuthFailed();
+}
+
+// CloudPrintURLFetcher::Delegate implementation.
+CloudPrintURLFetcher::ResponseAction CloudPrintConnector::HandleRawData(
+ const content::URLFetcher* source,
+ const GURL& url,
+ const std::string& data) {
+ // If this notification came as a result of user message call, stop it.
+ // Otherwise proceed continue processing.
+ if (user_message_request_.get() &&
+ user_message_request_->IsSameRequest(source))
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+ return CloudPrintURLFetcher::CONTINUE_PROCESSING;
+}
+
+CloudPrintURLFetcher::ResponseAction CloudPrintConnector::HandleJSONData(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ if (!IsRunning()) // Orphant response. Connector has been stopped already.
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+
+ DCHECK(next_response_handler_);
+ return (this->*next_response_handler_)(source, url, json_data, succeeded);
+}
+
+CloudPrintURLFetcher::ResponseAction
+CloudPrintConnector::HandlePrinterListResponse(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ DCHECK(succeeded);
+ if (!succeeded)
+ return CloudPrintURLFetcher::RETRY_REQUEST;
+
+ // Now we need to get the list of printers from the print system
+ // and split printers into 3 categories:
+ // - existing and registered printers
+ // - new printers
+ // - deleted printers
+
+ // Get list of the printers from the print system.
+ printing::PrinterList local_printers;
+ cloud_print::PrintSystem::PrintSystemResult result =
+ print_system_->EnumeratePrinters(&local_printers);
+ bool full_list = result.succeeded();
+ if (!result.succeeded()) {
+ std::string message = result.message();
+ if (message.empty())
+ message = l10n_util::GetStringUTF8(IDS_CLOUD_PRINT_ENUM_FAILED);
+ // There was a failure enumerating printers. Send a message to the server.
+ ReportUserMessage(kEnumPrintersFailedMessageId, message);
+ }
+
+ // Go through the list of the cloud printers and init print job handlers.
+ ListValue* printer_list = NULL;
+ // There may be no "printers" value in the JSON
+ if (json_data->GetList(kPrinterListValue, &printer_list) && 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);
+ if (RemovePrinterFromList(printer_name, &local_printers)) {
+ InitJobHandlerForPrinter(printer_data);
+ } else {
+ // Cloud printer is not found on the local system.
+ if (full_list) { // Delete only if we get the full list of printer.
+ std::string printer_id;
+ printer_data->GetString(kIdValue, &printer_id);
+ AddPendingDeleteTask(printer_id);
+ }
+ }
+ } else {
+ NOTREACHED();
+ }
+ }
+ }
+
+ request_ = NULL;
+ if (!local_printers.empty()) {
+ // Notify client that we have a list of printers available.
+ // Client will call us back to finish registration
+ client_->OnPrintersAvailable(local_printers);
+ }
+ ContinuePendingTaskProcessing(); // Continue processing background tasks.
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+CloudPrintURLFetcher::ResponseAction
+CloudPrintConnector::HandlePrinterDeleteResponse(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ VLOG(1) << "CP_CONNECTOR: Handler printer delete response, succeeded:"
+ << succeeded << " url: " << url;
+ ContinuePendingTaskProcessing(); // Continue processing background tasks.
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+CloudPrintURLFetcher::ResponseAction
+CloudPrintConnector::HandleRegisterPrinterResponse(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded) {
+ VLOG(1) << "CP_CONNECTOR: Handler printer register response, succeeded:"
+ << succeeded << " url: " << url;
+ if (succeeded) {
+ ListValue* printer_list = NULL;
+ // There should be a "printers" value in the JSON
+ if (json_data->GetList(kPrinterListValue, &printer_list)) {
+ DictionaryValue* printer_data = NULL;
+ if (printer_list->GetDictionary(0, &printer_data))
+ InitJobHandlerForPrinter(printer_data);
+ }
+ }
+ ContinuePendingTaskProcessing(); // Continue processing background tasks.
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+
+CloudPrintURLFetcher::ResponseAction CloudPrintConnector::OnRequestAuthError() {
+ OnAuthError();
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+std::string CloudPrintConnector::GetAuthHeader() {
+ return CloudPrintHelpers::GetCloudPrintAuthHeader();
+}
+
+void CloudPrintConnector::StartGetRequest(const GURL& url,
+ int max_retries,
+ ResponseHandler handler) {
+ next_response_handler_ = handler;
+ request_ = new CloudPrintURLFetcher;
+ request_->StartGetRequest(url, this, max_retries, std::string());
+}
+
+void CloudPrintConnector::StartPostRequest(const GURL& url,
+ int max_retries,
+ const std::string& mime_type,
+ const std::string& post_data,
+ ResponseHandler handler) {
+ next_response_handler_ = handler;
+ request_ = new CloudPrintURLFetcher;
+ request_->StartPostRequest(
+ url, this, max_retries, mime_type, post_data, std::string());
+}
+
+void CloudPrintConnector::ReportUserMessage(const std::string& message_id,
+ const std::string& failure_msg) {
+ // This is a fire and forget type of function.
+ // Result of this request will be ignored.
+ std::string mime_boundary;
+ CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary);
+ GURL url = CloudPrintHelpers::GetUrlForUserMessage(cloud_print_server_url_,
+ message_id);
+ std::string post_data;
+ CloudPrintHelpers::AddMultipartValueForUpload(kMessageTextValue,
+ failure_msg,
+ 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;
+ user_message_request_ = new CloudPrintURLFetcher;
+ user_message_request_->StartPostRequest(url, this, 1, mime_type, post_data,
+ std::string());
+}
+
+bool CloudPrintConnector::RemovePrinterFromList(
+ const std::string& printer_name,
+ printing::PrinterList* printer_list) {
+ for (printing::PrinterList::iterator index = printer_list->begin();
+ index != printer_list->end(); index++) {
+ if (IsSamePrinter(index->printer_name, printer_name)) {
+ index = printer_list->erase(index);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CloudPrintConnector::InitJobHandlerForPrinter(
+ DictionaryValue* printer_data) {
+ DCHECK(printer_data);
+ PrinterJobHandler::PrinterInfoFromCloud printer_info_cloud;
+ printer_data->GetString(kIdValue, &printer_info_cloud.printer_id);
+ DCHECK(!printer_info_cloud.printer_id.empty());
+ VLOG(1) << "CP_CONNECTOR: Init job handler for printer id: "
+ << printer_info_cloud.printer_id;
+ JobHandlerMap::iterator index = job_handler_map_.find(
+ printer_info_cloud.printer_id);
+ if (index != job_handler_map_.end())
+ return; // Nothing to do if we already have a job handler for this printer.
+
+ printing::PrinterBasicInfo printer_info;
+ printer_data->GetString(kNameValue, &printer_info.printer_name);
+ DCHECK(!printer_info.printer_name.empty());
+ printer_data->GetString(kPrinterDescValue,
+ &printer_info.printer_description);
+ // Printer status is a string value which actually contains an integer.
+ std::string printer_status;
+ if (printer_data->GetString(kPrinterStatusValue, &printer_status)) {
+ base::StringToInt(printer_status, &printer_info.printer_status);
+ }
+ printer_data->GetString(kPrinterCapsHashValue,
+ &printer_info_cloud.caps_hash);
+ ListValue* tags_list = NULL;
+ if (printer_data->GetList(kTagsValue, &tags_list) && tags_list) {
+ for (size_t index = 0; index < tags_list->GetSize(); index++) {
+ std::string tag;
+ if (tags_list->GetString(index, &tag) &&
+ StartsWithASCII(tag, kTagsHashTagName, false)) {
+ std::vector<std::string> tag_parts;
+ base::SplitStringDontTrim(tag, '=', &tag_parts);
+ DCHECK_EQ(tag_parts.size(), 2U);
+ if (tag_parts.size() == 2)
+ printer_info_cloud.tags_hash = tag_parts[1];
+ }
+ }
+ }
+ scoped_refptr<PrinterJobHandler> job_handler;
+ job_handler = new PrinterJobHandler(printer_info,
+ printer_info_cloud,
+ cloud_print_server_url_,
+ print_system_.get(),
+ this);
+ job_handler_map_[printer_info_cloud.printer_id] = job_handler;
+ job_handler->Initialize();
+}
+
+void CloudPrintConnector::AddPendingAvailableTask() {
+ PendingTask task;
+ task.type = PENDING_PRINTERS_AVAILABLE;
+ AddPendingTask(task);
+}
+
+void CloudPrintConnector::AddPendingDeleteTask(const std::string& id) {
+ PendingTask task;
+ task.type = PENDING_PRINTER_DELETE;
+ task.printer_id = id;
+ AddPendingTask(task);
+}
+
+void CloudPrintConnector::AddPendingRegisterTask(
+ const printing::PrinterBasicInfo& info) {
+ PendingTask task;
+ task.type = PENDING_PRINTER_REGISTER;
+ task.printer_info = info;
+ AddPendingTask(task);
+}
+
+void CloudPrintConnector::AddPendingTask(const PendingTask& task) {
+ pending_tasks_.push_back(task);
+ // If this is the only pending task, we need to start the process.
+ if (pending_tasks_.size() == 1) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &CloudPrintConnector::ProcessPendingTask));
+ }
+}
+
+void CloudPrintConnector::ProcessPendingTask() {
+ if (!IsRunning())
+ return; // Orphant call.
+ if (pending_tasks_.size() == 0)
+ return; // No peding tasks.
+
+ PendingTask task = pending_tasks_.front();
+
+ switch (task.type) {
+ case PENDING_PRINTERS_AVAILABLE :
+ OnPrintersAvailable();
+ break;
+ case PENDING_PRINTER_REGISTER :
+ OnPrinterRegister(task.printer_info);
+ break;
+ case PENDING_PRINTER_DELETE :
+ OnPrinterDelete(task.printer_id);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void CloudPrintConnector::OnPrintersAvailable() {
+ GURL printer_list_url =
+ CloudPrintHelpers::GetUrlForPrinterList(cloud_print_server_url_,
+ proxy_id_);
+ StartGetRequest(printer_list_url,
+ kCloudPrintRegisterMaxRetryCount,
+ &CloudPrintConnector::HandlePrinterListResponse);
+}
+
+void CloudPrintConnector::OnPrinterRegister(
+ const printing::PrinterBasicInfo& info) {
+ for (JobHandlerMap::iterator it = job_handler_map_.begin();
+ it != job_handler_map_.end(); ++it) {
+ if (IsSamePrinter(it->second->GetPrinterName(), info.printer_name)) {
+ // Printer already registered, continue to the next task.
+ ContinuePendingTaskProcessing();
+ return;
+ }
+ }
+
+ cloud_print::PrintSystem::PrinterCapsAndDefaultsCallback* callback =
+ NewCallback(this, &CloudPrintConnector::OnReceivePrinterCaps);
+ // Asnchronously fetch the printer caps and defaults. The story will
+ // continue in OnReceivePrinterCaps.
+ print_system_->GetPrinterCapsAndDefaults(
+ info.printer_name.c_str(), callback);
+}
+
+void CloudPrintConnector::OnPrinterDelete(const std::string& printer_id) {
+ // Remove corresponding printer job handler.
+ JobHandlerMap::iterator it = job_handler_map_.find(printer_id);
+ if (it != job_handler_map_.end()) {
+ it->second->Shutdown();
+ job_handler_map_.erase(it);
+ }
+
+ // TODO(gene): We probably should not try indefinitely here. Just once or
+ // twice should be enough.
+ // Bug: http://code.google.com/p/chromium/issues/detail?id=101850
+ GURL url = CloudPrintHelpers::GetUrlForPrinterDelete(cloud_print_server_url_,
+ printer_id);
+ StartGetRequest(url,
+ kCloudPrintAPIMaxRetryCount,
+ &CloudPrintConnector::HandlePrinterDeleteResponse);
+}
+
+void CloudPrintConnector::ContinuePendingTaskProcessing() {
+ if (pending_tasks_.size() == 0)
+ return; // No peding tasks.
+
+ // Delete current task and repost if we have more task avaialble.
+ pending_tasks_.pop_front();
+ if (pending_tasks_.size() != 0) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &CloudPrintConnector::ProcessPendingTask));
+ }
+}
+
+void CloudPrintConnector::OnReceivePrinterCaps(
+ bool succeeded,
+ const std::string& printer_name,
+ const printing::PrinterCapsAndDefaults& caps_and_defaults) {
+ if (!IsRunning())
+ return; // Orphant call.
+ DCHECK(pending_tasks_.size() > 0 &&
+ pending_tasks_.front().type == PENDING_PRINTER_REGISTER);
+
+ if (!succeeded) {
+ LOG(ERROR) << "CP_CONNECTOR: Failed to get printer info for: " <<
+ printer_name;
+ // This printer failed to register, notify the server of this failure.
+ string16 printer_name_utf16 = UTF8ToUTF16(printer_name);
+ std::string status_message = l10n_util::GetStringFUTF8(
+ IDS_CLOUD_PRINT_REGISTER_PRINTER_FAILED,
+ printer_name_utf16);
+ ReportUserMessage(kGetPrinterCapsFailedMessageId, status_message);
+
+ ContinuePendingTaskProcessing(); // Skip this printer registration.
+ return;
+ }
+
+ const printing::PrinterBasicInfo& info = pending_tasks_.front().printer_info;
+ DCHECK(IsSamePrinter(info.printer_name, 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, base::StringPrintf("%d", info.printer_status),
+ mime_boundary, std::string(), &post_data);
+ // Add printer options as tags.
+ CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags(info.options,
+ mime_boundary,
+ &post_data);
+
+ CloudPrintHelpers::AddMultipartValueForUpload(
+ kPrinterCapsValue, caps_and_defaults.printer_capabilities,
+ mime_boundary, caps_and_defaults.caps_mime_type,
+ &post_data);
+ CloudPrintHelpers::AddMultipartValueForUpload(
+ kPrinterDefaultsValue, caps_and_defaults.printer_defaults,
+ mime_boundary, caps_and_defaults.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(
+ kPrinterCapsHashValue,
+ base::MD5String(caps_and_defaults.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;
+
+ GURL post_url = CloudPrintHelpers::GetUrlForPrinterRegistration(
+ cloud_print_server_url_);
+ StartPostRequest(post_url,
+ kCloudPrintAPIMaxRetryCount,
+ mime_type,
+ post_data,
+ &CloudPrintConnector::HandleRegisterPrinterResponse);
+}
+
+bool CloudPrintConnector::IsSamePrinter(const std::string& name1,
+ const std::string& name2) const {
+ return (0 == base::strcasecmp(name1.c_str(), name2.c_str()));
+}
+
diff --git a/chrome/service/cloud_print/cloud_print_connector.h b/chrome/service/cloud_print/cloud_print_connector.h
new file mode 100644
index 0000000..8394b23
--- /dev/null
+++ b/chrome/service/cloud_print/cloud_print_connector.h
@@ -0,0 +1,187 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONNECTOR_H_
+#define CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONNECTOR_H_
+#pragma once
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "base/threading/thread.h"
+#include "base/values.h"
+#include "chrome/service/cloud_print/print_system.h"
+#include "chrome/service/cloud_print/printer_job_handler.h"
+
+// CloudPrintConnector handles top printer management tasks.
+// - Matching local and cloud printers
+// - Registration of local printers
+// - Deleting cloud printers
+// All tasks are posted to the commond queue (PendingTasks) and executed
+// one-by-one in FIFO order.
+// CloudPrintConnector will notify client over Client interface.
+class CloudPrintConnector
+ : public base::RefCountedThreadSafe<CloudPrintConnector>,
+ public cloud_print::PrintServerWatcherDelegate,
+ public PrinterJobHandlerDelegate,
+ public CloudPrintURLFetcherDelegate {
+ public:
+ class Client {
+ public:
+ virtual void OnPrintersAvailable(const printing::PrinterList& printers) = 0;
+ virtual void OnAuthFailed() = 0;
+ protected:
+ virtual ~Client() {}
+ };
+
+ CloudPrintConnector(Client* client,
+ const std::string& proxy_id,
+ const GURL& cloud_print_server_url,
+ const DictionaryValue* print_system_settings);
+ virtual ~CloudPrintConnector();
+
+ bool Start();
+ void Stop();
+ bool IsRunning();
+
+ // Register printer from the list.
+ void RegisterPrinters(const printing::PrinterList& printers);
+
+ // Check for jobs for specific printer. If printer id is empty
+ // jobs will be checked for all available printers.
+ void CheckForJobs(const std::string& reason, const std::string& printer_id);
+
+ // cloud_print::PrintServerWatcherDelegate implementation
+ virtual void OnPrinterAdded();
+ // PrinterJobHandler::Delegate implementation
+ virtual void OnPrinterDeleted(const std::string& printer_name);
+ virtual void OnAuthError();
+
+ // CloudPrintURLFetcher::Delegate implementation.
+ virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
+ const content::URLFetcher* source,
+ const GURL& url,
+ const std::string& data);
+
+ virtual CloudPrintURLFetcher::ResponseAction HandleJSONData(
+ const content::URLFetcher* source,
+ const GURL& url,
+ base::DictionaryValue* json_data,
+ bool succeeded);
+ virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError();
+ virtual std::string GetAuthHeader();
+
+ private:
+ // Prototype for a response handler.
+ typedef CloudPrintURLFetcher::ResponseAction
+ (CloudPrintConnector::*ResponseHandler)(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded);
+
+ // Begin response handlers
+ CloudPrintURLFetcher::ResponseAction HandlePrinterListResponse(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded);
+
+ CloudPrintURLFetcher::ResponseAction HandlePrinterDeleteResponse(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded);
+
+ CloudPrintURLFetcher::ResponseAction HandleRegisterPrinterResponse(
+ const content::URLFetcher* source,
+ const GURL& url,
+ DictionaryValue* json_data,
+ bool succeeded);
+ // End response handlers
+
+ // Helper functions for network requests.
+ void StartGetRequest(const GURL& url,
+ int max_retries,
+ ResponseHandler handler);
+ void StartPostRequest(const GURL& url,
+ int max_retries,
+ const std::string& mime_type,
+ const std::string& post_data,
+ ResponseHandler handler);
+
+ // Reports a diagnostic message to the server.
+ void ReportUserMessage(const std::string& message_id,
+ const std::string& failure_message);
+
+ bool RemovePrinterFromList(const std::string& printer_name,
+ printing::PrinterList* printer_list);
+
+ void InitJobHandlerForPrinter(DictionaryValue* printer_data);
+
+ enum PendingTaskType {
+ PENDING_PRINTERS_AVAILABLE,
+ PENDING_PRINTER_REGISTER,
+ PENDING_PRINTER_DELETE
+ };
+
+ struct PendingTask {
+ PendingTaskType type;
+ // Optional members, depending on type.
+ std::string printer_id; // For pending delete.
+ printing::PrinterBasicInfo printer_info; // For pending registration.
+
+ PendingTask() {}
+ ~PendingTask() {}
+ };
+
+ void AddPendingAvailableTask();
+ void AddPendingDeleteTask(const std::string& id);
+ void AddPendingRegisterTask(const printing::PrinterBasicInfo& info);
+ void AddPendingTask(const PendingTask& task);
+ void ProcessPendingTask();
+ void ContinuePendingTaskProcessing();
+ void OnPrintersAvailable();
+ void OnPrinterRegister(const printing::PrinterBasicInfo& info);
+ void OnPrinterDelete(const std::string& name);
+
+ void OnReceivePrinterCaps(
+ bool succeeded,
+ const std::string& printer_name,
+ const printing::PrinterCapsAndDefaults& caps_and_defaults);
+
+ bool IsSamePrinter(const std::string& name1, const std::string& name2) const;
+
+ // CloudPrintConnector client.
+ Client* client_;
+ // Print system settings.
+ scoped_ptr<DictionaryValue> print_system_settings_;
+ // Pointer to current print system.
+ scoped_refptr<cloud_print::PrintSystem> print_system_;
+ // Watcher for print system updates.
+ scoped_refptr<cloud_print::PrintSystem::PrintServerWatcher>
+ print_server_watcher_;
+ // Id of the Cloud Print proxy.
+ std::string proxy_id_;
+ // Cloud Print server url.
+ GURL cloud_print_server_url_;
+ // A map of printer id to job handler.
+ typedef std::map<std::string, scoped_refptr<PrinterJobHandler> >
+ JobHandlerMap;
+ JobHandlerMap job_handler_map_;
+ // Next response handler.
+ ResponseHandler next_response_handler_;
+ // The list of peding tasks to be done in the background.
+ std::list<PendingTask> pending_tasks_;
+ // The CloudPrintURLFetcher instance for the current request.
+ scoped_refptr<CloudPrintURLFetcher> request_;
+ // The CloudPrintURLFetcher instance for the user message request.
+ scoped_refptr<CloudPrintURLFetcher> user_message_request_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPrintConnector);
+};
+
+#endif // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONNECTOR_H_
+
diff --git a/chrome/service/cloud_print/cloud_print_consts.cc b/chrome/service/cloud_print/cloud_print_consts.cc
index 41fbb85..39275b9 100644
--- a/chrome/service/cloud_print/cloud_print_consts.cc
+++ b/chrome/service/cloud_print/cloud_print_consts.cc
@@ -38,6 +38,7 @@ const char kTagDryRunFlag[] = "__cp__dry_run";
const char kDefaultCloudPrintServerUrl[] = "https://www.google.com/cloudprint";
const char kCloudPrintGaiaServiceId[] = "cloudprint";
const char kSyncGaiaServiceId[] = "chromiumsync";
+const char kProxyAuthUserAgent[] = "ChromiumBrowser";
const char kCloudPrintPushNotificationsSource[] = "cloudprint.google.com";
// The cloud print server expects the X-Google-CloudPrint-Proxy header for
// certain requests.
diff --git a/chrome/service/cloud_print/cloud_print_consts.h b/chrome/service/cloud_print/cloud_print_consts.h
index 1ff6ef7..319e2f4 100644
--- a/chrome/service/cloud_print/cloud_print_consts.h
+++ b/chrome/service/cloud_print/cloud_print_consts.h
@@ -18,6 +18,7 @@ extern const char kPrinterStatusValue[];
extern const char kPrinterTagValue[];
extern const char kPrinterRemoveTagValue[];
extern const char kMessageTextValue[];
+
// Values in the respone JSON from the cloud print server
extern const char kPrinterListValue[];
extern const char kSuccessValue[];
@@ -38,6 +39,7 @@ extern const char kTagDryRunFlag[];
extern const char kDefaultCloudPrintServerUrl[];
extern const char kCloudPrintGaiaServiceId[];
extern const char kSyncGaiaServiceId[];
+extern const char kProxyAuthUserAgent[];
extern const char kCloudPrintPushNotificationsSource[];
extern const char kChromeCloudPrintProxyHeader[];
extern const char kCloudPrintUserAgent[];
@@ -56,6 +58,10 @@ extern const char kDefaultCloudPrintOAuthClientSecret[];
const int kJobDataMaxRetryCount = 5;
// Max retry count (infinity) for API fetch requests.
const int kCloudPrintAPIMaxRetryCount = -1;
+// Max retry count (infinity) for Registration requests.
+const int kCloudPrintRegisterMaxRetryCount = -1;
+// Max retry count (infinity) for authentication requests.
+const int kCloudPrintAuthMaxRetryCount = -1;
// When we don't have XMPP notifications available, we resort to polling for
// print jobs. We choose a random interval in seconds between these 2 values.
diff --git a/chrome/service/cloud_print/cloud_print_helpers.cc b/chrome/service/cloud_print/cloud_print_helpers.cc
index 492c46a..1a441d7 100644
--- a/chrome/service/cloud_print/cloud_print_helpers.cc
+++ b/chrome/service/cloud_print/cloud_print_helpers.cc
@@ -14,6 +14,7 @@
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/service/cloud_print/cloud_print_consts.h"
+#include "chrome/service/cloud_print/cloud_print_token_store.h"
#include "chrome/service/service_process.h"
std::string StringFromJobStatus(cloud_print::PrintJobStatus status) {
@@ -266,3 +267,20 @@ bool CloudPrintHelpers::IsDryRunJob(const std::vector<std::string>& tags) {
}
return false;
}
+
+std::string CloudPrintHelpers::GetCloudPrintAuthHeader() {
+ std::string header;
+ CloudPrintTokenStore* token_store = CloudPrintTokenStore::current();
+ if (!token_store || token_store->token().empty()) {
+ // Using LOG here for critical errors. GCP connector may run in the headless
+ // mode and error indication might be useful for user in that case.
+ LOG(ERROR) << "CP_PROXY: Missing OAuth token for request";
+ }
+
+ if (token_store) {
+ header = "Authorization: OAuth ";
+ header += token_store->token();
+ }
+ return header;
+}
+
diff --git a/chrome/service/cloud_print/cloud_print_helpers.h b/chrome/service/cloud_print/cloud_print_helpers.h
index 5fb73c7..dfe5ded 100644
--- a/chrome/service/cloud_print/cloud_print_helpers.h
+++ b/chrome/service/cloud_print/cloud_print_helpers.h
@@ -70,6 +70,8 @@ class CloudPrintHelpers {
// Returns true is tags indicate a dry run (test) job.
static bool IsDryRunJob(const std::vector<std::string>& tags);
+
+ static std::string GetCloudPrintAuthHeader();
private:
CloudPrintHelpers() {
}
diff --git a/chrome/service/cloud_print/cloud_print_proxy.cc b/chrome/service/cloud_print/cloud_print_proxy.cc
index 802a973..6dc7b1b 100644
--- a/chrome/service/cloud_print/cloud_print_proxy.cc
+++ b/chrome/service/cloud_print/cloud_print_proxy.cc
@@ -158,7 +158,8 @@ bool CloudPrintProxy::CreateBackend() {
GURL cloud_print_server_url(cloud_print_server_url_str.c_str());
DCHECK(cloud_print_server_url.is_valid());
- backend_.reset(new CloudPrintProxyBackend(this, cloud_print_server_url,
+ backend_.reset(new CloudPrintProxyBackend(this, proxy_id_,
+ cloud_print_server_url,
print_system_settings,
oauth_client_info,
enable_job_poll));
diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc
index 5483405..9f4327a 100644
--- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc
+++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc
@@ -8,20 +8,15 @@
#include <vector>
#include "base/file_util.h"
-#include "base/md5.h"
#include "base/rand_util.h"
-#include "base/string_number_conversions.h"
-#include "base/string_split.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/net/gaia/gaia_oauth_client.h"
#include "chrome/common/net/gaia/gaia_urls.h"
+#include "chrome/service/cloud_print/cloud_print_auth.h"
+#include "chrome/service/cloud_print/cloud_print_connector.h"
#include "chrome/service/cloud_print/cloud_print_consts.h"
#include "chrome/service/cloud_print/cloud_print_helpers.h"
#include "chrome/service/cloud_print/cloud_print_token_store.h"
-#include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
-#include "chrome/service/cloud_print/printer_job_handler.h"
#include "chrome/service/gaia/service_gaia_authenticator.h"
#include "chrome/service/net/service_url_request_context.h"
#include "chrome/service/service_process.h"
@@ -30,21 +25,19 @@
#include "jingle/notifier/base/notifier_options.h"
#include "jingle/notifier/listener/mediator_thread_impl.h"
#include "jingle/notifier/listener/talk_mediator_impl.h"
-#include "net/url_request/url_request_status.h"
#include "ui/base/l10n/l10n_util.h"
// The real guts of CloudPrintProxyBackend, to keep the public client API clean.
class CloudPrintProxyBackend::Core
: public base::RefCountedThreadSafe<CloudPrintProxyBackend::Core>,
- public CloudPrintURLFetcherDelegate,
- public cloud_print::PrintServerWatcherDelegate,
- public PrinterJobHandlerDelegate,
- public notifier::TalkMediator::Delegate,
- public gaia::GaiaOAuthClient::Delegate {
+ public CloudPrintAuth::Client,
+ public CloudPrintConnector::Client,
+ public notifier::TalkMediator::Delegate {
public:
// It is OK for print_server_url to be empty. In this case system should
// use system default (local) print server.
Core(CloudPrintProxyBackend* backend,
+ const std::string& proxy_id,
const GURL& cloud_print_server_url,
const DictionaryValue* print_system_settings,
const gaia::OAuthClientInfo& oauth_client_info,
@@ -80,23 +73,17 @@ class CloudPrintProxyBackend::Core
void DoRegisterSelectedPrinters(
const printing::PrinterList& printer_list);
- // CloudPrintURLFetcher::Delegate implementation.
- virtual CloudPrintURLFetcher::ResponseAction HandleJSONData(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
+ // CloudPrintAuth::Client implementation.
+ virtual void OnAuthenticationComplete(
+ const std::string& access_token,
+ const std::string& robot_oauth_refresh_token,
+ const std::string& robot_email,
+ const std::string& user_email);
+ virtual void OnInvalidCredentials();
- virtual void OnRequestAuthError();
-
- // cloud_print::PrintServerWatcherDelegate implementation
- virtual void OnPrinterAdded();
- // PrinterJobHandler::Delegate implementation
- virtual void OnPrinterJobHandlerShutdown(PrinterJobHandler* job_handler,
- const std::string& printer_id);
- virtual void OnAuthError();
- virtual void OnPrinterNotFound(const std::string& printer_name,
- bool* delete_from_server);
+ // CloudPrintConnector::Client implementation.
+ virtual void OnPrintersAvailable(const printing::PrinterList& printers);
+ virtual void OnAuthFailed();
// notifier::TalkMediator::Delegate implementation.
virtual void OnNotificationStateChange(
@@ -105,62 +92,7 @@ class CloudPrintProxyBackend::Core
const notifier::Notification& notification);
virtual void OnOutgoingNotification();
- // gaia::GaiaOAuthClient::Delegate implementation.
- virtual void OnGetTokensResponse(const std::string& refresh_token,
- const std::string& access_token,
- int expires_in_seconds);
- virtual void OnRefreshTokenResponse(const std::string& access_token,
- int expires_in_seconds);
- virtual void OnOAuthError();
- virtual void OnNetworkError(int response_code);
-
private:
- // Prototype for a response handler.
- typedef CloudPrintURLFetcher::ResponseAction
- (CloudPrintProxyBackend::Core::*ResponseHandler)(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
- // Begin response handlers
- CloudPrintURLFetcher::ResponseAction HandlePrinterListResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
-
- CloudPrintURLFetcher::ResponseAction HandleRegisterPrinterResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
-
- CloudPrintURLFetcher::ResponseAction HandleRegisterFailedStatusResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
-
- CloudPrintURLFetcher::ResponseAction HandlePrintSystemUnavailableResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
-
- CloudPrintURLFetcher::ResponseAction HandleEnumPrintersFailedResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
-
- CloudPrintURLFetcher::ResponseAction HandleGetAuthCodeResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded);
-
- // End response handlers
-
// NotifyXXX is how the Core communicates with the frontend across
// threads.
void NotifyPrinterListAvailable(
@@ -172,37 +104,9 @@ class CloudPrintProxyBackend::Core
void NotifyAuthenticationFailed();
void NotifyPrintSystemUnavailable();
- // Once we have robot credentials, this method gets the ball rolling.
- void PostAuthInitialization();
- // 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();
- // 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);
- // Reports a diagnostic message to the server.
- void ReportUserMessage(const std::string& message_id,
- const std::string& failure_message,
- ResponseHandler handler);
- // Make a GAIA request to refresh the access token.
- void RefreshAccessToken();
-
- // Callback method for GetPrinterCapsAndDefaults.
- void OnReceivePrinterCaps(
- bool succeeded,
- const std::string& printer_name,
- const printing::PrinterCapsAndDefaults& caps_and_defaults);
+ // Init XMPP channel
+ void InitNotifications(const std::string& robot_email,
+ const std::string& access_token);
void HandlePrinterNotification(const std::string& printer_id);
void PollForJobs();
@@ -214,50 +118,16 @@ class CloudPrintProxyBackend::Core
// Our parent CloudPrintProxyBackend
CloudPrintProxyBackend* backend_;
+ // Cloud Print authenticator.
+ scoped_refptr<CloudPrintAuth> auth_;
+
+ // Cloud Print connector.
+ scoped_refptr<CloudPrintConnector> connector_;
+
+ // Server URL.
GURL cloud_print_server_url_;
- gaia::OAuthClientInfo oauth_client_info_;
- scoped_ptr<DictionaryValue> print_system_settings_;
- // Pointer to current print system.
- scoped_refptr<cloud_print::PrintSystem> print_system_;
- // The list of printers to be registered with the cloud print server.
- // To begin with,this list is initialized with the list of local and network
- // printers available. Then we query the server for the list of printers
- // 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.
- printing::PrinterList printer_list_;
- // Indicates whether the printers in printer_list_ is the complete set of
- // printers to be registered for this proxy.
- bool complete_list_available_;
- // The CloudPrintURLFetcher instance for the current request.
- scoped_refptr<CloudPrintURLFetcher> request_;
- // The index of the nex printer to be uploaded.
- size_t next_upload_index_;
- // The unique id for this proxy
+ // Proxy Id.
std::string proxy_id_;
- // The OAuth2 refresh token for the robot.
- std::string refresh_token_;
- // The email address of the user. This is only used during initial
- // authentication with an LSID. This is only used for storing in prefs for
- // display purposes.
- std::string user_email_;
- // The email address of the robot account.
- std::string robot_email_;
- // 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_;
- printing::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_;
- scoped_refptr<cloud_print::PrintSystem::PrintServerWatcher>
- print_server_watcher_;
- bool new_printers_available_;
- bool registration_in_progress_;
// Notification (xmpp) handler.
scoped_ptr<notifier::TalkMediator> talk_mediator_;
// Indicates whether XMPP notifications are currently enabled.
@@ -269,7 +139,6 @@ class CloudPrintProxyBackend::Core
bool job_poll_scheduled_;
// Indicates whether we should poll for jobs when we lose XMPP connection.
bool enable_job_poll_;
- scoped_ptr<gaia::GaiaOAuthClient> oauth_client_;
scoped_ptr<CloudPrintTokenStore> token_store_;
DISALLOW_COPY_AND_ASSIGN(Core);
@@ -277,6 +146,7 @@ class CloudPrintProxyBackend::Core
CloudPrintProxyBackend::CloudPrintProxyBackend(
CloudPrintProxyFrontend* frontend,
+ const std::string& proxy_id,
const GURL& cloud_print_server_url,
const DictionaryValue* print_system_settings,
const gaia::OAuthClientInfo& oauth_client_info,
@@ -286,6 +156,7 @@ CloudPrintProxyBackend::CloudPrintProxyBackend(
frontend_(frontend) {
DCHECK(frontend_);
core_ = new Core(this,
+ proxy_id,
cloud_print_server_url,
print_system_settings,
oauth_client_info,
@@ -379,25 +250,25 @@ void CloudPrintProxyBackend::RegisterPrinters(
CloudPrintProxyBackend::Core::Core(
CloudPrintProxyBackend* backend,
+ const std::string& proxy_id,
const GURL& cloud_print_server_url,
const DictionaryValue* print_system_settings,
const gaia::OAuthClientInfo& oauth_client_info,
bool enable_job_poll)
: backend_(backend),
cloud_print_server_url_(cloud_print_server_url),
- oauth_client_info_(oauth_client_info),
- complete_list_available_(false),
- next_upload_index_(0),
- next_response_handler_(NULL),
- new_printers_available_(false),
- registration_in_progress_(false),
- notifications_enabled_(false),
+ proxy_id_(proxy_id),
job_poll_scheduled_(false),
enable_job_poll_(enable_job_poll) {
- if (print_system_settings) {
- // It is possible to have no print settings specified.
- print_system_settings_.reset(print_system_settings->DeepCopy());
- }
+ auth_ = new CloudPrintAuth(this,
+ cloud_print_server_url,
+ print_system_settings,
+ oauth_client_info,
+ proxy_id);
+ connector_ = new CloudPrintConnector(this,
+ proxy_id,
+ cloud_print_server_url,
+ print_system_settings);
}
void CloudPrintProxyBackend::Core::DoInitializeWithLsid(
@@ -410,333 +281,150 @@ void CloudPrintProxyBackend::Core::DoInitializeWithLsid(
// Note: The GAIA login is synchronous but that should be OK because we are in
// the CloudPrintProxyCoreThread and we cannot really do anything else until
// the GAIA signin is successful.
- std::string user_agent = "ChromiumBrowser";
- scoped_refptr<ServiceGaiaAuthenticator> gaia_auth_for_print(
- new ServiceGaiaAuthenticator(
- user_agent, kCloudPrintGaiaServiceId,
- GaiaUrls::GetInstance()->client_login_url(),
- g_service_process->io_thread()->message_loop_proxy()));
- gaia_auth_for_print->set_message_loop(MessageLoop::current());
- if (gaia_auth_for_print->AuthenticateWithLsid(lsid)) {
- // Stash away the user email so we can save it in prefs.
- user_email_ = gaia_auth_for_print->email();
- // If the same user is re-enabling Cloud Print and we have stashed robot
- // credentials, we will use those.
- if ((0 == base::strcasecmp(user_email_.c_str(), last_user_email.c_str())) &&
- !last_robot_refresh_token.empty() &&
- !last_robot_email.empty()) {
- DoInitializeWithRobotToken(last_robot_refresh_token,
- last_robot_email,
- proxy_id);
- }
- DoInitializeWithToken(gaia_auth_for_print->auth_token(),
- proxy_id);
- } else {
- // Let the frontend know the of authentication failure.
- OnAuthError();
- }
+ auth_->AuthenticateWithLsid(lsid, last_robot_refresh_token,
+ last_robot_email, last_user_email);
}
void CloudPrintProxyBackend::Core::DoInitializeWithToken(
const std::string cloud_print_token,
const std::string& proxy_id) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- VLOG(1) << "CP_PROXY: Starting proxy, id: " << proxy_id;
- proxy_id_ = proxy_id;
- GetTokenStore()->SetToken(cloud_print_token, false);
-
- // We need to get the credentials of the robot here.
- GURL get_authcode_url =
- CloudPrintHelpers::GetUrlForGetAuthCode(cloud_print_server_url_,
- oauth_client_info_.client_id,
- proxy_id_);
- next_response_handler_ =
- &CloudPrintProxyBackend::Core::HandleGetAuthCodeResponse;
- request_ = new CloudPrintURLFetcher;
- request_->StartGetRequest(get_authcode_url,
- this,
- kCloudPrintAPIMaxRetryCount,
- std::string());
+ auth_->AuthenticateWithToken(cloud_print_token);
}
void CloudPrintProxyBackend::Core::DoInitializeWithRobotToken(
const std::string& robot_oauth_refresh_token,
const std::string& robot_email,
const std::string& proxy_id) {
- robot_email_ = robot_email;
- proxy_id_ = proxy_id;
- refresh_token_ = robot_oauth_refresh_token;
- RefreshAccessToken();
+ DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
+ auth_->AuthenticateWithRobotToken(robot_oauth_refresh_token, robot_email);
}
void CloudPrintProxyBackend::Core::DoInitializeWithRobotAuthCode(
const std::string& robot_oauth_auth_code,
const std::string& robot_email,
const std::string& proxy_id) {
- robot_email_ = robot_email;
- proxy_id_ = proxy_id;
- // Now that we have an auth code we need to get the refresh and access tokens.
- oauth_client_.reset(new gaia::GaiaOAuthClient(
- gaia::kGaiaOAuth2Url,
- g_service_process->GetServiceURLRequestContextGetter()));
- oauth_client_->GetTokensFromAuthCode(oauth_client_info_,
- robot_oauth_auth_code,
- kCloudPrintAPIMaxRetryCount,
- this);
-}
-
-void CloudPrintProxyBackend::Core::PostAuthInitialization() {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- // Now we can get down to registering printers.
- print_system_ =
- cloud_print::PrintSystem::CreateInstance(print_system_settings_.get());
- if (!print_system_.get()) {
- NOTREACHED();
- return; // No print system available, fail initalization.
- }
- cloud_print::PrintSystem::PrintSystemResult result = print_system_->Init();
-
- if (result.succeeded()) {
- notifier::NotifierOptions notifier_options;
- notifier_options.request_context_getter =
- g_service_process->GetServiceURLRequestContextGetter();
- notifier_options.auth_mechanism = "X-OAUTH2";
- talk_mediator_.reset(new notifier::TalkMediatorImpl(
- new notifier::MediatorThreadImpl(notifier_options),
- notifier_options));
- notifier::Subscription subscription;
- subscription.channel = kCloudPrintPushNotificationsSource;
- subscription.from = kCloudPrintPushNotificationsSource;
- talk_mediator_->AddSubscription(subscription);
- talk_mediator_->SetDelegate(this);
- talk_mediator_->SetAuthToken(
- robot_email_,
- CloudPrintTokenStore::current()->token(),
- kSyncGaiaServiceId);
- talk_mediator_->Login();
-
- print_server_watcher_ = print_system_->CreatePrintServerWatcher();
- print_server_watcher_->StartWatching(this);
+ auth_->AuthenticateWithRobotAuthCode(robot_oauth_auth_code, robot_email);
+}
- StartRegistration();
+void CloudPrintProxyBackend::Core::OnAuthenticationComplete(
+ const std::string& access_token,
+ const std::string& robot_oauth_refresh_token,
+ const std::string& robot_email,
+ const std::string& user_email) {
+ CloudPrintTokenStore* token_store = GetTokenStore();
+ bool first_time = token_store->token().empty();
+ token_store->SetToken(access_token);
+ // Let the frontend know that we have authenticated.
+ backend_->frontend_loop_->PostTask(
+ FROM_HERE, NewRunnableMethod(this,
+ &Core::NotifyAuthenticated,
+ robot_oauth_refresh_token,
+ robot_email,
+ user_email));
+ if (first_time) {
+ InitNotifications(robot_email, access_token);
} else {
- // We could not initialize the print system. We need to notify the server.
- ReportUserMessage(
- kPrintSystemFailedMessageId,
- result.message(),
- &CloudPrintProxyBackend::Core::HandlePrintSystemUnavailableResponse);
+ // If we are refreshing a token, update the XMPP token too.
+ DCHECK(talk_mediator_.get());
+ talk_mediator_->SetAuthToken(robot_email,
+ access_token,
+ kSyncGaiaServiceId);
+ }
+ // Start cloud print connector if needed.
+ if (!connector_->IsRunning()) {
+ if (!connector_->Start()) {
+ // Let the frontend know that we do not have a print system.
+ backend_->frontend_loop_->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this,
+ &Core::NotifyPrintSystemUnavailable));
+ }
}
}
-void CloudPrintProxyBackend::Core::StartRegistration() {
+void CloudPrintProxyBackend::Core::OnInvalidCredentials() {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- printer_list_.clear();
- cloud_print::PrintSystem::PrintSystemResult result =
- print_system_->EnumeratePrinters(&printer_list_);
- complete_list_available_ = result.succeeded();
- registration_in_progress_ = true;
- if (!result.succeeded()) {
- std::string message = result.message();
- if (message.empty())
- message = l10n_util::GetStringUTF8(IDS_CLOUD_PRINT_ENUM_FAILED);
- // There was a failure enumerating printers. Send a message to the server.
- ReportUserMessage(
- kEnumPrintersFailedMessageId,
- message,
- &CloudPrintProxyBackend::Core::HandleEnumPrintersFailedResponse);
- } else {
- // Now we need to ask the server about printers that were registered on the
- // server so that we can trim this list.
- GetRegisteredPrinters();
- }
+ VLOG(1) << "CP_CONNECTOR: Auth Error";
+ backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &Core::NotifyAuthenticationFailed));
+}
+
+void CloudPrintProxyBackend::Core::OnPrintersAvailable(
+ const printing::PrinterList& printers) {
+ // Let the frontend know that we have a list of printers available.
+ backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &Core::NotifyPrinterListAvailable, printers));
+}
+
+void CloudPrintProxyBackend::Core::OnAuthFailed() {
+ VLOG(1) << "CP_CONNECTOR: Authentication failed in connector.";
+ // Let's stop connecter and refresh token. We'll restart connecter once
+ // new token available.
+ if (connector_->IsRunning())
+ connector_->Stop();
+
+ // Refresh Auth token.
+ auth_->RefreshAccessToken();
}
-void CloudPrintProxyBackend::Core::EndRegistration() {
+void CloudPrintProxyBackend::Core::InitNotifications(
+ const std::string& robot_email,
+ const std::string& access_token) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- request_ = NULL;
- registration_in_progress_ = false;
- if (new_printers_available_) {
- new_printers_available_ = false;
- StartRegistration();
- }
+
+ notifier::NotifierOptions notifier_options;
+ notifier_options.request_context_getter =
+ g_service_process->GetServiceURLRequestContextGetter();
+ notifier_options.auth_mechanism = "X-OAUTH2";
+ talk_mediator_.reset(new notifier::TalkMediatorImpl(
+ new notifier::MediatorThreadImpl(notifier_options),
+ notifier_options));
+ notifier::Subscription subscription;
+ subscription.channel = kCloudPrintPushNotificationsSource;
+ subscription.from = kCloudPrintPushNotificationsSource;
+ talk_mediator_->AddSubscription(subscription);
+ talk_mediator_->SetDelegate(this);
+ talk_mediator_->SetAuthToken(robot_email, access_token, kSyncGaiaServiceId);
+ talk_mediator_->Login();
}
void CloudPrintProxyBackend::Core::DoShutdown() {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- VLOG(1) << "CP_PROXY: Shutdown proxy, id: " << proxy_id_;
- if (print_server_watcher_ != NULL)
- print_server_watcher_->StopWatching();
+ VLOG(1) << "CP_CONNECTOR: Shutdown connector, id: " << proxy_id_;
+
+ if (connector_->IsRunning())
+ connector_->Stop();
- // 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();
- }
// Important to delete the TalkMediator on this thread.
if (talk_mediator_.get())
talk_mediator_->Logout();
talk_mediator_.reset();
notifications_enabled_ = false;
notifications_enabled_since_ = base::TimeTicks();
- request_ = NULL;
token_store_.reset();
}
void CloudPrintProxyBackend::Core::DoRegisterSelectedPrinters(
const printing::PrinterList& printer_list) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- if (!print_system_.get())
- return; // No print system available.
- printer_list_.assign(printer_list.begin(), printer_list.end());
- next_upload_index_ = 0;
- RegisterNextPrinter();
-}
-
-void CloudPrintProxyBackend::Core::GetRegisteredPrinters() {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- GURL printer_list_url =
- CloudPrintHelpers::GetUrlForPrinterList(cloud_print_server_url_,
- proxy_id_);
- next_response_handler_ =
- &CloudPrintProxyBackend::Core::HandlePrinterListResponse;
- request_ = new CloudPrintURLFetcher;
- request_->StartGetRequest(printer_list_url,
- this,
- kCloudPrintAPIMaxRetryCount,
- std::string());
-}
-
-void CloudPrintProxyBackend::Core::RegisterNextPrinter() {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- // 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 printing::PrinterBasicInfo& info =
- printer_list_.at(next_upload_index_);
- // 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_) {
- cloud_print::PrintSystem::PrinterCapsAndDefaultsCallback* callback =
- NewCallback(this,
- &CloudPrintProxyBackend::Core::OnReceivePrinterCaps);
- // Asnchronously fetch the printer caps and defaults. The story will
- // continue in OnReceivePrinterCaps.
- print_system_->GetPrinterCapsAndDefaults(
- info.printer_name.c_str(), callback);
- } else {
- OnReceivePrinterCaps(true,
- last_uploaded_printer_name_,
- last_uploaded_printer_info_);
- }
- } else {
- EndRegistration();
- }
-}
-
-void CloudPrintProxyBackend::Core::OnReceivePrinterCaps(
- bool succeeded,
- const std::string& printer_name,
- const printing::PrinterCapsAndDefaults& caps_and_defaults) {
- DCHECK(next_upload_index_ < printer_list_.size());
- if (succeeded) {
- const printing::PrinterBasicInfo& info =
- printer_list_.at(next_upload_index_);
-
- last_uploaded_printer_name_ = info.printer_name;
- last_uploaded_printer_info_ = caps_and_defaults;
-
- 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, base::StringPrintf("%d", info.printer_status),
- mime_boundary, std::string(), &post_data);
- // Add printer options as tags.
- CloudPrintHelpers::GenerateMultipartPostDataForPrinterTags(info.options,
- mime_boundary,
- &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(
- kPrinterCapsHashValue,
- base::MD5String(last_uploaded_printer_info_.printer_capabilities),
- mime_boundary, std::string(), &post_data);
- GURL post_url = CloudPrintHelpers::GetUrlForPrinterRegistration(
- cloud_print_server_url_);
-
- next_response_handler_ =
- &CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse;
- // Terminate the request body
- post_data.append("--" + mime_boundary + "--\r\n");
- std::string mime_type("multipart/form-data; boundary=");
- mime_type += mime_boundary;
- request_ = new CloudPrintURLFetcher;
- request_->StartPostRequest(post_url,
- this,
- kCloudPrintAPIMaxRetryCount,
- mime_type,
- post_data,
- std::string());
- } else {
- LOG(ERROR) << "CP_PROXY: Failed to get printer info for: " <<
- printer_name;
- // This printer failed to register, notify the server of this failure.
- string16 printer_name_utf16 = UTF8ToUTF16(printer_name);
- std::string status_message = l10n_util::GetStringFUTF8(
- IDS_CLOUD_PRINT_REGISTER_PRINTER_FAILED,
- printer_name_utf16);
- ReportUserMessage(
- kGetPrinterCapsFailedMessageId,
- status_message,
- &CloudPrintProxyBackend::Core::HandleRegisterFailedStatusResponse);
- }
+ connector_->RegisterPrinters(printer_list);
}
void CloudPrintProxyBackend::Core::HandlePrinterNotification(
const std::string& printer_id) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- VLOG(1) << "CP_PROXY: Handle printer notification, id: " << printer_id;
- JobHandlerMap::iterator index = job_handler_map_.find(printer_id);
- if (index != job_handler_map_.end())
- index->second->CheckForJobs(kJobFetchReasonNotified);
+ VLOG(1) << "CP_CONNECTOR: Handle printer notification, id: " << printer_id;
+ connector_->CheckForJobs(kJobFetchReasonNotified, printer_id);
}
void CloudPrintProxyBackend::Core::PollForJobs() {
- VLOG(1) << "CP_PROXY: Polling for jobs.";
+ VLOG(1) << "CP_CONNECTOR: Polling for jobs.";
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- for (JobHandlerMap::iterator index = job_handler_map_.begin();
- index != job_handler_map_.end(); index++) {
- // If notifications are on, then we should poll for this printer only if
- // the last time it fetched jobs was before notifications were last enabled.
- bool should_poll =
- !notifications_enabled_ ||
- (index->second->last_job_fetch_time() <= notifications_enabled_since_);
- if (should_poll)
- index->second->CheckForJobs(kJobFetchReasonPoll);
- }
+ // Check all printers for jobs.
+ connector_->CheckForJobs(kJobFetchReasonPoll, std::string());
+
job_poll_scheduled_ = false;
// If we don't have notifications and job polling is enabled, poll again
// after a while.
@@ -763,21 +451,6 @@ CloudPrintTokenStore* CloudPrintProxyBackend::Core::GetTokenStore() {
return token_store_.get();
}
-// CloudPrintURLFetcher::Delegate implementation.
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandleJSONData(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(next_response_handler_);
- return (this->*next_response_handler_)(source, url, json_data, succeeded);
-}
-
-void CloudPrintProxyBackend::Core::OnRequestAuthError() {
- OnAuthError();
-}
-
void CloudPrintProxyBackend::Core::NotifyPrinterListAvailable(
const printing::PrinterList& printer_list) {
DCHECK(MessageLoop::current() == backend_->frontend_loop_);
@@ -804,256 +477,17 @@ void CloudPrintProxyBackend::Core::NotifyPrintSystemUnavailable() {
backend_->frontend_->OnPrintSystemUnavailable();
}
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandleGetAuthCodeResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- if (!succeeded) {
- OnAuthError();
- return CloudPrintURLFetcher::STOP_PROCESSING;
- }
- std::string auth_code;
- if (!json_data->GetString(kOAuthCodeValue, &auth_code)) {
- OnAuthError();
- return CloudPrintURLFetcher::STOP_PROCESSING;
- }
- json_data->GetString(kXMPPJidValue, &robot_email_);
- // Now that we have an auth code we need to get the refresh and access tokens.
- oauth_client_.reset(new gaia::GaiaOAuthClient(
- gaia::kGaiaOAuth2Url,
- g_service_process->GetServiceURLRequestContextGetter()));
- oauth_client_->GetTokensFromAuthCode(oauth_client_info_,
- auth_code,
- kCloudPrintAPIMaxRetryCount,
- this);
-
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandlePrinterListResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- if (!succeeded) {
- NOTREACHED();
- return CloudPrintURLFetcher::RETRY_REQUEST;
- }
- ListValue* printer_list = NULL;
- // There may be no "printers" value in the JSON
- if (json_data->GetList(kPrinterListValue, &printer_list) && 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();
- }
- }
- }
- request_ = NULL;
- 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::NotifyPrinterListAvailable, printer_list_));
- } else {
- // No more work to be done here.
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &Core::EndRegistration));
- }
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-void CloudPrintProxyBackend::Core::InitJobHandlerForPrinter(
- DictionaryValue* printer_data) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- DCHECK(printer_data);
- PrinterJobHandler::PrinterInfoFromCloud printer_info_cloud;
- printer_data->GetString(kIdValue, &printer_info_cloud.printer_id);
- DCHECK(!printer_info_cloud.printer_id.empty());
- VLOG(1) << "CP_PROXY: Init job handler for printer id: "
- << printer_info_cloud.printer_id;
- JobHandlerMap::iterator index = job_handler_map_.find(
- printer_info_cloud.printer_id);
- // We might already have a job handler for this printer
- if (index == job_handler_map_.end()) {
- printing::PrinterBasicInfo printer_info;
- printer_data->GetString(kNameValue, &printer_info.printer_name);
- DCHECK(!printer_info.printer_name.empty());
- printer_data->GetString(kPrinterDescValue,
- &printer_info.printer_description);
- // Printer status is a string value which actually contains an integer.
- std::string printer_status;
- if (printer_data->GetString(kPrinterStatusValue, &printer_status)) {
- base::StringToInt(printer_status, &printer_info.printer_status);
- }
- printer_data->GetString(kPrinterCapsHashValue,
- &printer_info_cloud.caps_hash);
- ListValue* tags_list = NULL;
- if (printer_data->GetList(kTagsValue, &tags_list) && tags_list) {
- for (size_t index = 0; index < tags_list->GetSize(); index++) {
- std::string tag;
- if (tags_list->GetString(index, &tag) &&
- StartsWithASCII(tag, kTagsHashTagName, false)) {
- std::vector<std::string> tag_parts;
- base::SplitStringDontTrim(tag, '=', &tag_parts);
- DCHECK_EQ(tag_parts.size(), 2U);
- if (tag_parts.size() == 2)
- printer_info_cloud.tags_hash = tag_parts[1];
- }
- }
- }
- scoped_refptr<PrinterJobHandler> job_handler;
- job_handler = new PrinterJobHandler(printer_info,
- printer_info_cloud,
- cloud_print_server_url_,
- print_system_.get(),
- this);
- job_handler_map_[printer_info_cloud.printer_id] = job_handler;
- job_handler->Initialize();
- }
-}
-
-void CloudPrintProxyBackend::Core::ReportUserMessage(
- const std::string& message_id,
- const std::string& failure_message,
- ResponseHandler handler) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- std::string mime_boundary;
- CloudPrintHelpers::CreateMimeBoundaryForUpload(&mime_boundary);
- GURL post_url = CloudPrintHelpers::GetUrlForUserMessage(
- cloud_print_server_url_,
- message_id);
- std::string post_data;
- CloudPrintHelpers::AddMultipartValueForUpload(kMessageTextValue,
- failure_message,
- mime_boundary,
- std::string(),
- &post_data);
- next_response_handler_ = handler;
- // Terminate the request body
- post_data.append("--" + mime_boundary + "--\r\n");
- std::string mime_type("multipart/form-data; boundary=");
- mime_type += mime_boundary;
- request_ = new CloudPrintURLFetcher;
- request_->StartPostRequest(post_url,
- this,
- kCloudPrintAPIMaxRetryCount,
- mime_type,
- post_data,
- std::string());
-}
-
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- if (succeeded) {
- ListValue* printer_list = NULL;
- // There should be a "printers" value in the JSON
- if (json_data->GetList(kPrinterListValue, &printer_list)) {
- DictionaryValue* printer_data = NULL;
- if (printer_list->GetDictionary(0, &printer_data))
- InitJobHandlerForPrinter(printer_data);
- }
- }
- next_upload_index_++;
- MessageLoop::current()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this,
- &CloudPrintProxyBackend::Core::RegisterNextPrinter));
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandleRegisterFailedStatusResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- next_upload_index_++;
- MessageLoop::current()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this,
- &CloudPrintProxyBackend::Core::RegisterNextPrinter));
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandlePrintSystemUnavailableResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- // Let the frontend know that we do not have a print system.
- backend_->frontend_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this,
- &Core::NotifyPrintSystemUnavailable));
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-CloudPrintURLFetcher::ResponseAction
-CloudPrintProxyBackend::Core::HandleEnumPrintersFailedResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- // Now proceed with printer registration.
- GetRegisteredPrinters();
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-
-bool CloudPrintProxyBackend::Core::RemovePrinterFromList(
- const std::string& printer_name) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- for (printing::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);
- return true;
- }
- }
- return false;
-}
-
-void CloudPrintProxyBackend::Core::RefreshAccessToken() {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- oauth_client_.reset(new gaia::GaiaOAuthClient(
- gaia::kGaiaOAuth2Url,
- g_service_process->GetServiceURLRequestContextGetter()));
- oauth_client_->RefreshToken(oauth_client_info_,
- refresh_token_,
- kCloudPrintAPIMaxRetryCount,
- this);
-}
-
void CloudPrintProxyBackend::Core::OnNotificationStateChange(
bool notification_enabled) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
notifications_enabled_ = notification_enabled;
if (notifications_enabled_) {
notifications_enabled_since_ = base::TimeTicks::Now();
- VLOG(1) << "Notifications for proxy " << proxy_id_ << " were enabled at "
+ VLOG(1) << "Notifications for connector " << proxy_id_
+ << " were enabled at "
<< notifications_enabled_since_.ToInternalValue();
} else {
- LOG(ERROR) << "Notifications for proxy " << proxy_id_ << " disabled.";
+ LOG(ERROR) << "Notifications for connector " << proxy_id_ << " disabled.";
notifications_enabled_since_ = base::TimeTicks();
}
// A state change means one of two cases.
@@ -1071,98 +505,10 @@ void CloudPrintProxyBackend::Core::OnNotificationStateChange(
void CloudPrintProxyBackend::Core::OnIncomingNotification(
const notifier::Notification& notification) {
DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- VLOG(1) << "CP_PROXY: Incoming notification.";
+ VLOG(1) << "CP_CONNECTOR: Incoming notification.";
if (0 == base::strcasecmp(kCloudPrintPushNotificationsSource,
notification.channel.c_str()))
HandlePrinterNotification(notification.data);
}
void CloudPrintProxyBackend::Core::OnOutgoingNotification() {}
-
-// cloud_print::PrinterChangeNotifier::Delegate implementation
-void CloudPrintProxyBackend::Core::OnPrinterAdded() {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- if (registration_in_progress_)
- new_printers_available_ = true;
- else
- StartRegistration();
-}
-
-// PrinterJobHandler::Delegate implementation
-void CloudPrintProxyBackend::Core::OnPrinterJobHandlerShutdown(
- PrinterJobHandler* job_handler, const std::string& printer_id) {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- VLOG(1) << "CP_PROXY: Printer job handle shutdown, id " << printer_id;
- job_handler_map_.erase(printer_id);
-}
-
-void CloudPrintProxyBackend::Core::OnAuthError() {
- DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop());
- VLOG(1) << "CP_PROXY: Auth Error";
- backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &Core::NotifyAuthenticationFailed));
-}
-
-void CloudPrintProxyBackend::Core::OnPrinterNotFound(
- const std::string& printer_name,
- bool* delete_from_server) {
- // If we have a complete list of local printers, then this needs to be deleted
- // from the server.
- *delete_from_server = complete_list_available_;
-}
-
- // gaia::GaiaOAuthClient::Delegate implementation.
-void CloudPrintProxyBackend::Core::OnGetTokensResponse(
- const std::string& refresh_token,
- const std::string& access_token,
- int expires_in_seconds) {
- refresh_token_ = refresh_token;
- // After saving the refresh token, this is just like having just refreshed
- // the access token. Just call OnRefreshTokenResponse.
- OnRefreshTokenResponse(access_token, expires_in_seconds);
-}
-
-void CloudPrintProxyBackend::Core::OnRefreshTokenResponse(
- const std::string& access_token, int expires_in_seconds) {
- // If our current token is not OAuth, we either have no token at all or we
- // have a ClientLogin token which we just exchanged for an OAuth token.
- // In this case we need to do the startup initialiazation.
- // TODO(sanjeevr): Use an enum for state instead of using this as a signal.
- // I will do this in a follow-up change.
- CloudPrintTokenStore* token_store = GetTokenStore();
- bool first_time = !token_store->token_is_oauth();
- token_store->SetToken(access_token, true);
- // Let the frontend know that we have authenticated.
- backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &Core::NotifyAuthenticated, refresh_token_, robot_email_, user_email_));
- if (first_time) {
- PostAuthInitialization();
- } else {
- // If we are refreshing a token, update the XMPP token too.
- DCHECK(talk_mediator_.get());
- talk_mediator_->SetAuthToken(robot_email_,
- access_token,
- kSyncGaiaServiceId);
- }
- // Schedule a task to refresh the access token again when it is about to
- // expire.
- DCHECK(expires_in_seconds > kTokenRefreshGracePeriodSecs);
- int64 refresh_delay =
- (expires_in_seconds - kTokenRefreshGracePeriodSecs)*1000;
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- NewRunnableMethod(this, &Core::RefreshAccessToken),
- refresh_delay);
-}
-
-void CloudPrintProxyBackend::Core::OnOAuthError() {
- OnAuthError();
-}
-
-void CloudPrintProxyBackend::Core::OnNetworkError(int response_code) {
- // Since we specify inifinite retries on network errors, this should never
- // be called.
- NOTREACHED() <<
- "OnNetworkError invoked when not expected, response code is " <<
- response_code;
-}
diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.h b/chrome/service/cloud_print/cloud_print_proxy_backend.h
index 8841ade..d66152e 100644
--- a/chrome/service/cloud_print/cloud_print_proxy_backend.h
+++ b/chrome/service/cloud_print/cloud_print_proxy_backend.h
@@ -58,6 +58,7 @@ class CloudPrintProxyBackend {
// use system default settings.
CloudPrintProxyBackend(
CloudPrintProxyFrontend* frontend,
+ const std::string& proxy_id,
const GURL& cloud_print_server_url,
const base::DictionaryValue* print_sys_settings,
const gaia::OAuthClientInfo& oauth_client_info,
diff --git a/chrome/service/cloud_print/cloud_print_token_store.cc b/chrome/service/cloud_print/cloud_print_token_store.cc
index 5c38314..e0bb0b0 100644
--- a/chrome/service/cloud_print/cloud_print_token_store.cc
+++ b/chrome/service/cloud_print/cloud_print_token_store.cc
@@ -16,7 +16,7 @@ CloudPrintTokenStore* CloudPrintTokenStore::current() {
return lazy_tls.Pointer()->Get();
}
-CloudPrintTokenStore::CloudPrintTokenStore() : token_is_oauth_(false) {
+CloudPrintTokenStore::CloudPrintTokenStore() {
lazy_tls.Pointer()->Set(this);
}
@@ -24,8 +24,7 @@ CloudPrintTokenStore::~CloudPrintTokenStore() {
lazy_tls.Pointer()->Set(NULL);
}
-void CloudPrintTokenStore::SetToken(const std::string& token, bool is_oauth) {
+void CloudPrintTokenStore::SetToken(const std::string& token) {
DCHECK(CalledOnValidThread());
token_ = token;
- token_is_oauth_ = is_oauth;
}
diff --git a/chrome/service/cloud_print/cloud_print_token_store.h b/chrome/service/cloud_print/cloud_print_token_store.h
index b136983..d6b4a4a 100644
--- a/chrome/service/cloud_print/cloud_print_token_store.h
+++ b/chrome/service/cloud_print/cloud_print_token_store.h
@@ -23,19 +23,14 @@ class CloudPrintTokenStore : public base::NonThreadSafe {
CloudPrintTokenStore();
~CloudPrintTokenStore();
- void SetToken(const std::string& token, bool is_oauth);
+ void SetToken(const std::string& token);
std::string token() const {
DCHECK(CalledOnValidThread());
return token_;
}
- bool token_is_oauth() const {
- DCHECK(CalledOnValidThread());
- return token_is_oauth_;
- }
private:
std::string token_;
- bool token_is_oauth_;
DISALLOW_COPY_AND_ASSIGN(CloudPrintTokenStore);
};
diff --git a/chrome/service/cloud_print/cloud_print_token_store_unittest.cc b/chrome/service/cloud_print/cloud_print_token_store_unittest.cc
index 9cf9339..1dff537 100644
--- a/chrome/service/cloud_print/cloud_print_token_store_unittest.cc
+++ b/chrome/service/cloud_print/cloud_print_token_store_unittest.cc
@@ -10,12 +10,8 @@ TEST(CloudPrintTokenStoreTest, Basic) {
EXPECT_EQ(NULL, CloudPrintTokenStore::current());
CloudPrintTokenStore* store = new CloudPrintTokenStore;
EXPECT_EQ(store, CloudPrintTokenStore::current());
- CloudPrintTokenStore::current()->SetToken("myclientlogintoken", false);
+ CloudPrintTokenStore::current()->SetToken("myclientlogintoken");
EXPECT_EQ(CloudPrintTokenStore::current()->token(), "myclientlogintoken");
- EXPECT_FALSE(CloudPrintTokenStore::current()->token_is_oauth());
- CloudPrintTokenStore::current()->SetToken("myoauth2token", true);
- EXPECT_EQ(CloudPrintTokenStore::current()->token(), "myoauth2token");
- EXPECT_TRUE(CloudPrintTokenStore::current()->token_is_oauth());
delete store;
EXPECT_EQ(NULL, CloudPrintTokenStore::current());
}
diff --git a/chrome/service/cloud_print/cloud_print_url_fetcher.cc b/chrome/service/cloud_print/cloud_print_url_fetcher.cc
index e686685..8cc0700 100644
--- a/chrome/service/cloud_print/cloud_print_url_fetcher.cc
+++ b/chrome/service/cloud_print/cloud_print_url_fetcher.cc
@@ -20,6 +20,10 @@ CloudPrintURLFetcher::CloudPrintURLFetcher()
num_retries_(0) {
}
+bool CloudPrintURLFetcher::IsSameRequest(const content::URLFetcher* source) {
+ return (request_.get() == source);
+}
+
void CloudPrintURLFetcher::StartGetRequest(
const GURL& url,
Delegate* delegate,
@@ -65,15 +69,14 @@ void CloudPrintURLFetcher::OnURLFetchComplete(
source->GetResponseCode(),
source->GetCookies(),
data);
+
+ // If we get auth error, notify delegate and check if it wants to proceed.
+ if (action == CONTINUE_PROCESSING &&
+ source->GetResponseCode() == RC_FORBIDDEN) {
+ action = delegate_->OnRequestAuthError();
+ }
+
if (action == CONTINUE_PROCESSING) {
- // If we are not using an OAuth token, and we got an auth error, we are
- // done. Else, the token may have been refreshed. Let us try again.
- if ((RC_FORBIDDEN == source->GetResponseCode()) &&
- (!CloudPrintTokenStore::current() ||
- !CloudPrintTokenStore::current()->token_is_oauth())) {
- delegate_->OnRequestAuthError();
- return;
- }
// We need to retry on all network errors.
if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200))
action = RETRY_REQUEST;
@@ -105,6 +108,12 @@ void CloudPrintURLFetcher::OnURLFetchComplete(
// be ignored.
request_->ReceivedContentWasMalformed();
+ // If we receive error code from the server "Media Type Not Supported",
+ // there is no reason to retry, request will never succeed.
+ // In that case we should call OnRequestGiveUp() right away.
+ if (source->GetResponseCode() == RC_UNSUPPORTED_MEDIA_TYPE)
+ num_retries_ = source->GetMaxRetries();
+
++num_retries_;
if ((-1 != source->GetMaxRetries()) &&
(num_retries_ > source->GetMaxRetries())) {
@@ -136,8 +145,8 @@ void CloudPrintURLFetcher::StartRequestHelper(
// Since we implement our own retry logic, disable the retry in URLFetcher.
request_->SetAutomaticallyRetryOn5xx(false);
request_->SetMaxRetries(max_retries);
- SetupRequestHeaders();
delegate_ = delegate;
+ SetupRequestHeaders();
if (request_type == content::URLFetcher::POST) {
request_->SetUploadData(post_data_mime_type, post_data);
}
@@ -146,14 +155,9 @@ void CloudPrintURLFetcher::StartRequestHelper(
}
void CloudPrintURLFetcher::SetupRequestHeaders() {
- std::string headers;
- CloudPrintTokenStore* token_store = CloudPrintTokenStore::current();
- if (token_store) {
- headers = token_store->token_is_oauth() ?
- "Authorization: OAuth " : "Authorization: GoogleLogin auth=";
- headers += token_store->token();
+ std::string headers = delegate_->GetAuthHeader();
+ if (!headers.empty())
headers += "\r\n";
- }
headers += kChromeCloudPrintProxyHeader;
if (!additional_headers_.empty()) {
headers += "\r\n";
diff --git a/chrome/service/cloud_print/cloud_print_url_fetcher.h b/chrome/service/cloud_print/cloud_print_url_fetcher.h
index 17e538d..2d26bb8 100644
--- a/chrome/service/cloud_print/cloud_print_url_fetcher.h
+++ b/chrome/service/cloud_print/cloud_print_url_fetcher.h
@@ -38,6 +38,7 @@ class CloudPrintURLFetcher
STOP_PROCESSING,
RETRY_REQUEST,
};
+
class Delegate {
public:
virtual ~Delegate() { }
@@ -80,10 +81,20 @@ class CloudPrintURLFetcher
virtual void OnRequestGiveUp() { }
// Invoked when the request returns a 403 error (applicable only when
// HandleRawResponse returns CONTINUE_PROCESSING).
- virtual void OnRequestAuthError() = 0;
+ // Returning RETRY_REQUEST will retry current request. (auth information
+ // may have been updated and new info is available through the
+ // Authenticator interface).
+ // Returning CONTINUE_PROCESSING will treat auth error as a network error.
+ virtual ResponseAction OnRequestAuthError() = 0;
+
+ // Authentication information may change between retries.
+ // CloudPrintURLFetcher will request auth info before sending any request.
+ virtual std::string GetAuthHeader() = 0;
};
CloudPrintURLFetcher();
+ bool IsSameRequest(const content::URLFetcher* source);
+
void StartGetRequest(const GURL& url,
Delegate* delegate,
int max_retries,
diff --git a/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc b/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc
index ac2aeab..319ac8c 100644
--- a/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc
+++ b/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc
@@ -84,8 +84,13 @@ class CloudPrintURLFetcherTest : public testing::Test,
const net::ResponseCookies& cookies,
const std::string& data);
- virtual void OnRequestAuthError() {
+ virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError() {
ADD_FAILURE();
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+ }
+
+ virtual std::string GetAuthHeader() {
+ return std::string();
}
scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
diff --git a/chrome/service/cloud_print/job_status_updater.cc b/chrome/service/cloud_print/job_status_updater.cc
index 9fffc95..c2d7fc1 100644
--- a/chrome/service/cloud_print/job_status_updater.cc
+++ b/chrome/service/cloud_print/job_status_updater.cc
@@ -89,7 +89,17 @@ CloudPrintURLFetcher::ResponseAction JobStatusUpdater::HandleJSONData(
return CloudPrintURLFetcher::STOP_PROCESSING;
}
-void JobStatusUpdater::OnRequestAuthError() {
+CloudPrintURLFetcher::ResponseAction JobStatusUpdater::OnRequestAuthError() {
+ // We got an Auth error and have no idea how long it will take to refresh
+ // auth information (may take forever). We'll drop current request and
+ // propagate this error to the upper level. After auth issues will be
+ // resolved, GCP connector will restart.
if (delegate_)
delegate_->OnAuthError();
+ return CloudPrintURLFetcher::STOP_PROCESSING;
+}
+
+std::string JobStatusUpdater::GetAuthHeader() {
+ return CloudPrintHelpers::GetCloudPrintAuthHeader();
}
+
diff --git a/chrome/service/cloud_print/job_status_updater.h b/chrome/service/cloud_print/job_status_updater.h
index 49b106e..aaacc2c 100644
--- a/chrome/service/cloud_print/job_status_updater.h
+++ b/chrome/service/cloud_print/job_status_updater.h
@@ -50,7 +50,8 @@ class JobStatusUpdater : public base::RefCountedThreadSafe<JobStatusUpdater>,
const GURL& url,
base::DictionaryValue* json_data,
bool succeeded);
- virtual void OnRequestAuthError();
+ virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError();
+ virtual std::string GetAuthHeader();
private:
std::string printer_name_;
diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc
index 3128b2a..36fd51a 100644
--- a/chrome/service/cloud_print/printer_job_handler.cc
+++ b/chrome/service/cloud_print/printer_job_handler.cc
@@ -51,26 +51,17 @@ PrinterJobHandler::PrinterJobHandler(
shutting_down_(false),
job_check_pending_(false),
printer_update_pending_(true),
- printer_delete_pending_(false),
task_in_progress_(false) {
}
bool PrinterJobHandler::Initialize() {
- if (print_system_->IsValidPrinter(
- printer_info_.printer_name)) {
- printer_watcher_ = print_system_->CreatePrinterWatcher(
- printer_info_.printer_name);
- printer_watcher_->StartWatching(this);
- CheckForJobs(kJobFetchReasonStartup);
- } else {
- // This printer does not exist any more. Check if we should delete it from
- // the server.
- bool delete_from_server = false;
- delegate_->OnPrinterNotFound(printer_info_.printer_name,
- &delete_from_server);
- if (delete_from_server)
- OnPrinterDeleted();
- }
+ if (!print_system_->IsValidPrinter(printer_info_.printer_name))
+ return false;
+
+ printer_watcher_ = print_system_->CreatePrinterWatcher(
+ printer_info_.printer_name);
+ printer_watcher_->StartWatching(this);
+ CheckForJobs(kJobFetchReasonStartup);
return true;
}
@@ -86,8 +77,12 @@ void PrinterJobHandler::Reset() {
print_thread_.Stop();
}
+std::string PrinterJobHandler::GetPrinterName() const {
+ return printer_info_.printer_name;
+}
+
void PrinterJobHandler::Start() {
- VLOG(1) << "CP_PROXY: Start printer job handler, id: "
+ VLOG(1) << "CP_CONNECTOR: Start printer job handler, id: "
<< printer_info_cloud_.printer_id
<< ", task in progress: " << task_in_progress_;
if (task_in_progress_) {
@@ -99,18 +94,6 @@ void PrinterJobHandler::Start() {
if (!shutting_down_) {
// Check if we have work to do.
if (HavePendingTasks()) {
- if (printer_delete_pending_) {
- printer_delete_pending_ = false;
- task_in_progress_ = true;
- SetNextJSONHandler(&PrinterJobHandler::HandlePrinterDeleteResponse);
- request_ = new CloudPrintURLFetcher;
- request_->StartGetRequest(
- CloudPrintHelpers::GetUrlForPrinterDelete(
- cloud_print_server_url_, printer_info_cloud_.printer_id),
- this,
- kCloudPrintAPIMaxRetryCount,
- std::string());
- }
if (!task_in_progress_ && printer_update_pending_) {
printer_update_pending_ = false;
task_in_progress_ = UpdatePrinterInfo();
@@ -139,7 +122,7 @@ void PrinterJobHandler::Start() {
}
void PrinterJobHandler::Stop() {
- VLOG(1) << "CP_PROXY: Stop printer job handler, id: "
+ VLOG(1) << "CP_CONNECTOR: Stop printer job handler, id: "
<< printer_info_cloud_.printer_id;
task_in_progress_ = false;
Reset();
@@ -150,7 +133,7 @@ void PrinterJobHandler::Stop() {
}
void PrinterJobHandler::CheckForJobs(const std::string& reason) {
- VLOG(1) << "CP_PROXY: CheckForJobs, id: "
+ VLOG(1) << "CP_CONNECTOR: CheckForJobs, id: "
<< printer_info_cloud_.printer_id
<< ", reason: " << reason
<< ", task in progress: " << task_in_progress_;
@@ -164,13 +147,13 @@ void PrinterJobHandler::CheckForJobs(const std::string& reason) {
bool PrinterJobHandler::UpdatePrinterInfo() {
if (!printer_watcher_) {
- LOG(ERROR) << "CP_PROXY: Printer watcher is missing."
+ LOG(ERROR) << "CP_CONNECTOR: Printer watcher is missing."
<< "Check printer server url for printer id: "
<< printer_info_cloud_.printer_id;
return false;
}
- VLOG(1) << "CP_PROXY: Update printer info, id: "
+ VLOG(1) << "CP_CONNECTOR: Update printer info, id: "
<< printer_info_cloud_.printer_id;
// We need to update the parts of the printer info that have changed
// (could be printer name, description, status or capabilities).
@@ -316,10 +299,7 @@ CloudPrintURLFetcher::ResponseAction PrinterJobHandler::HandleJSONData(
DictionaryValue* json_data,
bool succeeded) {
DCHECK(next_json_data_handler_);
- return (this->*next_json_data_handler_)(source,
- url,
- json_data,
- succeeded);
+ return (this->*next_json_data_handler_)(source, url, json_data, succeeded);
}
void PrinterJobHandler::OnRequestGiveUp() {
@@ -333,8 +313,15 @@ void PrinterJobHandler::OnRequestGiveUp() {
JOB_DOWNLOAD_FAILED));
}
-void PrinterJobHandler::OnRequestAuthError() {
+CloudPrintURLFetcher::ResponseAction PrinterJobHandler::OnRequestAuthError() {
+ // TODO(gene): We might consider stop processing if we get auth error here.
OnAuthError();
+ // Continue processing as a network error.
+ return CloudPrintURLFetcher::CONTINUE_PROCESSING;
+}
+
+std::string PrinterJobHandler::GetAuthHeader() {
+ return CloudPrintHelpers::GetCloudPrintAuthHeader();
}
// JobStatusUpdater::Delegate implementation
@@ -357,11 +344,8 @@ void PrinterJobHandler::OnAuthError() {
}
void PrinterJobHandler::OnPrinterDeleted() {
- printer_delete_pending_ = true;
- if (!task_in_progress_) {
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Start));
- }
+ if (delegate_)
+ delegate_->OnPrinterDeleted(printer_info_cloud_.printer_id);
}
void PrinterJobHandler::OnPrinterChanged() {
@@ -390,7 +374,7 @@ PrinterJobHandler::HandlePrinterUpdateResponse(
const GURL& url,
DictionaryValue* json_data,
bool succeeded) {
- VLOG(1) << "CP_PROXY: Handle printer update response, id: "
+ VLOG(1) << "CP_CONNECTOR: Handle printer update response, id: "
<< printer_info_cloud_.printer_id;
// We are done here. Go to the Stop state
MessageLoop::current()->PostTask(
@@ -399,26 +383,12 @@ PrinterJobHandler::HandlePrinterUpdateResponse(
}
CloudPrintURLFetcher::ResponseAction
-PrinterJobHandler::HandlePrinterDeleteResponse(
- const content::URLFetcher* source,
- const GURL& url,
- DictionaryValue* json_data,
- bool succeeded) {
- VLOG(1) << "CP_PROXY: Handler printer delete response, id: "
- << printer_info_cloud_.printer_id;
- // The printer has been deleted. Shutdown the handler class.
- MessageLoop::current()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Shutdown));
- return CloudPrintURLFetcher::STOP_PROCESSING;
-}
-
-CloudPrintURLFetcher::ResponseAction
PrinterJobHandler::HandleJobMetadataResponse(
const content::URLFetcher* source,
const GURL& url,
DictionaryValue* json_data,
bool succeeded) {
- VLOG(1) << "CP_PROXY: Handle job metadata response, id: "
+ VLOG(1) << "CP_CONNECTOR: Handle job metadata response, id: "
<< printer_info_cloud_.printer_id;
bool job_available = false;
if (succeeded) {
@@ -465,7 +435,7 @@ CloudPrintURLFetcher::ResponseAction
PrinterJobHandler::HandlePrintTicketResponse(const content::URLFetcher* source,
const GURL& url,
const std::string& data) {
- VLOG(1) << "CP_PROXY: Handle print ticket response, id: "
+ VLOG(1) << "CP_CONNECTOR: Handle print ticket response, id: "
<< printer_info_cloud_.printer_id;
if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) {
job_details_.print_ticket_ = data;
@@ -488,7 +458,7 @@ CloudPrintURLFetcher::ResponseAction
PrinterJobHandler::HandlePrintDataResponse(const content::URLFetcher* source,
const GURL& url,
const std::string& data) {
- VLOG(1) << "CP_PROXY: Handle print data response, id: "
+ VLOG(1) << "CP_CONNECTOR: Handle print data response, id: "
<< printer_info_cloud_.printer_id;
Task* next_task = NULL;
if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) {
@@ -518,7 +488,7 @@ PrinterJobHandler::HandleSuccessStatusUpdateResponse(
const GURL& url,
DictionaryValue* json_data,
bool succeeded) {
- VLOG(1) << "CP_PROXY: Handle success status update response, id: "
+ VLOG(1) << "CP_CONNECTOR: Handle success status update response, id: "
<< printer_info_cloud_.printer_id;
// 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.
@@ -545,7 +515,7 @@ PrinterJobHandler::HandleFailureStatusUpdateResponse(
const GURL& url,
DictionaryValue* json_data,
bool succeeded) {
- VLOG(1) << "CP_PROXY: Handle failure status update response, id: "
+ VLOG(1) << "CP_CONNECTOR: Handle failure status update response, id: "
<< printer_info_cloud_.printer_id;
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableMethod(this, &PrinterJobHandler::Stop));
@@ -554,7 +524,8 @@ PrinterJobHandler::HandleFailureStatusUpdateResponse(
// End Response handlers
void PrinterJobHandler::StartPrinting() {
- VLOG(1) << "CP_PROXY: Start printing, id: " << printer_info_cloud_.printer_id;
+ VLOG(1) << "CP_CONNECTOR: Start printing, id: "
+ << printer_info_cloud_.printer_id;
// We are done with the request object for now.
request_ = NULL;
if (!shutting_down_) {
@@ -570,14 +541,14 @@ void PrinterJobHandler::StartPrinting() {
}
void PrinterJobHandler::JobFailed(PrintJobError error) {
- VLOG(1) << "CP_PROXY: Job failed, id: " << printer_info_cloud_.printer_id;
+ VLOG(1) << "CP_CONNECTOR: Job failed, id: " << printer_info_cloud_.printer_id;
if (!shutting_down_) {
UpdateJobStatus(cloud_print::PRINT_JOB_STATUS_ERROR, error);
}
}
void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) {
- VLOG(1) << "CP_PROXY: Job spooled, printer id: "
+ VLOG(1) << "CP_CONNECTOR: Job spooled, printer id: "
<< printer_info_cloud_.printer_id << ", job id: " << local_job_id;
if (!shutting_down_) {
local_job_id_ = local_job_id;
@@ -587,7 +558,7 @@ void PrinterJobHandler::JobSpooled(cloud_print::PlatformJobId local_job_id) {
}
void PrinterJobHandler::Shutdown() {
- VLOG(1) << "CP_PROXY: Printer job handler shutdown, id: "
+ VLOG(1) << "CP_CONNECTOR: Printer job handler shutdown, id: "
<< printer_info_cloud_.printer_id;
Reset();
shutting_down_ = true;
@@ -596,20 +567,16 @@ void PrinterJobHandler::Shutdown() {
// remove the updater object from the list.
job_status_updater_list_.front()->Stop();
}
- if (delegate_) {
- delegate_->OnPrinterJobHandlerShutdown(this,
- printer_info_cloud_.printer_id);
- }
}
void PrinterJobHandler::UpdateJobStatus(cloud_print::PrintJobStatus status,
PrintJobError error) {
- VLOG(1) << "CP_PROXY: Update job status, id: "
+ VLOG(1) << "CP_CONNECTOR: Update job status, id: "
<< printer_info_cloud_.printer_id;
if (!shutting_down_) {
if (!job_details_.job_id_.empty()) {
- VLOG(1) << "CP_PROXY: Updating status, job id: " << job_details_.job_id_
- << ", status: " << status;
+ VLOG(1) << "CP_CONNECTOR: Updating status, job id: "
+ << job_details_.job_id_ << ", status: " << status;
if (error == SUCCESS) {
SetNextJSONHandler(
&PrinterJobHandler::HandleSuccessStatusUpdateResponse);
@@ -640,13 +607,12 @@ void PrinterJobHandler::SetNextDataHandler(DataHandler handler) {
}
bool PrinterJobHandler::HavePendingTasks() {
- return (job_check_pending_ || printer_update_pending_ ||
- printer_delete_pending_);
+ return (job_check_pending_ || printer_update_pending_);
}
void PrinterJobHandler::FailedFetchingJobData() {
if (!shutting_down_) {
- LOG(ERROR) << "CP_PROXY: Failed fetching job data for printer: " <<
+ LOG(ERROR) << "CP_CONNECTOR: Failed fetching job data for printer: " <<
printer_info_.printer_name << ", job id: " << job_details_.job_id_;
JobFailed(INVALID_JOB_DATA);
}
diff --git a/chrome/service/cloud_print/printer_job_handler.h b/chrome/service/cloud_print/printer_job_handler.h
index 1db7171..03b50f7 100644
--- a/chrome/service/cloud_print/printer_job_handler.h
+++ b/chrome/service/cloud_print/printer_job_handler.h
@@ -33,12 +33,12 @@ class URLFetcher;
// | Have Pending tasks
// |
// |
-// <----Delete Pending -- | ---Update Pending----->
-// | | |
-// | | |
-// | | |
-// Delete Printer from server | Update Printer info on server
-// Shutdown | Go to Stop
+// | ---Update Pending----->
+// | |
+// | |
+// | |
+// | Update Printer info on server
+// | Go to Stop
// |
// | Job Available
// |
@@ -88,14 +88,10 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
public:
class Delegate {
public:
- virtual void OnPrinterJobHandlerShutdown(
- PrinterJobHandler* job_handler, const std::string& printer_id) = 0;
+ // Notify delegate about authentication error.
virtual void OnAuthError() = 0;
- // Called when the PrinterJobHandler cannot find the printer locally. The
- // delegate returns |delete_from_server| to true if the printer should be
- // deleted from the server,false otherwise.
- virtual void OnPrinterNotFound(const std::string& printer_name,
- bool* delete_from_server) = 0;
+ // Notify delegate that printer has been deleted.
+ virtual void OnPrinterDeleted(const std::string& printer_name) = 0;
protected:
virtual ~Delegate() {}
@@ -115,6 +111,7 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
Delegate* delegate);
virtual ~PrinterJobHandler();
bool Initialize();
+ std::string GetPrinterName() const;
// Requests a job check. |reason| is the reason for fetching the job. Used
// for logging and diagnostc purposes.
void CheckForJobs(const std::string& reason);
@@ -143,7 +140,8 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
base::DictionaryValue* json_data,
bool succeeded);
virtual void OnRequestGiveUp();
- virtual void OnRequestAuthError();
+ virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError();
+ virtual std::string GetAuthHeader();
// JobStatusUpdater::Delegate implementation
virtual bool OnJobCompleted(JobStatusUpdater* updater);
@@ -180,12 +178,6 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
base::DictionaryValue* json_data,
bool succeeded);
- CloudPrintURLFetcher::ResponseAction HandlePrinterDeleteResponse(
- const content::URLFetcher* source,
- const GURL& url,
- base::DictionaryValue* json_data,
- bool succeeded);
-
CloudPrintURLFetcher::ResponseAction HandleJobMetadataResponse(
const content::URLFetcher* source,
const GURL& url,
@@ -288,7 +280,6 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>,
// Flags that specify various pending server updates
bool job_check_pending_;
bool printer_update_pending_;
- bool printer_delete_pending_;
// Some task in the state machine is in progress.
bool task_in_progress_;