diff options
-rw-r--r-- | chrome/service/cloud_print/cloud_print_auth.cc | 62 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_connector.cc | 47 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_connector.h | 7 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy.cc | 3 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_proxy_backend.cc | 3 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_url_fetcher.cc | 100 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_url_fetcher.h | 25 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc | 9 | ||||
-rw-r--r-- | chrome/service/cloud_print/cloud_print_wipeout.cc | 7 | ||||
-rw-r--r-- | chrome/service/cloud_print/connector_settings.cc | 11 | ||||
-rw-r--r-- | chrome/service/cloud_print/job_status_updater.cc | 9 | ||||
-rw-r--r-- | chrome/service/cloud_print/job_status_updater.h | 5 | ||||
-rw-r--r-- | chrome/service/cloud_print/printer_job_handler.cc | 120 | ||||
-rw-r--r-- | chrome/service/cloud_print/printer_job_handler.h | 17 | ||||
-rw-r--r-- | chrome/service/service_utility_process_host.cc | 60 | ||||
-rw-r--r-- | chrome/service/service_utility_process_host.h | 2 |
16 files changed, 414 insertions, 73 deletions
diff --git a/chrome/service/cloud_print/cloud_print_auth.cc b/chrome/service/cloud_print/cloud_print_auth.cc index 5abfb99..482b9c3 100644 --- a/chrome/service/cloud_print/cloud_print_auth.cc +++ b/chrome/service/cloud_print/cloud_print_auth.cc @@ -5,6 +5,7 @@ #include "chrome/service/cloud_print/cloud_print_auth.h" #include "base/bind.h" +#include "base/metrics/histogram.h" #include "base/strings/string_util.h" #include "chrome/common/cloud_print/cloud_print_constants.h" #include "chrome/common/cloud_print/cloud_print_helpers.h" @@ -15,6 +16,26 @@ namespace cloud_print { +namespace { + +enum CloudPrintAuthEvent { + AUTH_EVENT_ROBO_CREATE, + AUTH_EVENT_ROBO_SUCCEEDED, + AUTH_EVENT_ROBO_FAILED, + AUTH_EVENT_ROBO_JSON_ERROR, + AUTH_EVENT_ROBO_AUTH_ERROR, + AUTH_EVENT_AUTH_WITH_TOKEN, + AUTH_EVENT_AUTH_WITH_CODE, + AUTH_EVENT_TOKEN_RESPONSE, + AUTH_EVENT_REFRESH_REQUEST, + AUTH_EVENT_REFRESH_RESPONSE, + AUTH_EVENT_AUTH_ERROR, + AUTH_EVENT_NET_ERROR, + AUTH_EVENT_MAX +}; + +} // namespace + CloudPrintAuth::CloudPrintAuth( Client* client, const GURL& cloud_print_server_url, @@ -31,6 +52,9 @@ void CloudPrintAuth::AuthenticateWithToken( const std::string& cloud_print_token) { VLOG(1) << "CP_AUTH: Authenticating with token"; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_ROBO_CREATE, + AUTH_EVENT_MAX); + client_login_token_ = cloud_print_token; // We need to get the credentials of the robot here. @@ -38,10 +62,9 @@ void CloudPrintAuth::AuthenticateWithToken( oauth_client_info_.client_id, proxy_id_); request_ = CloudPrintURLFetcher::Create(); - request_->StartGetRequest(get_authcode_url, - this, - kCloudPrintAuthMaxRetryCount, - std::string()); + request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_AUTH_CODE, + get_authcode_url, this, + kCloudPrintAuthMaxRetryCount, std::string()); } void CloudPrintAuth::AuthenticateWithRobotToken( @@ -49,6 +72,9 @@ void CloudPrintAuth::AuthenticateWithRobotToken( const std::string& robot_email) { VLOG(1) << "CP_AUTH: Authenticating with robot token"; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_AUTH_WITH_TOKEN, + AUTH_EVENT_MAX); + robot_email_ = robot_email; refresh_token_ = robot_oauth_refresh_token; RefreshAccessToken(); @@ -59,6 +85,9 @@ void CloudPrintAuth::AuthenticateWithRobotAuthCode( const std::string& robot_email) { VLOG(1) << "CP_AUTH: Authenticating with robot auth code"; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_AUTH_WITH_CODE, + AUTH_EVENT_MAX); + robot_email_ = robot_email; // Now that we have an auth code we need to get the refresh and access tokens. oauth_client_.reset(new gaia::GaiaOAuthClient( @@ -70,6 +99,8 @@ void CloudPrintAuth::AuthenticateWithRobotAuthCode( } void CloudPrintAuth::RefreshAccessToken() { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_REFRESH_REQUEST, + AUTH_EVENT_MAX); oauth_client_.reset(new gaia::GaiaOAuthClient( g_service_process->GetServiceURLRequestContextGetter())); std::vector<std::string> empty_scope_list; // (Use scope from refresh token.) @@ -83,6 +114,8 @@ void CloudPrintAuth::RefreshAccessToken() { void CloudPrintAuth::OnGetTokensResponse(const std::string& refresh_token, const std::string& access_token, int expires_in_seconds) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_TOKEN_RESPONSE, + AUTH_EVENT_MAX); refresh_token_ = refresh_token; // After saving the refresh token, this is just like having just refreshed // the access token. Just call OnRefreshTokenResponse. @@ -91,6 +124,8 @@ void CloudPrintAuth::OnGetTokensResponse(const std::string& refresh_token, void CloudPrintAuth::OnRefreshTokenResponse(const std::string& access_token, int expires_in_seconds) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_REFRESH_RESPONSE, + AUTH_EVENT_MAX); client_->OnAuthenticationComplete(access_token, refresh_token_, robot_email_, user_email_); @@ -106,11 +141,15 @@ void CloudPrintAuth::OnRefreshTokenResponse(const std::string& access_token, } void CloudPrintAuth::OnOAuthError() { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_AUTH_ERROR, + AUTH_EVENT_MAX); // Notify client about authentication error. client_->OnInvalidCredentials(); } void CloudPrintAuth::OnNetworkError(int response_code) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_NET_ERROR, + AUTH_EVENT_MAX); // Since we specify infinite retries on network errors, this should never // be called. NOTREACHED() << @@ -125,6 +164,9 @@ CloudPrintURLFetcher::ResponseAction CloudPrintAuth::HandleJSONData( bool succeeded) { if (!succeeded) { VLOG(1) << "CP_AUTH: Creating robot account failed"; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", + AUTH_EVENT_ROBO_FAILED, + AUTH_EVENT_MAX); client_->OnInvalidCredentials(); return CloudPrintURLFetcher::STOP_PROCESSING; } @@ -132,10 +174,17 @@ CloudPrintURLFetcher::ResponseAction CloudPrintAuth::HandleJSONData( std::string auth_code; if (!json_data->GetString(kOAuthCodeValue, &auth_code)) { VLOG(1) << "CP_AUTH: Creating robot account returned invalid json response"; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", + AUTH_EVENT_ROBO_JSON_ERROR, + AUTH_EVENT_MAX); client_->OnInvalidCredentials(); return CloudPrintURLFetcher::STOP_PROCESSING; } + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", + AUTH_EVENT_ROBO_SUCCEEDED, + AUTH_EVENT_MAX); + json_data->GetString(kXMPPJidValue, &robot_email_); // Now that we have an auth code we need to get the refresh and access tokens. oauth_client_.reset(new gaia::GaiaOAuthClient( @@ -150,6 +199,11 @@ CloudPrintURLFetcher::ResponseAction CloudPrintAuth::HandleJSONData( CloudPrintURLFetcher::ResponseAction CloudPrintAuth::OnRequestAuthError() { VLOG(1) << "CP_AUTH: Creating robot account authentication error"; + + UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", + AUTH_EVENT_ROBO_AUTH_ERROR, + AUTH_EVENT_MAX); + // Notify client about authentication error. client_->OnInvalidCredentials(); return CloudPrintURLFetcher::STOP_PROCESSING; diff --git a/chrome/service/cloud_print/cloud_print_connector.cc b/chrome/service/cloud_print/cloud_print_connector.cc index 27372cf..26de215 100644 --- a/chrome/service/cloud_print/cloud_print_connector.cc +++ b/chrome/service/cloud_print/cloud_print_connector.cc @@ -25,7 +25,8 @@ namespace cloud_print { CloudPrintConnector::CloudPrintConnector(Client* client, const ConnectorSettings& settings) : client_(client), - next_response_handler_(NULL) { + next_response_handler_(NULL), + stats_ptr_factory_(this) { settings_.CopyFrom(settings); } @@ -48,6 +49,19 @@ bool CloudPrintConnector::InitPrintSystem() { return true; } +void CloudPrintConnector::ScheduleStatsReport() { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&CloudPrintConnector::ReportStats, + stats_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromHours(1)); +} + +void CloudPrintConnector::ReportStats() { + PrinterJobHandler::ReportsStats(); + ScheduleStatsReport(); +} + bool CloudPrintConnector::Start() { VLOG(1) << "CP_CONNECTOR: Starting connector" << ", proxy id: " << settings_.proxy_id(); @@ -57,6 +71,8 @@ bool CloudPrintConnector::Start() { if (!InitPrintSystem()) return false; + ScheduleStatsReport(); + // Start watching for updates from the print system. print_server_watcher_ = print_system_->CreatePrintServerWatcher(); print_server_watcher_->StartWatching(this); @@ -71,6 +87,7 @@ void CloudPrintConnector::Stop() { << ", proxy id: " << settings_.proxy_id(); DCHECK(IsRunning()); // Do uninitialization here. + stats_ptr_factory_.InvalidateWeakPtrs(); pending_tasks_.clear(); print_server_watcher_ = NULL; request_ = NULL; @@ -319,18 +336,21 @@ void CloudPrintConnector::StartGetRequest(const GURL& url, ResponseHandler handler) { next_response_handler_ = handler; request_ = CloudPrintURLFetcher::Create(); - request_->StartGetRequest(url, this, max_retries, std::string()); + request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_UPDATE_JOB, + url, this, max_retries, std::string()); } -void CloudPrintConnector::StartPostRequest(const GURL& url, - int max_retries, - const std::string& mime_type, - const std::string& post_data, - ResponseHandler handler) { +void CloudPrintConnector::StartPostRequest( + CloudPrintURLFetcher::RequestType type, + const GURL& url, + int max_retries, + const std::string& mime_type, + const std::string& post_data, + ResponseHandler handler) { next_response_handler_ = handler; request_ = CloudPrintURLFetcher::Create(); request_->StartPostRequest( - url, this, max_retries, mime_type, post_data, std::string()); + type, url, this, max_retries, mime_type, post_data, std::string()); } void CloudPrintConnector::ReportUserMessage(const std::string& message_id, @@ -347,8 +367,9 @@ void CloudPrintConnector::ReportUserMessage(const std::string& message_id, std::string mime_type("multipart/form-data; boundary="); mime_type += mime_boundary; user_message_request_ = CloudPrintURLFetcher::Create(); - user_message_request_->StartPostRequest(url, this, 1, mime_type, post_data, - std::string()); + user_message_request_->StartPostRequest( + CloudPrintURLFetcher::REQUEST_USER_MESSAGE, url, this, 1, mime_type, + post_data, std::string()); } bool CloudPrintConnector::RemovePrinterFromList( @@ -617,10 +638,8 @@ void CloudPrintConnector::OnReceivePrinterCaps( mime_type += mime_boundary; GURL post_url = GetUrlForPrinterRegistration(settings_.server_url()); - StartPostRequest(post_url, - kCloudPrintAPIMaxRetryCount, - mime_type, - post_data, + StartPostRequest(CloudPrintURLFetcher::REQUEST_REGISTER, post_url, + kCloudPrintAPIMaxRetryCount, mime_type, post_data, &CloudPrintConnector::HandleRegisterPrinterResponse); } diff --git a/chrome/service/cloud_print/cloud_print_connector.h b/chrome/service/cloud_print/cloud_print_connector.h index 1cf1bd7..f7f85dd 100644 --- a/chrome/service/cloud_print/cloud_print_connector.h +++ b/chrome/service/cloud_print/cloud_print_connector.h @@ -133,7 +133,8 @@ class CloudPrintConnector void StartGetRequest(const GURL& url, int max_retries, ResponseHandler handler); - void StartPostRequest(const GURL& url, + void StartPostRequest(CloudPrintURLFetcher::RequestType type, + const GURL& url, int max_retries, const std::string& mime_type, const std::string& post_data, @@ -171,6 +172,9 @@ class CloudPrintConnector bool IsSamePrinter(const std::string& name1, const std::string& name2) const; bool InitPrintSystem(); + void ScheduleStatsReport(); + void ReportStats(); + // CloudPrintConnector client. Client* client_; // Connector settings. @@ -192,6 +196,7 @@ class CloudPrintConnector scoped_refptr<CloudPrintURLFetcher> request_; // The CloudPrintURLFetcher instance for the user message request. scoped_refptr<CloudPrintURLFetcher> user_message_request_; + base::WeakPtrFactory<CloudPrintConnector> stats_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CloudPrintConnector); }; diff --git a/chrome/service/cloud_print/cloud_print_proxy.cc b/chrome/service/cloud_print/cloud_print_proxy.cc index eb22186..9e07db9 100644 --- a/chrome/service/cloud_print/cloud_print_proxy.cc +++ b/chrome/service/cloud_print/cloud_print_proxy.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/metrics/histogram.h" #include "base/path_service.h" #include "base/process/kill.h" #include "base/process/launch.h" @@ -249,6 +250,8 @@ void CloudPrintProxy::OnPrintSystemUnavailable() { void CloudPrintProxy::OnUnregisterPrinters( const std::string& auth_token, const std::list<std::string>& printer_ids) { + UMA_HISTOGRAM_COUNTS_10000("CloudPrint.UnregisterPrinters", + printer_ids.size()); ShutdownBackend(); wipeout_.reset(new CloudPrintWipeout(this, settings_.server_url())); wipeout_->UnregisterPrinters(auth_token, printer_ids); diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc index db8a4d9..5a596c4 100644 --- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc +++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/compiler_specific.h" +#include "base/metrics/histogram.h" #include "base/rand_util.h" #include "base/values.h" #include "chrome/common/chrome_switches.h" @@ -464,6 +465,7 @@ void CloudPrintProxyBackend::Core::ScheduleXmppPing() { void CloudPrintProxyBackend::Core::CheckXmppPingStatus() { if (pending_xmpp_pings_ >= kMaxFailedXmppPings) { + UMA_HISTOGRAM_COUNTS_100("CloudPrint.XmppPingTry", 99); // Max on fail. // Reconnect to XMPP. pending_xmpp_pings_ = 0; push_client_.reset(); @@ -554,6 +556,7 @@ void CloudPrintProxyBackend::Core::OnIncomingNotification( } void CloudPrintProxyBackend::Core::OnPingResponse() { + UMA_HISTOGRAM_COUNTS_100("CloudPrint.XmppPingTry", pending_xmpp_pings_); pending_xmpp_pings_ = 0; VLOG(1) << "CP_CONNECTOR: Ping response received."; } diff --git a/chrome/service/cloud_print/cloud_print_url_fetcher.cc b/chrome/service/cloud_print/cloud_print_url_fetcher.cc index f99b6f2..96372b1 100644 --- a/chrome/service/cloud_print/cloud_print_url_fetcher.cc +++ b/chrome/service/cloud_print/cloud_print_url_fetcher.cc @@ -4,6 +4,7 @@ #include "chrome/service/cloud_print/cloud_print_url_fetcher.h" +#include "base/metrics/histogram.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/common/cloud_print/cloud_print_constants.h" @@ -20,7 +21,67 @@ namespace cloud_print { -static CloudPrintURLFetcherFactory* g_factory = NULL; +namespace { + +void ReportRequestTime(CloudPrintURLFetcher::RequestType type, + base::TimeDelta time) { + if (type == CloudPrintURLFetcher::REQUEST_REGISTER) { + UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.Register", time); + } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) { + UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.UpdatePrinter", time); + } else if (type == CloudPrintURLFetcher::REQUEST_DATA) { + UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.DownloadData", time); + } else { + UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.Other", time); + } +} + +void ReportRetriesCount(CloudPrintURLFetcher::RequestType type, + int retries) { + if (type == CloudPrintURLFetcher::REQUEST_REGISTER) { + UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.Register", retries); + } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) { + UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.UpdatePrinter", + retries); + } else if (type == CloudPrintURLFetcher::REQUEST_DATA) { + UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.DownloadData", + retries); + } else { + UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.Other", retries); + } +} + +void ReportDownloadSize(CloudPrintURLFetcher::RequestType type, size_t size) { + if (type == CloudPrintURLFetcher::REQUEST_REGISTER) { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.Register", size); + } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.UpdatePrinter", + size); + } else if (type == CloudPrintURLFetcher::REQUEST_DATA) { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.DownloadData", + size); + } else { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.Other", size); + } +} + +void ReportUploadSize(CloudPrintURLFetcher::RequestType type, size_t size) { + if (type == CloudPrintURLFetcher::REQUEST_REGISTER) { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.Register", size); + } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.UpdatePrinter", + size); + } else if (type == CloudPrintURLFetcher::REQUEST_DATA) { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.DownloadData", + size); + } else { + UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.Other", size); + } +} + +CloudPrintURLFetcherFactory* g_factory = NULL; + +} // namespace // virtual CloudPrintURLFetcherFactory::~CloudPrintURLFetcherFactory() {} @@ -72,7 +133,8 @@ CloudPrintURLFetcher::Delegate::HandleJSONData( CloudPrintURLFetcher::CloudPrintURLFetcher() : delegate_(NULL), - num_retries_(0) { + num_retries_(0), + type_(REQUEST_MAX) { } bool CloudPrintURLFetcher::IsSameRequest(const net::URLFetcher* source) { @@ -80,33 +142,25 @@ bool CloudPrintURLFetcher::IsSameRequest(const net::URLFetcher* source) { } void CloudPrintURLFetcher::StartGetRequest( + RequestType type, const GURL& url, Delegate* delegate, int max_retries, const std::string& additional_headers) { - StartRequestHelper(url, - net::URLFetcher::GET, - delegate, - max_retries, - std::string(), - std::string(), - additional_headers); + StartRequestHelper(type, url, net::URLFetcher::GET, delegate, max_retries, + std::string(), std::string(), additional_headers); } void CloudPrintURLFetcher::StartPostRequest( + RequestType type, const GURL& url, Delegate* delegate, int max_retries, const std::string& post_data_mime_type, const std::string& post_data, const std::string& additional_headers) { - StartRequestHelper(url, - net::URLFetcher::POST, - delegate, - max_retries, - post_data_mime_type, - post_data, - additional_headers); + StartRequestHelper(type, url, net::URLFetcher::POST, delegate, max_retries, + post_data_mime_type, post_data, additional_headers); } void CloudPrintURLFetcher::OnURLFetchComplete( @@ -117,6 +171,8 @@ void CloudPrintURLFetcher::OnURLFetchComplete( scoped_refptr<CloudPrintURLFetcher> keep_alive(this); std::string data; source->GetResponseAsString(&data); + ReportRequestTime(type_, base::Time::Now() - start_time_); + ReportDownloadSize(type_, data.size()); ResponseAction action = delegate_->HandleRawResponse( source, source->GetURL(), @@ -176,18 +232,24 @@ void CloudPrintURLFetcher::OnURLFetchComplete( (num_retries_ > source->GetMaxRetriesOn5xx())) { // Retry limit reached. Give up. delegate_->OnRequestGiveUp(); + action = STOP_PROCESSING; } else { // Either no retry limit specified or retry limit has not yet been // reached. Try again. Set up the request headers again because the token // may have changed. SetupRequestHeaders(); request_->SetRequestContext(GetRequestContextGetter()); + start_time_ = base::Time::Now(); request_->Start(); } } + if (action != RETRY_REQUEST) { + ReportRetriesCount(type_, num_retries_); + } } void CloudPrintURLFetcher::StartRequestHelper( + RequestType type, const GURL& url, net::URLFetcher::RequestType request_type, Delegate* delegate, @@ -196,6 +258,9 @@ void CloudPrintURLFetcher::StartRequestHelper( const std::string& post_data, const std::string& additional_headers) { DCHECK(delegate); + type_ = type; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.UrlFetcherRequestType", type, + REQUEST_MAX); // Persist the additional headers in case we need to retry the request. additional_headers_ = additional_headers; request_.reset(net::URLFetcher::Create(0, url, request_type, this)); @@ -209,8 +274,9 @@ void CloudPrintURLFetcher::StartRequestHelper( net::LOAD_DO_NOT_SAVE_COOKIES); if (request_type == net::URLFetcher::POST) { request_->SetUploadData(post_data_mime_type, post_data); + ReportUploadSize(type_, post_data.size()); } - + start_time_ = base::Time::Now(); request_->Start(); } diff --git a/chrome/service/cloud_print/cloud_print_url_fetcher.h b/chrome/service/cloud_print/cloud_print_url_fetcher.h index 3977160..a71a8da 100644 --- a/chrome/service/cloud_print/cloud_print_url_fetcher.h +++ b/chrome/service/cloud_print/cloud_print_url_fetcher.h @@ -48,6 +48,19 @@ class CloudPrintURLFetcher RETRY_REQUEST, }; + enum RequestType { + REQUEST_AUTH_CODE, + REQUEST_REGISTER, + REQUEST_UNREGISTER, + REQUEST_UPDATE_PRINTER, + REQUEST_UPDATE_JOB, + REQUEST_USER_MESSAGE, + REQUEST_TICKET, + REQUEST_DATA, + REQUEST_JOB_FETCH, + REQUEST_MAX, + }; + class Delegate { public: // Override this to handle the raw response as it is available. No response @@ -106,11 +119,13 @@ class CloudPrintURLFetcher bool IsSameRequest(const net::URLFetcher* source); - void StartGetRequest(const GURL& url, + void StartGetRequest(RequestType type, + const GURL& url, Delegate* delegate, int max_retries, const std::string& additional_headers); - void StartPostRequest(const GURL& url, + void StartPostRequest(RequestType type, + const GURL& url, Delegate* delegate, int max_retries, const std::string& post_data_mime_type, @@ -129,7 +144,8 @@ class CloudPrintURLFetcher virtual net::URLRequestContextGetter* GetRequestContextGetter(); private: - void StartRequestHelper(const GURL& url, + void StartRequestHelper(RequestType type, + const GURL& url, net::URLFetcher::RequestType request_type, Delegate* delegate, int max_retries, @@ -146,6 +162,9 @@ class CloudPrintURLFetcher std::string additional_headers_; std::string post_data_mime_type_; std::string post_data_; + + RequestType type_; + base::Time start_time_; }; typedef CloudPrintURLFetcher::Delegate CloudPrintURLFetcherDelegate; diff --git a/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc b/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc index dcdb912..bc6f0c9 100644 --- a/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc +++ b/chrome/service/cloud_print/cloud_print_url_fetcher_unittest.cc @@ -223,7 +223,8 @@ void CloudPrintURLFetcherTest::CreateFetcher(const GURL& url, int max_retries) { max_retries_ = max_retries; start_time_ = Time::Now(); - fetcher_->StartGetRequest(url, this, max_retries_, std::string()); + fetcher_->StartGetRequest(CloudPrintURLFetcher::REQUEST_MAX, url, this, + max_retries_, std::string()); } CloudPrintURLFetcher::ResponseAction @@ -299,10 +300,8 @@ CloudPrintURLFetcherOverloadTest::HandleRawData( const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); response_count_++; if (response_count_ < 20) { - fetcher_->StartGetRequest(url, - this, - max_retries_, - std::string()); + fetcher_->StartGetRequest(CloudPrintURLFetcher::REQUEST_MAX, url, this, + max_retries_, std::string()); } else { // We have already sent 20 requests continuously. And we expect that // it takes more than 1 second due to the overload protection settings. diff --git a/chrome/service/cloud_print/cloud_print_wipeout.cc b/chrome/service/cloud_print/cloud_print_wipeout.cc index 38deacc..bac2197 100644 --- a/chrome/service/cloud_print/cloud_print_wipeout.cc +++ b/chrome/service/cloud_print/cloud_print_wipeout.cc @@ -39,7 +39,8 @@ void CloudPrintWipeout::UnregisterNextPrinter() { printer_id, "connector_disabled"); request_ = CloudPrintURLFetcher::Create(); - request_->StartGetRequest(url, this, kMaxWipeoutAttempts, std::string()); + request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_UNREGISTER, + url, this, kMaxWipeoutAttempts, std::string()); } CloudPrintURLFetcher::ResponseAction CloudPrintWipeout::HandleJSONData( @@ -47,7 +48,7 @@ CloudPrintURLFetcher::ResponseAction CloudPrintWipeout::HandleJSONData( const GURL& url, base::DictionaryValue* json_data, bool succeeded) { - // We don't care if delete was sucessful or not here. + // We don't care if delete was successful or not here. UnregisterNextPrinter(); return CloudPrintURLFetcher::STOP_PROCESSING; } @@ -57,7 +58,7 @@ void CloudPrintWipeout::OnRequestGiveUp() { } CloudPrintURLFetcher::ResponseAction CloudPrintWipeout::OnRequestAuthError() { - // We can't recover from auth rrror. Report complition to stop service. + // We can't recover from auth error. Report completion to stop service. client_->OnUnregisterPrintersComplete(); return CloudPrintURLFetcher::STOP_PROCESSING; } diff --git a/chrome/service/cloud_print/connector_settings.cc b/chrome/service/cloud_print/connector_settings.cc index c2137e4..35ed6eb 100644 --- a/chrome/service/cloud_print/connector_settings.cc +++ b/chrome/service/cloud_print/connector_settings.cc @@ -5,6 +5,7 @@ #include "chrome/service/cloud_print/connector_settings.h" #include "base/command_line.h" +#include "base/metrics/histogram.h" #include "base/values.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/cloud_print/cloud_print_constants.h" @@ -76,6 +77,9 @@ void ConnectorSettings::InitFrom(ServiceProcessPrefs* prefs) { int timeout = prefs->GetInt( prefs::kCloudPrintXmppPingTimeout, kDefaultXmppPingTimeoutSecs); SetXmppPingTimeoutSec(timeout); + UMA_HISTOGRAM_LONG_TIMES( + "CloudPrint.XmppTimeout", + base::TimeDelta::FromSeconds(xmpp_ping_timeout_sec_)); const base::ListValue* printers = prefs->GetList(prefs::kCloudPrintPrinters); if (printers) { @@ -93,6 +97,13 @@ void ConnectorSettings::InitFrom(ServiceProcessPrefs* prefs) { } } } + if (connect_new_printers_) { + UMA_HISTOGRAM_COUNTS_10000("CloudPrint.PrinterBlacklistSize", + printers_.size()); + } else { + UMA_HISTOGRAM_COUNTS_10000("CloudPrint.PrinterWhitelistSize", + printers_.size()); + } } bool ConnectorSettings::ShouldConnect(const std::string& printer_name) const { diff --git a/chrome/service/cloud_print/job_status_updater.cc b/chrome/service/cloud_print/job_status_updater.cc index af0f9ed..c89f0ac 100644 --- a/chrome/service/cloud_print/job_status_updater.cc +++ b/chrome/service/cloud_print/job_status_updater.cc @@ -21,10 +21,14 @@ JobStatusUpdater::JobStatusUpdater(const std::string& printer_name, const GURL& cloud_print_server_url, PrintSystem* print_system, Delegate* delegate) - : printer_name_(printer_name), job_id_(job_id), + : start_time_(base::Time::Now()), + printer_name_(printer_name), + job_id_(job_id), local_job_id_(local_job_id), cloud_print_server_url_(cloud_print_server_url), - print_system_(print_system), delegate_(delegate), stopped_(false) { + print_system_(print_system), + delegate_(delegate), + stopped_(false) { DCHECK(delegate_); } @@ -60,6 +64,7 @@ void JobStatusUpdater::UpdateStatus() { if (need_update) { request_ = CloudPrintURLFetcher::Create(); request_->StartGetRequest( + CloudPrintURLFetcher::REQUEST_UPDATE_JOB, GetUrlForJobStatusUpdate( cloud_print_server_url_, job_id_, last_job_details_), this, diff --git a/chrome/service/cloud_print/job_status_updater.h b/chrome/service/cloud_print/job_status_updater.h index 5d7a5c4..2fdc356 100644 --- a/chrome/service/cloud_print/job_status_updater.h +++ b/chrome/service/cloud_print/job_status_updater.h @@ -53,10 +53,15 @@ class JobStatusUpdater : public base::RefCountedThreadSafe<JobStatusUpdater>, virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError() OVERRIDE; virtual std::string GetAuthHeader() OVERRIDE; + base::Time start_time() const { + return start_time_; + } + private: friend class base::RefCountedThreadSafe<JobStatusUpdater>; virtual ~JobStatusUpdater(); + base::Time start_time_; std::string printer_name_; std::string job_id_; PlatformJobId local_job_id_; diff --git a/chrome/service/cloud_print/printer_job_handler.cc b/chrome/service/cloud_print/printer_job_handler.cc index 6a4f1bb..53d88d5 100644 --- a/chrome/service/cloud_print/printer_job_handler.cc +++ b/chrome/service/cloud_print/printer_job_handler.cc @@ -9,6 +9,7 @@ #include "base/file_util.h" #include "base/json/json_reader.h" #include "base/md5.h" +#include "base/metrics/histogram.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -26,6 +27,32 @@ namespace cloud_print { +namespace { + +base::subtle::Atomic32 g_total_jobs_started = 0; +base::subtle::Atomic32 g_total_jobs_done = 0; + +enum PrinterJobHandlerEvent { + JOB_HANDLER_CHECK_FOR_JOBS, + JOB_HANDLER_START, + JOB_HANDLER_PENDING_TASK, + JOB_HANDLER_PRINTER_UPDATE, + JOB_HANDLER_JOB_CHECK, + JOB_HANDLER_JOB_STARTED, + JOB_HANDLER_VALID_TICKET, + JOB_HANDLER_DATA, + JOB_HANDLER_SET_IN_PROGRESS, + JOB_HANDLER_SET_START_PRINTING, + JOB_HANDLER_START_SPOOLING, + JOB_HANDLER_SPOOLED, + JOB_HANDLER_JOB_COMPLETED, + JOB_HANDLER_INVALID_TICKET, + JOB_HANDLER_INVALID_DATA, + JOB_HANDLER_MAX, +}; + +} // namespace + PrinterJobHandler::PrinterInfoFromCloud::PrinterInfoFromCloud() : current_xmpp_timeout(0), pending_xmpp_timeout(0) { } @@ -75,6 +102,8 @@ void PrinterJobHandler::CheckForJobs(const std::string& reason) { << ", printer id: " << printer_info_cloud_.printer_id << ", reason: " << reason << ", task in progress: " << task_in_progress_; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_CHECK_FOR_JOBS, JOB_HANDLER_MAX); job_fetch_reason_ = reason; job_check_pending_ = true; if (!task_in_progress_) { @@ -165,8 +194,12 @@ std::string PrinterJobHandler::GetAuthHeader() { // JobStatusUpdater::Delegate implementation bool PrinterJobHandler::OnJobCompleted(JobStatusUpdater* updater) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_JOB_COMPLETED, JOB_HANDLER_MAX); + UMA_HISTOGRAM_LONG_TIMES("CloudPrint.PrintingTime", + base::Time::Now() - updater->start_time()); bool ret = false; - + base::subtle::NoBarrier_AtomicIncrement(&g_total_jobs_done, 1); job_queue_handler_.JobDone(job_details_.job_id_); for (JobStatusUpdaterList::iterator index = job_status_updater_list_.begin(); @@ -222,7 +255,17 @@ void PrinterJobHandler::OnJobSpoolFailed() { job_spooler_ = NULL; VLOG(1) << "CP_CONNECTOR: Job failed (spool failed)"; job_handler_message_loop_proxy_->PostTask( - FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, PRINT_FAILED)); + FROM_HERE, base::Bind(&PrinterJobHandler::JobFailed, this, JOB_FAILED)); +} + +// static +void PrinterJobHandler::ReportsStats() { + base::subtle::Atomic32 started = + base::subtle::NoBarrier_AtomicExchange(&g_total_jobs_started, 0); + base::subtle::Atomic32 done = + base::subtle::NoBarrier_AtomicExchange(&g_total_jobs_done, 0); + UMA_HISTOGRAM_COUNTS_100("CloudPrint.JobsStartedPerInterval", started); + UMA_HISTOGRAM_COUNTS_100("CloudPrint.JobsDonePerInterval", done); } PrinterJobHandler::~PrinterJobHandler() { @@ -263,13 +306,15 @@ PrinterJobHandler::HandleJobMetadataResponse( if (jobs[0].time_remaining_ == base::TimeDelta()) { job_available = true; job_details_ = jobs[0]; - + job_start_time_ = base::Time::Now(); + base::subtle::NoBarrier_AtomicIncrement(&g_total_jobs_started, 1); + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_JOB_STARTED, JOB_HANDLER_MAX); SetNextDataHandler(&PrinterJobHandler::HandlePrintTicketResponse); request_ = CloudPrintURLFetcher::Create(); - request_->StartGetRequest(GURL(job_details_.print_ticket_url_), - this, - kJobDataMaxRetryCount, - std::string()); + request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_TICKET, + GURL(job_details_.print_ticket_url_), this, kJobDataMaxRetryCount, + std::string()); } else { job_available = false; base::MessageLoop::current()->PostDelayedTask( @@ -297,16 +342,19 @@ PrinterJobHandler::HandlePrintTicketResponse(const net::URLFetcher* source, VLOG(1) << "CP_CONNECTOR: Handling print ticket response" << ", printer id: " << printer_info_cloud_.printer_id; if (print_system_->ValidatePrintTicket(printer_info_.printer_name, data)) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_VALID_TICKET, JOB_HANDLER_MAX); job_details_.print_ticket_ = data; SetNextDataHandler(&PrinterJobHandler::HandlePrintDataResponse); request_ = CloudPrintURLFetcher::Create(); std::string accept_headers = "Accept: "; accept_headers += print_system_->GetSupportedMimeTypes(); - request_->StartGetRequest(GURL(job_details_.print_data_url_), - this, - kJobDataMaxRetryCount, - accept_headers); + request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_DATA, + GURL(job_details_.print_data_url_), this, kJobDataMaxRetryCount, + accept_headers); } else { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_INVALID_TICKET, JOB_HANDLER_MAX); // The print ticket was not valid. We are done here. ValidatePrintTicketFailed(); } @@ -320,17 +368,20 @@ PrinterJobHandler::HandlePrintDataResponse(const net::URLFetcher* source, VLOG(1) << "CP_CONNECTOR: Handling print data response" << ", printer id: " << printer_info_cloud_.printer_id; if (file_util::CreateTemporaryFile(&job_details_.print_data_file_path_)) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", JOB_HANDLER_DATA, + JOB_HANDLER_MAX); int ret = file_util::WriteFile(job_details_.print_data_file_path_, - data.c_str(), - data.length()); + data.c_str(), data.length()); source->GetResponseHeaders()->GetMimeType( &job_details_.print_data_mime_type_); DCHECK(ret == static_cast<int>(data.length())); if (ret == static_cast<int>(data.length())) { - UpdateJobStatus(PRINT_JOB_STATUS_IN_PROGRESS, SUCCESS); + UpdateJobStatus(PRINT_JOB_STATUS_IN_PROGRESS, JOB_SUCCESS); return CloudPrintURLFetcher::STOP_PROCESSING; } } + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_INVALID_DATA, JOB_HANDLER_MAX); // If we are here, then there was an error in saving the print data, bail out // here. @@ -372,6 +423,8 @@ void PrinterJobHandler::Start() { VLOG(1) << "CP_CONNECTOR: Starting printer job handler" << ", printer id: " << printer_info_cloud_.printer_id << ", task in progress: " << task_in_progress_; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_START, JOB_HANDLER_MAX); if (task_in_progress_) { // Multiple Starts can get posted because of multiple notifications // We want to ignore the other ones that happen when a task is in progress. @@ -381,7 +434,11 @@ void PrinterJobHandler::Start() { if (!shutting_down_) { // Check if we have work to do. if (HavePendingTasks()) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_PENDING_TASK, JOB_HANDLER_MAX); if (!task_in_progress_ && printer_update_pending_) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_PRINTER_UPDATE, JOB_HANDLER_MAX); printer_update_pending_ = false; task_in_progress_ = UpdatePrinterInfo(); VLOG(1) << "CP_CONNECTOR: Changed task in progress" @@ -389,6 +446,8 @@ void PrinterJobHandler::Start() { << ", task in progress: " << task_in_progress_; } if (!task_in_progress_ && job_check_pending_) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_JOB_CHECK, JOB_HANDLER_MAX); task_in_progress_ = true; VLOG(1) << "CP_CONNECTOR: Changed task in progress" ", printer id: " << printer_info_cloud_.printer_id @@ -398,6 +457,7 @@ void PrinterJobHandler::Start() { SetNextJSONHandler(&PrinterJobHandler::HandleJobMetadataResponse); request_ = CloudPrintURLFetcher::Create(); request_->StartGetRequest( + CloudPrintURLFetcher::REQUEST_JOB_FETCH, GetUrlForJobFetch( cloud_print_server_url_, printer_info_cloud_.printer_id, job_fetch_reason_), @@ -431,13 +491,15 @@ void PrinterJobHandler::Stop() { void PrinterJobHandler::StartPrinting() { VLOG(1) << "CP_CONNECTOR: Starting printing" << ", printer id: " << printer_info_cloud_.printer_id; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_SET_START_PRINTING, JOB_HANDLER_MAX); // We are done with the request object for now. request_ = NULL; if (!shutting_down_) { if (!print_thread_.Start()) { VLOG(1) << "CP_CONNECTOR: Failed to start print thread" << ", printer id: " << printer_info_cloud_.printer_id; - JobFailed(PRINT_FAILED); + JobFailed(JOB_FAILED); } else { print_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&PrinterJobHandler::DoPrint, this, job_details_, @@ -470,8 +532,12 @@ void PrinterJobHandler::UpdateJobStatus(PrintJobStatus status, return; } - if (error == SUCCESS) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobStatus", error, JOB_MAX); + + if (error == JOB_SUCCESS) { DCHECK_EQ(status, PRINT_JOB_STATUS_IN_PROGRESS); + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_SET_IN_PROGRESS, JOB_HANDLER_MAX); SetNextJSONHandler( &PrinterJobHandler::HandleInProgressStatusUpdateResponse); } else { @@ -480,6 +546,7 @@ void PrinterJobHandler::UpdateJobStatus(PrintJobStatus status, } request_ = CloudPrintURLFetcher::Create(); request_->StartGetRequest( + CloudPrintURLFetcher::REQUEST_UPDATE_JOB, GetUrlForJobStatusUpdate(cloud_print_server_url_, job_details_.job_id_, status, error), this, kCloudPrintAPIMaxRetryCount, std::string()); @@ -516,6 +583,10 @@ void PrinterJobHandler::JobSpooled(PlatformJobId local_job_id) { VLOG(1) << "CP_CONNECTOR: Job spooled" << ", printer id: " << printer_info_cloud_.printer_id << ", job id: " << local_job_id; + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", JOB_HANDLER_SPOOLED, + JOB_HANDLER_MAX); + UMA_HISTOGRAM_LONG_TIMES("CloudPrint.SpoolingTime", + base::Time::Now() - spooling_start_time_); if (shutting_down_) return; @@ -578,7 +649,7 @@ void PrinterJobHandler::ValidatePrintTicketFailed() { LOG(ERROR) << "CP_CONNECTOR: Failed validating print ticket" << ", printer name: " << printer_info_.printer_name << ", job id: " << job_details_.job_id_; - JobFailed(VALIDATE_PRINT_TICKET_FAILED); + JobFailed(JOB_VALIDATE_TICKET_FAILED); } } @@ -624,6 +695,15 @@ void PrinterJobHandler::OnReceivePrinterCaps( cp_tag_wildcard += ".*"; net::AddMultipartValueForUpload(kPrinterRemoveTagValue, cp_tag_wildcard, mime_boundary, std::string(), &post_data); + + if (!last_caps_update_time_.is_null()) { + UMA_HISTOGRAM_CUSTOM_TIMES( + "CloudPrint.CapsUpdateInterval", + base::Time::Now() - last_caps_update_time_, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromDays(30), 50); + } + last_caps_update_time_ = base::Time::Now(); } if (printer_info.printer_name != printer_info_.printer_name) { @@ -658,6 +738,7 @@ void PrinterJobHandler::OnReceivePrinterCaps( SetNextJSONHandler(&PrinterJobHandler::HandlePrinterUpdateResponse); request_ = CloudPrintURLFetcher::Create(); request_->StartPostRequest( + CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER, GetUrlForPrinterUpdate( cloud_print_server_url_, printer_info_cloud_.printer_id), this, @@ -680,6 +761,8 @@ void PrinterJobHandler::OnReceivePrinterCaps( void PrinterJobHandler::DoPrint(const JobDetails& job_details, const std::string& printer_name) { job_spooler_ = print_system_->CreateJobSpooler(); + UMA_HISTOGRAM_LONG_TIMES("CloudPrint.PrepareTime", + base::Time::Now() - job_start_time_); DCHECK(job_spooler_.get()); if (!job_spooler_.get()) return; @@ -690,6 +773,9 @@ void PrinterJobHandler::DoPrint(const JobDetails& job_details, document_name = printing::PrintBackend::SimplifyDocumentTitle( l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE)); } + UMA_HISTOGRAM_ENUMERATION("CloudPrint.JobHandlerEvent", + JOB_HANDLER_START_SPOOLING, JOB_HANDLER_MAX); + spooling_start_time_ = base::Time::Now(); if (!job_spooler_->Spool(job_details.print_ticket_, job_details.print_data_file_path_, job_details.print_data_mime_type_, diff --git a/chrome/service/cloud_print/printer_job_handler.h b/chrome/service/cloud_print/printer_job_handler.h index 10c74ed..dada250 100644 --- a/chrome/service/cloud_print/printer_job_handler.h +++ b/chrome/service/cloud_print/printer_job_handler.h @@ -151,14 +151,17 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, // End Delegate implementations + static void ReportsStats(); + private: friend class base::RefCountedThreadSafe<PrinterJobHandler>; enum PrintJobError { - SUCCESS, + JOB_SUCCESS, JOB_DOWNLOAD_FAILED, - VALIDATE_PRINT_TICKET_FAILED, - PRINT_FAILED, + JOB_VALIDATE_TICKET_FAILED, + JOB_FAILED, + JOB_MAX, }; // Prototype for a JSON data handler. @@ -227,9 +230,9 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, // Run a job check as the result of a scheduled check void RunScheduledJobCheck(); - // Sets the next response handler to the specifed JSON data handler. + // Sets the next response handler to the specified JSON data handler. void SetNextJSONHandler(JSONDataHandler handler); - // Sets the next response handler to the specifed data handler. + // Sets the next response handler to the specified data handler. void SetNextDataHandler(DataHandler handler); void JobFailed(PrintJobError error); @@ -302,6 +305,10 @@ class PrinterJobHandler : public base::RefCountedThreadSafe<PrinterJobHandler>, base::TimeTicks last_job_fetch_time_; base::WeakPtrFactory<PrinterJobHandler> weak_ptr_factory_; + base::Time job_start_time_; + base::Time spooling_start_time_; + base::Time last_caps_update_time_; + DISALLOW_COPY_AND_ASSIGN(PrinterJobHandler); }; diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index de55b4b..d3b0aa6 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_proxy.h" +#include "base/metrics/histogram.h" #include "base/process/kill.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/chrome_switches.h" @@ -33,6 +34,7 @@ #include "printing/emf_win.h" namespace { + // NOTE: changes to this class need to be reviewed by the security team. class ServiceSandboxedProcessLauncherDelegate : public content::SandboxedProcessLauncherDelegate { @@ -50,12 +52,27 @@ class ServiceSandboxedProcessLauncherDelegate private: base::FilePath exposed_dir_; }; -} + +} // namespace #endif // OS_WIN using content::ChildProcessHost; +namespace { + enum ServiceUtilityProcessHostEvent { + SERVICE_UTILITY_STARTED, + SERVICE_UTILITY_DISCONNECTED, + SERVICE_UTILITY_METAFILE_REQUEST, + SERVICE_UTILITY_METAFILE_SUCCEEDED, + SERVICE_UTILITY_METAFILE_FAILED, + SERVICE_UTILITY_CAPS_REQUEST, + SERVICE_UTILITY_CAPS_SUCCEEDED, + SERVICE_UTILITY_CAPS_FAILED, + SERVICE_UTILITY_EVENT_MAX, +}; +} // namespace + ServiceUtilityProcessHost::ServiceUtilityProcessHost( Client* client, base::MessageLoopProxy* client_message_loop_proxy) : handle_(base::kNullProcessHandle), @@ -74,6 +91,10 @@ bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile( const base::FilePath& pdf_path, const printing::PdfRenderSettings& render_settings, const std::vector<printing::PageRange>& page_ranges) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_METAFILE_REQUEST, + SERVICE_UTILITY_EVENT_MAX); + start_time_ = base::Time::Now(); #if !defined(OS_WIN) // This is only implemented on Windows (because currently it is only needed // on Windows). Will add implementations on other platforms when needed. @@ -119,6 +140,10 @@ bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile( bool ServiceUtilityProcessHost::StartGetPrinterCapsAndDefaults( const std::string& printer_name) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_CAPS_REQUEST, + SERVICE_UTILITY_EVENT_MAX); + start_time_ = base::Time::Now(); base::FilePath exposed_path; if (!StartProcess(true, exposed_path)) return false; @@ -145,7 +170,13 @@ bool ServiceUtilityProcessHost::StartProcess( cmd_line.AppendSwitchASCII(switches::kProcessChannelID, channel_id); cmd_line.AppendSwitch(switches::kLang); - return Launch(&cmd_line, no_sandbox, exposed_dir); + if (Launch(&cmd_line, no_sandbox, exposed_dir)) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_STARTED, + SERVICE_UTILITY_EVENT_MAX); + return true; + } + return false; } bool ServiceUtilityProcessHost::Launch(CommandLine* cmd_line, @@ -184,6 +215,11 @@ void ServiceUtilityProcessHost::OnChildDisconnected() { // child died. client_message_loop_proxy_->PostTask( FROM_HERE, base::Bind(&Client::OnChildDied, client_.get())); + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_DISCONNECTED, + SERVICE_UTILITY_EVENT_MAX); + UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityDisconnectTime", + base::Time::Now() - start_time_); } delete this; } @@ -209,6 +245,11 @@ bool ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) { void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafileSucceeded( int highest_rendered_page_number, double scale_factor) { + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_METAFILE_SUCCEEDED, + SERVICE_UTILITY_EVENT_MAX); + UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityMetafileTime", + base::Time::Now() - start_time_); DCHECK(waiting_for_reply_); waiting_for_reply_ = false; // If the metafile was successfully created, we need to take our hands off the @@ -223,6 +264,11 @@ void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafileSucceeded( void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafileFailed() { DCHECK(waiting_for_reply_); + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_METAFILE_FAILED, + SERVICE_UTILITY_EVENT_MAX); + UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityMetafileFailTime", + base::Time::Now() - start_time_); waiting_for_reply_ = false; client_message_loop_proxy_->PostTask( FROM_HERE, @@ -233,6 +279,11 @@ void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsSucceeded( const std::string& printer_name, const printing::PrinterCapsAndDefaults& caps_and_defaults) { DCHECK(waiting_for_reply_); + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_CAPS_SUCCEEDED, + SERVICE_UTILITY_EVENT_MAX); + UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityCapsTime", + base::Time::Now() - start_time_); waiting_for_reply_ = false; client_message_loop_proxy_->PostTask( FROM_HERE, @@ -243,6 +294,11 @@ void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsSucceeded( void ServiceUtilityProcessHost::OnGetPrinterCapsAndDefaultsFailed( const std::string& printer_name) { DCHECK(waiting_for_reply_); + UMA_HISTOGRAM_ENUMERATION("CloudPrint.ServiceUtilityProcessHostEvent", + SERVICE_UTILITY_CAPS_FAILED, + SERVICE_UTILITY_EVENT_MAX); + UMA_HISTOGRAM_TIMES("CloudPrint.ServiceUtilityCapsFailTime", + base::Time::Now() - start_time_); waiting_for_reply_ = false; client_message_loop_proxy_->PostTask( FROM_HERE, diff --git a/chrome/service/service_utility_process_host.h b/chrome/service/service_utility_process_host.h index 6876a61..1e41066 100644 --- a/chrome/service/service_utility_process_host.h +++ b/chrome/service/service_utility_process_host.h @@ -147,6 +147,8 @@ class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate { base::FilePath metafile_path_; // The temporary folder created for the metafile. scoped_ptr<base::ScopedTempDir> scratch_metafile_dir_; + // Start time of operation. + base::Time start_time_; DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost); }; |