summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
};