diff options
author | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-13 19:09:33 +0000 |
---|---|---|
committer | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-13 19:09:33 +0000 |
commit | b6c98a837a4af01daeaf36cf4beaa170c33df417 (patch) | |
tree | a36ffa952f27a3ac0424a880276d96b893ac78dd /chrome/service | |
parent | 84e6824ab0c0b979c7f9eee493f1057cef419fa7 (diff) | |
download | chromium_src-b6c98a837a4af01daeaf36cf4beaa170c33df417.zip chromium_src-b6c98a837a4af01daeaf36cf4beaa170c33df417.tar.gz chromium_src-b6c98a837a4af01daeaf36cf4beaa170c33df417.tar.bz2 |
The Cloud Print proxy now handles auth errors and disables the cloud print proxy. Also we detect loss of XMPP notifications and enter a job poll mode when we don't have notifications available.
BUG=None.
TEST=Test that the cloud print proxy disables itself when the token is invalid/expired. Also when the Talk token is invalid/expired, it should enter a job poll state.
Review URL: http://codereview.chromium.org/3374007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59257 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/service')
-rw-r--r-- | chrome/service/cloud_print/cloud_print_consts.h | 4 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy.cc | 6 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy.h | 1 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy_backend.cc | 161 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy_backend.h | 3 | ||||
-rw-r--r-- | chrome/service/cloud_print/job_status_updater.cc | 8 | ||||
-rw-r--r-- | chrome/service/cloud_print/job_status_updater.h | 1 | ||||
-rw-r--r-- | chrome/service/cloud_print/printer_job_handler.cc | 11 | ||||
-rw-r--r-- | chrome/service/cloud_print/printer_job_handler.h | 3 | ||||
-rw-r--r-- | chrome/service/service_process.cc | 14 | ||||
-rw-r--r-- | chrome/service/service_process.h | 2 |
11 files changed, 178 insertions, 36 deletions
diff --git a/chrome/service/cloud_print/cloud_print_consts.h b/chrome/service/cloud_print/cloud_print_consts.h index 33381dc..71f9225 100644 --- a/chrome/service/cloud_print/cloud_print_consts.h +++ b/chrome/service/cloud_print/cloud_print_consts.h @@ -43,6 +43,10 @@ const int64 kMaxRetryInterval = 5*60*1000; // 5 minutes in millseconds const int64 kBaseRetryInterval = 5*1000; // 5 seconds const int kMaxRetryCount = 2; const int64 kJobStatusUpdateInterval = 10*1000; // 10 seconds +// 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. +const int kMinJobPollIntervalSecs = 5*60; // 5 minutes in seconds +const int kMaxJobPollIntervalSecs = 8*60; // 8 minutes in seconds #endif // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_CONSTS_H_ diff --git a/chrome/service/cloud_print/cloud_print_proxy.cc b/chrome/service/cloud_print/cloud_print_proxy.cc index 41083cc..daa1fb3 100644 --- a/chrome/service/cloud_print/cloud_print_proxy.cc +++ b/chrome/service/cloud_print/cloud_print_proxy.cc @@ -115,3 +115,9 @@ void CloudPrintProxy::OnAuthenticated( service_prefs_->WritePrefs(); } +void CloudPrintProxy::OnAuthenticationFailed() { + DCHECK(CalledOnValidThread()); + // If authenticated failed, we will disable the cloud print proxy. + DisableForUser(); +} + diff --git a/chrome/service/cloud_print/cloud_print_proxy.h b/chrome/service/cloud_print/cloud_print_proxy.h index d682589..755337f 100644 --- a/chrome/service/cloud_print/cloud_print_proxy.h +++ b/chrome/service/cloud_print/cloud_print_proxy.h @@ -43,6 +43,7 @@ class CloudPrintProxy : public CloudPrintProxyFrontend, virtual void OnAuthenticated(const std::string& cloud_print_token, const std::string& cloud_print_xmpp_token, const std::string& email); + virtual void OnAuthenticationFailed(); protected: void Shutdown(); diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc index 865ec8e..993605f 100644 --- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc +++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc @@ -6,9 +6,11 @@ #include "base/file_util.h" #include "base/md5.h" +#include "base/rand_util.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/common/net/http_return.h" #include "chrome/service/cloud_print/cloud_print_consts.h" #include "chrome/service/cloud_print/cloud_print_helpers.h" #include "chrome/service/cloud_print/printer_job_handler.h" @@ -56,7 +58,6 @@ class CloudPrintProxyBackend::Core void DoShutdown(); void DoRegisterSelectedPrinters( const cloud_print::PrinterList& printer_list); - void DoHandlePrinterNotification(const std::string& printer_id); // URLFetcher::Delegate implementation. virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, @@ -67,16 +68,15 @@ class CloudPrintProxyBackend::Core // cloud_print::PrintServerWatcherDelegate implementation virtual void OnPrinterAdded(); // PrinterJobHandler::Delegate implementation - void OnPrinterJobHandlerShutdown(PrinterJobHandler* job_handler, + virtual void OnPrinterJobHandlerShutdown(PrinterJobHandler* job_handler, const std::string& printer_id); + virtual void OnAuthError(); // notifier::TalkMediator::Delegate implementation. virtual void OnNotificationStateChange( bool notifications_enabled); - virtual void OnIncomingNotification( const IncomingNotificationData& notification_data); - virtual void OnOutgoingNotification(); protected: @@ -107,6 +107,8 @@ class CloudPrintProxyBackend::Core const std::string& cloud_print_token, const std::string& cloud_print_xmpp_token, const std::string& email); + void NotifyAuthenticationFailed(); + // Starts a new printer registration process. void StartRegistration(); // Ends the printer registration process. @@ -126,6 +128,12 @@ class CloudPrintProxyBackend::Core // printer and print them. void InitJobHandlerForPrinter(DictionaryValue* printer_data); + void HandlePrinterNotification(const std::string& printer_id); + void PollForJobs(); + // Schedules a task to poll for jobs. Does nothing if a task is already + // scheduled. + void ScheduleJobPoll(); + // Our parent CloudPrintProxyBackend CloudPrintProxyBackend* backend_; @@ -166,6 +174,10 @@ class CloudPrintProxyBackend::Core bool new_printers_available_; // Notification (xmpp) handler. scoped_ptr<notifier::TalkMediator> talk_mediator_; + // Indicates whether XMPP notifications are currently enabled. + bool notifications_enabled_; + // Indicates whether a task to poll for jobs has been scheduled. + bool job_poll_scheduled_; DISALLOW_COPY_AND_ASSIGN(Core); }; @@ -227,21 +239,13 @@ void CloudPrintProxyBackend::RegisterPrinters( printer_list)); } -void CloudPrintProxyBackend::HandlePrinterNotification( - const std::string& printer_id) { - core_thread_.message_loop()->PostTask(FROM_HERE, - NewRunnableMethod( - core_.get(), - &CloudPrintProxyBackend::Core::DoHandlePrinterNotification, - printer_id)); -} - CloudPrintProxyBackend::Core::Core(CloudPrintProxyBackend* backend, const GURL& cloud_print_server_url, const DictionaryValue* print_system_settings) : backend_(backend), cloud_print_server_url_(cloud_print_server_url), next_upload_index_(0), server_error_count_(0), - next_response_handler_(NULL), new_printers_available_(false) { + next_response_handler_(NULL), new_printers_available_(false), + notifications_enabled_(false), job_poll_scheduled_(false) { if (print_system_settings) { // It is possible to have no print settings specified. print_system_settings_.reset( @@ -264,8 +268,7 @@ void CloudPrintProxyBackend::Core::DoInitializeWithLsid( user_agent, kSyncGaiaServiceId, kGaiaUrl, g_service_process->io_thread()->message_loop_proxy()); gaia_auth_for_talk->set_message_loop(MessageLoop::current()); - // TODO(sanjeevr): Handle auth failure case. We basically need to disable - // cloud print and shutdown. + bool auth_succeeded = false; if (gaia_auth_for_talk->AuthenticateWithLsid(lsid)) { scoped_refptr<ServiceGaiaAuthenticator> gaia_auth_for_print = new ServiceGaiaAuthenticator( @@ -273,16 +276,26 @@ void CloudPrintProxyBackend::Core::DoInitializeWithLsid( g_service_process->io_thread()->message_loop_proxy()); gaia_auth_for_print->set_message_loop(MessageLoop::current()); if (gaia_auth_for_print->AuthenticateWithLsid(lsid)) { + auth_succeeded = true; // Let the frontend know that we have authenticated. backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &Core::NotifyAuthenticated, gaia_auth_for_print->auth_token(), gaia_auth_for_talk->auth_token(), gaia_auth_for_talk->email())); + backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &Core::NotifyAuthenticated, gaia_auth_for_print->auth_token(), + gaia_auth_for_talk->auth_token(), gaia_auth_for_talk->email())); DoInitializeWithToken(gaia_auth_for_print->auth_token(), gaia_auth_for_talk->auth_token(), gaia_auth_for_talk->email(), proxy_id); } } + + if (!auth_succeeded) { + // Let the frontend know the of authentication failure. + backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &Core::NotifyAuthenticationFailed)); + } } void CloudPrintProxyBackend::Core::DoInitializeWithToken( @@ -323,6 +336,7 @@ void CloudPrintProxyBackend::Core::DoInitializeWithToken( } void CloudPrintProxyBackend::Core::StartRegistration() { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); printer_list_.clear(); print_system_->EnumeratePrinters(&printer_list_); server_error_count_ = 0; @@ -332,6 +346,7 @@ void CloudPrintProxyBackend::Core::StartRegistration() { } void CloudPrintProxyBackend::Core::EndRegistration() { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); request_.reset(); if (new_printers_available_) { new_printers_available_ = false; @@ -340,6 +355,7 @@ void CloudPrintProxyBackend::Core::EndRegistration() { } void CloudPrintProxyBackend::Core::DoShutdown() { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); LOG(INFO) << "CP_PROXY: Shutdown proxy, id: " << proxy_id_; if (print_server_watcher_ != NULL) print_server_watcher_->StopWatching(); @@ -351,28 +367,26 @@ void CloudPrintProxyBackend::Core::DoShutdown() { // remove this from the map. index->second->Shutdown(); } + // Important to delete the TalkMediator on this thread. + talk_mediator_.reset(); + notifications_enabled_ = false; + request_.reset(); + MessageLoop::current()->QuitNow(); } void CloudPrintProxyBackend::Core::DoRegisterSelectedPrinters( const cloud_print::PrinterList& printer_list) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); if (!print_system_.get()) return; // No print system available. server_error_count_ = 0; printer_list_.assign(printer_list.begin(), printer_list.end()); - DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); next_upload_index_ = 0; RegisterNextPrinter(); } -void CloudPrintProxyBackend::Core::DoHandlePrinterNotification( - const std::string& printer_id) { - LOG(INFO) << "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->NotifyJobAvailable(); -} - void CloudPrintProxyBackend::Core::GetRegisteredPrinters() { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); request_.reset( new URLFetcher( CloudPrintHelpers::GetUrlForPrinterList(cloud_print_server_url_, @@ -385,6 +399,7 @@ void CloudPrintProxyBackend::Core::GetRegisteredPrinters() { } 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()) { @@ -461,20 +476,63 @@ void CloudPrintProxyBackend::Core::RegisterNextPrinter() { } } +void CloudPrintProxyBackend::Core::HandlePrinterNotification( + const std::string& printer_id) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); + LOG(INFO) << "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->NotifyJobAvailable(); +} + +void CloudPrintProxyBackend::Core::PollForJobs() { + LOG(INFO) << "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++) { + index->second->NotifyJobAvailable(); + } + job_poll_scheduled_ = false; + // If we don't have notifications, poll again after a while. + if (!notifications_enabled_) { + ScheduleJobPoll(); + } +} + +void CloudPrintProxyBackend::Core::ScheduleJobPoll() { + if (!job_poll_scheduled_) { + int interval_in_seconds = base::RandInt(kMinJobPollIntervalSecs, + kMaxJobPollIntervalSecs); + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + NewRunnableMethod(this, &CloudPrintProxyBackend::Core::PollForJobs), + interval_in_seconds * 1000); + job_poll_scheduled_ = true; + } +} + // URLFetcher::Delegate implementation. void CloudPrintProxyBackend::Core::OnURLFetchComplete( const URLFetcher* source, const GURL& url, const URLRequestStatus& status, int response_code, const ResponseCookies& cookies, const std::string& data) { DCHECK(source == request_.get()); - // We need a next response handler - DCHECK(next_response_handler_); - (this->*next_response_handler_)(source, url, status, response_code, - cookies, data); + // If we get an auth error, we need to give up right away and notify the + // frontend loop. + if (RC_FORBIDDEN == response_code) { + backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &Core::NotifyAuthenticationFailed)); + } else { + // We need a next response handler + DCHECK(next_response_handler_); + (this->*next_response_handler_)(source, url, status, response_code, + cookies, data); + } } void CloudPrintProxyBackend::Core::NotifyPrinterListAvailable( const cloud_print::PrinterList& printer_list) { + DCHECK(MessageLoop::current() == backend_->frontend_loop_); backend_->frontend_->OnPrinterListAvailable(printer_list); } @@ -482,14 +540,21 @@ void CloudPrintProxyBackend::Core::NotifyAuthenticated( const std::string& cloud_print_token, const std::string& cloud_print_xmpp_token, const std::string& email) { + DCHECK(MessageLoop::current() == backend_->frontend_loop_); backend_->frontend_->OnAuthenticated(cloud_print_token, cloud_print_xmpp_token, email); } +void CloudPrintProxyBackend::Core::NotifyAuthenticationFailed() { + DCHECK(MessageLoop::current() == backend_->frontend_loop_); + backend_->frontend_->OnAuthenticationFailed(); +} + void CloudPrintProxyBackend::Core::HandlePrinterListResponse( const URLFetcher* source, const GURL& url, const URLRequestStatus& status, int response_code, const ResponseCookies& cookies, const std::string& data) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); bool succeeded = false; if (status.is_success() && response_code == 200) { server_error_count_ = 0; @@ -537,6 +602,7 @@ void CloudPrintProxyBackend::Core::HandlePrinterListResponse( 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); @@ -585,6 +651,7 @@ void CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse( const URLFetcher* source, const GURL& url, const URLRequestStatus& status, int response_code, const ResponseCookies& cookies, const std::string& data) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); LOG(INFO) << "CP_PROXY: Handle register printer response, code: " << response_code; Task* next_task = @@ -616,6 +683,7 @@ void CloudPrintProxyBackend::Core::HandleRegisterPrinterResponse( } void CloudPrintProxyBackend::Core::HandleServerError(Task* task_to_retry) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); LOG(INFO) << "CP_PROXY: Server error."; CloudPrintHelpers::HandleServerError( &server_error_count_, -1, kMaxRetryInterval, kBaseRetryInterval, @@ -624,6 +692,7 @@ void CloudPrintProxyBackend::Core::HandleServerError(Task* task_to_retry) { bool CloudPrintProxyBackend::Core::RemovePrinterFromList( const std::string& printer_name) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); bool ret = false; for (cloud_print::PrinterList::iterator index = printer_list_.begin(); index != printer_list_.end(); index++) { @@ -638,18 +707,30 @@ bool CloudPrintProxyBackend::Core::RemovePrinterFromList( } void CloudPrintProxyBackend::Core::OnNotificationStateChange( - bool notification_enabled) {} + bool notification_enabled) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); + bool previously_enabled = notifications_enabled_; + notifications_enabled_ = notification_enabled; + // If we lost notifications, we want to schedule a job poll. Also if + // notifications just got re-enabled, we want to poll once for jobs we might + // have missed when we were dark. + // Note that ScheduleJobPoll will not schedule again if a job poll task is + // already scheduled. + if (!notifications_enabled_) { + ScheduleJobPoll(); + } else if (!previously_enabled) { + PollForJobs(); + } +} + void CloudPrintProxyBackend::Core::OnIncomingNotification( const IncomingNotificationData& notification_data) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); LOG(INFO) << "CP_PROXY: Incoming notification."; if (0 == base::strcasecmp(kCloudPrintTalkServiceUrl, notification_data.service_url.c_str())) { - backend_->core_thread_.message_loop()->PostTask( - FROM_HERE, - NewRunnableMethod( - this, &CloudPrintProxyBackend::Core::DoHandlePrinterNotification, - notification_data.service_specific_data)); + HandlePrinterNotification(notification_data.service_specific_data); } } @@ -657,6 +738,7 @@ void CloudPrintProxyBackend::Core::OnOutgoingNotification() {} // cloud_print::PrinterChangeNotifier::Delegate implementation void CloudPrintProxyBackend::Core::OnPrinterAdded() { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); if (request_.get()) { new_printers_available_ = true; } else { @@ -667,6 +749,15 @@ void CloudPrintProxyBackend::Core::OnPrinterAdded() { // PrinterJobHandler::Delegate implementation void CloudPrintProxyBackend::Core::OnPrinterJobHandlerShutdown( PrinterJobHandler* job_handler, const std::string& printer_id) { + DCHECK(MessageLoop::current() == backend_->core_thread_.message_loop()); LOG(INFO) << "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()); + LOG(INFO) << "CP_PROXY: Auth Error"; + backend_->frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &Core::NotifyAuthenticationFailed)); +} + diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.h b/chrome/service/cloud_print/cloud_print_proxy_backend.h index 713e368..e5a82c7 100644 --- a/chrome/service/cloud_print/cloud_print_proxy_backend.h +++ b/chrome/service/cloud_print/cloud_print_proxy_backend.h @@ -33,6 +33,8 @@ class CloudPrintProxyFrontend { virtual void OnAuthenticated(const std::string& cloud_print_token, const std::string& cloud_print_xmpp_token, const std::string& email) = 0; + // We have invalid/expired credentials. + virtual void OnAuthenticationFailed() = 0; protected: // Don't delete through SyncFrontend interface. @@ -58,7 +60,6 @@ class CloudPrintProxyBackend { const std::string& proxy_id); void Shutdown(); void RegisterPrinters(const cloud_print::PrinterList& printer_list); - void HandlePrinterNotification(const std::string& printer_id); private: // The real guts of SyncBackendHost, to keep the public client API clean. diff --git a/chrome/service/cloud_print/job_status_updater.cc b/chrome/service/cloud_print/job_status_updater.cc index 8ef52de..7c7d1ca 100644 --- a/chrome/service/cloud_print/job_status_updater.cc +++ b/chrome/service/cloud_print/job_status_updater.cc @@ -7,6 +7,7 @@ #include "base/json/json_reader.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "chrome/common/net/http_return.h" #include "chrome/service/cloud_print/cloud_print_consts.h" #include "chrome/service/cloud_print/cloud_print_helpers.h" #include "googleurl/src/gurl.h" @@ -78,6 +79,13 @@ void JobStatusUpdater::OnURLFetchComplete(const URLFetcher* source, int response_code, const ResponseCookies& cookies, const std::string& data) { + // If there was an auth error, we are done. + if (RC_FORBIDDEN == response_code) { + if (delegate_) { + delegate_->OnAuthError(); + } + return; + } int64 next_update_interval = kJobStatusUpdateInterval; if (!status.is_success() || (response_code != 200)) { next_update_interval *= 10; diff --git a/chrome/service/cloud_print/job_status_updater.h b/chrome/service/cloud_print/job_status_updater.h index 4fa07eb..d617bde 100644 --- a/chrome/service/cloud_print/job_status_updater.h +++ b/chrome/service/cloud_print/job_status_updater.h @@ -26,6 +26,7 @@ class JobStatusUpdater : public base::RefCountedThreadSafe<JobStatusUpdater>, class Delegate { public: virtual bool OnJobCompleted(JobStatusUpdater* updater) = 0; + virtual void OnAuthError() = 0; protected: virtual ~Delegate() {} diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc index 36cc67e..caaffe3 100644 --- a/chrome/service/cloud_print/printer_job_handler.cc +++ b/chrome/service/cloud_print/printer_job_handler.cc @@ -10,6 +10,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/common/net/http_return.h" #include "chrome/service/cloud_print/cloud_print_consts.h" #include "chrome/service/cloud_print/cloud_print_helpers.h" #include "chrome/service/cloud_print/job_status_updater.h" @@ -219,6 +220,11 @@ void PrinterJobHandler::OnURLFetchComplete( const std::string& data) { LOG(INFO) << "CP_PROXY: Printer job handler, OnURLFetchComplete, url: " << url << ", response code: " << response_code; + // If there was an auth error, we are done. + if (RC_FORBIDDEN == response_code) { + OnAuthError(); + return; + } if (!shutting_down_) { DCHECK(source == request_.get()); // We need a next response handler because we are strictly a sequential @@ -249,6 +255,11 @@ bool PrinterJobHandler::OnJobCompleted(JobStatusUpdater* updater) { return ret; } +void PrinterJobHandler::OnAuthError() { + if (delegate_) + delegate_->OnAuthError(); +} + void PrinterJobHandler::OnPrinterDeleted() { printer_delete_pending_ = true; if (!task_in_progress_) { diff --git a/chrome/service/cloud_print/printer_job_handler.h b/chrome/service/cloud_print/printer_job_handler.h index ea7e9ec..2831fb90 100644 --- a/chrome/service/cloud_print/printer_job_handler.h +++ b/chrome/service/cloud_print/printer_job_handler.h @@ -91,6 +91,7 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, public: virtual void OnPrinterJobHandlerShutdown( PrinterJobHandler* job_handler, const std::string& printer_id) = 0; + virtual void OnAuthError() = 0; protected: virtual ~Delegate() {} @@ -127,6 +128,8 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, const std::string& data); // JobStatusUpdater::Delegate implementation virtual bool OnJobCompleted(JobStatusUpdater* updater); + virtual void OnAuthError(); + // cloud_print::PrinterWatcherDelegate implementation virtual void OnPrinterDeleted(); virtual void OnPrinterChanged(); diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index e7d9d03..69649b4 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc @@ -46,6 +46,10 @@ ServiceProcess* g_service_process = NULL; +// Delay in millseconds after the last service is disabled before we attempt +// a shutdown. +static const int64 kShutdownDelay = 60000; + ServiceProcess::ServiceProcess() : shutdown_event_(true, false), main_message_loop_(NULL), @@ -168,6 +172,16 @@ void ServiceProcess::OnServiceDisabled() { enabled_services_--; if (0 == enabled_services_) { RemoveServiceProcessFromAutoStart(); + // We will wait for some time to respond to IPCs before shutting down. + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + NewRunnableMethod(this, &ServiceProcess::ShutdownIfNoServices), + kShutdownDelay); + } +} + +void ServiceProcess::ShutdownIfNoServices() { + if (0 == enabled_services_) { Shutdown(); } } diff --git a/chrome/service/service_process.h b/chrome/service/service_process.h index 7b8a79f..96e112d 100644 --- a/chrome/service/service_process.h +++ b/chrome/service/service_process.h @@ -102,6 +102,8 @@ class ServiceProcess : public RemotingDirectoryService::Client, #endif private: + // Shuts down the process if no services are enabled. + void ShutdownIfNoServices(); // Called exactly ONCE per process instance for each service that gets // enabled in this process. void OnServiceEnabled(); |