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" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 return DATA_MESSAGE; | 108 return DATA_MESSAGE; |
109 return UNKNOWN; | 109 return UNKNOWN; |
110 } | 110 } |
111 | 111 |
112 } // namespace | 112 } // namespace |
113 | 113 |
114 GCMClientImpl::GCMClientImpl() | 114 GCMClientImpl::GCMClientImpl() |
115 : state_(UNINITIALIZED), | 115 : state_(UNINITIALIZED), |
116 clock_(new base::DefaultClock()), | 116 clock_(new base::DefaultClock()), |
117 url_request_context_getter_(NULL), | 117 url_request_context_getter_(NULL), |
118 pending_registrations_deleter_(&pending_registrations_), | 118 pending_registration_requests_deleter_(&pending_registration_requests_), |
119 pending_unregistrations_deleter_(&pending_unregistrations_), | 119 pending_unregistration_requests_deleter_( |
120 &pending_unregistration_requests_), | |
120 weak_ptr_factory_(this) { | 121 weak_ptr_factory_(this) { |
121 } | 122 } |
122 | 123 |
123 GCMClientImpl::~GCMClientImpl() { | 124 GCMClientImpl::~GCMClientImpl() { |
124 } | 125 } |
125 | 126 |
126 void GCMClientImpl::Initialize( | 127 void GCMClientImpl::Initialize( |
127 const checkin_proto::ChromeBuildProto& chrome_build_proto, | 128 const checkin_proto::ChromeBuildProto& chrome_build_proto, |
128 const base::FilePath& path, | 129 const base::FilePath& path, |
129 const std::vector<std::string>& account_ids, | 130 const std::vector<std::string>& account_ids, |
(...skipping 26 matching lines...) Expand all Loading... | |
156 } | 157 } |
157 | 158 |
158 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { | 159 void GCMClientImpl::OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result) { |
159 DCHECK_EQ(LOADING, state_); | 160 DCHECK_EQ(LOADING, state_); |
160 | 161 |
161 if (!result->success) { | 162 if (!result->success) { |
162 ResetState(); | 163 ResetState(); |
163 return; | 164 return; |
164 } | 165 } |
165 | 166 |
167 registrations_ = result->registrations; | |
168 | |
166 device_checkin_info_.android_id = result->device_android_id; | 169 device_checkin_info_.android_id = result->device_android_id; |
167 device_checkin_info_.secret = result->device_security_token; | 170 device_checkin_info_.secret = result->device_security_token; |
168 InitializeMCSClient(result.Pass()); | 171 InitializeMCSClient(result.Pass()); |
169 if (!device_checkin_info_.IsValid()) { | 172 if (!device_checkin_info_.IsValid()) { |
170 device_checkin_info_.Reset(); | 173 device_checkin_info_.Reset(); |
171 state_ = INITIAL_DEVICE_CHECKIN; | 174 state_ = INITIAL_DEVICE_CHECKIN; |
172 StartCheckin(device_checkin_info_); | 175 StartCheckin(device_checkin_info_); |
173 return; | 176 return; |
174 } | 177 } |
175 | 178 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 // TODO(fgorski): Reset the checkin timer. | 280 // TODO(fgorski): Reset the checkin timer. |
278 } | 281 } |
279 } | 282 } |
280 } | 283 } |
281 | 284 |
282 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { | 285 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { |
283 // TODO(fgorski): This is one of the signals that store needs a rebuild. | 286 // TODO(fgorski): This is one of the signals that store needs a rebuild. |
284 DCHECK(success); | 287 DCHECK(success); |
285 } | 288 } |
286 | 289 |
290 void GCMClientImpl::UpdateRegistrationCallback(bool success) { | |
291 // TODO(fgorski): This is one of the signals that store needs a rebuild. | |
292 DCHECK(success); | |
293 } | |
294 | |
287 void GCMClientImpl::Stop() { | 295 void GCMClientImpl::Stop() { |
288 device_checkin_info_.Reset(); | 296 device_checkin_info_.Reset(); |
289 mcs_client_.reset(); | 297 mcs_client_.reset(); |
290 checkin_request_.reset(); | 298 checkin_request_.reset(); |
291 pending_registrations_.clear(); | 299 pending_registration_requests_.clear(); |
292 state_ = INITIALIZED; | 300 state_ = INITIALIZED; |
293 gcm_store_->Close(); | 301 gcm_store_->Close(); |
294 } | 302 } |
295 | 303 |
296 void GCMClientImpl::CheckOut() { | 304 void GCMClientImpl::CheckOut() { |
297 Stop(); | 305 Stop(); |
298 gcm_store_->Destroy(base::Bind(&GCMClientImpl::OnGCMStoreDestroyed, | 306 gcm_store_->Destroy(base::Bind(&GCMClientImpl::OnGCMStoreDestroyed, |
299 weak_ptr_factory_.GetWeakPtr())); | 307 weak_ptr_factory_.GetWeakPtr())); |
300 } | 308 } |
301 | 309 |
302 void GCMClientImpl::Register(const std::string& app_id, | 310 void GCMClientImpl::Register(const std::string& app_id, |
303 const std::vector<std::string>& sender_ids) { | 311 const std::vector<std::string>& sender_ids) { |
304 DCHECK_EQ(state_, READY); | 312 DCHECK_EQ(state_, READY); |
313 | |
314 // If the same sender ids is provided, return the cached registration ID | |
315 // directly. | |
316 RegistrationInfoMap::const_iterator registrations_iter = | |
317 registrations_.find(app_id); | |
318 if (registrations_iter != registrations_.end() && | |
319 registrations_iter->second.sender_ids == sender_ids) { | |
320 delegate_->OnRegisterFinished( | |
321 app_id, registrations_iter->second.registration_id, SUCCESS); | |
322 return; | |
323 } | |
324 | |
305 RegistrationRequest::RequestInfo request_info( | 325 RegistrationRequest::RequestInfo request_info( |
306 device_checkin_info_.android_id, | 326 device_checkin_info_.android_id, |
307 device_checkin_info_.secret, | 327 device_checkin_info_.secret, |
308 app_id, | 328 app_id, |
309 sender_ids); | 329 sender_ids); |
310 DCHECK_EQ(0u, pending_registrations_.count(app_id)); | 330 DCHECK_EQ(0u, pending_registration_requests_.count(app_id)); |
311 | 331 |
312 RegistrationRequest* registration_request = | 332 RegistrationRequest* registration_request = |
313 new RegistrationRequest(request_info, | 333 new RegistrationRequest(request_info, |
314 kDefaultBackoffPolicy, | 334 kDefaultBackoffPolicy, |
315 base::Bind(&GCMClientImpl::OnRegisterCompleted, | 335 base::Bind(&GCMClientImpl::OnRegisterCompleted, |
316 weak_ptr_factory_.GetWeakPtr(), | 336 weak_ptr_factory_.GetWeakPtr(), |
317 app_id), | 337 app_id, |
338 sender_ids), | |
318 kMaxRegistrationRetries, | 339 kMaxRegistrationRetries, |
319 url_request_context_getter_); | 340 url_request_context_getter_); |
320 pending_registrations_[app_id] = registration_request; | 341 pending_registration_requests_[app_id] = registration_request; |
321 registration_request->Start(); | 342 registration_request->Start(); |
322 } | 343 } |
323 | 344 |
324 void GCMClientImpl::OnRegisterCompleted(const std::string& app_id, | 345 void GCMClientImpl::OnRegisterCompleted( |
325 RegistrationRequest::Status status, | 346 const std::string& app_id, |
326 const std::string& registration_id) { | 347 const std::vector<std::string>& sender_ids, |
348 RegistrationRequest::Status status, | |
349 const std::string& registration_id) { | |
327 DCHECK(delegate_); | 350 DCHECK(delegate_); |
328 | 351 |
329 Result result; | 352 Result result; |
330 PendingRegistrations::iterator iter = pending_registrations_.find(app_id); | 353 PendingRegistrationRequests::iterator iter = |
331 if (iter == pending_registrations_.end()) | 354 pending_registration_requests_.find(app_id); |
355 if (iter == pending_registration_requests_.end()) | |
332 result = UNKNOWN_ERROR; | 356 result = UNKNOWN_ERROR; |
333 else if (status == RegistrationRequest::INVALID_SENDER) | 357 else if (status == RegistrationRequest::INVALID_SENDER) |
334 result = INVALID_PARAMETER; | 358 result = INVALID_PARAMETER; |
335 else if (registration_id.empty()) | 359 else if (registration_id.empty()) |
336 result = SERVER_ERROR; | 360 result = SERVER_ERROR; |
337 else | 361 else |
338 result = SUCCESS; | 362 result = SUCCESS; |
339 | 363 |
364 if (result == SUCCESS) { | |
365 // Cache it. | |
366 RegistrationInfo registration; | |
367 registration.sender_ids = sender_ids; | |
368 registration.registration_id = registration_id; | |
369 registrations_[app_id] = registration; | |
370 | |
371 // Save it in the persistent store. | |
372 gcm_store_->AddRegistration( | |
373 app_id, | |
374 registration, | |
375 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, | |
376 weak_ptr_factory_.GetWeakPtr())); | |
377 } | |
378 | |
340 delegate_->OnRegisterFinished( | 379 delegate_->OnRegisterFinished( |
341 app_id, result == SUCCESS ? registration_id : std::string(), result); | 380 app_id, result == SUCCESS ? registration_id : std::string(), result); |
342 | 381 |
343 if (iter != pending_registrations_.end()) { | 382 if (iter != pending_registration_requests_.end()) { |
344 delete iter->second; | 383 delete iter->second; |
345 pending_registrations_.erase(iter); | 384 pending_registration_requests_.erase(iter); |
346 } | 385 } |
347 } | 386 } |
348 | 387 |
349 void GCMClientImpl::Unregister(const std::string& app_id) { | 388 void GCMClientImpl::Unregister(const std::string& app_id) { |
350 DCHECK_EQ(state_, READY); | 389 DCHECK_EQ(state_, READY); |
351 if (pending_unregistrations_.count(app_id) == 1) | 390 if (pending_unregistration_requests_.count(app_id) == 1) |
352 return; | 391 return; |
353 | 392 |
393 // Remove from the cache and persistent store. | |
394 registrations_.erase(app_id); | |
395 gcm_store_->RemoveRegistration( | |
396 app_id, | |
397 base::Bind(&GCMClientImpl::UpdateRegistrationCallback, | |
398 weak_ptr_factory_.GetWeakPtr())); | |
399 | |
354 UnregistrationRequest::RequestInfo request_info( | 400 UnregistrationRequest::RequestInfo request_info( |
355 device_checkin_info_.android_id, | 401 device_checkin_info_.android_id, |
356 device_checkin_info_.secret, | 402 device_checkin_info_.secret, |
357 app_id); | 403 app_id); |
358 | 404 |
359 UnregistrationRequest* unregistration_request = | 405 UnregistrationRequest* unregistration_request = |
360 new UnregistrationRequest( | 406 new UnregistrationRequest( |
361 request_info, | 407 request_info, |
362 kDefaultBackoffPolicy, | 408 kDefaultBackoffPolicy, |
363 base::Bind(&GCMClientImpl::OnUnregisterCompleted, | 409 base::Bind(&GCMClientImpl::OnUnregisterCompleted, |
364 weak_ptr_factory_.GetWeakPtr(), | 410 weak_ptr_factory_.GetWeakPtr(), |
365 app_id), | 411 app_id), |
366 url_request_context_getter_); | 412 url_request_context_getter_); |
367 pending_unregistrations_[app_id] = unregistration_request; | 413 pending_unregistration_requests_[app_id] = unregistration_request; |
368 unregistration_request->Start(); | 414 unregistration_request->Start(); |
369 } | 415 } |
370 | 416 |
371 void GCMClientImpl::OnUnregisterCompleted( | 417 void GCMClientImpl::OnUnregisterCompleted( |
372 const std::string& app_id, | 418 const std::string& app_id, |
373 UnregistrationRequest::Status status) { | 419 UnregistrationRequest::Status status) { |
374 DVLOG(1) << "Unregister completed for app: " << app_id | 420 DVLOG(1) << "Unregister completed for app: " << app_id |
375 << " with " << (status ? "success." : "failure."); | 421 << " with " << (status ? "success." : "failure."); |
376 delegate_->OnUnregisterFinished( | 422 delegate_->OnUnregisterFinished( |
377 app_id, | 423 app_id, |
378 status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); | 424 status == UnregistrationRequest::SUCCESS ? SUCCESS : SERVER_ERROR); |
379 | 425 |
380 PendingUnregistrations::iterator iter = pending_unregistrations_.find(app_id); | 426 PendingUnregistrationRequests::iterator iter = |
381 if (iter == pending_unregistrations_.end()) | 427 pending_unregistration_requests_.find(app_id); |
428 if (iter == pending_unregistration_requests_.end()) | |
382 return; | 429 return; |
383 | 430 |
384 delete iter->second; | 431 delete iter->second; |
385 pending_unregistrations_.erase(iter); | 432 pending_unregistration_requests_.erase(iter); |
386 } | 433 } |
387 | 434 |
388 void GCMClientImpl::OnGCMStoreDestroyed(bool success) { | 435 void GCMClientImpl::OnGCMStoreDestroyed(bool success) { |
389 DLOG_IF(ERROR, !success) << "GCM store failed to be destroyed!"; | 436 DLOG_IF(ERROR, !success) << "GCM store failed to be destroyed!"; |
390 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success); | 437 UMA_HISTOGRAM_BOOLEAN("GCM.StoreDestroySucceeded", success); |
391 } | 438 } |
392 | 439 |
393 void GCMClientImpl::Send(const std::string& app_id, | 440 void GCMClientImpl::Send(const std::string& app_id, |
394 const std::string& receiver_id, | 441 const std::string& receiver_id, |
395 const OutgoingMessage& message) { | 442 const OutgoingMessage& message) { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
532 default: // Treat default the same as UNKNOWN. | 579 default: // Treat default the same as UNKNOWN. |
533 DVLOG(1) << "Unknown message_type received. Message ignored. " | 580 DVLOG(1) << "Unknown message_type received. Message ignored. " |
534 << "App ID: " << data_message_stanza.category() << "."; | 581 << "App ID: " << data_message_stanza.category() << "."; |
535 break; | 582 break; |
536 } | 583 } |
537 } | 584 } |
538 | 585 |
539 void GCMClientImpl::HandleIncomingDataMessage( | 586 void GCMClientImpl::HandleIncomingDataMessage( |
540 const mcs_proto::DataMessageStanza& data_message_stanza, | 587 const mcs_proto::DataMessageStanza& data_message_stanza, |
541 MessageData& message_data) { | 588 MessageData& message_data) { |
589 std::string app_id = data_message_stanza.category(); | |
590 | |
591 // Dropping the message when the app is not registered for the sender of the | |
Nicolas Zea
2014/03/21 19:52:40
nit: Dropping -> Drop
| |
592 // message. | |
593 RegistrationInfoMap::iterator iter = registrations_.find(app_id); | |
594 if (iter == registrations_.end() || | |
595 std::find(iter->second.sender_ids.begin(), | |
596 iter->second.sender_ids.end(), | |
597 data_message_stanza.from()) == iter->second.sender_ids.end()) { | |
598 return; | |
599 } | |
600 | |
542 IncomingMessage incoming_message; | 601 IncomingMessage incoming_message; |
543 incoming_message.sender_id = data_message_stanza.from(); | 602 incoming_message.sender_id = data_message_stanza.from(); |
544 if (data_message_stanza.has_token()) | 603 if (data_message_stanza.has_token()) |
545 incoming_message.collapse_key = data_message_stanza.token(); | 604 incoming_message.collapse_key = data_message_stanza.token(); |
546 incoming_message.data = message_data; | 605 incoming_message.data = message_data; |
547 delegate_->OnMessageReceived(data_message_stanza.category(), | 606 delegate_->OnMessageReceived(app_id, incoming_message); |
548 incoming_message); | |
549 } | 607 } |
550 | 608 |
551 void GCMClientImpl::HandleIncomingSendError( | 609 void GCMClientImpl::HandleIncomingSendError( |
552 const mcs_proto::DataMessageStanza& data_message_stanza, | 610 const mcs_proto::DataMessageStanza& data_message_stanza, |
553 MessageData& message_data) { | 611 MessageData& message_data) { |
554 SendErrorDetails send_error_details; | 612 SendErrorDetails send_error_details; |
555 send_error_details.additional_data = message_data; | 613 send_error_details.additional_data = message_data; |
556 send_error_details.result = SERVER_ERROR; | 614 send_error_details.result = SERVER_ERROR; |
557 | 615 |
558 MessageData::iterator iter = | 616 MessageData::iterator iter = |
559 send_error_details.additional_data.find(kSendErrorMessageIdKey); | 617 send_error_details.additional_data.find(kSendErrorMessageIdKey); |
560 if (iter != send_error_details.additional_data.end()) { | 618 if (iter != send_error_details.additional_data.end()) { |
561 send_error_details.message_id = iter->second; | 619 send_error_details.message_id = iter->second; |
562 send_error_details.additional_data.erase(iter); | 620 send_error_details.additional_data.erase(iter); |
563 } | 621 } |
564 | 622 |
565 delegate_->OnMessageSendError(data_message_stanza.category(), | 623 delegate_->OnMessageSendError(data_message_stanza.category(), |
566 send_error_details); | 624 send_error_details); |
567 } | 625 } |
568 | 626 |
569 void GCMClientImpl::SetMCSClientForTesting(scoped_ptr<MCSClient> mcs_client) { | 627 void GCMClientImpl::SetMCSClientForTesting(scoped_ptr<MCSClient> mcs_client) { |
570 mcs_client_ = mcs_client.Pass(); | 628 mcs_client_ = mcs_client.Pass(); |
571 } | 629 } |
572 | 630 |
573 } // namespace gcm | 631 } // namespace gcm |
OLD | NEW |