[Cronet] Delay StartNetLog and StopNetLog until native request context is initialized
[chromium-blink-merge.git] / chrome / service / cloud_print / cloud_print_proxy.cc
bloba98fecb4e5be00535e0fbadc089dfbf963b6ae31
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 {
27 void LaunchBrowserProcessWithSwitch(const std::string& switch_string) {
28 DCHECK(g_service_process->io_thread()->message_loop_proxy()->
29 BelongsToCurrentThread());
30 base::FilePath exe_path;
31 PathService::Get(base::FILE_EXE, &exe_path);
32 if (exe_path.empty()) {
33 NOTREACHED() << "Unable to get browser process binary name.";
35 base::CommandLine cmd_line(exe_path);
37 const base::CommandLine& process_command_line =
38 *base::CommandLine::ForCurrentProcess();
39 base::FilePath user_data_dir =
40 process_command_line.GetSwitchValuePath(switches::kUserDataDir);
41 if (!user_data_dir.empty())
42 cmd_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
43 cmd_line.AppendSwitch(switch_string);
45 #if defined(OS_POSIX) && !defined(OS_MACOSX)
46 base::Process process = base::LaunchProcess(cmd_line, base::LaunchOptions());
47 if (process.IsValid())
48 base::EnsureProcessGetsReaped(process.Pid());
49 #else
50 base::LaunchOptions launch_options;
51 #if defined(OS_WIN)
52 launch_options.force_breakaway_from_job_ = true;
53 #endif // OS_WIN
54 base::LaunchProcess(cmd_line, launch_options);
55 #endif
58 void CheckCloudPrintProxyPolicyInBrowser() {
59 LaunchBrowserProcessWithSwitch(switches::kCheckCloudPrintConnectorPolicy);
62 } // namespace
64 namespace cloud_print {
66 CloudPrintProxy::CloudPrintProxy()
67 : service_prefs_(NULL),
68 client_(NULL),
69 enabled_(false) {
72 CloudPrintProxy::~CloudPrintProxy() {
73 DCHECK(CalledOnValidThread());
74 ShutdownBackend();
77 void CloudPrintProxy::Initialize(ServiceProcessPrefs* service_prefs,
78 Client* client) {
79 DCHECK(CalledOnValidThread());
80 service_prefs_ = service_prefs;
81 client_ = client;
84 void CloudPrintProxy::EnableForUser() {
85 DCHECK(CalledOnValidThread());
86 if (!CreateBackend())
87 return;
88 DCHECK(backend_.get());
89 // Read persisted robot credentials because we may decide to reuse it if the
90 // passed in LSID belongs the same user.
91 std::string robot_refresh_token = service_prefs_->GetString(
92 prefs::kCloudPrintRobotRefreshToken, std::string());
93 std::string robot_email =
94 service_prefs_->GetString(prefs::kCloudPrintRobotEmail, std::string());
95 user_email_ = service_prefs_->GetString(prefs::kCloudPrintEmail, user_email_);
97 // See if we have persisted robot credentials.
98 if (!robot_refresh_token.empty()) {
99 DCHECK(!robot_email.empty());
100 backend_->InitializeWithRobotToken(robot_refresh_token, robot_email);
101 } else {
102 // Finally see if we have persisted user credentials (legacy case).
103 std::string cloud_print_token =
104 service_prefs_->GetString(prefs::kCloudPrintAuthToken, std::string());
105 DCHECK(!cloud_print_token.empty());
106 backend_->InitializeWithToken(cloud_print_token);
108 if (client_) {
109 client_->OnCloudPrintProxyEnabled(true);
113 void CloudPrintProxy::EnableForUserWithRobot(
114 const std::string& robot_auth_code,
115 const std::string& robot_email,
116 const std::string& user_email,
117 const base::DictionaryValue& user_settings) {
118 DCHECK(CalledOnValidThread());
120 ShutdownBackend();
121 std::string proxy_id(
122 service_prefs_->GetString(prefs::kCloudPrintProxyId, std::string()));
123 service_prefs_->RemovePref(prefs::kCloudPrintRoot);
124 if (!proxy_id.empty()) {
125 // Keep only proxy id;
126 service_prefs_->SetString(prefs::kCloudPrintProxyId, proxy_id);
128 service_prefs_->SetValue(prefs::kCloudPrintUserSettings,
129 user_settings.DeepCopy());
130 service_prefs_->WritePrefs();
132 if (!CreateBackend())
133 return;
134 DCHECK(backend_.get());
135 user_email_ = user_email;
136 backend_->InitializeWithRobotAuthCode(robot_auth_code, robot_email);
137 if (client_) {
138 client_->OnCloudPrintProxyEnabled(true);
142 bool CloudPrintProxy::CreateBackend() {
143 DCHECK(CalledOnValidThread());
144 if (backend_.get())
145 return false;
147 ConnectorSettings settings;
148 settings.InitFrom(service_prefs_);
150 // By default we don't poll for jobs when we lose XMPP connection. But this
151 // behavior can be overridden by a preference.
152 bool enable_job_poll =
153 service_prefs_->GetBoolean(prefs::kCloudPrintEnableJobPoll, false);
155 gaia::OAuthClientInfo oauth_client_info;
156 oauth_client_info.client_id =
157 google_apis::GetOAuth2ClientID(google_apis::CLIENT_CLOUD_PRINT);
158 oauth_client_info.client_secret =
159 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_CLOUD_PRINT);
160 oauth_client_info.redirect_uri = "oob";
161 backend_.reset(new CloudPrintProxyBackend(
162 this, settings, oauth_client_info, enable_job_poll));
163 return true;
166 void CloudPrintProxy::UnregisterPrintersAndDisableForUser() {
167 DCHECK(CalledOnValidThread());
168 if (backend_.get()) {
169 // Try getting auth and printers info from the backend.
170 // We'll get notified in this case.
171 backend_->UnregisterPrinters();
172 } else {
173 // If no backend avaialble, disable connector immidiately.
174 DisableForUser();
178 void CloudPrintProxy::DisableForUser() {
179 DCHECK(CalledOnValidThread());
180 user_email_.clear();
181 enabled_ = false;
182 if (client_) {
183 client_->OnCloudPrintProxyDisabled(true);
185 ShutdownBackend();
188 void CloudPrintProxy::GetProxyInfo(CloudPrintProxyInfo* info) {
189 info->enabled = enabled_;
190 info->email.clear();
191 if (enabled_)
192 info->email = user_email();
193 ConnectorSettings settings;
194 settings.InitFrom(service_prefs_);
195 info->proxy_id = settings.proxy_id();
198 void CloudPrintProxy::GetPrinters(std::vector<std::string>* printers) {
199 ConnectorSettings settings;
200 settings.InitFrom(service_prefs_);
201 scoped_refptr<PrintSystem> print_system =
202 PrintSystem::CreateInstance(settings.print_system_settings());
203 if (!print_system.get())
204 return;
205 PrintSystem::PrintSystemResult result = print_system->Init();
206 if (!result.succeeded())
207 return;
208 printing::PrinterList printer_list;
209 print_system->EnumeratePrinters(&printer_list);
210 for (size_t i = 0; i < printer_list.size(); ++i)
211 printers->push_back(printer_list[i].printer_name);
214 void CloudPrintProxy::CheckCloudPrintProxyPolicy() {
215 g_service_process->io_thread()->message_loop_proxy()->PostTask(
216 FROM_HERE, base::Bind(&CheckCloudPrintProxyPolicyInBrowser));
219 void CloudPrintProxy::OnAuthenticated(
220 const std::string& robot_oauth_refresh_token,
221 const std::string& robot_email,
222 const std::string& user_email) {
223 DCHECK(CalledOnValidThread());
224 service_prefs_->SetString(prefs::kCloudPrintRobotRefreshToken,
225 robot_oauth_refresh_token);
226 service_prefs_->SetString(prefs::kCloudPrintRobotEmail,
227 robot_email);
228 // If authenticating from a robot, the user email will be empty.
229 if (!user_email.empty()) {
230 user_email_ = user_email;
232 service_prefs_->SetString(prefs::kCloudPrintEmail, user_email_);
233 enabled_ = true;
234 DCHECK(!user_email_.empty());
235 service_prefs_->WritePrefs();
236 // When this switch used we don't want connector continue running, we just
237 // need authentication.
238 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
239 switches::kCloudPrintSetupProxy)) {
240 ShutdownBackend();
241 if (client_) {
242 client_->OnCloudPrintProxyDisabled(false);
247 void CloudPrintProxy::OnAuthenticationFailed() {
248 DCHECK(CalledOnValidThread());
249 // Don't disable permanently. Could be just connection issue.
250 ShutdownBackend();
251 if (client_) {
252 client_->OnCloudPrintProxyDisabled(false);
256 void CloudPrintProxy::OnPrintSystemUnavailable() {
257 // If the print system is unavailable, we want to shutdown the proxy and
258 // disable it non-persistently.
259 ShutdownBackend();
260 if (client_) {
261 client_->OnCloudPrintProxyDisabled(false);
265 void CloudPrintProxy::OnUnregisterPrinters(
266 const std::string& auth_token,
267 const std::list<std::string>& printer_ids) {
268 UMA_HISTOGRAM_COUNTS_10000("CloudPrint.UnregisterPrinters",
269 printer_ids.size());
270 ShutdownBackend();
271 ConnectorSettings settings;
272 settings.InitFrom(service_prefs_);
273 wipeout_.reset(new CloudPrintWipeout(this, settings.server_url()));
274 wipeout_->UnregisterPrinters(auth_token, printer_ids);
277 void CloudPrintProxy::OnXmppPingUpdated(int ping_timeout) {
278 DCHECK(CalledOnValidThread());
279 service_prefs_->SetInt(prefs::kCloudPrintXmppPingTimeout, ping_timeout);
280 service_prefs_->WritePrefs();
283 void CloudPrintProxy::OnUnregisterPrintersComplete() {
284 wipeout_.reset();
285 // Finish disabling cloud print for this user.
286 DisableForUser();
289 void CloudPrintProxy::ShutdownBackend() {
290 DCHECK(CalledOnValidThread());
291 if (backend_.get())
292 backend_->Shutdown();
293 backend_.reset();
296 } // namespace cloud_print