Cloud print connector policy.

This implements the policy inside the browser process, shutting down the cloud
print connector if the policy is set to disabled. This isn't a complete
solution, as the browser needs to be running or be launched for the policy to
take effect. (It will take a lot more refactoring for the service process to
use the policy code). The hole without the refactoring is that if you enable
the connector, quit Chromium, and set the policy, the connector will stay alive
until the next launch of Chromium.

The browser process checks the policy on startup, and listens for it changing
as long as it is up. You can sit on the Under the Hood page and watch the
button change state on Windows as you fiddle with the policy.

BUG=59769
TEST=Set Cloud Print Proxy policy to disabled, bring up browser, Options/Under
the Hood - Sign in to Google Cloud print will be disabled.  Unset policy, wait,
button becomes active.  Log in to cloud print.  Quit Chromium, note service
process hangs around for more than a minute.  Set policy, launch and quit
Chromium. Note that the service process quits within a minute.


Review URL: http://codereview.chromium.org/8438020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110332 0039d316-1c4b-4281-b951-d872f2087c98
parent 19432bb9
......@@ -424,9 +424,8 @@
{
'name': 'CloudPrintProxyEnabled',
'type': 'main',
'supported_on': ['chrome.*:X-'],
'supported_on': ['chrome.*:17-'],
'features': {'dynamic_refresh': 1},
'future': True,
'example_value': True,
'id': 13,
'caption': '''Enable <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> proxy''',
......
......@@ -19,6 +19,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/cloud_print/cloud_print_proxy_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/service_messages.h"
......@@ -66,11 +67,17 @@ CloudPrintProxyService::~CloudPrintProxyService() {
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.
(!profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty() ||
!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled))) {
// If the cloud print proxy is enabled, or the policy preventing it from
// being enabled is set, establish a channel with the service process and
// update the status. This will check the policy when the status is sent
// back.
RefreshStatusFromService();
}
pref_change_registrar_.Init(profile_->GetPrefs());
pref_change_registrar_.Add(prefs::kCloudPrintProxyEnabled, this);
}
void CloudPrintProxyService::RefreshStatusFromService() {
......@@ -81,22 +88,25 @@ void CloudPrintProxyService::RefreshStatusFromService() {
void CloudPrintProxyService::EnableForUser(const std::string& lsid,
const std::string& email) {
InvokeServiceTask(
base::Bind(&CloudPrintProxyService::EnableCloudPrintProxy,
weak_factory_.GetWeakPtr(), lsid, email));
if (profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
InvokeServiceTask(
base::Bind(&CloudPrintProxyService::EnableCloudPrintProxy,
weak_factory_.GetWeakPtr(), lsid, email));
}
}
void CloudPrintProxyService::EnableForUserWithRobot(
const std::string& robot_auth_code,
const std::string& robot_email,
const std::string& user_email) {
InvokeServiceTask(
base::Bind(&CloudPrintProxyService::EnableCloudPrintProxyWithRobot,
weak_factory_.GetWeakPtr(), robot_auth_code, robot_email,
user_email));
if (profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
InvokeServiceTask(
base::Bind(&CloudPrintProxyService::EnableCloudPrintProxyWithRobot,
weak_factory_.GetWeakPtr(), robot_auth_code, robot_email,
user_email));
}
}
void CloudPrintProxyService::DisableForUser() {
InvokeServiceTask(
base::Bind(&CloudPrintProxyService::DisableCloudPrintProxy,
......@@ -153,14 +163,36 @@ void CloudPrintProxyService::TokenExpiredNotificationDone(bool keep_alive) {
}
}
void CloudPrintProxyService::ApplyCloudPrintConnectorPolicy() {
if (!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
std::string email;
email = profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail);
if (!email.empty()) {
DisableForUser();
profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
}
}
}
void CloudPrintProxyService::OnCloudPrintSetupClosed() {
MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&BrowserList::EndKeepAlive));
}
void CloudPrintProxyService::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type == chrome::NOTIFICATION_PREF_CHANGED) {
ApplyCloudPrintConnectorPolicy();
} else {
NOTREACHED();
}
}
void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
ServiceProcessControl* process_control = ServiceProcessControl::GetInstance();
ServiceProcessControl* process_control = GetServiceProcessControl();
DCHECK(process_control->is_connected());
ServiceProcessControl::CloudPrintProxyInfoHandler callback =
base::Bind(&CloudPrintProxyService::ProxyInfoCallback,
......@@ -171,7 +203,7 @@ void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
void CloudPrintProxyService::EnableCloudPrintProxy(const std::string& lsid,
const std::string& email) {
ServiceProcessControl* process_control = ServiceProcessControl::GetInstance();
ServiceProcessControl* process_control = GetServiceProcessControl();
DCHECK(process_control->is_connected());
process_control->Send(new ServiceMsg_EnableCloudPrintProxy(lsid));
// Assume the IPC worked.
......@@ -182,7 +214,7 @@ void CloudPrintProxyService::EnableCloudPrintProxyWithRobot(
const std::string& robot_auth_code,
const std::string& robot_email,
const std::string& user_email) {
ServiceProcessControl* process_control = ServiceProcessControl::GetInstance();
ServiceProcessControl* process_control = GetServiceProcessControl();
DCHECK(process_control->is_connected());
process_control->Send(new ServiceMsg_EnableCloudPrintProxyWithRobot(
robot_auth_code,
......@@ -192,9 +224,8 @@ void CloudPrintProxyService::EnableCloudPrintProxyWithRobot(
profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, user_email);
}
void CloudPrintProxyService::DisableCloudPrintProxy() {
ServiceProcessControl* process_control = ServiceProcessControl::GetInstance();
ServiceProcessControl* process_control = GetServiceProcessControl();
DCHECK(process_control->is_connected());
process_control->Send(new ServiceMsg_DisableCloudPrintProxy);
// Assume the IPC worked.
......@@ -207,9 +238,14 @@ void CloudPrintProxyService::ProxyInfoCallback(
profile_->GetPrefs()->SetString(
prefs::kCloudPrintEmail,
proxy_info.enabled ? proxy_info.email : std::string());
ApplyCloudPrintConnectorPolicy();
}
bool CloudPrintProxyService::InvokeServiceTask(const base::Closure& task) {
ServiceProcessControl::GetInstance()->Launch(task, base::Closure());
GetServiceProcessControl()->Launch(task, base::Closure());
return true;
}
ServiceProcessControl* CloudPrintProxyService::GetServiceProcessControl() {
return ServiceProcessControl::GetInstance();
}
......@@ -12,10 +12,13 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/task.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/browser/printing/cloud_print/cloud_print_setup_handler.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "content/public/browser/notification_observer.h"
class Profile;
class ServiceProcessControl;
namespace cloud_print {
struct CloudPrintProxyInfo;
......@@ -25,7 +28,8 @@ struct CloudPrintProxyInfo;
// running in the service process.
class CloudPrintProxyService
: public CloudPrintSetupHandlerDelegate,
public ProfileKeyedService {
public ProfileKeyedService,
public content::NotificationObserver {
public:
explicit CloudPrintProxyService(Profile* profile);
virtual ~CloudPrintProxyService();
......@@ -51,6 +55,11 @@ class CloudPrintProxyService
// CloudPrintSetupHandler::Delegate implementation.
virtual void OnCloudPrintSetupClosed();
// content::NotificationObserver implementation.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
private:
// NotificationDelegate implementation for the token expired notification.
class TokenExpiredNotificationDelegate;
......@@ -82,9 +91,16 @@ class CloudPrintProxyService
void OnTokenExpiredNotificationClosed(bool by_user);
void OnTokenExpiredNotificationClick();
void TokenExpiredNotificationDone(bool keep_alive);
void ApplyCloudPrintConnectorPolicy();
// Virtual for testing.
virtual ServiceProcessControl* GetServiceProcessControl();
base::WeakPtrFactory<CloudPrintProxyService> weak_factory_;
// For watching for connector enablement policy changes.
PrefChangeRegistrar pref_change_registrar_;
DISALLOW_COPY_AND_ASSIGN(CloudPrintProxyService);
};
......
......@@ -78,6 +78,10 @@ void ServiceProcessControl::RunAllTasksHelper(TaskList* task_list) {
}
}
bool ServiceProcessControl::is_connected() const {
return channel_.get() != NULL;
}
void ServiceProcessControl::Launch(const base::Closure& success_task,
const base::Closure& failure_task) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
......
......@@ -48,8 +48,10 @@ class ServiceProcessControl : public IPC::Channel::Sender,
// Returns the singleton instance of this class.
static ServiceProcessControl* GetInstance();
// Return true if this object is connected to the service.
bool is_connected() const { return channel_.get() != NULL; }
// Virtual for testing.
virtual bool is_connected() const;
// If no service process is currently running, creates a new service process
// and connects to it. If a service process is already running this method
......@@ -61,11 +63,13 @@ class ServiceProcessControl : public IPC::Channel::Sender,
// this case, the task is invoked on success or failure.
// Note that if we are already connected to service process then
// |success_task| can be invoked in the context of the Launch call.
void Launch(const base::Closure& success_task,
const base::Closure& failure_task);
// Virtual for testing.
virtual void Launch(const base::Closure& success_task,
const base::Closure& failure_task);
// Disconnect the IPC channel from the service process.
void Disconnect();
// Virtual for testing.
virtual void Disconnect();
// IPC::Channel::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
......@@ -87,7 +91,8 @@ class ServiceProcessControl : public IPC::Channel::Sender,
// Send a shutdown message to the service process. IPC channel will be
// destroyed after calling this method.
// Return true if the message was sent.
bool Shutdown();
// Virtual for testing.
virtual bool Shutdown();
// Send request for cloud print proxy info (enabled state, email, proxy id).
// The callback gets the information when received.
......@@ -125,6 +130,7 @@ class ServiceProcessControl : public IPC::Channel::Sender,
uint32 retry_count_;
};
friend class MockServiceProcessControl;
ServiceProcessControl();
virtual ~ServiceProcessControl();
......
......@@ -1529,6 +1529,7 @@
'browser/prerender/prerender_manager_unittest.cc',
'browser/prerender/prerender_tracker_unittest.cc',
'browser/prerender/prerender_util_unittest.cc',
'browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc',
'browser/printing/cloud_print/cloud_print_setup_source_unittest.cc',
'browser/printing/print_dialog_cloud_unittest.cc',
'browser/printing/print_job_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment