OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chrome_to_mobile_service.h" | 5 #include "chrome/browser/chrome_to_mobile_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/guid.h" | 10 #include "base/guid.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 return search_url.ReplaceComponents(replacements); | 133 return search_url.ReplaceComponents(replacements); |
134 } | 134 } |
135 | 135 |
136 // A callback to continue snapshot generation after creating the temp file. | 136 // A callback to continue snapshot generation after creating the temp file. |
137 typedef base::Callback<void(const FilePath& path, bool success)> | 137 typedef base::Callback<void(const FilePath& path, bool success)> |
138 CreateSnapshotFileCallback; | 138 CreateSnapshotFileCallback; |
139 | 139 |
140 // Create a temp file and post the callback on the UI thread with the results. | 140 // Create a temp file and post the callback on the UI thread with the results. |
141 // Call this as a BlockingPoolTask to avoid the FILE thread. | 141 // Call this as a BlockingPoolTask to avoid the FILE thread. |
142 void CreateSnapshotFile(CreateSnapshotFileCallback callback) { | 142 void CreateSnapshotFile(CreateSnapshotFileCallback callback) { |
143 FilePath snapshot; | 143 FilePath file; |
144 bool success = file_util::CreateTemporaryFile(&snapshot); | 144 bool success = file_util::CreateTemporaryFile(&file); |
145 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 145 if (!content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
146 base::Bind(callback, snapshot, success)); | 146 base::Bind(callback, file, success))) { |
| 147 NOTREACHED(); |
| 148 } |
147 } | 149 } |
148 | 150 |
149 // Delete the snapshot file; DCHECK, but really ignore the result of the delete. | 151 // Delete the snapshot file; DCHECK, but really ignore the result of the delete. |
150 // Call this as a BlockingPoolSequencedTask [after posting SubmitSnapshotFile]. | 152 // Call this as a BlockingPoolSequencedTask [after posting SubmitSnapshotFile]. |
151 void DeleteSnapshotFile(const FilePath& snapshot) { | 153 void DeleteSnapshotFile(const FilePath& snapshot) { |
152 bool success = file_util::Delete(snapshot, false); | 154 bool success = file_util::Delete(snapshot, false); |
153 DCHECK(success); | 155 DCHECK(success); |
154 } | 156 } |
155 | 157 |
156 } // namespace | 158 } // namespace |
(...skipping 23 matching lines...) Expand all Loading... |
180 PrefService::UNSYNCABLE_PREF); | 182 PrefService::UNSYNCABLE_PREF); |
181 prefs->RegisterInt64Pref(prefs::kChromeToMobileTimestamp, 0, | 183 prefs->RegisterInt64Pref(prefs::kChromeToMobileTimestamp, 0, |
182 PrefService::UNSYNCABLE_PREF); | 184 PrefService::UNSYNCABLE_PREF); |
183 } | 185 } |
184 | 186 |
185 ChromeToMobileService::ChromeToMobileService(Profile* profile) | 187 ChromeToMobileService::ChromeToMobileService(Profile* profile) |
186 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | 188 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
187 profile_(profile), | 189 profile_(profile), |
188 cloud_print_url_(new CloudPrintURL(profile)), | 190 cloud_print_url_(new CloudPrintURL(profile)), |
189 cloud_print_accessible_(false) { | 191 cloud_print_accessible_(false) { |
190 // Skip initialization if constructed without a profile. | 192 // TODO(msw): Fix GMock tests, which lack profiles (http://crbug.com/122183). |
191 if (profile_) { | 193 if (profile_) { |
192 // Get an access token as soon as the Gaia login refresh token is available. | 194 // Get an access token as soon as the Gaia login refresh token is available. |
193 TokenService* service = TokenServiceFactory::GetForProfile(profile_); | 195 TokenService* service = TokenServiceFactory::GetForProfile(profile_); |
194 registrar_.Add(this, chrome::NOTIFICATION_TOKEN_AVAILABLE, | 196 registrar_.Add(this, chrome::NOTIFICATION_TOKEN_AVAILABLE, |
195 content::Source<TokenService>(service)); | 197 content::Source<TokenService>(service)); |
196 if (service->HasOAuthLoginToken()) | 198 if (service->HasOAuthLoginToken()) |
197 RefreshAccessToken(); | 199 RequestAccessToken(); |
198 } | 200 } |
199 } | 201 } |
200 | 202 |
201 ChromeToMobileService::~ChromeToMobileService() { | 203 ChromeToMobileService::~ChromeToMobileService() { |
202 while (!snapshots_.empty()) | 204 while (!snapshots_.empty()) |
203 DeleteSnapshot(*snapshots_.begin()); | 205 DeleteSnapshot(*snapshots_.begin()); |
204 } | 206 } |
205 | 207 |
206 bool ChromeToMobileService::HasMobiles() { | 208 bool ChromeToMobileService::HasMobiles() const { |
207 return !GetMobiles()->empty(); | 209 return !GetMobiles()->empty(); |
208 } | 210 } |
209 | 211 |
210 const base::ListValue* ChromeToMobileService::GetMobiles() const { | 212 const base::ListValue* ChromeToMobileService::GetMobiles() const { |
211 return profile_->GetPrefs()->GetList(prefs::kChromeToMobileDeviceList); | 213 return profile_->GetPrefs()->GetList(prefs::kChromeToMobileDeviceList); |
212 } | 214 } |
213 | 215 |
214 void ChromeToMobileService::RequestMobileListUpdate() { | 216 void ChromeToMobileService::RequestMobileListUpdate() { |
215 if (access_token_.empty()) | 217 if (access_token_.empty()) |
216 RefreshAccessToken(); | 218 RequestAccessToken(); |
217 else if (cloud_print_accessible_) | 219 else if (cloud_print_accessible_) |
218 RequestSearch(); | 220 RequestDeviceSearch(); |
219 } | 221 } |
220 | 222 |
221 void ChromeToMobileService::GenerateSnapshot(Browser* browser, | 223 void ChromeToMobileService::GenerateSnapshot(Browser* browser, |
222 base::WeakPtr<Observer> observer) { | 224 base::WeakPtr<Observer> observer) { |
223 // Callback SnapshotFileCreated from CreateSnapshotFile to continue. | 225 // Callback SnapshotFileCreated from CreateSnapshotFile to continue. |
224 CreateSnapshotFileCallback callback = | 226 CreateSnapshotFileCallback callback = |
225 base::Bind(&ChromeToMobileService::SnapshotFileCreated, | 227 base::Bind(&ChromeToMobileService::SnapshotFileCreated, |
226 weak_ptr_factory_.GetWeakPtr(), observer, | 228 weak_ptr_factory_.GetWeakPtr(), observer, |
227 browser->session_id().id()); | 229 browser->session_id().id()); |
228 // Create a temporary file via the blocking pool for snapshot storage. | 230 // Create a temporary file via the blocking pool for snapshot storage. |
229 content::BrowserThread::PostBlockingPoolTask(FROM_HERE, | 231 if (!content::BrowserThread::PostBlockingPoolTask(FROM_HERE, |
230 base::Bind(&CreateSnapshotFile, callback)); | 232 base::Bind(&CreateSnapshotFile, callback))) { |
| 233 NOTREACHED(); |
| 234 } |
231 } | 235 } |
232 | 236 |
233 void ChromeToMobileService::SendToMobile(const base::DictionaryValue& mobile, | 237 void ChromeToMobileService::SendToMobile(const base::DictionaryValue& mobile, |
234 const FilePath& snapshot, | 238 const FilePath& snapshot, |
235 Browser* browser, | 239 Browser* browser, |
236 base::WeakPtr<Observer> observer) { | 240 base::WeakPtr<Observer> observer) { |
237 LogMetric(SENDING_URL); | 241 LogMetric(SENDING_URL); |
238 | 242 |
239 DCHECK(!access_token_.empty()); | |
240 JobData data; | 243 JobData data; |
241 std::string mobile_os; | 244 std::string mobile_os; |
242 if (!mobile.GetString("type", &mobile_os)) | 245 if (!mobile.GetString("type", &mobile_os)) |
243 NOTREACHED(); | 246 NOTREACHED(); |
244 data.mobile_os = (mobile_os.compare(kTypeAndroid) == 0) ? | 247 data.mobile_os = (mobile_os.compare(kTypeAndroid) == 0) ? |
245 ChromeToMobileService::ANDROID : ChromeToMobileService::IOS; | 248 ChromeToMobileService::ANDROID : ChromeToMobileService::IOS; |
246 if (!mobile.GetString("id", &data.mobile_id)) | 249 if (!mobile.GetString("id", &data.mobile_id)) |
247 NOTREACHED(); | 250 NOTREACHED(); |
248 content::WebContents* web_contents = chrome::GetActiveWebContents(browser); | 251 content::WebContents* web_contents = chrome::GetActiveWebContents(browser); |
249 data.url = web_contents->GetURL(); | 252 data.url = web_contents->GetURL(); |
250 data.title = web_contents->GetTitle(); | 253 data.title = web_contents->GetTitle(); |
251 data.snapshot = snapshot; | 254 data.snapshot = snapshot; |
252 data.snapshot_id = base::GenerateGUID(); | 255 data.snapshot_id = base::GenerateGUID(); |
253 data.type = !snapshot.empty() ? DELAYED_SNAPSHOT : URL; | 256 data.type = !snapshot.empty() ? DELAYED_SNAPSHOT : URL; |
254 | 257 |
255 net::URLFetcher* submit_url = CreateRequest(data); | 258 net::URLFetcher* submit_url = CreateRequest(data); |
256 request_observer_map_[submit_url] = observer; | 259 request_observer_map_[submit_url] = observer; |
257 SendRequest(submit_url, data); | 260 SendRequest(submit_url, data); |
258 | 261 |
259 if (data.type == DELAYED_SNAPSHOT) { | 262 if (data.type == DELAYED_SNAPSHOT) { |
260 LogMetric(SENDING_SNAPSHOT); | 263 LogMetric(SENDING_SNAPSHOT); |
261 | 264 |
262 data.type = SNAPSHOT; | 265 data.type = SNAPSHOT; |
263 net::URLFetcher* submit_snapshot = CreateRequest(data); | 266 net::URLFetcher* submit_snapshot = CreateRequest(data); |
264 request_observer_map_[submit_snapshot] = observer; | 267 request_observer_map_[submit_snapshot] = observer; |
265 content::BrowserThread::PostBlockingPoolSequencedTask( | 268 if (!content::BrowserThread::PostBlockingPoolSequencedTask( |
266 data.snapshot.AsUTF8Unsafe(), FROM_HERE, | 269 data.snapshot.AsUTF8Unsafe(), FROM_HERE, |
267 base::Bind(&ChromeToMobileService::SendRequest, | 270 base::Bind(&ChromeToMobileService::SendRequest, |
268 weak_ptr_factory_.GetWeakPtr(), submit_snapshot, data)); | 271 weak_ptr_factory_.GetWeakPtr(), |
| 272 submit_snapshot, data))) { |
| 273 NOTREACHED(); |
| 274 } |
269 } | 275 } |
270 } | 276 } |
271 | 277 |
272 void ChromeToMobileService::DeleteSnapshot(const FilePath& snapshot) { | 278 void ChromeToMobileService::DeleteSnapshot(const FilePath& snapshot) { |
273 DCHECK(snapshot.empty() || snapshots_.find(snapshot) != snapshots_.end()); | 279 DCHECK(snapshot.empty() || snapshots_.find(snapshot) != snapshots_.end()); |
274 if (snapshots_.find(snapshot) != snapshots_.end()) { | 280 if (snapshots_.find(snapshot) != snapshots_.end()) { |
275 if (!snapshot.empty()) | 281 if (!snapshot.empty()) { |
276 content::BrowserThread::PostBlockingPoolSequencedTask( | 282 if (!content::BrowserThread::PostBlockingPoolSequencedTask( |
277 snapshot.AsUTF8Unsafe(), FROM_HERE, | 283 snapshot.AsUTF8Unsafe(), FROM_HERE, |
278 base::Bind(&DeleteSnapshotFile, snapshot)); | 284 base::Bind(&DeleteSnapshotFile, snapshot))) { |
| 285 NOTREACHED(); |
| 286 } |
| 287 } |
279 snapshots_.erase(snapshot); | 288 snapshots_.erase(snapshot); |
280 } | 289 } |
281 } | 290 } |
282 | 291 |
283 void ChromeToMobileService::LogMetric(Metric metric) const { | 292 void ChromeToMobileService::LogMetric(Metric metric) const { |
284 UMA_HISTOGRAM_ENUMERATION("ChromeToMobile.Service", metric, NUM_METRICS); | 293 UMA_HISTOGRAM_ENUMERATION("ChromeToMobile.Service", metric, NUM_METRICS); |
285 } | 294 } |
286 | 295 |
287 void ChromeToMobileService::LearnMore(Browser* browser) const { | 296 void ChromeToMobileService::LearnMore(Browser* browser) const { |
288 LogMetric(LEARN_MORE_CLICKED); | 297 LogMetric(LEARN_MORE_CLICKED); |
(...skipping 14 matching lines...) Expand all Loading... |
303 } | 312 } |
304 | 313 |
305 void ChromeToMobileService::Observe( | 314 void ChromeToMobileService::Observe( |
306 int type, | 315 int type, |
307 const content::NotificationSource& source, | 316 const content::NotificationSource& source, |
308 const content::NotificationDetails& details) { | 317 const content::NotificationDetails& details) { |
309 DCHECK_EQ(type, chrome::NOTIFICATION_TOKEN_AVAILABLE); | 318 DCHECK_EQ(type, chrome::NOTIFICATION_TOKEN_AVAILABLE); |
310 TokenService::TokenAvailableDetails* token_details = | 319 TokenService::TokenAvailableDetails* token_details = |
311 content::Details<TokenService::TokenAvailableDetails>(details).ptr(); | 320 content::Details<TokenService::TokenAvailableDetails>(details).ptr(); |
312 if (token_details->service() == GaiaConstants::kGaiaOAuth2LoginRefreshToken) | 321 if (token_details->service() == GaiaConstants::kGaiaOAuth2LoginRefreshToken) |
313 RefreshAccessToken(); | 322 RequestAccessToken(); |
314 } | 323 } |
315 | 324 |
316 void ChromeToMobileService::OnGetTokenSuccess( | 325 void ChromeToMobileService::OnGetTokenSuccess( |
317 const std::string& access_token, | 326 const std::string& access_token, |
318 const base::Time& expiration_time) { | 327 const base::Time& expiration_time) { |
319 DCHECK(!access_token.empty()); | 328 DCHECK(!access_token.empty()); |
320 access_token_fetcher_.reset(); | 329 access_token_fetcher_.reset(); |
321 auth_retry_timer_.Stop(); | 330 auth_retry_timer_.Stop(); |
322 access_token_ = access_token; | 331 access_token_ = access_token; |
323 RequestAccountInfo(); | 332 RequestAccountInfo(); |
324 } | 333 } |
325 | 334 |
326 void ChromeToMobileService::OnGetTokenFailure( | 335 void ChromeToMobileService::OnGetTokenFailure( |
327 const GoogleServiceAuthError& error) { | 336 const GoogleServiceAuthError& error) { |
328 access_token_fetcher_.reset(); | 337 access_token_fetcher_.reset(); |
329 auth_retry_timer_.Stop(); | 338 auth_retry_timer_.Stop(); |
330 auth_retry_timer_.Start( | 339 auth_retry_timer_.Start( |
331 FROM_HERE, base::TimeDelta::FromHours(kAuthRetryDelayHours), | 340 FROM_HERE, base::TimeDelta::FromHours(kAuthRetryDelayHours), |
332 this, &ChromeToMobileService::RefreshAccessToken); | 341 this, &ChromeToMobileService::RequestAccessToken); |
| 342 } |
| 343 |
| 344 void ChromeToMobileService::UpdateCommandState() const { |
| 345 // Ensure the feature is not disabled by commandline options. |
| 346 DCHECK(IsChromeToMobileEnabled()); |
| 347 const bool has_mobiles = HasMobiles(); |
| 348 for (BrowserList::const_iterator i = BrowserList::begin(); |
| 349 i != BrowserList::end(); ++i) { |
| 350 Browser* browser = *i; |
| 351 if (browser->profile() == profile_) |
| 352 browser->command_controller()->SendToMobileStateChanged(has_mobiles); |
| 353 } |
333 } | 354 } |
334 | 355 |
335 void ChromeToMobileService::SnapshotFileCreated( | 356 void ChromeToMobileService::SnapshotFileCreated( |
336 base::WeakPtr<Observer> observer, | 357 base::WeakPtr<Observer> observer, |
337 SessionID::id_type browser_id, | 358 SessionID::id_type browser_id, |
338 const FilePath& path, | 359 const FilePath& path, |
339 bool success) { | 360 bool success) { |
340 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 361 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
341 // Track the set of temporary files to be deleted later. | 362 // Track the set of temporary files to be deleted later. |
342 snapshots_.insert(path); | 363 snapshots_.insert(path); |
(...skipping 13 matching lines...) Expand all Loading... |
356 const GURL service_url(cloud_print_url_->GetCloudPrintServiceURL()); | 377 const GURL service_url(cloud_print_url_->GetCloudPrintServiceURL()); |
357 net::URLFetcher* request = net::URLFetcher::Create( | 378 net::URLFetcher* request = net::URLFetcher::Create( |
358 cloud_print::GetUrlForSubmit(service_url), net::URLFetcher::POST, this); | 379 cloud_print::GetUrlForSubmit(service_url), net::URLFetcher::POST, this); |
359 InitRequest(request); | 380 InitRequest(request); |
360 return request; | 381 return request; |
361 } | 382 } |
362 | 383 |
363 void ChromeToMobileService::InitRequest(net::URLFetcher* request) { | 384 void ChromeToMobileService::InitRequest(net::URLFetcher* request) { |
364 request->SetRequestContext(profile_->GetRequestContext()); | 385 request->SetRequestContext(profile_->GetRequestContext()); |
365 request->SetMaxRetries(kMaxRetries); | 386 request->SetMaxRetries(kMaxRetries); |
| 387 DCHECK(!access_token_.empty()); |
366 request->SetExtraRequestHeaders("Authorization: OAuth " + | 388 request->SetExtraRequestHeaders("Authorization: OAuth " + |
367 access_token_ + "\r\n" + cloud_print::kChromeCloudPrintProxyHeader); | 389 access_token_ + "\r\n" + cloud_print::kChromeCloudPrintProxyHeader); |
368 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 390 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
369 net::LOAD_DO_NOT_SAVE_COOKIES); | 391 net::LOAD_DO_NOT_SAVE_COOKIES); |
370 } | 392 } |
371 | 393 |
372 void ChromeToMobileService::SendRequest(net::URLFetcher* request, | 394 void ChromeToMobileService::SendRequest(net::URLFetcher* request, |
373 const JobData& data) { | 395 const JobData& data) { |
374 std::string post, bound; | 396 std::string post, bound; |
375 cloud_print::CreateMimeBoundaryForUpload(&bound); | 397 cloud_print::CreateMimeBoundaryForUpload(&bound); |
(...skipping 29 matching lines...) Expand all Loading... |
405 return; | 427 return; |
406 } | 428 } |
407 cloud_print::AddMultipartValueForUpload("content", file, bound, | 429 cloud_print::AddMultipartValueForUpload("content", file, bound, |
408 "text/mhtml", &post); | 430 "text/mhtml", &post); |
409 | 431 |
410 post.append("--" + bound + "--\r\n"); | 432 post.append("--" + bound + "--\r\n"); |
411 request->SetUploadData("multipart/form-data; boundary=" + bound, post); | 433 request->SetUploadData("multipart/form-data; boundary=" + bound, post); |
412 request->Start(); | 434 request->Start(); |
413 } | 435 } |
414 | 436 |
415 void ChromeToMobileService::RefreshAccessToken() { | 437 void ChromeToMobileService::RequestAccessToken() { |
416 if (access_token_fetcher_.get()) | 438 // Deny concurrent requests and bail without a valid Gaia login refresh token. |
417 return; | 439 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
418 | 440 if (access_token_fetcher_.get() || !token_service->HasOAuthLoginToken()) |
419 std::string token = TokenServiceFactory::GetForProfile(profile_)-> | |
420 GetOAuth2LoginRefreshToken(); | |
421 if (token.empty()) | |
422 return; | 441 return; |
423 | 442 |
424 auth_retry_timer_.Stop(); | 443 auth_retry_timer_.Stop(); |
425 access_token_fetcher_.reset( | 444 access_token_fetcher_.reset( |
426 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext())); | 445 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext())); |
427 std::vector<std::string> scopes(1, kCloudPrintAuth); | |
428 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); | 446 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); |
429 access_token_fetcher_->Start(gaia_urls->oauth2_chrome_client_id(), | 447 access_token_fetcher_->Start(gaia_urls->oauth2_chrome_client_id(), |
430 gaia_urls->oauth2_chrome_client_secret(), token, scopes); | 448 gaia_urls->oauth2_chrome_client_secret(), |
| 449 token_service->GetOAuth2LoginRefreshToken(), |
| 450 std::vector<std::string>(1, kCloudPrintAuth)); |
431 } | 451 } |
432 | 452 |
433 void ChromeToMobileService::RequestAccountInfo() { | 453 void ChromeToMobileService::RequestAccountInfo() { |
434 // Deny concurrent requests. | 454 // Deny concurrent requests. |
435 if (account_info_request_.get()) | 455 if (account_info_request_.get()) |
436 return; | 456 return; |
437 | 457 |
438 std::string url_string = StringPrintf(kAccountInfoURL, | 458 std::string url_string = StringPrintf(kAccountInfoURL, |
439 base::GenerateGUID().c_str(), kChromeToMobileRequestor); | 459 base::GenerateGUID().c_str(), kChromeToMobileRequestor); |
440 GURL url(url_string); | 460 GURL url(url_string); |
(...skipping 10 matching lines...) Expand all Loading... |
451 | 471 |
452 account_info_request_.reset( | 472 account_info_request_.reset( |
453 net::URLFetcher::Create(url, net::URLFetcher::GET, this)); | 473 net::URLFetcher::Create(url, net::URLFetcher::GET, this)); |
454 account_info_request_->SetRequestContext(profile_->GetRequestContext()); | 474 account_info_request_->SetRequestContext(profile_->GetRequestContext()); |
455 account_info_request_->SetMaxRetries(kMaxRetries); | 475 account_info_request_->SetMaxRetries(kMaxRetries); |
456 // This request sends the user's cookie to check the cloud print service flag. | 476 // This request sends the user's cookie to check the cloud print service flag. |
457 account_info_request_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); | 477 account_info_request_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); |
458 account_info_request_->Start(); | 478 account_info_request_->Start(); |
459 } | 479 } |
460 | 480 |
461 void ChromeToMobileService::RequestSearch() { | 481 void ChromeToMobileService::RequestDeviceSearch() { |
462 DCHECK(!access_token_.empty()); | |
463 | |
464 // Deny requests if cloud print is inaccessible, and deny concurrent requests. | 482 // Deny requests if cloud print is inaccessible, and deny concurrent requests. |
465 if (!cloud_print_accessible_ || search_request_.get()) | 483 if (!cloud_print_accessible_ || search_request_.get()) |
466 return; | 484 return; |
467 | 485 |
468 PrefService* prefs = profile_->GetPrefs(); | 486 PrefService* prefs = profile_->GetPrefs(); |
469 base::TimeTicks previous_search_time = base::TimeTicks::FromInternalValue( | 487 base::TimeTicks previous_search_time = base::TimeTicks::FromInternalValue( |
470 prefs->GetInt64(prefs::kChromeToMobileTimestamp)); | 488 prefs->GetInt64(prefs::kChromeToMobileTimestamp)); |
471 | 489 |
472 // Deny requests before the delay period has passed since the last request. | 490 // Deny requests before the delay period has passed since the last request. |
473 base::TimeDelta elapsed_time = base::TimeTicks::Now() - previous_search_time; | 491 base::TimeDelta elapsed_time = base::TimeTicks::Now() - previous_search_time; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 dictionary->GetList(cloud_print::kPrinterListValue, &list)) { | 535 dictionary->GetList(cloud_print::kPrinterListValue, &list)) { |
518 ListValue mobiles; | 536 ListValue mobiles; |
519 std::string type, name, id; | 537 std::string type, name, id; |
520 DictionaryValue* printer = NULL; | 538 DictionaryValue* printer = NULL; |
521 DictionaryValue* mobile = NULL; | 539 DictionaryValue* mobile = NULL; |
522 for (size_t index = 0; index < list->GetSize(); ++index) { | 540 for (size_t index = 0; index < list->GetSize(); ++index) { |
523 if (list->GetDictionary(index, &printer) && | 541 if (list->GetDictionary(index, &printer) && |
524 printer->GetString("type", &type) && | 542 printer->GetString("type", &type) && |
525 (type.compare(kTypeAndroid) == 0 || type.compare(kTypeIOS) == 0)) { | 543 (type.compare(kTypeAndroid) == 0 || type.compare(kTypeIOS) == 0)) { |
526 // Copy just the requisite values from the full |printer| definition. | 544 // Copy just the requisite values from the full |printer| definition. |
527 if (printer->GetString("name", &name) && | 545 if (printer->GetString("displayName", &name) && |
528 printer->GetString("id", &id)) { | 546 printer->GetString("id", &id)) { |
529 mobile = new DictionaryValue(); | 547 mobile = new DictionaryValue(); |
530 mobile->SetString("type", type); | 548 mobile->SetString("type", type); |
531 mobile->SetString("name", name); | 549 mobile->SetString("name", name); |
532 mobile->SetString("id", id); | 550 mobile->SetString("id", id); |
533 mobiles.Append(mobile); | 551 mobiles.Append(mobile); |
534 } else { | 552 } else { |
535 NOTREACHED(); | 553 NOTREACHED(); |
536 } | 554 } |
537 } | 555 } |
538 } | 556 } |
539 | 557 |
540 // Update the mobile list and timestamp in prefs. | 558 // Update the mobile list and timestamp in prefs. |
541 PrefService* prefs = profile_->GetPrefs(); | 559 PrefService* prefs = profile_->GetPrefs(); |
542 prefs->Set(prefs::kChromeToMobileDeviceList, mobiles); | 560 prefs->Set(prefs::kChromeToMobileDeviceList, mobiles); |
543 prefs->SetInt64(prefs::kChromeToMobileTimestamp, | 561 prefs->SetInt64(prefs::kChromeToMobileTimestamp, |
544 base::TimeTicks::Now().ToInternalValue()); | 562 base::TimeTicks::Now().ToInternalValue()); |
545 | 563 |
546 const bool has_mobiles = HasMobiles(); | 564 if (HasMobiles()) |
547 if (has_mobiles) | |
548 LogMetric(DEVICES_AVAILABLE); | 565 LogMetric(DEVICES_AVAILABLE); |
549 | 566 UpdateCommandState(); |
550 for (BrowserList::const_iterator i = BrowserList::begin(); | |
551 i != BrowserList::end(); ++i) { | |
552 Browser* browser = *i; | |
553 if (browser->profile() == profile_) | |
554 browser->command_controller()->SendToMobileStateChanged(has_mobiles); | |
555 } | |
556 } | 567 } |
557 } | 568 } |
558 | 569 |
559 void ChromeToMobileService::HandleSubmitResponse( | 570 void ChromeToMobileService::HandleSubmitResponse( |
560 const net::URLFetcher* source) { | 571 const net::URLFetcher* source) { |
561 // Get the observer for this response; bail if there is none or it is NULL. | 572 // Get the observer for this response; bail if there is none or it is NULL. |
562 RequestObserverMap::iterator i = request_observer_map_.find(source); | 573 RequestObserverMap::iterator i = request_observer_map_.find(source); |
563 if (i == request_observer_map_.end()) | 574 if (i == request_observer_map_.end()) |
564 return; | 575 return; |
565 base::WeakPtr<Observer> observer = i->second; | 576 base::WeakPtr<Observer> observer = i->second; |
(...skipping 20 matching lines...) Expand all Loading... |
586 | 597 |
587 // Ensure a second response is not sent after reporting failure below. | 598 // Ensure a second response is not sent after reporting failure below. |
588 request_observer_map_.erase(other); | 599 request_observer_map_.erase(other); |
589 break; | 600 break; |
590 } | 601 } |
591 } | 602 } |
592 | 603 |
593 LogMetric(success ? SEND_SUCCESS : SEND_ERROR); | 604 LogMetric(success ? SEND_SUCCESS : SEND_ERROR); |
594 observer->OnSendComplete(success); | 605 observer->OnSendComplete(success); |
595 } | 606 } |
OLD | NEW |