1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/services/gcm/gcm_profile_service.h" 6 7#include "base/logging.h" 8#include "base/prefs/pref_service.h" 9#include "chrome/browser/profiles/profile.h" 10#include "chrome/common/pref_names.h" 11#include "components/pref_registry/pref_registry_syncable.h" 12 13#if defined(OS_ANDROID) 14#include "components/gcm_driver/gcm_driver_android.h" 15#else 16#include "base/files/file_path.h" 17#include "chrome/browser/services/gcm/gcm_desktop_utils.h" 18#include "chrome/browser/signin/profile_identity_provider.h" 19#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 20#include "chrome/browser/signin/signin_manager_factory.h" 21#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" 22#include "chrome/common/chrome_constants.h" 23#include "components/gcm_driver/gcm_client_factory.h" 24#include "components/signin/core/browser/signin_manager.h" 25#include "google_apis/gaia/identity_provider.h" 26#include "net/url_request/url_request_context_getter.h" 27#endif 28 29namespace gcm { 30 31#if !defined(OS_ANDROID) 32class GCMProfileService::IdentityObserver : public IdentityProvider::Observer { 33 public: 34 IdentityObserver(Profile* profile, GCMDriver* driver); 35 virtual ~IdentityObserver(); 36 37 // IdentityProvider::Observer: 38 virtual void OnActiveAccountLogin() OVERRIDE; 39 virtual void OnActiveAccountLogout() OVERRIDE; 40 41 std::string SignedInUserName() const; 42 43 private: 44 GCMDriver* driver_; 45 scoped_ptr<IdentityProvider> identity_provider_; 46 47 // The account ID that this service is responsible for. Empty when the service 48 // is not running. 49 std::string account_id_; 50 51 DISALLOW_COPY_AND_ASSIGN(IdentityObserver); 52}; 53 54GCMProfileService::IdentityObserver::IdentityObserver(Profile* profile, 55 GCMDriver* driver) 56 : driver_(driver) { 57 identity_provider_.reset(new ProfileIdentityProvider( 58 SigninManagerFactory::GetForProfile(profile), 59 ProfileOAuth2TokenServiceFactory::GetForProfile(profile), 60 LoginUIServiceFactory::GetForProfile(profile))); 61 identity_provider_->AddObserver(this); 62 63 OnActiveAccountLogin(); 64} 65 66GCMProfileService::IdentityObserver::~IdentityObserver() { 67 identity_provider_->RemoveObserver(this); 68} 69 70void GCMProfileService::IdentityObserver::OnActiveAccountLogin() { 71 // This might be called multiple times when the password changes. 72 const std::string account_id = identity_provider_->GetActiveAccountId(); 73 if (account_id == account_id_) 74 return; 75 account_id_ = account_id; 76 77 driver_->OnSignedIn(); 78} 79 80void GCMProfileService::IdentityObserver::OnActiveAccountLogout() { 81 driver_->Purge(); 82} 83 84std::string GCMProfileService::IdentityObserver::SignedInUserName() const { 85 return driver_->IsStarted() ? account_id_ : std::string(); 86} 87#endif // !defined(OS_ANDROID) 88 89// static 90bool GCMProfileService::IsGCMEnabled(Profile* profile) { 91 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled); 92} 93 94// static 95void GCMProfileService::RegisterProfilePrefs( 96 user_prefs::PrefRegistrySyncable* registry) { 97 registry->RegisterBooleanPref( 98 prefs::kGCMChannelEnabled, 99 true, 100 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 101 PushMessagingServiceImpl::RegisterProfilePrefs(registry); 102} 103 104#if defined(OS_ANDROID) 105GCMProfileService::GCMProfileService(Profile* profile) 106 : profile_(profile), 107 push_messaging_service_(this, profile) { 108 DCHECK(!profile->IsOffTheRecord()); 109 110 driver_.reset(new GCMDriverAndroid); 111} 112#else 113GCMProfileService::GCMProfileService( 114 Profile* profile, 115 scoped_ptr<GCMClientFactory> gcm_client_factory) 116 : profile_(profile), 117 push_messaging_service_(this, profile) { 118 DCHECK(!profile->IsOffTheRecord()); 119 120 driver_ = CreateGCMDriverDesktop( 121 gcm_client_factory.Pass(), 122 profile_->GetPath().Append(chrome::kGCMStoreDirname), 123 profile_->GetRequestContext()); 124 125 identity_observer_.reset(new IdentityObserver(profile, driver_.get())); 126} 127#endif // defined(OS_ANDROID) 128 129GCMProfileService::GCMProfileService() 130 : profile_(NULL), 131 push_messaging_service_(this, NULL) { 132} 133 134GCMProfileService::~GCMProfileService() { 135} 136 137void GCMProfileService::AddAppHandler(const std::string& app_id, 138 GCMAppHandler* handler) { 139 if (driver_) 140 driver_->AddAppHandler(app_id, handler); 141} 142 143void GCMProfileService::RemoveAppHandler(const std::string& app_id) { 144 if (driver_) 145 driver_->RemoveAppHandler(app_id); 146} 147 148void GCMProfileService::Register(const std::string& app_id, 149 const std::vector<std::string>& sender_ids, 150 const GCMDriver::RegisterCallback& callback) { 151 if (driver_) 152 driver_->Register(app_id, sender_ids, callback); 153} 154 155void GCMProfileService::Shutdown() { 156#if !defined(OS_ANDROID) 157 identity_observer_.reset(); 158#endif // !defined(OS_ANDROID) 159 160 if (driver_) { 161 driver_->Shutdown(); 162 driver_.reset(); 163 } 164} 165 166std::string GCMProfileService::SignedInUserName() const { 167#if defined(OS_ANDROID) 168 return std::string(); 169#else 170 return identity_observer_ ? identity_observer_->SignedInUserName() 171 : std::string(); 172#endif // defined(OS_ANDROID) 173} 174 175void GCMProfileService::SetDriverForTesting(GCMDriver* driver) { 176 driver_.reset(driver); 177} 178 179} // namespace gcm 180