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/files/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/location.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/single_thread_task_runner.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/lifetime/application_lifetime.h"
24 #include "chrome/browser/notifications/notification.h"
25 #include "chrome/browser/notifications/notification_ui_manager.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/service_process/service_process_control.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/cloud_print/cloud_print_proxy_info.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/service_messages.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "printing/backend/print_backend.h"
35 using content::BrowserThread
;
37 CloudPrintProxyService::CloudPrintProxyService(Profile
* profile
)
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
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
,
69 &CloudPrintProxyService::ApplyCloudPrintConnectorPolicy
),
70 base::Unretained(this)));
73 void CloudPrintProxyService::RefreshStatusFromService() {
74 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
76 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus
,
77 weak_factory_
.GetWeakPtr()));
80 void CloudPrintProxyService::EnableForUserWithRobot(
81 const std::string
& robot_auth_code
,
82 const std::string
& robot_email
,
83 const std::string
& user_email
,
84 const base::DictionaryValue
& user_preferences
) {
85 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
86 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
87 ServiceProcessControl::SERVICE_EVENT_ENABLE
,
88 ServiceProcessControl::SERVICE_EVENT_MAX
);
89 if (profile_
->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled
)) {
91 base::Bind(&CloudPrintProxyService::EnableCloudPrintProxyWithRobot
,
92 weak_factory_
.GetWeakPtr(), robot_auth_code
, robot_email
,
93 user_email
, base::Owned(user_preferences
.DeepCopy())));
97 void CloudPrintProxyService::DisableForUser() {
98 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
99 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
100 ServiceProcessControl::SERVICE_EVENT_DISABLE
,
101 ServiceProcessControl::SERVICE_EVENT_MAX
);
103 base::Bind(&CloudPrintProxyService::DisableCloudPrintProxy
,
104 weak_factory_
.GetWeakPtr()));
107 bool CloudPrintProxyService::ApplyCloudPrintConnectorPolicy() {
108 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
109 if (!profile_
->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled
)) {
111 profile_
->GetPrefs()->GetString(prefs::kCloudPrintEmail
);
112 if (!email
.empty()) {
113 UMA_HISTOGRAM_ENUMERATION(
114 "CloudPrint.ServiceEvents",
115 ServiceProcessControl::SERVICE_EVENT_DISABLE_BY_POLICY
,
116 ServiceProcessControl::SERVICE_EVENT_MAX
);
118 profile_
->GetPrefs()->SetString(prefs::kCloudPrintEmail
, std::string());
125 void CloudPrintProxyService::GetPrinters(const PrintersCallback
& callback
) {
126 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
127 if (!profile_
->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled
))
130 base::FilePath
list_path(
131 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
132 switches::kCloudPrintSetupProxy
));
133 if (!list_path
.empty()) {
134 std::string printers_json
;
135 base::ReadFileToString(list_path
, &printers_json
);
136 scoped_ptr
<base::Value
> value
= base::JSONReader::Read(printers_json
);
137 base::ListValue
* list
= NULL
;
138 std::vector
<std::string
> printers
;
139 if (value
&& value
->GetAsList(&list
) && list
) {
140 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
142 if (list
->GetString(i
, &printer
))
143 printers
.push_back(printer
);
146 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrintersList",
148 base::ThreadTaskRunnerHandle::Get()->PostTask(
149 FROM_HERE
, base::Bind(callback
, printers
));
152 base::Bind(&CloudPrintProxyService::GetCloudPrintProxyPrinters
,
153 weak_factory_
.GetWeakPtr(),
158 void CloudPrintProxyService::GetCloudPrintProxyPrinters(
159 const PrintersCallback
& callback
) {
160 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
161 ServiceProcessControl
* process_control
= GetServiceProcessControl();
162 DCHECK(process_control
->IsConnected());
163 process_control
->GetPrinters(callback
);
166 void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
167 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
168 ServiceProcessControl
* process_control
= GetServiceProcessControl();
169 DCHECK(process_control
->IsConnected());
170 ServiceProcessControl::CloudPrintProxyInfoCallback callback
= base::Bind(
171 &CloudPrintProxyService::ProxyInfoCallback
, base::Unretained(this));
172 process_control
->GetCloudPrintProxyInfo(callback
);
175 void CloudPrintProxyService::EnableCloudPrintProxyWithRobot(
176 const std::string
& robot_auth_code
,
177 const std::string
& robot_email
,
178 const std::string
& user_email
,
179 const base::DictionaryValue
* user_preferences
) {
180 ServiceProcessControl
* process_control
= GetServiceProcessControl();
181 DCHECK(process_control
->IsConnected());
182 process_control
->Send(
183 new ServiceMsg_EnableCloudPrintProxyWithRobot(
184 robot_auth_code
, robot_email
, user_email
, *user_preferences
));
185 // Assume the IPC worked.
186 profile_
->GetPrefs()->SetString(prefs::kCloudPrintEmail
, user_email
);
189 void CloudPrintProxyService::DisableCloudPrintProxy() {
190 ServiceProcessControl
* process_control
= GetServiceProcessControl();
191 DCHECK(process_control
->IsConnected());
192 process_control
->Send(new ServiceMsg_DisableCloudPrintProxy
);
193 // Assume the IPC worked.
194 profile_
->GetPrefs()->SetString(prefs::kCloudPrintEmail
, std::string());
197 void CloudPrintProxyService::ProxyInfoCallback(
198 const cloud_print::CloudPrintProxyInfo
& proxy_info
) {
199 proxy_id_
= proxy_info
.proxy_id
;
200 profile_
->GetPrefs()->SetString(
201 prefs::kCloudPrintEmail
,
202 proxy_info
.enabled
? proxy_info
.email
: std::string());
203 ApplyCloudPrintConnectorPolicy();
206 bool CloudPrintProxyService::InvokeServiceTask(const base::Closure
& task
) {
207 GetServiceProcessControl()->Launch(task
, base::Closure());
211 ServiceProcessControl
* CloudPrintProxyService::GetServiceProcessControl() {
212 return ServiceProcessControl::GetInstance();