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.
5 #include "chrome/browser/services/gcm/gcm_profile_service.h"
9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/pref_names.h"
13 #include "components/gcm_driver/gcm_driver.h"
14 #include "components/pref_registry/pref_registry_syncable.h"
16 #if defined(OS_ANDROID)
17 #include "components/gcm_driver/gcm_driver_android.h"
19 #include "base/bind.h"
20 #if defined(OS_CHROMEOS)
21 #include "chrome/browser/services/gcm/chromeos_gcm_connection_observer.h"
23 #include "base/files/file_path.h"
24 #include "base/memory/weak_ptr.h"
25 #include "chrome/browser/services/gcm/gcm_account_tracker.h"
26 #include "chrome/browser/services/gcm/gcm_desktop_utils.h"
27 #include "chrome/browser/signin/profile_identity_provider.h"
28 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
29 #include "chrome/browser/signin/signin_manager_factory.h"
30 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
31 #include "chrome/common/chrome_constants.h"
32 #include "components/gcm_driver/gcm_client_factory.h"
33 #include "components/gcm_driver/gcm_driver_desktop.h"
34 #include "components/signin/core/browser/signin_manager.h"
35 #include "google_apis/gaia/account_tracker.h"
36 #include "google_apis/gaia/identity_provider.h"
37 #include "net/url_request/url_request_context_getter.h"
42 #if !defined(OS_ANDROID)
43 // Identity observer only has actual work to do when the user is actually signed
44 // in. It ensures that account tracker is taking
45 class GCMProfileService::IdentityObserver : public IdentityProvider::Observer {
47 IdentityObserver(Profile* profile, GCMDriver* driver);
48 ~IdentityObserver() override;
50 // IdentityProvider::Observer:
51 void OnActiveAccountLogin() override;
52 void OnActiveAccountLogout() override;
54 std::string SignedInUserName() const;
57 void StartAccountTracker();
61 scoped_ptr<IdentityProvider> identity_provider_;
62 scoped_ptr<GCMAccountTracker> gcm_account_tracker_;
64 // The account ID that this service is responsible for. Empty when the service
66 std::string account_id_;
68 base::WeakPtrFactory<GCMProfileService::IdentityObserver> weak_ptr_factory_;
70 DISALLOW_COPY_AND_ASSIGN(IdentityObserver);
73 GCMProfileService::IdentityObserver::IdentityObserver(Profile* profile,
75 : profile_(profile), driver_(driver), weak_ptr_factory_(this) {
76 identity_provider_.reset(new ProfileIdentityProvider(
77 SigninManagerFactory::GetForProfile(profile),
78 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
79 LoginUIServiceFactory::GetForProfile(profile)));
80 identity_provider_->AddObserver(this);
82 OnActiveAccountLogin();
83 StartAccountTracker();
86 GCMProfileService::IdentityObserver::~IdentityObserver() {
87 if (gcm_account_tracker_)
88 gcm_account_tracker_->Shutdown();
89 identity_provider_->RemoveObserver(this);
92 void GCMProfileService::IdentityObserver::OnActiveAccountLogin() {
93 // This might be called multiple times when the password changes.
94 const std::string account_id = identity_provider_->GetActiveAccountId();
95 if (account_id == account_id_)
98 account_id_ = account_id;
99 driver_->OnSignedIn();
102 void GCMProfileService::IdentityObserver::OnActiveAccountLogout() {
105 // When sign-in enforcement is not dropped, OnSignedOut will also clear all
106 // the GCM data and a new GCM ID will be retrieved after the user signs in
107 // again. Otherwise, the user sign-out will not affect the existing GCM
109 driver_->OnSignedOut();
112 std::string GCMProfileService::IdentityObserver::SignedInUserName() const {
113 return driver_->IsStarted() ? account_id_ : std::string();
116 void GCMProfileService::IdentityObserver::StartAccountTracker() {
117 if (gcm_account_tracker_)
120 scoped_ptr<gaia::AccountTracker> gaia_account_tracker(
121 new gaia::AccountTracker(identity_provider_.get(),
122 profile_->GetRequestContext()));
124 gcm_account_tracker_.reset(
125 new GCMAccountTracker(gaia_account_tracker.Pass(), driver_));
127 gcm_account_tracker_->Start();
130 #endif // !defined(OS_ANDROID)
133 bool GCMProfileService::IsGCMEnabled(Profile* profile) {
134 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled);
138 void GCMProfileService::RegisterProfilePrefs(
139 user_prefs::PrefRegistrySyncable* registry) {
140 registry->RegisterBooleanPref(
141 prefs::kGCMChannelEnabled,
143 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
144 PushMessagingServiceImpl::RegisterProfilePrefs(registry);
147 #if defined(OS_ANDROID)
148 GCMProfileService::GCMProfileService(Profile* profile)
150 push_messaging_service_(this, profile) {
151 DCHECK(!profile->IsOffTheRecord());
153 driver_.reset(new GCMDriverAndroid);
156 GCMProfileService::GCMProfileService(
158 scoped_ptr<GCMClientFactory> gcm_client_factory)
160 push_messaging_service_(this, profile) {
161 DCHECK(!profile->IsOffTheRecord());
163 driver_ = CreateGCMDriverDesktop(
164 gcm_client_factory.Pass(),
165 profile_->GetPrefs(),
166 profile_->GetPath().Append(chrome::kGCMStoreDirname),
167 profile_->GetRequestContext());
169 #if defined(OS_CHROMEOS)
170 chromeos_connection_observer_.reset(new gcm::ChromeOSGCMConnectionObserver);
171 driver_->AddConnectionObserver(chromeos_connection_observer_.get());
174 identity_observer_.reset(new IdentityObserver(profile, driver_.get()));
176 #endif // defined(OS_ANDROID)
178 GCMProfileService::GCMProfileService()
180 push_messaging_service_(this, NULL) {
183 GCMProfileService::~GCMProfileService() {
186 void GCMProfileService::Shutdown() {
187 #if !defined(OS_ANDROID)
188 identity_observer_.reset();
189 #endif // !defined(OS_ANDROID)
191 #if defined(OS_CHROMEOS)
192 driver_->RemoveConnectionObserver(chromeos_connection_observer_.get());
193 chromeos_connection_observer_.reset();
200 std::string GCMProfileService::SignedInUserName() const {
201 #if defined(OS_ANDROID)
202 return std::string();
204 return identity_observer_ ? identity_observer_->SignedInUserName()
206 #endif // defined(OS_ANDROID)
209 void GCMProfileService::SetDriverForTesting(GCMDriver* driver) {
210 driver_.reset(driver);
211 #if !defined(OS_ANDROID)
212 if (identity_observer_)
213 identity_observer_.reset(new IdentityObserver(profile_, driver));
214 #endif // !defined(OS_ANDROID)