| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 if (!content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 387 if (!content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 388 task_queue_.front())) { | 388 task_queue_.front())) { |
| 389 NOTREACHED(); | 389 NOTREACHED(); |
| 390 } | 390 } |
| 391 task_queue_.pop(); | 391 task_queue_.pop(); |
| 392 } | 392 } |
| 393 } | 393 } |
| 394 | 394 |
| 395 void ChromeToMobileService::OnGetTokenFailure( | 395 void ChromeToMobileService::OnGetTokenFailure( |
| 396 const GoogleServiceAuthError& error) { | 396 const GoogleServiceAuthError& error) { |
| 397 // Log a general auth error metric for the "ChromeToMobile.Service" histogram. |
| 397 LogMetric(BAD_TOKEN); | 398 LogMetric(BAD_TOKEN); |
| 399 // Log a more detailed metric for the "ChromeToMobile.AuthError" histogram. |
| 400 UMA_HISTOGRAM_ENUMERATION("ChromeToMobile.AuthError", error.state(), |
| 401 GoogleServiceAuthError::NUM_STATES); |
| 402 VLOG(0) << "ChromeToMobile auth failed: " << error.ToString(); |
| 403 |
| 398 access_token_.clear(); | 404 access_token_.clear(); |
| 399 access_token_fetcher_.reset(); | 405 access_token_fetcher_.reset(); |
| 400 auth_retry_timer_.Stop(); | 406 auth_retry_timer_.Stop(); |
| 401 | 407 |
| 402 base::TimeDelta delay = std::max(base::TimeDelta::FromHours(kDelayHours), | 408 base::TimeDelta delay = std::max(base::TimeDelta::FromHours(kDelayHours), |
| 403 auth_retry_timer_.GetCurrentDelay() * 2); | 409 auth_retry_timer_.GetCurrentDelay() * 2); |
| 404 auth_retry_timer_.Start(FROM_HERE, delay, this, | 410 auth_retry_timer_.Start(FROM_HERE, delay, this, |
| 405 &ChromeToMobileService::RequestAccessToken); | 411 &ChromeToMobileService::RequestAccessToken); |
| 406 | 412 |
| 407 // Clear the mobile list, which may be (or become) out of date. | 413 // Clear the mobile list, which may be (or become) out of date. |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 search_request->Start(); | 593 search_request->Start(); |
| 588 } | 594 } |
| 589 | 595 |
| 590 void ChromeToMobileService::HandleSearchResponse( | 596 void ChromeToMobileService::HandleSearchResponse( |
| 591 const net::URLFetcher* source) { | 597 const net::URLFetcher* source) { |
| 592 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 598 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 593 DCHECK_EQ(source->GetURL(), GetSearchURL(cloud_print_url_)); | 599 DCHECK_EQ(source->GetURL(), GetSearchURL(cloud_print_url_)); |
| 594 | 600 |
| 595 ListValue mobiles; | 601 ListValue mobiles; |
| 596 std::string data; | 602 std::string data; |
| 603 bool success = false; |
| 597 ListValue* list = NULL; | 604 ListValue* list = NULL; |
| 598 DictionaryValue* dictionary = NULL; | 605 DictionaryValue* dictionary = NULL; |
| 599 source->GetResponseAsString(&data); | 606 source->GetResponseAsString(&data); |
| 600 scoped_ptr<Value> json(base::JSONReader::Read(data)); | 607 scoped_ptr<Value> json(base::JSONReader::Read(data)); |
| 601 if (json.get() && json->GetAsDictionary(&dictionary) && dictionary && | 608 if (json.get() && json->GetAsDictionary(&dictionary) && dictionary) { |
| 602 dictionary->GetList(cloud_print::kPrinterListValue, &list)) { | 609 dictionary->GetBoolean("success", &success); |
| 603 std::string type, name, id; | 610 if (dictionary->GetList(cloud_print::kPrinterListValue, &list)) { |
| 604 DictionaryValue* printer = NULL; | 611 std::string type, name, id; |
| 605 DictionaryValue* mobile = NULL; | 612 DictionaryValue* printer = NULL; |
| 606 for (size_t index = 0; index < list->GetSize(); ++index) { | 613 DictionaryValue* mobile = NULL; |
| 607 if (list->GetDictionary(index, &printer) && | 614 for (size_t index = 0; index < list->GetSize(); ++index) { |
| 608 printer->GetString("type", &type) && | 615 if (list->GetDictionary(index, &printer) && |
| 609 (type.compare(kTypeAndroid) == 0 || type.compare(kTypeIOS) == 0)) { | 616 printer->GetString("type", &type) && |
| 610 // Copy just the requisite values from the full |printer| definition. | 617 (type.compare(kTypeAndroid) == 0 || type.compare(kTypeIOS) == 0)) { |
| 611 if (printer->GetString("displayName", &name) && | 618 // Copy just the requisite values from the full |printer| definition. |
| 612 printer->GetString("id", &id)) { | 619 if (printer->GetString("displayName", &name) && |
| 613 mobile = new DictionaryValue(); | 620 printer->GetString("id", &id)) { |
| 614 mobile->SetString("type", type); | 621 mobile = new DictionaryValue(); |
| 615 mobile->SetString("name", name); | 622 mobile->SetString("type", type); |
| 616 mobile->SetString("id", id); | 623 mobile->SetString("name", name); |
| 617 mobiles.Append(mobile); | 624 mobile->SetString("id", id); |
| 618 } else { | 625 mobiles.Append(mobile); |
| 619 NOTREACHED(); | 626 } else { |
| 627 NOTREACHED(); |
| 628 } |
| 620 } | 629 } |
| 621 } | 630 } |
| 622 } | 631 } |
| 623 } else if (source->GetResponseCode() == net::HTTP_FORBIDDEN) { | 632 } else if (source->GetResponseCode() == net::HTTP_FORBIDDEN) { |
| 624 LogMetric(BAD_SEARCH_AUTH); | 633 LogMetric(BAD_SEARCH_AUTH); |
| 625 // Invalidate the access token and retry a delayed search on access errors. | 634 // Invalidate the access token and retry a delayed search on access errors. |
| 626 access_token_.clear(); | 635 access_token_.clear(); |
| 627 search_retry_timer_.Stop(); | 636 search_retry_timer_.Stop(); |
| 628 base::TimeDelta delay = std::max(base::TimeDelta::FromHours(kDelayHours), | 637 base::TimeDelta delay = std::max(base::TimeDelta::FromHours(kDelayHours), |
| 629 search_retry_timer_.GetCurrentDelay() * 2); | 638 search_retry_timer_.GetCurrentDelay() * 2); |
| 630 search_retry_timer_.Start(FROM_HERE, delay, this, | 639 search_retry_timer_.Start(FROM_HERE, delay, this, |
| 631 &ChromeToMobileService::RequestDeviceSearch); | 640 &ChromeToMobileService::RequestDeviceSearch); |
| 632 } else { | 641 } else { |
| 633 LogMetric(BAD_SEARCH_OTHER); | 642 LogMetric(BAD_SEARCH_OTHER); |
| 634 } | 643 } |
| 635 | 644 |
| 636 // Update the cached mobile device list in profile prefs. | 645 // Update the cached mobile device list in profile prefs. |
| 637 profile_->GetPrefs()->Set(prefs::kChromeToMobileDeviceList, mobiles); | 646 profile_->GetPrefs()->Set(prefs::kChromeToMobileDeviceList, mobiles); |
| 647 |
| 638 if (HasMobiles()) | 648 if (HasMobiles()) |
| 639 LogMetric(DEVICES_AVAILABLE); | 649 LogMetric(DEVICES_AVAILABLE); |
| 650 LogMetric(success ? SEARCH_SUCCESS : SEARCH_ERROR); |
| 651 VLOG_IF(0, !success) << "ChromeToMobile search failed (" << |
| 652 source->GetResponseCode() << "): " << data; |
| 653 |
| 640 UpdateCommandState(); | 654 UpdateCommandState(); |
| 641 } | 655 } |
| 642 | 656 |
| 643 void ChromeToMobileService::HandleSubmitResponse( | 657 void ChromeToMobileService::HandleSubmitResponse( |
| 644 const net::URLFetcher* source) { | 658 const net::URLFetcher* source) { |
| 645 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 659 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 646 // Get the success value from the cloud print server response data. | 660 // Get the success value from the cloud print server response data. |
| 647 std::string data; | 661 std::string data; |
| 648 bool success = false; | 662 bool success = false; |
| 649 source->GetResponseAsString(&data); | 663 source->GetResponseAsString(&data); |
| 650 DictionaryValue* dictionary = NULL; | 664 DictionaryValue* dictionary = NULL; |
| 651 scoped_ptr<Value> json(base::JSONReader::Read(data)); | 665 scoped_ptr<Value> json(base::JSONReader::Read(data)); |
| 652 if (json.get() && json->GetAsDictionary(&dictionary) && dictionary) { | 666 if (json.get() && json->GetAsDictionary(&dictionary) && dictionary) { |
| 653 dictionary->GetBoolean("success", &success); | 667 dictionary->GetBoolean("success", &success); |
| 654 int error_code = -1; | 668 int error_code = -1; |
| 655 if (dictionary->GetInteger("errorCode", &error_code)) | 669 if (dictionary->GetInteger("errorCode", &error_code)) |
| 656 LogMetric(error_code == 407 ? BAD_SEND_407 : BAD_SEND_ERROR); | 670 LogMetric(error_code == 407 ? BAD_SEND_407 : BAD_SEND_ERROR); |
| 657 } else if (source->GetResponseCode() == net::HTTP_FORBIDDEN) { | 671 } else if (source->GetResponseCode() == net::HTTP_FORBIDDEN) { |
| 658 LogMetric(BAD_SEND_AUTH); | 672 LogMetric(BAD_SEND_AUTH); |
| 659 } else { | 673 } else { |
| 660 LogMetric(BAD_SEND_OTHER); | 674 LogMetric(BAD_SEND_OTHER); |
| 661 } | 675 } |
| 662 | 676 |
| 663 // Log each URL and [DELAYED_]SNAPSHOT job submission response. | 677 // Log each URL and [DELAYED_]SNAPSHOT job submission response. |
| 664 LogMetric(success ? SEND_SUCCESS : SEND_ERROR); | 678 LogMetric(success ? SEND_SUCCESS : SEND_ERROR); |
| 665 LOG_IF(INFO, !success) << "ChromeToMobile send failed (" << | 679 VLOG_IF(0, !success) << "ChromeToMobile send failed (" << |
| 666 source->GetResponseCode() << "): " << data; | 680 source->GetResponseCode() << "): " << data; |
| 667 | 681 |
| 668 // Get the observer for this job submission response. | 682 // Get the observer for this job submission response. |
| 669 base::WeakPtr<Observer> observer; | 683 base::WeakPtr<Observer> observer; |
| 670 RequestObserverMap::iterator i = request_observer_map_.find(source); | 684 RequestObserverMap::iterator i = request_observer_map_.find(source); |
| 671 if (i != request_observer_map_.end()) { | 685 if (i != request_observer_map_.end()) { |
| 672 observer = i->second; | 686 observer = i->second; |
| 673 request_observer_map_.erase(i); | 687 request_observer_map_.erase(i); |
| 674 } | 688 } |
| 675 | 689 |
| 676 // Check if the observer is waiting on a second response (url or snapshot). | 690 // Check if the observer is waiting on a second response (url or snapshot). |
| 677 for (RequestObserverMap::iterator other = request_observer_map_.begin(); | 691 for (RequestObserverMap::iterator other = request_observer_map_.begin(); |
| 678 observer.get() && (other != request_observer_map_.end()); ++other) { | 692 observer.get() && (other != request_observer_map_.end()); ++other) { |
| 679 if (other->second == observer) { | 693 if (other->second == observer) { |
| 680 // Delay reporting success until the second response is received. | 694 // Delay reporting success until the second response is received. |
| 681 if (success) | 695 if (success) |
| 682 return; | 696 return; |
| 683 | 697 |
| 684 // Report failure below and ignore the second response. | 698 // Report failure below and ignore the second response. |
| 685 request_observer_map_.erase(other); | 699 request_observer_map_.erase(other); |
| 686 break; | 700 break; |
| 687 } | 701 } |
| 688 } | 702 } |
| 689 | 703 |
| 690 if (observer.get()) | 704 if (observer.get()) |
| 691 observer->OnSendComplete(success); | 705 observer->OnSendComplete(success); |
| 692 } | 706 } |
| OLD | NEW |