summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-07 22:37:38 +0000
committersanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-07 22:37:38 +0000
commit17543d6da3e6078109e25358481fd3bbd98ab587 (patch)
tree9d92d94d76db72a6feb4becc2e7f77ec89ebcf10
parent4c974a138a20ec387ad0f347ca6d0804f26de74e (diff)
downloadchromium_src-17543d6da3e6078109e25358481fd3bbd98ab587.zip
chromium_src-17543d6da3e6078109e25358481fd3bbd98ab587.tar.gz
chromium_src-17543d6da3e6078109e25358481fd3bbd98ab587.tar.bz2
All communication with the cloud print proxy service from the browser now happens in the CloudPrintProxyService class. Added code to start the service process if the cloud print proxy was enabled. Also, when detect an auto-update, we send an IPC to the service process. The service process then shuts down when the browser disconnects.
BUG=None TEST=Unit-tests, test Cloud Print proxy UI, test that when an update is available, the service process shuts down when the browser does. TBR=phajdan.jr Review URL: http://codereview.chromium.org/3617008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61871 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser_main.cc6
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc82
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_proxy_service.h23
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc199
-rw-r--r--chrome/browser/printing/cloud_print/cloud_print_setup_flow.h14
-rw-r--r--chrome/browser/profile_impl.cc2
-rw-r--r--chrome/browser/profile_impl.h2
-rw-r--r--chrome/browser/service/service_process_control.cc22
-rw-r--r--chrome/browser/service/service_process_control.h12
-rw-r--r--chrome/browser/service/service_process_control_browsertest.cc40
-rw-r--r--chrome/browser/views/options/advanced_contents_view.cc15
-rw-r--r--chrome/common/service_messages_internal.h3
-rw-r--r--chrome/service/service_ipc_server.cc11
-rw-r--r--chrome/service/service_ipc_server.h1
-rw-r--r--chrome/service/service_process.cc16
-rw-r--r--chrome/service/service_process.h15
16 files changed, 220 insertions, 243 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 85d2c76..1e556d3 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -58,6 +58,7 @@
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_value_store.h"
+#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
#include "chrome/browser/process_singleton.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
@@ -1440,6 +1441,11 @@ int BrowserMain(const MainFunctionParams& parameters) {
}
}
+ // Create the instance of the cloud print proxy service so that it can launch
+ // the service process if needed. This is needed because the service process
+ // might have shutdown because an update was available.
+ profile->GetCloudPrintProxyService();
+
int result_code = ResultCodes::NORMAL_EXIT;
if (parameters.ui_task) {
// We are in test mode. Run one task and enter the main message loop.
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
index 1067923..20d0a73 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.cc
@@ -16,7 +16,10 @@
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
+#include "chrome/browser/service/service_process_control.h"
+#include "chrome/browser/service/service_process_control_manager.h"
#include "chrome/common/pref_names.h"
+#include "chrome/common/service_messages.h"
#include "grit/generated_resources.h"
// TODO(sanjeevr): Localize the product name?
@@ -51,25 +54,34 @@ CloudPrintProxyService::CloudPrintProxyService(Profile* profile)
}
CloudPrintProxyService::~CloudPrintProxyService() {
- Shutdown();
}
void CloudPrintProxyService::Initialize() {
+ if (profile_->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) &&
+ !profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty()) {
+ // If the cloud print proxy is enabled, establish a channel with the
+ // service process and update the status.
+ RefreshStatusFromService();
+ }
}
-
-void CloudPrintProxyService::EnableForUser(const std::string& auth_token) {
- // TODO(sanjeevr): Add code to communicate with the cloud print proxy code
- // running in the service process here.
+void CloudPrintProxyService::RefreshStatusFromService() {
+ InvokeServiceTask(
+ NewRunnableMethod(
+ this, &CloudPrintProxyService::RefreshCloudPrintProxyStatus));
}
-void CloudPrintProxyService::DisableForUser() {
- Shutdown();
+void CloudPrintProxyService::EnableForUser(const std::string& lsid,
+ const std::string& email) {
+ InvokeServiceTask(
+ NewRunnableMethod(
+ this, &CloudPrintProxyService::EnableCloudPrintProxy, lsid, email));
}
-void CloudPrintProxyService::Shutdown() {
- // TODO(sanjeevr): Add code to communicate with the cloud print proxy code
- // running in the service process here.
+void CloudPrintProxyService::DisableForUser() {
+ InvokeServiceTask(
+ NewRunnableMethod(
+ this, &CloudPrintProxyService::DisableCloudPrintProxy));
}
bool CloudPrintProxyService::ShowTokenExpiredNotification() {
@@ -126,3 +138,53 @@ void CloudPrintProxyService::OnDialogClosed() {
FROM_HERE, NewRunnableFunction(&BrowserList::EndKeepAlive));
}
+void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ ServiceProcessControl* process_control =
+ ServiceProcessControlManager::instance()->GetProcessControl(profile_);
+ DCHECK(process_control && process_control->is_connected());
+ if (process_control && process_control->is_connected()) {
+ Callback2<bool, std::string>::Type* callback =
+ NewCallback(this, &CloudPrintProxyService::StatusCallback);
+ // GetCloudPrintProxyStatus takes ownership of callback.
+ process_control->GetCloudPrintProxyStatus(callback);
+ }
+}
+
+void CloudPrintProxyService::EnableCloudPrintProxy(const std::string& lsid,
+ const std::string& email) {
+ ServiceProcessControl* process_control =
+ ServiceProcessControlManager::instance()->GetProcessControl(profile_);
+ DCHECK(process_control && process_control->is_connected());
+ if (process_control->is_connected()) {
+ process_control->Send(new ServiceMsg_EnableCloudPrintProxy(lsid));
+ // Assume the IPC worked.
+ profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, email);
+ }
+}
+
+void CloudPrintProxyService::DisableCloudPrintProxy() {
+ ServiceProcessControl* process_control =
+ ServiceProcessControlManager::instance()->GetProcessControl(profile_);
+ DCHECK(process_control && process_control->is_connected());
+ if (process_control->is_connected()) {
+ process_control->Send(new ServiceMsg_DisableCloudPrintProxy);
+ // Assume the IPC worked.
+ profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
+ }
+}
+
+void CloudPrintProxyService::StatusCallback(bool enabled, std::string email) {
+ profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail,
+ enabled ? email : std::string());
+}
+
+bool CloudPrintProxyService::InvokeServiceTask(Task* task) {
+ ServiceProcessControl* process_control =
+ ServiceProcessControlManager::instance()->GetProcessControl(profile_);
+ DCHECK(process_control);
+ if (process_control)
+ process_control->Launch(task);
+ return !!process_control;
+}
+
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h
index 538da2c..220cbd1 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h
@@ -17,7 +17,9 @@ class Profile;
// Layer between the browser user interface and the cloud print proxy code
// running in the service process.
-class CloudPrintProxyService : public CloudPrintSetupFlow::Delegate {
+class CloudPrintProxyService
+ : public CloudPrintSetupFlow::Delegate,
+ public base::RefCountedThreadSafe<CloudPrintProxyService> {
public:
explicit CloudPrintProxyService(Profile* profile);
virtual ~CloudPrintProxyService();
@@ -27,9 +29,13 @@ class CloudPrintProxyService : public CloudPrintSetupFlow::Delegate {
void Initialize();
// Enables/disables cloud printing for the user
- virtual void EnableForUser(const std::string& auth_token);
+ virtual void EnableForUser(const std::string& lsid, const std::string& email);
virtual void DisableForUser();
+ // Query the service process for the status of the cloud print proxy and
+ // update the browser prefs.
+ void RefreshStatusFromService();
+
bool ShowTokenExpiredNotification();
// CloudPrintSetupFlow::Delegate implementation.
@@ -43,7 +49,18 @@ class CloudPrintProxyService : public CloudPrintSetupFlow::Delegate {
Profile* profile_;
scoped_refptr<TokenExpiredNotificationDelegate> token_expired_delegate_;
- void Shutdown();
+ // Methods that send an IPC to the service.
+ void RefreshCloudPrintProxyStatus();
+ void EnableCloudPrintProxy(const std::string& lsid, const std::string& email);
+ void DisableCloudPrintProxy();
+
+ // Callback that gets the cloud print proxy status.
+ void StatusCallback(bool enabled, std::string email);
+ // Invoke a task that gets run after the service process successfully
+ // launches. The task typically involves sending an IPC to the service
+ // process.
+ bool InvokeServiceTask(Task* task);
+
void OnTokenExpiredNotificationError();
void OnTokenExpiredNotificationClosed(bool by_user);
void OnTokenExpiredNotificationClick();
diff --git a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc
index f74f980..e361062 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc
@@ -19,6 +19,7 @@
#endif // defined(TOOLKIT_GTK)
#include "chrome/browser/platform_util.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
#include "chrome/browser/printing/cloud_print/cloud_print_setup_message_handler.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/remoting/remoting_resources_source.h"
@@ -41,139 +42,6 @@ static const wchar_t kLoginIFrameXPath[] = L"//iframe[@id='login']";
static const wchar_t kDoneIframeXPath[] = L"//iframe[@id='done']";
////////////////////////////////////////////////////////////////////////////////
-// CloudPrintServiceProcessHelper
-//
-// This is a helper class to perform actions when the service process
-// is connected or launched. The events are sent back to CloudPrintSetupFlow
-// when the dialog is still active. CloudPrintSetupFlow can detach from this
-// helper class when the dialog is closed.
-
-class CloudPrintServiceProcessHelper
- : public base::RefCountedThreadSafe<CloudPrintServiceProcessHelper> {
- public:
- explicit CloudPrintServiceProcessHelper(CloudPrintSetupFlow* flow)
- : flow_(flow) {
- }
-
- void Detach() {
- flow_ = NULL;
- }
-
- void OnProcessLaunched() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- // If the flow is detached then show the done page.
- if (!flow_)
- return;
-
- flow_->OnProcessLaunched();
- }
-
- private:
- CloudPrintSetupFlow* flow_;
-
- DISALLOW_COPY_AND_ASSIGN(CloudPrintServiceProcessHelper);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// CloudPrintServiceDisableTask
-//
-// This is a helper class to get the proxy service launched if it
-// isn't, in order to properly inform it that it should be disabled.
-
-class CloudPrintServiceDisableTask
- : public base::RefCountedThreadSafe<CloudPrintServiceDisableTask> {
- public:
- explicit CloudPrintServiceDisableTask(Profile* profile)
- : profile_(profile),
- process_control_(NULL) {
- }
-
- void StartDisable() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
-
- process_control_ =
- ServiceProcessControlManager::instance()->GetProcessControl(profile_);
-
- if (process_control_) {
- // If the process isn't connected, launch it now. This will run
- // the task whether the process is already launched or not, as
- // long as it's able to connect back up.
- process_control_->Launch(
- NewRunnableMethod(
- this, &CloudPrintServiceDisableTask::OnProcessLaunched));
- }
- }
-
- void OnProcessLaunched() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- DCHECK(process_control_);
- if (process_control_->is_connected())
- process_control_->Send(new ServiceMsg_DisableCloudPrintProxy());
- profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
- }
-
- private:
- Profile* profile_;
- ServiceProcessControl* process_control_;
-
- DISALLOW_COPY_AND_ASSIGN(CloudPrintServiceDisableTask);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// CloudPrintServiceRefreshTask
-//
-// This is a helper class to perform a preferences refresh of the
-// enablement state and registered e-mail from the cloud print proxy
-// service.
-
-class CloudPrintServiceRefreshTask
- : public base::RefCountedThreadSafe<CloudPrintServiceRefreshTask> {
- public:
- explicit CloudPrintServiceRefreshTask(
- Profile* profile,
- Callback2<bool, std::string>::Type* callback)
- : profile_(profile),
- process_control_(NULL),
- callback_(callback) {
- DCHECK(callback);
- }
-
- void StartRefresh() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
-
- process_control_ =
- ServiceProcessControlManager::instance()->GetProcessControl(profile_);
-
- if (process_control_) {
- // If the process isn't connected, launch it now. This will run
- // the task whether the process is already launched or not, as
- // long as it's able to connect back up.
- process_control_->Launch(
- NewRunnableMethod(
- this, &CloudPrintServiceRefreshTask::OnProcessLaunched));
- }
- }
-
- void OnProcessLaunched() {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- DCHECK(process_control_);
-
- if (callback_ != NULL)
- process_control_->GetCloudPrintProxyStatus(callback_.release());
- }
-
- private:
- Profile* profile_;
- ServiceProcessControl* process_control_;
-
- // Callback that gets invoked when a status message is received from
- // the cloud print proxy.
- scoped_ptr<Callback2<bool, std::string>::Type> callback_;
-
- DISALLOW_COPY_AND_ASSIGN(CloudPrintServiceRefreshTask);
-};
-
-////////////////////////////////////////////////////////////////////////////////
// CloudPrintSetupFlow implementation.
// static
@@ -216,28 +84,6 @@ CloudPrintSetupFlow* CloudPrintSetupFlow::OpenDialog(
return flow;
}
-// static
-void CloudPrintSetupFlow::DisableCloudPrintProxy(Profile* profile) {
- scoped_refptr<CloudPrintServiceDisableTask> refresh_task =
- new CloudPrintServiceDisableTask(profile);
- ChromeThread::PostTask(
- ChromeThread::UI, FROM_HERE,
- NewRunnableMethod(refresh_task.get(),
- &CloudPrintServiceDisableTask::StartDisable));
-}
-
-// static
-void CloudPrintSetupFlow::RefreshPreferencesFromService(
- Profile* profile,
- Callback2<bool, std::string>::Type* callback) {
- scoped_refptr<CloudPrintServiceRefreshTask> refresh_task =
- new CloudPrintServiceRefreshTask(profile, callback);
- ChromeThread::PostTask(
- ChromeThread::UI, FROM_HERE,
- NewRunnableMethod(refresh_task.get(),
- &CloudPrintServiceRefreshTask::StartRefresh));
-}
-
CloudPrintSetupFlow::CloudPrintSetupFlow(const std::string& args,
Profile* profile,
Delegate* delegate)
@@ -296,12 +142,6 @@ void CloudPrintSetupFlow::OnDialogClosed(const std::string& json_retval) {
if (authenticator_.get())
authenticator_->CancelRequest();
- // If the service process helper is still active then detach outself from it.
- // This is because the dialog is closing and this object is going to be
- // deleted but the service process launch is still in progress so we don't
- // the service process helper to call us when the process is launched.
- if (service_process_helper_.get())
- service_process_helper_->Detach();
if (delegate_) {
delegate_->OnDialogClosed();
}
@@ -342,26 +182,10 @@ void CloudPrintSetupFlow::OnClientLoginSuccess(
ShowGaiaSuccessAndSettingUp();
authenticator_.reset();
- // And then launch the service process if it has not started yet.
- // If we have already connected to the service process then submit the tokens
- // to it to register the host.
- process_control_ =
- ServiceProcessControlManager::instance()->GetProcessControl(profile_);
-
-#if defined(OS_WIN)
- // TODO(hclam): This call only works on Windows. I need to make it
- // work on other platforms.
- service_process_helper_ = new CloudPrintServiceProcessHelper(this);
-
- // If the process isn't connected, launch it now. This will run the
- // task whether the process is already launched or not, as long as
- // it's able to connect back up.
- process_control_->Launch(
- NewRunnableMethod(service_process_helper_.get(),
- &CloudPrintServiceProcessHelper::OnProcessLaunched));
-#else
+ profile_->GetCloudPrintProxyService()->EnableForUser(credentials.lsid,
+ login_);
+ // TODO(sanjeevr): Should we wait and verify that the enable succeeded?
ShowSetupDone();
-#endif
}
///////////////////////////////////////////////////////////////////////////////
@@ -387,21 +211,6 @@ void CloudPrintSetupFlow::OnUserSubmittedAuth(const std::string& user,
}
///////////////////////////////////////////////////////////////////////////////
-// Method called by CloudPrintServiceProcessHelper
-void CloudPrintSetupFlow::OnProcessLaunched() {
- DCHECK(process_control_->is_connected());
- // TODO(scottbyer): Need to wait for an ACK to be sure that it is
- // actually active.
- if (!lsid_.empty())
- process_control_->Send(new ServiceMsg_EnableCloudPrintProxy(lsid_));
-
- // Save the preference that we have completed the setup of cloud
- // print.
- profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, login_);
- ShowSetupDone();
-}
-
-///////////////////////////////////////////////////////////////////////////////
// Helper methods for showing contents of the DOM UI
void CloudPrintSetupFlow::ShowGaiaLogin(const DictionaryValue& args) {
if (dom_ui_)
diff --git a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.h b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.h
index 453c1e3..d79e578 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.h
+++ b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.h
@@ -56,15 +56,6 @@ class CloudPrintSetupFlow : public HtmlDialogUIDelegate,
static CloudPrintSetupFlow* OpenDialog(Profile* service, Delegate* delegate,
gfx::NativeWindow parent_window);
- // Disables the cloud print proxy if it's enabled and running.
- static void DisableCloudPrintProxy(Profile* profile);
-
- // Ping the cloud print proxy service in order to get the true
- // enablement state and user e-mail that the service is using, and
- // reflect those back into the browser preferences.
- static void RefreshPreferencesFromService(
- Profile* profile, Callback2<bool, std::string>::Type* callback);
-
// Focuses the dialog. This is useful in cases where the dialog has been
// obscured by a browser window.
void Focus();
@@ -105,9 +96,6 @@ class CloudPrintSetupFlow : public HtmlDialogUIDelegate,
const std::string& password,
const std::string& captcha);
- // Event triggered when the service process was launched.
- void OnProcessLaunched();
-
// The following methods control which iframe is visible.
void ShowGaiaLogin(const DictionaryValue& args);
void ShowGaiaSuccessAndSettingUp();
@@ -131,8 +119,6 @@ class CloudPrintSetupFlow : public HtmlDialogUIDelegate,
// Handle to the ServiceProcessControl which talks to the service process.
ServiceProcessControl* process_control_;
- scoped_refptr<CloudPrintServiceProcessHelper> service_process_helper_;
-
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(CloudPrintSetupFlow);
diff --git a/chrome/browser/profile_impl.cc b/chrome/browser/profile_impl.cc
index b89057d..af95572 100644
--- a/chrome/browser/profile_impl.cc
+++ b/chrome/browser/profile_impl.cc
@@ -1242,7 +1242,7 @@ void ProfileImpl::InitSyncService(const std::string& cros_user) {
}
void ProfileImpl::InitCloudPrintProxyService() {
- cloud_print_proxy_service_.reset(new CloudPrintProxyService(this));
+ cloud_print_proxy_service_ = new CloudPrintProxyService(this);
cloud_print_proxy_service_->Initialize();
}
diff --git a/chrome/browser/profile_impl.h b/chrome/browser/profile_impl.h
index 25a38a9..efa00c1 100644
--- a/chrome/browser/profile_impl.h
+++ b/chrome/browser/profile_impl.h
@@ -179,7 +179,7 @@ class ProfileImpl : public Profile,
scoped_ptr<TokenService> token_service_;
scoped_ptr<ProfileSyncFactory> profile_sync_factory_;
scoped_ptr<ProfileSyncService> sync_service_;
- scoped_ptr<CloudPrintProxyService> cloud_print_proxy_service_;
+ scoped_refptr<CloudPrintProxyService> cloud_print_proxy_service_;
scoped_refptr<ChromeURLRequestContextGetter> request_context_;
diff --git a/chrome/browser/service/service_process_control.cc b/chrome/browser/service/service_process_control.cc
index 6790b00..22ad863 100644
--- a/chrome/browser/service/service_process_control.cc
+++ b/chrome/browser/service/service_process_control.cc
@@ -11,8 +11,10 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/io_thread.h"
+#include "chrome/browser/upgrade_detector.h"
#include "chrome/common/child_process_host.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/service_messages.h"
#include "chrome/common/service_process_util.h"
@@ -108,6 +110,16 @@ void ServiceProcessControl::ConnectInternal(Task* task) {
io_thread->message_loop(), true,
g_browser_process->shutdown_event()));
channel_->set_sync_messages_with_no_timeout_allowed(false);
+
+ // We just established a channel with the service process. Notify it if an
+ // upgrade is available.
+ if (Singleton<UpgradeDetector>::get()->notify_upgrade()) {
+ Send(new ServiceMsg_UpdateAvailable);
+ } else {
+ if (registrar_.IsEmpty())
+ registrar_.Add(this, NotificationType::UPGRADE_RECOMMENDED,
+ NotificationService::AllSources());
+ }
}
void ServiceProcessControl::Launch(Task* task) {
@@ -200,6 +212,16 @@ bool ServiceProcessControl::Send(IPC::Message* message) {
return channel_->Send(message);
}
+// NotificationObserver implementation.
+void ServiceProcessControl::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::UPGRADE_RECOMMENDED) {
+ Send(new ServiceMsg_UpdateAvailable);
+ }
+}
+
+
void ServiceProcessControl::OnGoodDay() {
if (!message_handler_)
return;
diff --git a/chrome/browser/service/service_process_control.h b/chrome/browser/service/service_process_control.h
index 021b669..e6df376 100644
--- a/chrome/browser/service/service_process_control.h
+++ b/chrome/browser/service/service_process_control.h
@@ -13,6 +13,8 @@
#include "base/process.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
#include "ipc/ipc_sync_channel.h"
class Profile;
@@ -28,7 +30,8 @@ class Profile;
// This class is accessed on the UI thread through some UI actions. It then
// talks to the IPC channel on the IO thread.
class ServiceProcessControl : public IPC::Channel::Sender,
- public IPC::Channel::Listener {
+ public IPC::Channel::Listener,
+ public NotificationObserver {
public:
typedef IDMap<ServiceProcessControl>::iterator iterator;
typedef std::queue<IPC::Message> MessageQueue;
@@ -67,6 +70,11 @@ class ServiceProcessControl : public IPC::Channel::Sender,
// IPC::Channel::Sender implementation
virtual bool Send(IPC::Message* message);
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
// Message handlers
void OnGoodDay();
void OnCloudPrintProxyIsEnabled(bool enabled, std::string email);
@@ -127,6 +135,8 @@ class ServiceProcessControl : public IPC::Channel::Sender,
// Handler for messages from service process.
MessageHandler* message_handler_;
+
+ NotificationRegistrar registrar_;
};
#endif // CHROME_BROWSER_SERVICE_SERVICE_PROCESS_CONTROL_H_
diff --git a/chrome/browser/service/service_process_control_browsertest.cc b/chrome/browser/service/service_process_control_browsertest.cc
index 391f99f..e48a60c 100644
--- a/chrome/browser/service/service_process_control_browsertest.cc
+++ b/chrome/browser/service/service_process_control_browsertest.cc
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/test/in_process_browser_test.h"
-#include "chrome/test/ui_test_utils.h"
+#include "base/test/test_timeouts.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/service/service_process_control_manager.h"
+#include "chrome/common/service_process_util.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
class ServiceProcessControlBrowserTest
: public InProcessBrowserTest,
@@ -29,11 +31,32 @@ class ServiceProcessControlBrowserTest
}
void SayHelloAndWait() {
- // Send a hello message to the service process and wait for a reply.
+ // Send a hello message to the service process and wait for a reply.
process()->SendHello();
ui_test_utils::RunMessageLoop();
}
+ void DisconnectAndWaitForShutdown() {
+ // This will delete all instances of ServiceProcessControl and close the IPC
+ // connections.
+ ServiceProcessControlManager::instance()->Shutdown();
+ process_ = NULL;
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ NewRunnableMethod(this,
+ &ServiceProcessControlBrowserTest::DoDetectShutdown),
+ TestTimeouts::wait_for_terminate_timeout_ms());
+ ui_test_utils::RunMessageLoop();
+ }
+
+
+ void DoDetectShutdown() {
+ EXPECT_FALSE(CheckServiceProcessRunning());
+ // Quit the current message loop.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ new MessageLoop::QuitTask());
+ }
+
void ProcessControlLaunched() {
process()->SetMessageHandler(this);
// Quit the current message.
@@ -85,6 +108,17 @@ IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchTwice) {
// And then shutdown the service process.
EXPECT_TRUE(process()->Shutdown());
}
+
+// Tests whether disconnecting from the service IPC causes the service process
+// to die.
+IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, DieOnDisconnect) {
+ // Launch the service process the first time.
+ LaunchServiceProcessControl();
+ // Make sure we are connected to the service process.
+ EXPECT_TRUE(process()->is_connected());
+ DisconnectAndWaitForShutdown();
+}
+
#endif
DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcessControlBrowserTest);
diff --git a/chrome/browser/views/options/advanced_contents_view.cc b/chrome/browser/views/options/advanced_contents_view.cc
index 2212d89..d066c0f 100644
--- a/chrome/browser/views/options/advanced_contents_view.cc
+++ b/chrome/browser/views/options/advanced_contents_view.cc
@@ -32,6 +32,7 @@
#include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_set_observer.h"
+#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
#include "chrome/browser/printing/cloud_print/cloud_print_url.h"
#include "chrome/browser/profile.h"
@@ -1377,9 +1378,6 @@ class CloudPrintProxySection : public AdvancedSection,
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
- // Callback that gets the cloud print proxy status.
- void StatusCallback(bool enabled, std::string email);
-
// CloudPrintSetupFlow::Delegate implementation.
virtual void OnDialogClosed();
@@ -1421,7 +1419,7 @@ void CloudPrintProxySection::ButtonPressed(views::Button* sender,
// Enabled, we must be the disable button.
UserMetricsRecordAction(
UserMetricsAction("Options_DisableCloudPrintProxy"), NULL);
- CloudPrintSetupFlow::DisableCloudPrintProxy(profile());
+ profile()->GetCloudPrintProxyService()->DisableForUser();
} else {
UserMetricsRecordAction(
UserMetricsAction("Options_EnableCloudPrintProxy"), NULL);
@@ -1444,11 +1442,6 @@ void CloudPrintProxySection::ButtonPressed(views::Button* sender,
}
}
-void CloudPrintProxySection::StatusCallback(bool enabled, std::string email) {
- profile()->GetPrefs()->SetString(prefs::kCloudPrintEmail,
- enabled ? email : std::string());
-}
-
void CloudPrintProxySection::OnDialogClosed() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
enable_disable_button_->SetEnabled(true);
@@ -1498,9 +1491,7 @@ void CloudPrintProxySection::InitControlLayout() {
// Kick off a task to ask the background service what the real
// answer is.
- CloudPrintSetupFlow::RefreshPreferencesFromService(
- profile(),
- factory_.NewCallback(&CloudPrintProxySection::StatusCallback));
+ profile()->GetCloudPrintProxyService()->RefreshStatusFromService();
}
void CloudPrintProxySection::NotifyPrefChanged(const std::string* pref_name) {
diff --git a/chrome/common/service_messages_internal.h b/chrome/common/service_messages_internal.h
index bdacb34..bb6e34d 100644
--- a/chrome/common/service_messages_internal.h
+++ b/chrome/common/service_messages_internal.h
@@ -45,6 +45,9 @@ IPC_BEGIN_MESSAGES(Service)
// Tell the service process to shutdown.
IPC_MESSAGE_CONTROL0(ServiceMsg_Shutdown)
+ // Tell the service process that an update is available.
+ IPC_MESSAGE_CONTROL0(ServiceMsg_UpdateAvailable)
+
IPC_END_MESSAGES(Service)
//------------------------------------------------------------------------------
diff --git a/chrome/service/service_ipc_server.cc b/chrome/service/service_ipc_server.cc
index f912701..ae80d42 100644
--- a/chrome/service/service_ipc_server.cc
+++ b/chrome/service/service_ipc_server.cc
@@ -61,8 +61,11 @@ void ServiceIPCServer::OnChannelError() {
// client requests, we will recreate the channel.
bool client_was_connected = client_connected_;
client_connected_ = false;
- if (client_was_connected)
+ // TODO(sanjeevr): Instead of invoking the service process for such handlers,
+ // define a Client interface that the ServiceProcess can implement.
+ if (client_was_connected && g_service_process->HandleClientDisconnect()) {
CreateChannel();
+ }
}
bool ServiceIPCServer::Send(IPC::Message* msg) {
@@ -88,6 +91,7 @@ void ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
OnIsCloudPrintProxyEnabled)
IPC_MESSAGE_HANDLER(ServiceMsg_Hello, OnHello);
IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown);
+ IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable);
IPC_END_MESSAGE_MAP()
}
@@ -129,3 +133,8 @@ void ServiceIPCServer::OnHello() {
void ServiceIPCServer::OnShutdown() {
g_service_process->Shutdown();
}
+
+void ServiceIPCServer::OnUpdateAvailable() {
+ g_service_process->SetUpdateAvailable();
+}
+
diff --git a/chrome/service/service_ipc_server.h b/chrome/service/service_ipc_server.h
index 1c8c19b..79416a5 100644
--- a/chrome/service/service_ipc_server.h
+++ b/chrome/service/service_ipc_server.h
@@ -51,6 +51,7 @@ class ServiceIPCServer : public IPC::Channel::Listener,
void OnDisableCloudPrintProxy();
void OnHello();
void OnShutdown();
+ void OnUpdateAvailable();
// Helper method to create the sync channel.
void CreateChannel();
diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc
index 86d787b..db562c3 100644
--- a/chrome/service/service_process.cc
+++ b/chrome/service/service_process.cc
@@ -52,7 +52,8 @@ static const int64 kShutdownDelay = 60000;
ServiceProcess::ServiceProcess()
: shutdown_event_(true, false),
main_message_loop_(NULL),
- enabled_services_(0) {
+ enabled_services_(0),
+ update_available_(false) {
DCHECK(!g_service_process);
g_service_process = this;
}
@@ -150,6 +151,17 @@ void ServiceProcess::Shutdown() {
main_message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}
+bool ServiceProcess::HandleClientDisconnect() {
+ // If there are no enabled services or if there is an update available
+ // we want to shutdown right away. Else we want to keep listening for
+ // new connections.
+ if (!enabled_services_ || update_available()) {
+ Shutdown();
+ return false;
+ }
+ return true;
+}
+
CloudPrintProxy* ServiceProcess::GetCloudPrintProxy() {
if (!cloud_print_proxy_.get()) {
cloud_print_proxy_.reset(new CloudPrintProxy());
@@ -180,7 +192,7 @@ void ServiceProcess::OnServiceEnabled() {
}
void ServiceProcess::OnServiceDisabled() {
- DCHECK(0 != enabled_services_);
+ DCHECK_NE(enabled_services_, 0);
enabled_services_--;
if (0 == enabled_services_) {
RemoveServiceProcessFromAutoStart();
diff --git a/chrome/service/service_process.h b/chrome/service/service_process.h
index 3e99d21..a8a5e5a 100644
--- a/chrome/service/service_process.h
+++ b/chrome/service/service_process.h
@@ -6,6 +6,8 @@
#define CHROME_SERVICE_SERVICE_PROCESS_H_
#pragma once
+#include <string>
+
#include "base/gtest_prod_util.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
@@ -74,6 +76,16 @@ class ServiceProcess : public RemotingDirectoryService::Client,
// Shutdown the service process. This is likely triggered by a IPC message.
void Shutdown();
+ void SetUpdateAvailable() {
+ update_available_ = true;
+ }
+ bool update_available() const { return update_available_; }
+
+ // Called by the IPC server when a client disconnects. A return value of
+ // true indicates that the IPC server should continue listening for new
+ // connections.
+ bool HandleClientDisconnect();
+
CloudPrintProxy* GetCloudPrintProxy();
// CloudPrintProxy::Client implementation.
@@ -168,6 +180,9 @@ class ServiceProcess : public RemotingDirectoryService::Client,
// Count of currently enabled services in this process.
int enabled_services_;
+ // Speficies whether a product update is available.
+ bool update_available_;
+
DISALLOW_COPY_AND_ASSIGN(ServiceProcess);
};