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"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/command_line.h"
13 #include "base/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 "grit/generated_resources.h"
33 #include "printing/backend/print_backend.h"
34 #include "ui/base/l10n/l10n_util.h"
36 using content::BrowserThread
;
38 CloudPrintProxyService::CloudPrintProxyService(Profile
* profile
)
41 enforcing_connector_policy_(false) {
44 CloudPrintProxyService::~CloudPrintProxyService() {
47 void CloudPrintProxyService::Initialize() {
48 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
49 ServiceProcessControl::SERVICE_EVENT_INITIALIZE
,
50 ServiceProcessControl::SERVICE_EVENT_MAX
);
51 if (profile_
->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail
) &&
52 (!profile_
->GetPrefs()->GetString(prefs::kCloudPrintEmail
).empty() ||
53 !profile_
->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled
))) {
54 // If the cloud print proxy is enabled, or the policy preventing it from
55 // being enabled is set, establish a channel with the service process and
56 // update the status. This will check the policy when the status is sent
58 UMA_HISTOGRAM_ENUMERATION(
59 "CloudPrint.ServiceEvents",
60 ServiceProcessControl::SERVICE_EVENT_ENABLED_ON_LAUNCH
,
61 ServiceProcessControl::SERVICE_EVENT_MAX
);
62 RefreshStatusFromService();
65 pref_change_registrar_
.Init(profile_
->GetPrefs());
66 pref_change_registrar_
.Add(
67 prefs::kCloudPrintProxyEnabled
,
70 &CloudPrintProxyService::ApplyCloudPrintConnectorPolicy
),
71 base::Unretained(this)));
74 void CloudPrintProxyService::RefreshStatusFromService() {
76 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus
,
77 weak_factory_
.GetWeakPtr()));
80 bool CloudPrintProxyService::EnforceCloudPrintConnectorPolicyAndQuit() {
81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
82 enforcing_connector_policy_
= true;
83 if (ApplyCloudPrintConnectorPolicy())
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 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
94 ServiceProcessControl::SERVICE_EVENT_ENABLE
,
95 ServiceProcessControl::SERVICE_EVENT_MAX
);
96 if (profile_
->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled
)) {
98 base::Bind(&CloudPrintProxyService::EnableCloudPrintProxyWithRobot
,
99 weak_factory_
.GetWeakPtr(), robot_auth_code
, robot_email
,
100 user_email
, base::Owned(user_preferences
.DeepCopy())));
104 void CloudPrintProxyService::DisableForUser() {
105 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
106 ServiceProcessControl::SERVICE_EVENT_DISABLE
,
107 ServiceProcessControl::SERVICE_EVENT_MAX
);
109 base::Bind(&CloudPrintProxyService::DisableCloudPrintProxy
,
110 weak_factory_
.GetWeakPtr()));
113 bool CloudPrintProxyService::ApplyCloudPrintConnectorPolicy() {
114 if (!profile_
->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled
)) {
116 profile_
->GetPrefs()->GetString(prefs::kCloudPrintEmail
);
117 if (!email
.empty()) {
118 UMA_HISTOGRAM_ENUMERATION(
119 "CloudPrint.ServiceEvents",
120 ServiceProcessControl::SERVICE_EVENT_DISABLE_BY_POLICY
,
121 ServiceProcessControl::SERVICE_EVENT_MAX
);
123 profile_
->GetPrefs()->SetString(prefs::kCloudPrintEmail
, std::string());
124 if (enforcing_connector_policy_
) {
125 base::MessageLoop::current()->PostTask(
127 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus
,
128 weak_factory_
.GetWeakPtr()));
131 } else if (enforcing_connector_policy_
) {
132 base::MessageLoop::current()->PostTask(FROM_HERE
,
133 base::MessageLoop::QuitClosure());
139 void CloudPrintProxyService::GetPrintersAvalibleForRegistration(
140 std::vector
<std::string
>* printers
) {
141 base::FilePath
list_path(
142 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
143 switches::kCloudPrintSetupProxy
));
144 if (!list_path
.empty()) {
145 std::string printers_json
;
146 base::ReadFileToString(list_path
, &printers_json
);
147 scoped_ptr
<base::Value
> value(base::JSONReader::Read(printers_json
));
148 base::ListValue
* list
= NULL
;
149 if (value
&& value
->GetAsList(&list
) && list
) {
150 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
152 if (list
->GetString(i
, &printer
))
153 printers
->push_back(printer
);
156 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrintersList",
159 printing::PrinterList printer_list
;
160 scoped_refptr
<printing::PrintBackend
> backend(
161 printing::PrintBackend::CreateInstance(NULL
));
163 backend
->EnumeratePrinters(&printer_list
);
164 for (size_t i
= 0; i
< printer_list
.size(); ++i
)
165 printers
->push_back(printer_list
[i
].printer_name
);
166 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrinters",
171 void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
173 ServiceProcessControl
* process_control
= GetServiceProcessControl();
174 DCHECK(process_control
->IsConnected());
175 ServiceProcessControl::CloudPrintProxyInfoHandler callback
=
176 base::Bind(&CloudPrintProxyService::ProxyInfoCallback
,
177 base::Unretained(this));
178 // GetCloudPrintProxyInfo takes ownership of callback.
179 process_control
->GetCloudPrintProxyInfo(callback
);
182 void CloudPrintProxyService::EnableCloudPrintProxyWithRobot(
183 const std::string
& robot_auth_code
,
184 const std::string
& robot_email
,
185 const std::string
& user_email
,
186 const base::DictionaryValue
* user_preferences
) {
187 ServiceProcessControl
* process_control
= GetServiceProcessControl();
188 DCHECK(process_control
->IsConnected());
189 process_control
->Send(
190 new ServiceMsg_EnableCloudPrintProxyWithRobot(
191 robot_auth_code
, robot_email
, user_email
, *user_preferences
));
192 // Assume the IPC worked.
193 profile_
->GetPrefs()->SetString(prefs::kCloudPrintEmail
, user_email
);
196 void CloudPrintProxyService::DisableCloudPrintProxy() {
197 ServiceProcessControl
* process_control
= GetServiceProcessControl();
198 DCHECK(process_control
->IsConnected());
199 process_control
->Send(new ServiceMsg_DisableCloudPrintProxy
);
200 // Assume the IPC worked.
201 profile_
->GetPrefs()->SetString(prefs::kCloudPrintEmail
, std::string());
204 void CloudPrintProxyService::ProxyInfoCallback(
205 const cloud_print::CloudPrintProxyInfo
& proxy_info
) {
206 proxy_id_
= proxy_info
.proxy_id
;
207 profile_
->GetPrefs()->SetString(
208 prefs::kCloudPrintEmail
,
209 proxy_info
.enabled
? proxy_info
.email
: std::string());
210 ApplyCloudPrintConnectorPolicy();
213 bool CloudPrintProxyService::InvokeServiceTask(const base::Closure
& task
) {
214 GetServiceProcessControl()->Launch(task
, base::Closure());
218 ServiceProcessControl
* CloudPrintProxyService::GetServiceProcessControl() {
219 return ServiceProcessControl::GetInstance();