Add GCMChannelStatusSyncer to schedule requests and enable/disable GCM
[chromium-blink-merge.git] / chrome / browser / printing / cloud_print / cloud_print_proxy_service.cc
blob546f1129ed1d687c49f0978ddabe69808d54f951
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
7 #include <stack>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/command_line.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/lifetime/application_lifetime.h"
22 #include "chrome/browser/notifications/desktop_notification_service.h"
23 #include "chrome/browser/notifications/notification.h"
24 #include "chrome/browser/notifications/notification_ui_manager.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/service_process/service_process_control.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/cloud_print/cloud_print_proxy_info.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/service_messages.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "printing/backend/print_backend.h"
34 using content::BrowserThread;
36 CloudPrintProxyService::CloudPrintProxyService(Profile* profile)
37 : profile_(profile),
38 enforcing_connector_policy_(false),
39 weak_factory_(this) {
42 CloudPrintProxyService::~CloudPrintProxyService() {
45 void CloudPrintProxyService::Initialize() {
46 DCHECK_CURRENTLY_ON(BrowserThread::UI);
47 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
48 ServiceProcessControl::SERVICE_EVENT_INITIALIZE,
49 ServiceProcessControl::SERVICE_EVENT_MAX);
50 if (profile_->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) &&
51 (!profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty() ||
52 !profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled))) {
53 // If the cloud print proxy is enabled, or the policy preventing it from
54 // being enabled is set, establish a channel with the service process and
55 // update the status. This will check the policy when the status is sent
56 // back.
57 UMA_HISTOGRAM_ENUMERATION(
58 "CloudPrint.ServiceEvents",
59 ServiceProcessControl::SERVICE_EVENT_ENABLED_ON_LAUNCH,
60 ServiceProcessControl::SERVICE_EVENT_MAX);
61 RefreshStatusFromService();
64 pref_change_registrar_.Init(profile_->GetPrefs());
65 pref_change_registrar_.Add(
66 prefs::kCloudPrintProxyEnabled,
67 base::Bind(
68 base::IgnoreResult(
69 &CloudPrintProxyService::ApplyCloudPrintConnectorPolicy),
70 base::Unretained(this)));
73 void CloudPrintProxyService::RefreshStatusFromService() {
74 DCHECK_CURRENTLY_ON(BrowserThread::UI);
75 InvokeServiceTask(
76 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus,
77 weak_factory_.GetWeakPtr()));
80 bool CloudPrintProxyService::EnforceCloudPrintConnectorPolicyAndQuit() {
81 DCHECK_CURRENTLY_ON(BrowserThread::UI);
82 enforcing_connector_policy_ = true;
83 if (ApplyCloudPrintConnectorPolicy())
84 return true;
85 return false;
88 void CloudPrintProxyService::EnableForUserWithRobot(
89 const std::string& robot_auth_code,
90 const std::string& robot_email,
91 const std::string& user_email,
92 const base::DictionaryValue& user_preferences) {
93 DCHECK_CURRENTLY_ON(BrowserThread::UI);
94 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
95 ServiceProcessControl::SERVICE_EVENT_ENABLE,
96 ServiceProcessControl::SERVICE_EVENT_MAX);
97 if (profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
98 InvokeServiceTask(
99 base::Bind(&CloudPrintProxyService::EnableCloudPrintProxyWithRobot,
100 weak_factory_.GetWeakPtr(), robot_auth_code, robot_email,
101 user_email, base::Owned(user_preferences.DeepCopy())));
105 void CloudPrintProxyService::DisableForUser() {
106 DCHECK_CURRENTLY_ON(BrowserThread::UI);
107 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
108 ServiceProcessControl::SERVICE_EVENT_DISABLE,
109 ServiceProcessControl::SERVICE_EVENT_MAX);
110 InvokeServiceTask(
111 base::Bind(&CloudPrintProxyService::DisableCloudPrintProxy,
112 weak_factory_.GetWeakPtr()));
115 bool CloudPrintProxyService::ApplyCloudPrintConnectorPolicy() {
116 DCHECK_CURRENTLY_ON(BrowserThread::UI);
117 if (!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
118 std::string email =
119 profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail);
120 if (!email.empty()) {
121 UMA_HISTOGRAM_ENUMERATION(
122 "CloudPrint.ServiceEvents",
123 ServiceProcessControl::SERVICE_EVENT_DISABLE_BY_POLICY,
124 ServiceProcessControl::SERVICE_EVENT_MAX);
125 DisableForUser();
126 profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
127 if (enforcing_connector_policy_) {
128 base::MessageLoop::current()->PostTask(
129 FROM_HERE,
130 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus,
131 weak_factory_.GetWeakPtr()));
133 return false;
134 } else if (enforcing_connector_policy_) {
135 base::MessageLoop::current()->PostTask(FROM_HERE,
136 base::MessageLoop::QuitClosure());
139 return true;
142 void CloudPrintProxyService::GetPrinters(const PrintersCallback& callback) {
143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 if (!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled))
145 return;
147 base::FilePath list_path(
148 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
149 switches::kCloudPrintSetupProxy));
150 if (!list_path.empty()) {
151 std::string printers_json;
152 base::ReadFileToString(list_path, &printers_json);
153 scoped_ptr<base::Value> value(base::JSONReader::Read(printers_json));
154 base::ListValue* list = NULL;
155 std::vector<std::string> printers;
156 if (value && value->GetAsList(&list) && list) {
157 for (size_t i = 0; i < list->GetSize(); ++i) {
158 std::string printer;
159 if (list->GetString(i, &printer))
160 printers.push_back(printer);
163 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrintersList",
164 printers.size());
165 base::MessageLoop::current()->PostTask(FROM_HERE,
166 base::Bind(callback, printers));
167 } else {
168 InvokeServiceTask(
169 base::Bind(&CloudPrintProxyService::GetCloudPrintProxyPrinters,
170 weak_factory_.GetWeakPtr(),
171 callback));
175 void CloudPrintProxyService::GetCloudPrintProxyPrinters(
176 const PrintersCallback& callback) {
177 DCHECK_CURRENTLY_ON(BrowserThread::UI);
178 ServiceProcessControl* process_control = GetServiceProcessControl();
179 DCHECK(process_control->IsConnected());
180 process_control->GetPrinters(callback);
183 void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
184 DCHECK_CURRENTLY_ON(BrowserThread::UI);
185 ServiceProcessControl* process_control = GetServiceProcessControl();
186 DCHECK(process_control->IsConnected());
187 ServiceProcessControl::CloudPrintProxyInfoCallback callback = base::Bind(
188 &CloudPrintProxyService::ProxyInfoCallback, base::Unretained(this));
189 process_control->GetCloudPrintProxyInfo(callback);
192 void CloudPrintProxyService::EnableCloudPrintProxyWithRobot(
193 const std::string& robot_auth_code,
194 const std::string& robot_email,
195 const std::string& user_email,
196 const base::DictionaryValue* user_preferences) {
197 ServiceProcessControl* process_control = GetServiceProcessControl();
198 DCHECK(process_control->IsConnected());
199 process_control->Send(
200 new ServiceMsg_EnableCloudPrintProxyWithRobot(
201 robot_auth_code, robot_email, user_email, *user_preferences));
202 // Assume the IPC worked.
203 profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, user_email);
206 void CloudPrintProxyService::DisableCloudPrintProxy() {
207 ServiceProcessControl* process_control = GetServiceProcessControl();
208 DCHECK(process_control->IsConnected());
209 process_control->Send(new ServiceMsg_DisableCloudPrintProxy);
210 // Assume the IPC worked.
211 profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
214 void CloudPrintProxyService::ProxyInfoCallback(
215 const cloud_print::CloudPrintProxyInfo& proxy_info) {
216 proxy_id_ = proxy_info.proxy_id;
217 profile_->GetPrefs()->SetString(
218 prefs::kCloudPrintEmail,
219 proxy_info.enabled ? proxy_info.email : std::string());
220 ApplyCloudPrintConnectorPolicy();
223 bool CloudPrintProxyService::InvokeServiceTask(const base::Closure& task) {
224 GetServiceProcessControl()->Launch(task, base::Closure());
225 return true;
228 ServiceProcessControl* CloudPrintProxyService::GetServiceProcessControl() {
229 return ServiceProcessControl::GetInstance();