// 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 "components/gcm_driver/gcm_profile_service.h" #include #include "base/logging.h" #include "base/prefs/pref_service.h" #include "components/gcm_driver/gcm_driver.h" #include "components/gcm_driver/gcm_driver_constants.h" #include "components/pref_registry/pref_registry_syncable.h" #if defined(OS_ANDROID) #include "base/sequenced_task_runner.h" #include "base/threading/sequenced_worker_pool.h" #include "components/gcm_driver/gcm_driver_android.h" #else #include "base/bind.h" #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" #include "components/gcm_driver/gcm_account_tracker.h" #include "components/gcm_driver/gcm_channel_status_syncer.h" #include "components/gcm_driver/gcm_client_factory.h" #include "components/gcm_driver/gcm_desktop_utils.h" #include "components/gcm_driver/gcm_driver_desktop.h" #include "components/signin/core/browser/signin_manager.h" #include "google_apis/gaia/account_tracker.h" #include "google_apis/gaia/identity_provider.h" #include "net/url_request/url_request_context_getter.h" #endif namespace gcm { #if !defined(OS_ANDROID) // Identity observer only has actual work to do when the user is actually signed // in. It ensures that account tracker is taking class GCMProfileService::IdentityObserver : public IdentityProvider::Observer { public: IdentityObserver(ProfileIdentityProvider* identity_provider, net::URLRequestContextGetter* request_context, GCMDriver* driver); ~IdentityObserver() override; // IdentityProvider::Observer: void OnActiveAccountLogin() override; void OnActiveAccountLogout() override; private: void StartAccountTracker(net::URLRequestContextGetter* request_context); GCMDriver* driver_; IdentityProvider* identity_provider_; scoped_ptr gcm_account_tracker_; // The account ID that this service is responsible for. Empty when the service // is not running. std::string account_id_; base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(IdentityObserver); }; GCMProfileService::IdentityObserver::IdentityObserver( ProfileIdentityProvider* identity_provider, net::URLRequestContextGetter* request_context, GCMDriver* driver) : driver_(driver), identity_provider_(identity_provider), weak_ptr_factory_(this) { identity_provider_->AddObserver(this); OnActiveAccountLogin(); StartAccountTracker(request_context); } GCMProfileService::IdentityObserver::~IdentityObserver() { if (gcm_account_tracker_) gcm_account_tracker_->Shutdown(); identity_provider_->RemoveObserver(this); } void GCMProfileService::IdentityObserver::OnActiveAccountLogin() { // This might be called multiple times when the password changes. const std::string account_id = identity_provider_->GetActiveAccountId(); if (account_id == account_id_) return; account_id_ = account_id; // Still need to notify GCMDriver for UMA purpose. driver_->OnSignedIn(); } void GCMProfileService::IdentityObserver::OnActiveAccountLogout() { account_id_.clear(); // Still need to notify GCMDriver for UMA purpose. driver_->OnSignedOut(); } void GCMProfileService::IdentityObserver::StartAccountTracker( net::URLRequestContextGetter* request_context) { if (gcm_account_tracker_) return; scoped_ptr gaia_account_tracker( new gaia::AccountTracker(identity_provider_, request_context)); gcm_account_tracker_.reset( new GCMAccountTracker(gaia_account_tracker.Pass(), driver_)); gcm_account_tracker_->Start(); } #endif // !defined(OS_ANDROID) // static bool GCMProfileService::IsGCMEnabled(PrefService* prefs) { #if defined(OS_ANDROID) return true; #else return prefs->GetBoolean(gcm::prefs::kGCMChannelStatus); #endif // defined(OS_ANDROID) } #if defined(OS_ANDROID) GCMProfileService::GCMProfileService( base::FilePath path, scoped_refptr& blocking_task_runner) { driver_.reset(new GCMDriverAndroid(path.Append(gcm_driver::kGCMStoreDirname), blocking_task_runner)); } #else GCMProfileService::GCMProfileService( PrefService* prefs, base::FilePath path, net::URLRequestContextGetter* request_context, version_info::Channel channel, scoped_ptr identity_provider, scoped_ptr gcm_client_factory, const scoped_refptr& ui_task_runner, const scoped_refptr& io_task_runner, scoped_refptr& blocking_task_runner) : request_context_(request_context), profile_identity_provider_(identity_provider.Pass()) { driver_ = CreateGCMDriverDesktop(gcm_client_factory.Pass(), prefs, path.Append(gcm_driver::kGCMStoreDirname), request_context_, channel, ui_task_runner, io_task_runner, blocking_task_runner); identity_observer_.reset(new IdentityObserver( profile_identity_provider_.get(), request_context_, driver_.get())); } #endif // defined(OS_ANDROID) GCMProfileService::GCMProfileService() : request_context_(nullptr) {} GCMProfileService::~GCMProfileService() {} void GCMProfileService::Shutdown() { #if !defined(OS_ANDROID) identity_observer_.reset(); #endif // !defined(OS_ANDROID) if (driver_) { driver_->Shutdown(); driver_.reset(); } } void GCMProfileService::SetDriverForTesting(GCMDriver* driver) { driver_.reset(driver); #if !defined(OS_ANDROID) if (identity_observer_) { identity_observer_.reset(new IdentityObserver( profile_identity_provider_.get(), request_context_, driver)); } #endif // !defined(OS_ANDROID) } } // namespace gcm