Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / service / cloud_print / cloud_print_proxy.cc
blob58958c6a67d7f38b1c0e07f84717e9b03b928738
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/service/cloud_print/cloud_print_proxy.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/metrics/histogram.h"
10 #include "base/path_service.h"
11 #include "base/process/kill.h"
12 #include "base/process/launch.h"
13 #include "base/values.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/cloud_print/cloud_print_constants.h"
16 #include "chrome/common/cloud_print/cloud_print_proxy_info.h"
17 #include "chrome/common/pref_names.h"
18 #include "chrome/service/cloud_print/print_system.h"
19 #include "chrome/service/service_process.h"
20 #include "chrome/service/service_process_prefs.h"
21 #include "google_apis/gaia/gaia_oauth_client.h"
22 #include "google_apis/google_api_keys.h"
23 #include "url/gurl.h"
25 namespace cloud_print {
27 CloudPrintProxy::CloudPrintProxy()
28 : service_prefs_(NULL),
29 client_(NULL),
30 enabled_(false) {
33 CloudPrintProxy::~CloudPrintProxy() {
34 DCHECK(CalledOnValidThread());
35 ShutdownBackend();
38 void CloudPrintProxy::Initialize(ServiceProcessPrefs* service_prefs,
39 Client* client) {
40 DCHECK(CalledOnValidThread());
41 service_prefs_ = service_prefs;
42 client_ = client;
45 void CloudPrintProxy::EnableForUser() {
46 DCHECK(CalledOnValidThread());
47 if (!CreateBackend())
48 return;
49 DCHECK(backend_.get());
50 // Read persisted robot credentials because we may decide to reuse it if the
51 // passed in LSID belongs the same user.
52 std::string robot_refresh_token = service_prefs_->GetString(
53 prefs::kCloudPrintRobotRefreshToken, std::string());
54 std::string robot_email =
55 service_prefs_->GetString(prefs::kCloudPrintRobotEmail, std::string());
56 user_email_ = service_prefs_->GetString(prefs::kCloudPrintEmail, user_email_);
58 // See if we have persisted robot credentials.
59 if (!robot_refresh_token.empty()) {
60 DCHECK(!robot_email.empty());
61 backend_->InitializeWithRobotToken(robot_refresh_token, robot_email);
62 } else {
63 // Finally see if we have persisted user credentials (legacy case).
64 std::string cloud_print_token =
65 service_prefs_->GetString(prefs::kCloudPrintAuthToken, std::string());
66 DCHECK(!cloud_print_token.empty());
67 backend_->InitializeWithToken(cloud_print_token);
69 if (client_) {
70 client_->OnCloudPrintProxyEnabled(true);
74 void CloudPrintProxy::EnableForUserWithRobot(
75 const std::string& robot_auth_code,
76 const std::string& robot_email,
77 const std::string& user_email,
78 const base::DictionaryValue& user_settings) {
79 DCHECK(CalledOnValidThread());
81 ShutdownBackend();
82 std::string proxy_id(
83 service_prefs_->GetString(prefs::kCloudPrintProxyId, std::string()));
84 service_prefs_->RemovePref(prefs::kCloudPrintRoot);
85 if (!proxy_id.empty()) {
86 // Keep only proxy id;
87 service_prefs_->SetString(prefs::kCloudPrintProxyId, proxy_id);
89 service_prefs_->SetValue(prefs::kCloudPrintUserSettings,
90 user_settings.CreateDeepCopy());
91 service_prefs_->WritePrefs();
93 if (!CreateBackend())
94 return;
95 DCHECK(backend_.get());
96 user_email_ = user_email;
97 backend_->InitializeWithRobotAuthCode(robot_auth_code, robot_email);
98 if (client_) {
99 client_->OnCloudPrintProxyEnabled(true);
103 bool CloudPrintProxy::CreateBackend() {
104 DCHECK(CalledOnValidThread());
105 if (backend_.get())
106 return false;
108 ConnectorSettings settings;
109 settings.InitFrom(service_prefs_);
111 // By default we don't poll for jobs when we lose XMPP connection. But this
112 // behavior can be overridden by a preference.
113 bool enable_job_poll =
114 service_prefs_->GetBoolean(prefs::kCloudPrintEnableJobPoll, false);
116 gaia::OAuthClientInfo oauth_client_info;
117 oauth_client_info.client_id =
118 google_apis::GetOAuth2ClientID(google_apis::CLIENT_CLOUD_PRINT);
119 oauth_client_info.client_secret =
120 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_CLOUD_PRINT);
121 oauth_client_info.redirect_uri = "oob";
122 backend_.reset(new CloudPrintProxyBackend(
123 this, settings, oauth_client_info, enable_job_poll));
124 return true;
127 void CloudPrintProxy::UnregisterPrintersAndDisableForUser() {
128 DCHECK(CalledOnValidThread());
129 if (backend_.get()) {
130 // Try getting auth and printers info from the backend.
131 // We'll get notified in this case.
132 backend_->UnregisterPrinters();
133 } else {
134 // If no backend avaialble, disable connector immidiately.
135 DisableForUser();
139 void CloudPrintProxy::DisableForUser() {
140 DCHECK(CalledOnValidThread());
141 user_email_.clear();
142 enabled_ = false;
143 if (client_) {
144 client_->OnCloudPrintProxyDisabled(true);
146 ShutdownBackend();
149 void CloudPrintProxy::GetProxyInfo(CloudPrintProxyInfo* info) {
150 info->enabled = enabled_;
151 info->email.clear();
152 if (enabled_)
153 info->email = user_email();
154 ConnectorSettings settings;
155 settings.InitFrom(service_prefs_);
156 info->proxy_id = settings.proxy_id();
159 void CloudPrintProxy::GetPrinters(std::vector<std::string>* printers) {
160 ConnectorSettings settings;
161 settings.InitFrom(service_prefs_);
162 scoped_refptr<PrintSystem> print_system =
163 PrintSystem::CreateInstance(settings.print_system_settings());
164 if (!print_system.get())
165 return;
166 PrintSystem::PrintSystemResult result = print_system->Init();
167 if (!result.succeeded())
168 return;
169 printing::PrinterList printer_list;
170 print_system->EnumeratePrinters(&printer_list);
171 for (size_t i = 0; i < printer_list.size(); ++i)
172 printers->push_back(printer_list[i].printer_name);
175 void CloudPrintProxy::OnAuthenticated(
176 const std::string& robot_oauth_refresh_token,
177 const std::string& robot_email,
178 const std::string& user_email) {
179 DCHECK(CalledOnValidThread());
180 service_prefs_->SetString(prefs::kCloudPrintRobotRefreshToken,
181 robot_oauth_refresh_token);
182 service_prefs_->SetString(prefs::kCloudPrintRobotEmail,
183 robot_email);
184 // If authenticating from a robot, the user email will be empty.
185 if (!user_email.empty()) {
186 user_email_ = user_email;
188 service_prefs_->SetString(prefs::kCloudPrintEmail, user_email_);
189 enabled_ = true;
190 DCHECK(!user_email_.empty());
191 service_prefs_->WritePrefs();
192 // When this switch used we don't want connector continue running, we just
193 // need authentication.
194 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
195 switches::kCloudPrintSetupProxy)) {
196 ShutdownBackend();
197 if (client_) {
198 client_->OnCloudPrintProxyDisabled(false);
203 void CloudPrintProxy::OnAuthenticationFailed() {
204 DCHECK(CalledOnValidThread());
205 // Don't disable permanently. Could be just connection issue.
206 ShutdownBackend();
207 if (client_) {
208 client_->OnCloudPrintProxyDisabled(false);
212 void CloudPrintProxy::OnPrintSystemUnavailable() {
213 // If the print system is unavailable, we want to shutdown the proxy and
214 // disable it non-persistently.
215 ShutdownBackend();
216 if (client_) {
217 client_->OnCloudPrintProxyDisabled(false);
221 void CloudPrintProxy::OnUnregisterPrinters(
222 const std::string& auth_token,
223 const std::list<std::string>& printer_ids) {
224 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.UnregisterPrinters",
225 printer_ids.size());
226 ShutdownBackend();
227 ConnectorSettings settings;
228 settings.InitFrom(service_prefs_);
229 wipeout_.reset(new CloudPrintWipeout(this, settings.server_url()));
230 wipeout_->UnregisterPrinters(auth_token, printer_ids);
233 void CloudPrintProxy::OnXmppPingUpdated(int ping_timeout) {
234 DCHECK(CalledOnValidThread());
235 service_prefs_->SetInt(prefs::kCloudPrintXmppPingTimeout, ping_timeout);
236 service_prefs_->WritePrefs();
239 void CloudPrintProxy::OnUnregisterPrintersComplete() {
240 wipeout_.reset();
241 // Finish disabling cloud print for this user.
242 DisableForUser();
245 void CloudPrintProxy::ShutdownBackend() {
246 DCHECK(CalledOnValidThread());
247 if (backend_.get())
248 backend_->Shutdown();
249 backend_.reset();
252 } // namespace cloud_print