Chromium Code Reviews| Index: chrome/browser/invalidation/ticl_invalidation_service.cc |
| diff --git a/chrome/browser/invalidation/ticl_invalidation_service.cc b/chrome/browser/invalidation/ticl_invalidation_service.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..14e59cc393b1a45622d6ed2ab58333e3d7e2b50f |
| --- /dev/null |
| +++ b/chrome/browser/invalidation/ticl_invalidation_service.cc |
| @@ -0,0 +1,254 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/invalidation/ticl_invalidation_service.h" |
| + |
| +#include "base/command_line.h" |
| +#include "chrome/browser/invalidation/invalidation_service_util.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/signin/signin_manager.h" |
| +#include "chrome/browser/signin/token_service.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| +#include "content/public/browser/notification_service.h" |
| +#include "google_apis/gaia/gaia_constants.h" |
| +#include "sync/notifier/invalidator.h" |
| +#include "sync/notifier/invalidator_state.h" |
| +#include "sync/notifier/non_blocking_invalidator.h" |
| + |
| +namespace invalidation { |
| + |
| +TiclInvalidationService::TiclInvalidationService(SigninManager* signin, |
| + TokenService* token_service) |
| + : signin_manager_(signin), |
| + token_service_(token_service), |
| + invalidator_registrar_(new syncer::InvalidatorRegistrar()) { } |
|
tim (not reviewing)
2013/05/03 17:48:23
init profile_ to NULL.
rlarocque
2013/05/03 22:16:14
Fixed with a refactoring.
|
| + |
| +TiclInvalidationService::TiclInvalidationService( |
| + SigninManager* signin, |
| + TokenService* token_service, |
| + Profile* profile, |
| + syncer::Invalidator* invalidator) |
| + : profile_(profile), |
| + signin_manager_(signin), |
| + token_service_(token_service), |
| + invalidator_registrar_(new syncer::InvalidatorRegistrar()), |
| + invalidator_(invalidator) { |
| + // Here we perform the equivalent of Init() and Start(), but with some minor |
| + // changes to account for the fact that we're injecting the invalidator. |
| + invalidator_storage_.reset(new InvalidatorStorage(profile_->GetPrefs())); |
| + if (invalidator_storage_->GetInvalidatorClientId().empty()) { |
| + // This also clears any existing state. We can't reuse old invalidator |
| + // state with the new ID anyway. |
| + invalidator_storage_->SetInvalidatorClientId(GenerateInvalidatorClientId()); |
| + } |
| + |
| + invalidator_->RegisterHandler(this); |
| + invalidator_->UpdateRegisteredIds( |
| + this, |
| + invalidator_registrar_->GetAllRegisteredIds()); |
| +} |
| + |
| +TiclInvalidationService::~TiclInvalidationService() { |
| + DCHECK(CalledOnValidThread()); |
| +} |
| + |
| +void TiclInvalidationService::Init(Profile* profile) { |
| + DCHECK(CalledOnValidThread()); |
| + profile_ = profile; |
|
tim (not reviewing)
2013/05/03 17:48:23
you could also DCHECK(!profile_) before assigning.
rlarocque
2013/05/03 22:16:14
Fixed with a refactoring.
|
| + |
| + invalidator_storage_.reset(new InvalidatorStorage(profile_->GetPrefs())); |
| + if (invalidator_storage_->GetInvalidatorClientId().empty()) { |
| + // This also clears any existing state. We can't reuse old invalidator |
| + // state with the new ID anyway. |
| + invalidator_storage_->SetInvalidatorClientId( |
| + GenerateInvalidatorClientId()); |
| + } |
| + |
| + if (IsReadyToStart()) { |
| + Start(); |
| + } |
| + |
| + notification_registrar_.Add(this, |
| + chrome::NOTIFICATION_TOKEN_AVAILABLE, |
| + content::Source<TokenService>(token_service_)); |
| + notification_registrar_.Add(this, |
| + chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, |
| + content::NotificationService::AllSources()); |
| +} |
| + |
| +void TiclInvalidationService::RegisterInvalidationHandler( |
| + syncer::InvalidationHandler* handler) { |
| + DCHECK(CalledOnValidThread()); |
| + DVLOG(2) << "Registering an invalidation handler"; |
| + invalidator_registrar_->RegisterHandler(handler); |
| +} |
| + |
| +void TiclInvalidationService::UpdateRegisteredInvalidationIds( |
| + syncer::InvalidationHandler* handler, |
| + const syncer::ObjectIdSet& ids) { |
| + DCHECK(CalledOnValidThread()); |
| + DVLOG(2) << "Registering ids: " << ids.size(); |
| + invalidator_registrar_->UpdateRegisteredIds(handler, ids); |
| + if (invalidator_) { |
| + invalidator_->UpdateRegisteredIds( |
| + this, |
| + invalidator_registrar_->GetAllRegisteredIds()); |
| + } |
| +} |
| + |
| +void TiclInvalidationService::UnregisterInvalidationHandler( |
| + syncer::InvalidationHandler* handler) { |
| + DCHECK(CalledOnValidThread()); |
| + DVLOG(2) << "Unregistering"; |
| + invalidator_registrar_->UnregisterHandler(handler); |
| + if (invalidator_) { |
| + invalidator_->UpdateRegisteredIds( |
| + this, |
| + invalidator_registrar_->GetAllRegisteredIds()); |
| + } |
| +} |
| + |
| +void TiclInvalidationService::AcknowledgeInvalidation( |
| + const invalidation::ObjectId& id, |
| + const syncer::AckHandle& ack_handle) { |
| + DCHECK(CalledOnValidThread()); |
| + if (invalidator_) { |
|
tim (not reviewing)
2013/05/03 17:48:23
Do we expect this function to be called if invalid
rlarocque
2013/05/03 22:16:14
I'm not sure, but I think it's possible. We'll re
|
| + invalidator_->Acknowledge(id, ack_handle); |
| + } |
| +} |
| + |
| +syncer::InvalidatorState TiclInvalidationService::GetInvalidatorState() const { |
| + DCHECK(CalledOnValidThread()); |
| + if (invalidator_) { |
| + DVLOG(2) << "GetInvalidatorState returning " << GetInvalidatorState(); |
| + return invalidator_->GetInvalidatorState(); |
| + } else { |
| + DVLOG(2) << "Invalidator currently stopped"; |
| + return syncer::TRANSIENT_INVALIDATION_ERROR; |
| + } |
| +} |
| + |
| +std::string TiclInvalidationService::GetInvalidatorClientId() const { |
| + DCHECK(CalledOnValidThread()); |
| + // invalidator_storage will be initialized between calls to Init() and Stop(). |
|
tim (not reviewing)
2013/05/03 17:48:23
nit - invalidator_storage_
rlarocque
2013/05/03 22:16:14
Done.
|
| + // No one should attempt to get the ID of an uninitialized or stopped service. |
| + return invalidator_storage_->GetInvalidatorClientId(); |
| +} |
| + |
| +void TiclInvalidationService::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + DCHECK(CalledOnValidThread()); |
| + |
| + switch (type) { |
| + case chrome::NOTIFICATION_TOKEN_AVAILABLE: { |
| + const TokenService::TokenAvailableDetails& token_details = |
| + *(content::Details<const TokenService::TokenAvailableDetails>( |
| + details).ptr()); |
| + if (token_details.service() == GaiaConstants::kSyncService) { |
| + DCHECK(IsReadyToStart()); |
| + if (!IsStarted()) { |
| + Start(); |
| + } else { |
| + UpdateToken(); |
| + } |
| + } |
| + break; |
| + } |
| + case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
| + Stop(); |
| + break; |
|
tim (not reviewing)
2013/05/03 17:48:23
It's common practice in NotificationObserver imple
rlarocque
2013/05/03 22:16:14
Done.
|
| + } |
| +} |
| + |
| +void TiclInvalidationService::OnInvalidatorStateChange( |
| + syncer::InvalidatorState state) { |
| + invalidator_registrar_->UpdateInvalidatorState(state); |
| +} |
| + |
| +void TiclInvalidationService::OnIncomingInvalidation( |
| + const syncer::ObjectIdInvalidationMap& invalidation_map) { |
| + invalidator_registrar_->DispatchInvalidationsToHandlers(invalidation_map); |
| +} |
| + |
| +void TiclInvalidationService::Shutdown() { |
| + DCHECK(CalledOnValidThread()); |
| + Stop(); |
| + invalidator_registrar_.reset(); |
| +} |
| + |
| +bool TiclInvalidationService::IsReadyToStart() { |
| + if (signin_manager_->GetAuthenticatedUsername().empty()) { |
| + DVLOG(2) << "Not starting TiclInvalidationService: user is not signed in."; |
| + return false; |
| + } |
| + |
| + if (!token_service_) { |
| + DVLOG(2) |
| + << "Not starting TiclInvalidationService: TokenService unavailable."; |
| + return false; |
| + } |
| + |
| + if (!token_service_->HasTokenForService(GaiaConstants::kSyncService)) { |
| + DVLOG(2) << "Not starting TiclInvalidationService: Sync token unavailable."; |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool TiclInvalidationService::IsStarted() { |
| + return !!invalidator_; |
|
tim (not reviewing)
2013/05/03 17:48:23
I personally really prefer invalidator_ != NULL fo
rlarocque
2013/05/03 22:16:14
Done.
|
| +} |
| + |
| +void TiclInvalidationService::Start() { |
| + DCHECK(CalledOnValidThread()); |
| + |
| + DCHECK(!invalidator_); |
| + |
| + notifier::NotifierOptions options = |
| + ParseNotifierOptions(*CommandLine::ForCurrentProcess()); |
| + options.request_context_getter = profile_->GetRequestContext(); |
| + invalidator_.reset(new syncer::NonBlockingInvalidator( |
| + options, |
| + invalidator_storage_->GetInvalidatorClientId(), |
| + invalidator_storage_->GetAllInvalidationStates(), |
| + invalidator_storage_->GetBootstrapData(), |
| + syncer::WeakHandle<syncer::InvalidationStateTracker>( |
| + invalidator_storage_->AsWeakPtr()), |
| + content::GetUserAgent(GURL()))); |
| + |
| + UpdateToken(); |
| + |
| + invalidator_->RegisterHandler(this); |
| + invalidator_->UpdateRegisteredIds( |
| + this, |
| + invalidator_registrar_->GetAllRegisteredIds()); |
| +} |
| + |
| +void TiclInvalidationService::UpdateToken() { |
| + std::string email = signin_manager_->GetAuthenticatedUsername(); |
| + DCHECK(!email.empty()) << "Expected user to be signed in."; |
| + DCHECK(token_service_->HasTokenForService(GaiaConstants::kSyncService)); |
| + |
| + std::string sync_token = token_service_->GetTokenForService( |
| + GaiaConstants::kSyncService); |
| + |
| + DVLOG(2) << "UpdateCredentials: " << email; |
| + invalidator_->UpdateCredentials(email, sync_token); |
| +} |
| + |
| +void TiclInvalidationService::Stop() { |
| + if (invalidator_) { |
| + invalidator_->UnregisterHandler(this); |
| + invalidator_.reset(); |
| + } |
| + if (invalidator_storage_) { |
| + invalidator_storage_->Clear(); |
| + invalidator_storage_.reset(); |
| + } |
| +} |
| + |
| +} // namespace invalidation |