Fix infinite recursion on hiding panel when created during fullscreen mode.
[chromium-blink-merge.git] / chrome / browser / printing / cloud_print / cloud_print_proxy_service.cc
blob6947c3b4cf74bb67daaf078f887b076b49da0f4c
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/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)
39 : profile_(profile),
40 weak_factory_(this),
41 enforcing_connector_policy_(false) {
44 CloudPrintProxyService::~CloudPrintProxyService() {
47 void CloudPrintProxyService::Initialize() {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
49 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
50 ServiceProcessControl::SERVICE_EVENT_INITIALIZE,
51 ServiceProcessControl::SERVICE_EVENT_MAX);
52 if (profile_->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) &&
53 (!profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty() ||
54 !profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled))) {
55 // If the cloud print proxy is enabled, or the policy preventing it from
56 // being enabled is set, establish a channel with the service process and
57 // update the status. This will check the policy when the status is sent
58 // back.
59 UMA_HISTOGRAM_ENUMERATION(
60 "CloudPrint.ServiceEvents",
61 ServiceProcessControl::SERVICE_EVENT_ENABLED_ON_LAUNCH,
62 ServiceProcessControl::SERVICE_EVENT_MAX);
63 RefreshStatusFromService();
66 pref_change_registrar_.Init(profile_->GetPrefs());
67 pref_change_registrar_.Add(
68 prefs::kCloudPrintProxyEnabled,
69 base::Bind(
70 base::IgnoreResult(
71 &CloudPrintProxyService::ApplyCloudPrintConnectorPolicy),
72 base::Unretained(this)));
75 void CloudPrintProxyService::RefreshStatusFromService() {
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77 InvokeServiceTask(
78 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus,
79 weak_factory_.GetWeakPtr()));
82 bool CloudPrintProxyService::EnforceCloudPrintConnectorPolicyAndQuit() {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84 enforcing_connector_policy_ = true;
85 if (ApplyCloudPrintConnectorPolicy())
86 return true;
87 return false;
90 void CloudPrintProxyService::EnableForUserWithRobot(
91 const std::string& robot_auth_code,
92 const std::string& robot_email,
93 const std::string& user_email,
94 const base::DictionaryValue& user_preferences) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
97 ServiceProcessControl::SERVICE_EVENT_ENABLE,
98 ServiceProcessControl::SERVICE_EVENT_MAX);
99 if (profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
100 InvokeServiceTask(
101 base::Bind(&CloudPrintProxyService::EnableCloudPrintProxyWithRobot,
102 weak_factory_.GetWeakPtr(), robot_auth_code, robot_email,
103 user_email, base::Owned(user_preferences.DeepCopy())));
107 void CloudPrintProxyService::DisableForUser() {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceEvents",
110 ServiceProcessControl::SERVICE_EVENT_DISABLE,
111 ServiceProcessControl::SERVICE_EVENT_MAX);
112 InvokeServiceTask(
113 base::Bind(&CloudPrintProxyService::DisableCloudPrintProxy,
114 weak_factory_.GetWeakPtr()));
117 bool CloudPrintProxyService::ApplyCloudPrintConnectorPolicy() {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 if (!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled)) {
120 std::string email =
121 profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail);
122 if (!email.empty()) {
123 UMA_HISTOGRAM_ENUMERATION(
124 "CloudPrint.ServiceEvents",
125 ServiceProcessControl::SERVICE_EVENT_DISABLE_BY_POLICY,
126 ServiceProcessControl::SERVICE_EVENT_MAX);
127 DisableForUser();
128 profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
129 if (enforcing_connector_policy_) {
130 base::MessageLoop::current()->PostTask(
131 FROM_HERE,
132 base::Bind(&CloudPrintProxyService::RefreshCloudPrintProxyStatus,
133 weak_factory_.GetWeakPtr()));
135 return false;
136 } else if (enforcing_connector_policy_) {
137 base::MessageLoop::current()->PostTask(FROM_HERE,
138 base::MessageLoop::QuitClosure());
141 return true;
144 void CloudPrintProxyService::GetPrinters(const PrintersCallback& callback) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
146 if (!profile_->GetPrefs()->GetBoolean(prefs::kCloudPrintProxyEnabled))
147 return;
149 base::FilePath list_path(
150 CommandLine::ForCurrentProcess()->GetSwitchValuePath(
151 switches::kCloudPrintSetupProxy));
152 if (!list_path.empty()) {
153 std::string printers_json;
154 base::ReadFileToString(list_path, &printers_json);
155 scoped_ptr<base::Value> value(base::JSONReader::Read(printers_json));
156 base::ListValue* list = NULL;
157 std::vector<std::string> printers;
158 if (value && value->GetAsList(&list) && list) {
159 for (size_t i = 0; i < list->GetSize(); ++i) {
160 std::string printer;
161 if (list->GetString(i, &printer))
162 printers.push_back(printer);
165 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.AvailablePrintersList",
166 printers.size());
167 base::MessageLoop::current()->PostTask(FROM_HERE,
168 base::Bind(callback, printers));
169 } else {
170 InvokeServiceTask(
171 base::Bind(&CloudPrintProxyService::GetCloudPrintProxyPrinters,
172 weak_factory_.GetWeakPtr(),
173 callback));
177 void CloudPrintProxyService::GetCloudPrintProxyPrinters(
178 const PrintersCallback& callback) {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
180 ServiceProcessControl* process_control = GetServiceProcessControl();
181 DCHECK(process_control->IsConnected());
182 process_control->GetPrinters(callback);
185 void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
187 ServiceProcessControl* process_control = GetServiceProcessControl();
188 DCHECK(process_control->IsConnected());
189 ServiceProcessControl::CloudPrintProxyInfoCallback callback = base::Bind(
190 &CloudPrintProxyService::ProxyInfoCallback, base::Unretained(this));
191 process_control->GetCloudPrintProxyInfo(callback);
194 void CloudPrintProxyService::EnableCloudPrintProxyWithRobot(
195 const std::string& robot_auth_code,
196 const std::string& robot_email,
197 const std::string& user_email,
198 const base::DictionaryValue* user_preferences) {
199 ServiceProcessControl* process_control = GetServiceProcessControl();
200 DCHECK(process_control->IsConnected());
201 process_control->Send(
202 new ServiceMsg_EnableCloudPrintProxyWithRobot(
203 robot_auth_code, robot_email, user_email, *user_preferences));
204 // Assume the IPC worked.
205 profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, user_email);
208 void CloudPrintProxyService::DisableCloudPrintProxy() {
209 ServiceProcessControl* process_control = GetServiceProcessControl();
210 DCHECK(process_control->IsConnected());
211 process_control->Send(new ServiceMsg_DisableCloudPrintProxy);
212 // Assume the IPC worked.
213 profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
216 void CloudPrintProxyService::ProxyInfoCallback(
217 const cloud_print::CloudPrintProxyInfo& proxy_info) {
218 proxy_id_ = proxy_info.proxy_id;
219 profile_->GetPrefs()->SetString(
220 prefs::kCloudPrintEmail,
221 proxy_info.enabled ? proxy_info.email : std::string());
222 ApplyCloudPrintConnectorPolicy();
225 bool CloudPrintProxyService::InvokeServiceTask(const base::Closure& task) {
226 GetServiceProcessControl()->Launch(task, base::Closure());
227 return true;
230 ServiceProcessControl* CloudPrintProxyService::GetServiceProcessControl() {
231 return ServiceProcessControl::GetInstance();