Index: chrome/service/cloud_print/cloud_print_proxy_backend.cc |
=================================================================== |
--- chrome/service/cloud_print/cloud_print_proxy_backend.cc (revision 107156) |
+++ chrome/service/cloud_print/cloud_print_proxy_backend.cc (working copy) |
@@ -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,24 +73,18 @@ |
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(); |
+ // CloudPrintConnector::Client implementation. |
+ virtual void OnPrintersAvailable(const printing::PrinterList& printers); |
+ virtual void OnAuthFailed(); |
- // 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); |
- |
// notifier::TalkMediator::Delegate implementation. |
virtual void OnNotificationStateChange( |
bool notifications_enabled); |
@@ -105,62 +92,7 @@ |
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,38 +104,10 @@ |
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(); |
+ // Init XMPP channel |
+ void InitNotifications(const std::string& robot_email, |
+ const std::string& access_token); |
- // Callback method for GetPrinterCapsAndDefaults. |
- void OnReceivePrinterCaps( |
- bool succeeded, |
- const std::string& printer_name, |
- const printing::PrinterCapsAndDefaults& caps_and_defaults); |
- |
void HandlePrinterNotification(const std::string& printer_id); |
void PollForJobs(); |
// Schedules a task to poll for jobs. Does nothing if a task is already |
@@ -214,50 +118,16 @@ |
// 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 @@ |
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 @@ |
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 @@ |
frontend_(frontend) { |
DCHECK(frontend_); |
core_ = new Core(this, |
+ proxy_id, |
cloud_print_server_url, |
print_system_settings, |
oauth_client_info, |
@@ -379,25 +250,25 @@ |
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,151 @@ |
// 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); |
+ DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); |
+ auth_->AuthenticateWithRobotAuthCode(robot_oauth_auth_code, robot_email); |
} |
-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); |
- |
- 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_PROXY: Auth Error"; |
+ backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, |
+ &Core::NotifyAuthenticationFailed)); |
} |
-void CloudPrintProxyBackend::Core::EndRegistration() { |
+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_PROXY: 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::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(); |
- // 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(); |
- } |
+ if (connector_->IsRunning()) |
+ connector_->Stop(); |
+ |
// 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; |
+// request_ = NULL; |
Albert Bodenhamer
2011/10/26 23:58:09
Remove
|
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(); |
+ connector_->RegisterPrinters(printer_list); |
} |
-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); |
- } |
-} |
- |
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); |
+ connector_->CheckForJobs(kJobFetchReasonNotified, printer_id); |
} |
void CloudPrintProxyBackend::Core::PollForJobs() { |
VLOG(1) << "CP_PROXY: 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 +452,6 @@ |
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,246 +478,6 @@ |
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()); |
@@ -1078,91 +512,3 @@ |
} |
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; |
-} |