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"
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"
25 namespace cloud_print
{
27 CloudPrintProxy::CloudPrintProxy()
28 : service_prefs_(NULL
),
33 CloudPrintProxy::~CloudPrintProxy() {
34 DCHECK(CalledOnValidThread());
38 void CloudPrintProxy::Initialize(ServiceProcessPrefs
* service_prefs
,
40 DCHECK(CalledOnValidThread());
41 service_prefs_
= service_prefs
;
45 void CloudPrintProxy::EnableForUser() {
46 DCHECK(CalledOnValidThread());
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
);
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
);
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());
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();
95 DCHECK(backend_
.get());
96 user_email_
= user_email
;
97 backend_
->InitializeWithRobotAuthCode(robot_auth_code
, robot_email
);
99 client_
->OnCloudPrintProxyEnabled(true);
103 bool CloudPrintProxy::CreateBackend() {
104 DCHECK(CalledOnValidThread());
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
));
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();
134 // If no backend avaialble, disable connector immidiately.
139 void CloudPrintProxy::DisableForUser() {
140 DCHECK(CalledOnValidThread());
144 client_
->OnCloudPrintProxyDisabled(true);
149 void CloudPrintProxy::GetProxyInfo(CloudPrintProxyInfo
* info
) {
150 info
->enabled
= 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())
166 PrintSystem::PrintSystemResult result
= print_system
->Init();
167 if (!result
.succeeded())
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
,
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_
);
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
)) {
198 client_
->OnCloudPrintProxyDisabled(false);
203 void CloudPrintProxy::OnAuthenticationFailed() {
204 DCHECK(CalledOnValidThread());
205 // Don't disable permanently. Could be just connection issue.
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.
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",
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() {
241 // Finish disabling cloud print for this user.
245 void CloudPrintProxy::ShutdownBackend() {
246 DCHECK(CalledOnValidThread());
248 backend_
->Shutdown();
252 } // namespace cloud_print