Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / printing / cloud_print / cloud_print_proxy_service.cc
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.
4
5 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
6
7 #include <stack>
8 #include <vector>
9
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 "printing/backend/print_backend.h"
33
34 using content::BrowserThread;
35
36 CloudPrintProxyService::CloudPrintProxyService(Profile* profile)
37     : profile_(profile),
38       weak_factory_(this),
39       enforcing_connector_policy_(false) {
40 }
41
42 CloudPrintProxyService::~CloudPrintProxyService() {
43 }
44
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();
62   }
63
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)));
71 }
72
73 void CloudPrintProxyService::RefreshStatusFromService() {
74   DCHECK_CURRENTLY_ON(BrowserThread::UI);
75   InvokeServiceTask(
76       base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus,
77                  weak_factory_.GetWeakPtr()));
78 }
79
80 bool CloudPrintProxyService::EnforceCloudPrintConnectorPolicyAndQuit() {
81   DCHECK_CURRENTLY_ON(BrowserThread::UI);
82   enforcing_connector_policy_ = true;
83   if (ApplyCloudPrintConnectorPolicy())
84     return true;
85   return false;
86 }
87
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())));
102   }
103 }
104
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()));
113 }
114
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()));
132       }
133       return false;
134     } else if (enforcing_connector_policy_) {
135       base::MessageLoop::current()->PostTask(FROM_HERE,
136                                              base::MessageLoop::QuitClosure());
137     }
138   }
139   return true;
140 }
141
142 void CloudPrintProxyService::GetPrinters(const PrintersCallback& callback) {
143   DCHECK_CURRENTLY_ON(BrowserThread::UI);
144   if (!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled))
145     return;
146
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);
161       }
162     }
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));
172   }
173 }
174
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);
181 }
182
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);
190 }
191
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);
204 }
205
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());
212 }
213
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();
221 }
222
223 bool CloudPrintProxyService::InvokeServiceTask(const base::Closure& task) {
224   GetServiceProcessControl()->Launch(task, base::Closure());
225   return true;
226 }
227
228 ServiceProcessControl* CloudPrintProxyService::GetServiceProcessControl() {
229   return ServiceProcessControl::GetInstance();
230 }