Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "google_apis/gcm/gcm_client_impl.h" | 5 #include "google_apis/gcm/gcm_client_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/metrics/histogram.h" | |
| 12 #include "base/sequenced_task_runner.h" | 13 #include "base/sequenced_task_runner.h" |
| 13 #include "base/time/default_clock.h" | 14 #include "base/time/default_clock.h" |
| 14 #include "google_apis/gcm/base/mcs_message.h" | 15 #include "google_apis/gcm/base/mcs_message.h" |
| 15 #include "google_apis/gcm/base/mcs_util.h" | 16 #include "google_apis/gcm/base/mcs_util.h" |
| 16 #include "google_apis/gcm/engine/checkin_request.h" | 17 #include "google_apis/gcm/engine/checkin_request.h" |
| 17 #include "google_apis/gcm/engine/connection_factory_impl.h" | 18 #include "google_apis/gcm/engine/connection_factory_impl.h" |
| 18 #include "google_apis/gcm/engine/gcm_store_impl.h" | 19 #include "google_apis/gcm/engine/gcm_store_impl.h" |
| 19 #include "google_apis/gcm/engine/mcs_client.h" | 20 #include "google_apis/gcm/engine/mcs_client.h" |
| 20 #include "google_apis/gcm/engine/registration_request.h" | 21 #include "google_apis/gcm/engine/registration_request.h" |
| 21 #include "google_apis/gcm/engine/unregistration_request.h" | 22 #include "google_apis/gcm/engine/unregistration_request.h" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 url_request_context_getter, | 132 url_request_context_getter, |
| 132 Delegate* delegate) { | 133 Delegate* delegate) { |
| 133 DCHECK_EQ(UNINITIALIZED, state_); | 134 DCHECK_EQ(UNINITIALIZED, state_); |
| 134 DCHECK(url_request_context_getter); | 135 DCHECK(url_request_context_getter); |
| 135 DCHECK(delegate); | 136 DCHECK(delegate); |
| 136 | 137 |
| 137 chrome_build_proto_.CopyFrom(chrome_build_proto); | 138 chrome_build_proto_.CopyFrom(chrome_build_proto); |
| 138 url_request_context_getter_ = url_request_context_getter; | 139 url_request_context_getter_ = url_request_context_getter; |
| 139 | 140 |
| 140 gcm_store_.reset(new GCMStoreImpl(false, path, blocking_task_runner)); | 141 gcm_store_.reset(new GCMStoreImpl(false, path, blocking_task_runner)); |
| 141 gcm_store_->Load(base::Bind(&GCMClientImpl::OnLoadCompleted, | |
| 142 weak_ptr_factory_.GetWeakPtr())); | |
| 143 | 142 |
| 144 delegate_ = delegate; | 143 delegate_ = delegate; |
| 145 | 144 |
| 146 // |mcs_client_| might already be set for testing at this point. No need to | 145 // |mcs_client_| might already be set for testing at this point. No need to |
| 147 // create a |connection_factory_|. | 146 // create a |connection_factory_|. |
| 148 if (!mcs_client_.get()) { | 147 if (!mcs_client_.get()) { |
| 149 const net::HttpNetworkSession::Params* network_session_params = | 148 const net::HttpNetworkSession::Params* network_session_params = |
| 150 url_request_context_getter->GetURLRequestContext()-> | 149 url_request_context_getter->GetURLRequestContext()-> |
| 151 GetNetworkSessionParams(); | 150 GetNetworkSessionParams(); |
| 152 DCHECK(network_session_params); | 151 DCHECK(network_session_params); |
| 153 network_session_ = new net::HttpNetworkSession(*network_session_params); | 152 network_session_ = new net::HttpNetworkSession(*network_session_params); |
| 154 connection_factory_.reset(new ConnectionFactoryImpl( | 153 connection_factory_.reset(new ConnectionFactoryImpl( |
| 155 GURL(kMCSEndpoint), | 154 GURL(kMCSEndpoint), |
| 156 kDefaultBackoffPolicy, | 155 kDefaultBackoffPolicy, |
| 157 network_session_, | 156 network_session_, |
| 158 net_log_.net_log())); | 157 net_log_.net_log())); |
| 159 mcs_client_.reset(new MCSClient(clock_.get(), | 158 mcs_client_.reset(new MCSClient(clock_.get(), |
| 160 connection_factory_.get(), | 159 connection_factory_.get(), |
| 161 gcm_store_.get())); | 160 gcm_store_.get())); |
| 162 } | 161 } |
|
fgorski
2014/02/20 22:18:40
Add a INITIALIZED to the State enum in the header
jianli
2014/02/21 18:25:11
Done.
| |
| 162 } | |
| 163 | 163 |
| 164 void GCMClientImpl::CheckIn() { | |
|
fgorski
2014/02/20 22:18:40
Add a DCHECK_EQ(state_, INITIALIZED);
jianli
2014/02/21 18:25:11
Done.
| |
| 165 // Once the loading is completed, the check-in will be initiated. | |
| 166 gcm_store_->Load(base::Bind(&GCMClientImpl::OnLoadCompleted, | |
| 167 weak_ptr_factory_.GetWeakPtr())); | |
| 164 state_ = LOADING; | 168 state_ = LOADING; |
| 165 } | 169 } |
| 166 | 170 |
| 167 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { | 171 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
| 168 DCHECK_EQ(LOADING, state_); | 172 DCHECK_EQ(LOADING, state_); |
| 169 | 173 |
| 170 if (!result->success) { | 174 if (!result->success) { |
| 171 ResetState(); | 175 ResetState(); |
| 172 return; | 176 return; |
| 173 } | 177 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 } | 274 } |
| 271 | 275 |
| 272 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { | 276 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { |
| 273 // TODO(fgorski): This is one of the signals that store needs a rebuild. | 277 // TODO(fgorski): This is one of the signals that store needs a rebuild. |
| 274 DCHECK(success); | 278 DCHECK(success); |
| 275 } | 279 } |
| 276 | 280 |
| 277 void GCMClientImpl::CheckOut() { | 281 void GCMClientImpl::CheckOut() { |
| 278 delegate_ = NULL; | 282 delegate_ = NULL; |
| 279 device_checkin_info_.Reset(); | 283 device_checkin_info_.Reset(); |
| 280 mcs_client_->Destroy(); // This will also destroy GCM store. | |
| 281 mcs_client_.reset(); | 284 mcs_client_.reset(); |
| 285 gcm_store_->Destroy(base::Bind(&GCMClientImpl::OnGCMStoreDestroyed, | |
| 286 weak_ptr_factory_.GetWeakPtr())); | |
| 282 checkin_request_.reset(); | 287 checkin_request_.reset(); |
| 283 pending_registrations_.clear(); | 288 pending_registrations_.clear(); |
| 284 } | 289 } |
| 285 | 290 |
| 286 void GCMClientImpl::Register(const std::string& app_id, | 291 void GCMClientImpl::Register(const std::string& app_id, |
| 287 const std::string& cert, | 292 const std::string& cert, |
| 288 const std::vector<std::string>& sender_ids) { | 293 const std::vector<std::string>& sender_ids) { |
| 289 DCHECK_EQ(state_, READY); | 294 DCHECK_EQ(state_, READY); |
| 290 RegistrationRequest::RequestInfo request_info( | 295 RegistrationRequest::RequestInfo request_info( |
| 291 device_checkin_info_.android_id, | 296 device_checkin_info_.android_id, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 delegate_->OnUnregisterFinished(app_id, status); | 365 delegate_->OnUnregisterFinished(app_id, status); |
| 361 | 366 |
| 362 PendingUnregistrations::iterator iter = pending_unregistrations_.find(app_id); | 367 PendingUnregistrations::iterator iter = pending_unregistrations_.find(app_id); |
| 363 if (iter == pending_unregistrations_.end()) | 368 if (iter == pending_unregistrations_.end()) |
| 364 return; | 369 return; |
| 365 | 370 |
| 366 delete iter->second; | 371 delete iter->second; |
| 367 pending_unregistrations_.erase(iter); | 372 pending_unregistrations_.erase(iter); |
| 368 } | 373 } |
| 369 | 374 |
| 375 void GCMClientImpl::OnGCMStoreDestroyed(bool success) { | |
| 376 LOG_IF(ERROR, !success) << "GCM store failed to be destroyed!"; | |
| 377 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success); | |
| 378 } | |
| 379 | |
| 370 void GCMClientImpl::Send(const std::string& app_id, | 380 void GCMClientImpl::Send(const std::string& app_id, |
| 371 const std::string& receiver_id, | 381 const std::string& receiver_id, |
| 372 const OutgoingMessage& message) { | 382 const OutgoingMessage& message) { |
| 373 DCHECK_EQ(state_, READY); | 383 DCHECK_EQ(state_, READY); |
| 374 | 384 |
| 375 mcs_proto::DataMessageStanza stanza; | 385 mcs_proto::DataMessageStanza stanza; |
| 376 stanza.set_ttl(message.time_to_live); | 386 stanza.set_ttl(message.time_to_live); |
| 377 stanza.set_sent(clock_->Now().ToInternalValue() / | 387 stanza.set_sent(clock_->Now().ToInternalValue() / |
| 378 base::Time::kMicrosecondsPerSecond); | 388 base::Time::kMicrosecondsPerSecond); |
| 379 stanza.set_id(message.id); | 389 stanza.set_id(message.id); |
| 380 stanza.set_from(kSendMessageFromValue); | 390 stanza.set_from(kSendMessageFromValue); |
| 381 stanza.set_to(receiver_id); | 391 stanza.set_to(receiver_id); |
| 382 stanza.set_category(app_id); | 392 stanza.set_category(app_id); |
| 383 | 393 |
| 384 for (MessageData::const_iterator iter = message.data.begin(); | 394 for (MessageData::const_iterator iter = message.data.begin(); |
| 385 iter != message.data.end(); | 395 iter != message.data.end(); |
| 386 ++iter) { | 396 ++iter) { |
| 387 mcs_proto::AppData* app_data = stanza.add_app_data(); | 397 mcs_proto::AppData* app_data = stanza.add_app_data(); |
| 388 app_data->set_key(iter->first); | 398 app_data->set_key(iter->first); |
| 389 app_data->set_value(iter->second); | 399 app_data->set_value(iter->second); |
| 390 } | 400 } |
| 391 | 401 |
| 392 MCSMessage mcs_message(stanza); | 402 MCSMessage mcs_message(stanza); |
| 393 DVLOG(1) << "MCS message size: " << mcs_message.size(); | 403 DVLOG(1) << "MCS message size: " << mcs_message.size(); |
| 394 mcs_client_->SendMessage(mcs_message); | 404 mcs_client_->SendMessage(mcs_message); |
| 395 } | 405 } |
| 396 | 406 |
| 397 bool GCMClientImpl::IsReady() const { | |
| 398 return state_ == READY; | |
| 399 } | |
| 400 | |
| 401 void GCMClientImpl::OnMessageReceivedFromMCS(const gcm::MCSMessage& message) { | 407 void GCMClientImpl::OnMessageReceivedFromMCS(const gcm::MCSMessage& message) { |
| 402 switch (message.tag()) { | 408 switch (message.tag()) { |
| 403 case kLoginResponseTag: | 409 case kLoginResponseTag: |
| 404 DVLOG(1) << "Login response received by GCM Client. Ignoring."; | 410 DVLOG(1) << "Login response received by GCM Client. Ignoring."; |
| 405 return; | 411 return; |
| 406 case kDataMessageStanzaTag: | 412 case kDataMessageStanzaTag: |
| 407 DVLOG(1) << "A downstream message received. Processing..."; | 413 DVLOG(1) << "A downstream message received. Processing..."; |
| 408 HandleIncomingMessage(message); | 414 HandleIncomingMessage(message); |
| 409 return; | 415 return; |
| 410 default: | 416 default: |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 if (iter != incoming_message.data.end()) | 493 if (iter != incoming_message.data.end()) |
| 488 message_id = iter->second; | 494 message_id = iter->second; |
| 489 delegate->OnMessageSendError(app_id, message_id, SERVER_ERROR); | 495 delegate->OnMessageSendError(app_id, message_id, SERVER_ERROR); |
| 490 } | 496 } |
| 491 | 497 |
| 492 void GCMClientImpl::SetMCSClientForTesting(scoped_ptr<MCSClient> mcs_client) { | 498 void GCMClientImpl::SetMCSClientForTesting(scoped_ptr<MCSClient> mcs_client) { |
| 493 mcs_client_ = mcs_client.Pass(); | 499 mcs_client_ = mcs_client.Pass(); |
| 494 } | 500 } |
| 495 | 501 |
| 496 } // namespace gcm | 502 } // namespace gcm |
| OLD | NEW |