| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/base64.h" | 5 #include "base/base64.h" |
| 6 #include "base/i18n/time_formatting.h" | 6 #include "base/i18n/time_formatting.h" |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/sha1.h" | 8 #include "base/sha1.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #if !defined(ANDROID) | 11 #if !defined(OS_ANDROID) |
| 12 // channel_common.proto defines ANDROID constant that conflicts with Android | 12 // channel_common.proto defines ANDROID constant that conflicts with Android |
| 13 // build. At the same time TiclInvalidationService is not used on Android so it | 13 // build. At the same time TiclInvalidationService is not used on Android so it |
| 14 // is safe to exclude these protos from Android build. | 14 // is safe to exclude these protos from Android build. |
| 15 #include "google/cacheinvalidation/android_channel.pb.h" | 15 #include "google/cacheinvalidation/android_channel.pb.h" |
| 16 #include "google/cacheinvalidation/channel_common.pb.h" | 16 #include "google/cacheinvalidation/channel_common.pb.h" |
| 17 #endif | 17 #endif |
| 18 #include "google_apis/gaia/google_service_auth_error.h" | 18 #include "google_apis/gaia/google_service_auth_error.h" |
| 19 #include "net/http/http_status_code.h" | 19 #include "net/http/http_status_code.h" |
| 20 #include "net/url_request/url_fetcher.h" | 20 #include "net/url_request/url_fetcher.h" |
| 21 #include "net/url_request/url_request_status.h" | 21 #include "net/url_request/url_request_status.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 } | 93 } |
| 94 | 94 |
| 95 void RecordOutgoingMessageStatus(OutgoingMessageStatus status) { | 95 void RecordOutgoingMessageStatus(OutgoingMessageStatus status) { |
| 96 UMA_HISTOGRAM_ENUMERATION(kOutgoingMessageStatusHistogram, | 96 UMA_HISTOGRAM_ENUMERATION(kOutgoingMessageStatusHistogram, |
| 97 MESSAGE_DISCARDED, | 97 MESSAGE_DISCARDED, |
| 98 OUTGOING_MESSAGE_STATUS_COUNT); | 98 OUTGOING_MESSAGE_STATUS_COUNT); |
| 99 } | 99 } |
| 100 | 100 |
| 101 } // namespace | 101 } // namespace |
| 102 | 102 |
| 103 GCMNetworkChannelDiagnostic::GCMNetworkChannelDiagnostic( | |
| 104 GCMNetworkChannel* parent) | |
| 105 : parent_(parent), | |
| 106 last_message_empty_echo_token_(false), | |
| 107 last_post_response_code_(0), | |
| 108 registration_result_(gcm::GCMClient::UNKNOWN_ERROR), | |
| 109 sent_messages_count_(0) {} | |
| 110 | |
| 111 scoped_ptr<base::DictionaryValue> | |
| 112 GCMNetworkChannelDiagnostic::CollectDebugData() const { | |
| 113 scoped_ptr<base::DictionaryValue> status(new base::DictionaryValue); | |
| 114 status->SetString("GCMNetworkChannel.Channel", "GCM"); | |
| 115 std::string reg_id_hash = base::SHA1HashString(registration_id_); | |
| 116 status->SetString("GCMNetworkChannel.HashedRegistrationID", | |
| 117 base::HexEncode(reg_id_hash.c_str(), reg_id_hash.size())); | |
| 118 status->SetString("GCMNetworkChannel.RegistrationResult", | |
| 119 GCMClientResultToString(registration_result_)); | |
| 120 status->SetBoolean("GCMNetworkChannel.HadLastMessageEmptyEchoToken", | |
| 121 last_message_empty_echo_token_); | |
| 122 status->SetString( | |
| 123 "GCMNetworkChannel.LastMessageReceivedTime", | |
| 124 base::TimeFormatShortDateAndTime(last_message_received_time_)); | |
| 125 status->SetInteger("GCMNetworkChannel.LastPostResponseCode", | |
| 126 last_post_response_code_); | |
| 127 status->SetInteger("GCMNetworkChannel.SentMessages", sent_messages_count_); | |
| 128 status->SetInteger("GCMNetworkChannel.ReceivedMessages", | |
| 129 parent_->GetReceivedMessagesCount()); | |
| 130 return status.Pass(); | |
| 131 } | |
| 132 | |
| 133 std::string GCMNetworkChannelDiagnostic::GCMClientResultToString( | |
| 134 const gcm::GCMClient::Result result) const { | |
| 135 #define ENUM_CASE(x) case x: return #x; break; | |
| 136 switch (result) { | |
| 137 ENUM_CASE(gcm::GCMClient::SUCCESS); | |
| 138 ENUM_CASE(gcm::GCMClient::NETWORK_ERROR); | |
| 139 ENUM_CASE(gcm::GCMClient::SERVER_ERROR); | |
| 140 ENUM_CASE(gcm::GCMClient::TTL_EXCEEDED); | |
| 141 ENUM_CASE(gcm::GCMClient::UNKNOWN_ERROR); | |
| 142 ENUM_CASE(gcm::GCMClient::NOT_SIGNED_IN); | |
| 143 ENUM_CASE(gcm::GCMClient::INVALID_PARAMETER); | |
| 144 ENUM_CASE(gcm::GCMClient::ASYNC_OPERATION_PENDING); | |
| 145 } | |
| 146 NOTREACHED(); | |
| 147 return ""; | |
| 148 } | |
| 149 | |
| 150 GCMNetworkChannel::GCMNetworkChannel( | 103 GCMNetworkChannel::GCMNetworkChannel( |
| 151 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 104 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 152 scoped_ptr<GCMNetworkChannelDelegate> delegate) | 105 scoped_ptr<GCMNetworkChannelDelegate> delegate) |
| 153 : request_context_getter_(request_context_getter), | 106 : request_context_getter_(request_context_getter), |
| 154 delegate_(delegate.Pass()), | 107 delegate_(delegate.Pass()), |
| 155 register_backoff_entry_(new net::BackoffEntry(&kRegisterBackoffPolicy)), | 108 register_backoff_entry_(new net::BackoffEntry(&kRegisterBackoffPolicy)), |
| 156 diagnostic_info_(this), | 109 diagnostic_info_(this), |
| 157 weak_factory_(this) { | 110 weak_factory_(this) { |
| 158 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); | 111 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); |
| 159 delegate_->Initialize(); | 112 delegate_->Initialize(); |
| 160 Register(); | 113 Register(); |
| 161 } | 114 } |
| 162 | 115 |
| 163 GCMNetworkChannel::~GCMNetworkChannel() { | 116 GCMNetworkChannel::~GCMNetworkChannel() { |
| 164 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); | 117 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); |
| 165 } | 118 } |
| 166 | 119 |
| 167 void GCMNetworkChannel::UpdateCredentials( | |
| 168 const std::string& email, | |
| 169 const std::string& token) { | |
| 170 // Do nothing. We get access token by requesting it for every message. | |
| 171 } | |
| 172 | |
| 173 void GCMNetworkChannel::RequestDetailedStatus( | |
| 174 base::Callback<void(const base::DictionaryValue&)> callback) { | |
| 175 callback.Run(*diagnostic_info_.CollectDebugData()); | |
| 176 } | |
| 177 | |
| 178 void GCMNetworkChannel::ResetRegisterBackoffEntryForTest( | |
| 179 const net::BackoffEntry::Policy* policy) { | |
| 180 register_backoff_entry_.reset(new net::BackoffEntry(policy)); | |
| 181 } | |
| 182 | |
| 183 void GCMNetworkChannel::Register() { | 120 void GCMNetworkChannel::Register() { |
| 184 delegate_->Register(base::Bind(&GCMNetworkChannel::OnRegisterComplete, | 121 delegate_->Register(base::Bind(&GCMNetworkChannel::OnRegisterComplete, |
| 185 weak_factory_.GetWeakPtr())); | 122 weak_factory_.GetWeakPtr())); |
| 186 } | 123 } |
| 187 | 124 |
| 188 void GCMNetworkChannel::OnRegisterComplete( | 125 void GCMNetworkChannel::OnRegisterComplete( |
| 189 const std::string& registration_id, | 126 const std::string& registration_id, |
| 190 gcm::GCMClient::Result result) { | 127 gcm::GCMClient::Result result) { |
| 191 DCHECK(CalledOnValidThread()); | 128 DCHECK(CalledOnValidThread()); |
| 192 if (result == gcm::GCMClient::SUCCESS) { | 129 if (result == gcm::GCMClient::SUCCESS) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 if (!cached_message_.empty()) { | 165 if (!cached_message_.empty()) { |
| 229 RecordOutgoingMessageStatus(MESSAGE_DISCARDED); | 166 RecordOutgoingMessageStatus(MESSAGE_DISCARDED); |
| 230 } | 167 } |
| 231 cached_message_ = message; | 168 cached_message_ = message; |
| 232 | 169 |
| 233 if (!registration_id_.empty()) { | 170 if (!registration_id_.empty()) { |
| 234 RequestAccessToken(); | 171 RequestAccessToken(); |
| 235 } | 172 } |
| 236 } | 173 } |
| 237 | 174 |
| 238 void GCMNetworkChannel::SetMessageReceiver( | |
| 239 invalidation::MessageCallback* incoming_receiver) { | |
| 240 delegate_->SetMessageReceiver(base::Bind( | |
| 241 &GCMNetworkChannel::OnIncomingMessage, weak_factory_.GetWeakPtr())); | |
| 242 SyncNetworkChannel::SetMessageReceiver(incoming_receiver); | |
| 243 } | |
| 244 | |
| 245 void GCMNetworkChannel::RequestAccessToken() { | 175 void GCMNetworkChannel::RequestAccessToken() { |
| 246 DCHECK(CalledOnValidThread()); | 176 DCHECK(CalledOnValidThread()); |
| 247 delegate_->RequestToken(base::Bind(&GCMNetworkChannel::OnGetTokenComplete, | 177 delegate_->RequestToken(base::Bind(&GCMNetworkChannel::OnGetTokenComplete, |
| 248 weak_factory_.GetWeakPtr())); | 178 weak_factory_.GetWeakPtr())); |
| 249 } | 179 } |
| 250 | 180 |
| 251 void GCMNetworkChannel::OnGetTokenComplete( | 181 void GCMNetworkChannel::OnGetTokenComplete( |
| 252 const GoogleServiceAuthError& error, | 182 const GoogleServiceAuthError& error, |
| 253 const std::string& token) { | 183 const std::string& token) { |
| 254 DCHECK(CalledOnValidThread()); | 184 DCHECK(CalledOnValidThread()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 283 if (!echo_token_.empty()) { | 213 if (!echo_token_.empty()) { |
| 284 const std::string echo_header("echo-token: " + echo_token_); | 214 const std::string echo_header("echo-token: " + echo_token_); |
| 285 fetcher_->AddExtraRequestHeader(echo_header); | 215 fetcher_->AddExtraRequestHeader(echo_header); |
| 286 } | 216 } |
| 287 fetcher_->SetUploadData("application/x-protobuffer", cached_message_); | 217 fetcher_->SetUploadData("application/x-protobuffer", cached_message_); |
| 288 fetcher_->Start(); | 218 fetcher_->Start(); |
| 289 // Clear message to prevent accidentally resending it in the future. | 219 // Clear message to prevent accidentally resending it in the future. |
| 290 cached_message_.clear(); | 220 cached_message_.clear(); |
| 291 } | 221 } |
| 292 | 222 |
| 223 void GCMNetworkChannel::OnURLFetchComplete(const net::URLFetcher* source) { |
| 224 DCHECK(CalledOnValidThread()); |
| 225 DCHECK_EQ(fetcher_, source); |
| 226 // Free fetcher at the end of function. |
| 227 scoped_ptr<net::URLFetcher> fetcher = fetcher_.Pass(); |
| 228 |
| 229 net::URLRequestStatus status = fetcher->GetStatus(); |
| 230 diagnostic_info_.last_post_response_code_ = |
| 231 status.is_success() ? source->GetResponseCode() : status.error(); |
| 232 |
| 233 if (status.is_success() && |
| 234 fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { |
| 235 DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; |
| 236 delegate_->InvalidateToken(access_token_); |
| 237 } |
| 238 |
| 239 if (!status.is_success() || |
| 240 (fetcher->GetResponseCode() != net::HTTP_OK && |
| 241 fetcher->GetResponseCode() != net::HTTP_NO_CONTENT)) { |
| 242 DVLOG(1) << "URLFetcher failure"; |
| 243 RecordOutgoingMessageStatus(POST_FAILURE); |
| 244 NotifyStateChange(TRANSIENT_INVALIDATION_ERROR); |
| 245 return; |
| 246 } |
| 247 |
| 248 RecordOutgoingMessageStatus(OUTGOING_MESSAGE_SUCCESS); |
| 249 NotifyStateChange(INVALIDATIONS_ENABLED); |
| 250 DVLOG(2) << "URLFetcher success"; |
| 251 } |
| 252 |
| 293 void GCMNetworkChannel::OnIncomingMessage(const std::string& message, | 253 void GCMNetworkChannel::OnIncomingMessage(const std::string& message, |
| 294 const std::string& echo_token) { | 254 const std::string& echo_token) { |
| 295 #if !defined(ANDROID) | 255 #if !defined(OS_ANDROID) |
| 296 if (!echo_token.empty()) | 256 if (!echo_token.empty()) |
| 297 echo_token_ = echo_token; | 257 echo_token_ = echo_token; |
| 298 diagnostic_info_.last_message_empty_echo_token_ = echo_token.empty(); | 258 diagnostic_info_.last_message_empty_echo_token_ = echo_token.empty(); |
| 299 diagnostic_info_.last_message_received_time_ = base::Time::Now(); | 259 diagnostic_info_.last_message_received_time_ = base::Time::Now(); |
| 300 | 260 |
| 301 if (message.empty()) { | 261 if (message.empty()) { |
| 302 RecordIncomingMessageStatus(MESSAGE_EMPTY); | 262 RecordIncomingMessageStatus(MESSAGE_EMPTY); |
| 303 return; | 263 return; |
| 304 } | 264 } |
| 305 std::string data; | 265 std::string data; |
| 306 if (!Base64DecodeURLSafe(message, &data)) { | 266 if (!Base64DecodeURLSafe(message, &data)) { |
| 307 RecordIncomingMessageStatus(INVALID_ENCODING); | 267 RecordIncomingMessageStatus(INVALID_ENCODING); |
| 308 return; | 268 return; |
| 309 } | 269 } |
| 310 ipc::invalidation::AddressedAndroidMessage android_message; | 270 ipc::invalidation::AddressedAndroidMessage android_message; |
| 311 if (!android_message.ParseFromString(data) || | 271 if (!android_message.ParseFromString(data) || |
| 312 !android_message.has_message()) { | 272 !android_message.has_message()) { |
| 313 RecordIncomingMessageStatus(INVALID_PROTO); | 273 RecordIncomingMessageStatus(INVALID_PROTO); |
| 314 return; | 274 return; |
| 315 } | 275 } |
| 316 DVLOG(2) << "Deliver incoming message"; | 276 DVLOG(2) << "Deliver incoming message"; |
| 317 RecordIncomingMessageStatus(INCOMING_MESSAGE_SUCCESS); | 277 RecordIncomingMessageStatus(INCOMING_MESSAGE_SUCCESS); |
| 318 DeliverIncomingMessage(android_message.message()); | 278 DeliverIncomingMessage(android_message.message()); |
| 319 #else | 279 #else |
| 320 // This code shouldn't be invoked on Android. | 280 // This code shouldn't be invoked on Android. |
| 321 NOTREACHED(); | 281 NOTREACHED(); |
| 322 #endif | 282 #endif |
| 323 } | 283 } |
| 324 | 284 |
| 325 void GCMNetworkChannel::OnURLFetchComplete(const net::URLFetcher* source) { | |
| 326 DCHECK(CalledOnValidThread()); | |
| 327 DCHECK_EQ(fetcher_, source); | |
| 328 // Free fetcher at the end of function. | |
| 329 scoped_ptr<net::URLFetcher> fetcher = fetcher_.Pass(); | |
| 330 | |
| 331 net::URLRequestStatus status = fetcher->GetStatus(); | |
| 332 diagnostic_info_.last_post_response_code_ = | |
| 333 status.is_success() ? source->GetResponseCode() : status.error(); | |
| 334 | |
| 335 if (status.is_success() && | |
| 336 fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { | |
| 337 DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; | |
| 338 delegate_->InvalidateToken(access_token_); | |
| 339 } | |
| 340 | |
| 341 if (!status.is_success() || | |
| 342 (fetcher->GetResponseCode() != net::HTTP_OK && | |
| 343 fetcher->GetResponseCode() != net::HTTP_NO_CONTENT)) { | |
| 344 DVLOG(1) << "URLFetcher failure"; | |
| 345 RecordOutgoingMessageStatus(POST_FAILURE); | |
| 346 NotifyStateChange(TRANSIENT_INVALIDATION_ERROR); | |
| 347 return; | |
| 348 } | |
| 349 | |
| 350 RecordOutgoingMessageStatus(OUTGOING_MESSAGE_SUCCESS); | |
| 351 NotifyStateChange(INVALIDATIONS_ENABLED); | |
| 352 DVLOG(2) << "URLFetcher success"; | |
| 353 } | |
| 354 | |
| 355 void GCMNetworkChannel::OnNetworkChanged( | 285 void GCMNetworkChannel::OnNetworkChanged( |
| 356 net::NetworkChangeNotifier::ConnectionType connection_type) { | 286 net::NetworkChangeNotifier::ConnectionType connection_type) { |
| 357 // Network connection is restored. Let's notify cacheinvalidations so it has | 287 // Network connection is restored. Let's notify cacheinvalidations so it has |
| 358 // chance to retry. | 288 // chance to retry. |
| 359 if (connection_type != net::NetworkChangeNotifier::CONNECTION_NONE) | 289 if (connection_type != net::NetworkChangeNotifier::CONNECTION_NONE) |
| 360 NotifyStateChange(INVALIDATIONS_ENABLED); | 290 NotifyStateChange(INVALIDATIONS_ENABLED); |
| 361 } | 291 } |
| 362 | 292 |
| 363 GURL GCMNetworkChannel::BuildUrl(const std::string& registration_id) { | 293 GURL GCMNetworkChannel::BuildUrl(const std::string& registration_id) { |
| 364 DCHECK(!registration_id.empty()); | 294 DCHECK(!registration_id.empty()); |
| 365 | 295 |
| 366 #if !defined(ANDROID) | 296 #if !defined(OS_ANDROID) |
| 367 ipc::invalidation::EndpointId endpoint_id; | 297 ipc::invalidation::EndpointId endpoint_id; |
| 368 endpoint_id.set_c2dm_registration_id(registration_id); | 298 endpoint_id.set_c2dm_registration_id(registration_id); |
| 369 endpoint_id.set_client_key(std::string()); | 299 endpoint_id.set_client_key(std::string()); |
| 370 endpoint_id.set_package_name(kCacheInvalidationPackageName); | 300 endpoint_id.set_package_name(kCacheInvalidationPackageName); |
| 371 endpoint_id.mutable_channel_version()->set_major_version( | 301 endpoint_id.mutable_channel_version()->set_major_version( |
| 372 ipc::invalidation::INITIAL); | 302 ipc::invalidation::INITIAL); |
| 373 std::string endpoint_id_buffer; | 303 std::string endpoint_id_buffer; |
| 374 endpoint_id.SerializeToString(&endpoint_id_buffer); | 304 endpoint_id.SerializeToString(&endpoint_id_buffer); |
| 375 | 305 |
| 376 ipc::invalidation::NetworkEndpointId network_endpoint_id; | 306 ipc::invalidation::NetworkEndpointId network_endpoint_id; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 // Add padding. | 341 // Add padding. |
| 412 size_t padded_size = (input.size() + 3) - (input.size() + 3) % 4; | 342 size_t padded_size = (input.size() + 3) - (input.size() + 3) % 4; |
| 413 std::string padded_input(input); | 343 std::string padded_input(input); |
| 414 padded_input.resize(padded_size, '='); | 344 padded_input.resize(padded_size, '='); |
| 415 // Convert to standard base64 alphabet. | 345 // Convert to standard base64 alphabet. |
| 416 base::ReplaceChars(padded_input, "-", "+", &padded_input); | 346 base::ReplaceChars(padded_input, "-", "+", &padded_input); |
| 417 base::ReplaceChars(padded_input, "_", "/", &padded_input); | 347 base::ReplaceChars(padded_input, "_", "/", &padded_input); |
| 418 return base::Base64Decode(padded_input, output); | 348 return base::Base64Decode(padded_input, output); |
| 419 } | 349 } |
| 420 | 350 |
| 351 void GCMNetworkChannel::SetMessageReceiver( |
| 352 invalidation::MessageCallback* incoming_receiver) { |
| 353 delegate_->SetMessageReceiver(base::Bind( |
| 354 &GCMNetworkChannel::OnIncomingMessage, weak_factory_.GetWeakPtr())); |
| 355 SyncNetworkChannel::SetMessageReceiver(incoming_receiver); |
| 356 } |
| 357 |
| 358 void GCMNetworkChannel::RequestDetailedStatus( |
| 359 base::Callback<void(const base::DictionaryValue&)> callback) { |
| 360 callback.Run(*diagnostic_info_.CollectDebugData()); |
| 361 } |
| 362 |
| 363 void GCMNetworkChannel::UpdateCredentials(const std::string& email, |
| 364 const std::string& token) { |
| 365 // Do nothing. We get access token by requesting it for every message. |
| 366 } |
| 367 |
| 368 void GCMNetworkChannel::ResetRegisterBackoffEntryForTest( |
| 369 const net::BackoffEntry::Policy* policy) { |
| 370 register_backoff_entry_.reset(new net::BackoffEntry(policy)); |
| 371 } |
| 372 |
| 373 GCMNetworkChannelDiagnostic::GCMNetworkChannelDiagnostic( |
| 374 GCMNetworkChannel* parent) |
| 375 : parent_(parent), |
| 376 last_message_empty_echo_token_(false), |
| 377 last_post_response_code_(0), |
| 378 registration_result_(gcm::GCMClient::UNKNOWN_ERROR), |
| 379 sent_messages_count_(0) {} |
| 380 |
| 381 scoped_ptr<base::DictionaryValue> |
| 382 GCMNetworkChannelDiagnostic::CollectDebugData() const { |
| 383 scoped_ptr<base::DictionaryValue> status(new base::DictionaryValue); |
| 384 status->SetString("GCMNetworkChannel.Channel", "GCM"); |
| 385 std::string reg_id_hash = base::SHA1HashString(registration_id_); |
| 386 status->SetString("GCMNetworkChannel.HashedRegistrationID", |
| 387 base::HexEncode(reg_id_hash.c_str(), reg_id_hash.size())); |
| 388 status->SetString("GCMNetworkChannel.RegistrationResult", |
| 389 GCMClientResultToString(registration_result_)); |
| 390 status->SetBoolean("GCMNetworkChannel.HadLastMessageEmptyEchoToken", |
| 391 last_message_empty_echo_token_); |
| 392 status->SetString( |
| 393 "GCMNetworkChannel.LastMessageReceivedTime", |
| 394 base::TimeFormatShortDateAndTime(last_message_received_time_)); |
| 395 status->SetInteger("GCMNetworkChannel.LastPostResponseCode", |
| 396 last_post_response_code_); |
| 397 status->SetInteger("GCMNetworkChannel.SentMessages", sent_messages_count_); |
| 398 status->SetInteger("GCMNetworkChannel.ReceivedMessages", |
| 399 parent_->GetReceivedMessagesCount()); |
| 400 return status.Pass(); |
| 401 } |
| 402 |
| 403 std::string GCMNetworkChannelDiagnostic::GCMClientResultToString( |
| 404 const gcm::GCMClient::Result result) const { |
| 405 #define ENUM_CASE(x) case x: return #x; break; |
| 406 switch (result) { |
| 407 ENUM_CASE(gcm::GCMClient::SUCCESS); |
| 408 ENUM_CASE(gcm::GCMClient::NETWORK_ERROR); |
| 409 ENUM_CASE(gcm::GCMClient::SERVER_ERROR); |
| 410 ENUM_CASE(gcm::GCMClient::TTL_EXCEEDED); |
| 411 ENUM_CASE(gcm::GCMClient::UNKNOWN_ERROR); |
| 412 ENUM_CASE(gcm::GCMClient::NOT_SIGNED_IN); |
| 413 ENUM_CASE(gcm::GCMClient::INVALID_PARAMETER); |
| 414 ENUM_CASE(gcm::GCMClient::ASYNC_OPERATION_PENDING); |
| 415 } |
| 416 NOTREACHED(); |
| 417 return ""; |
| 418 } |
| 419 |
| 421 } // namespace syncer | 420 } // namespace syncer |
| OLD | NEW |