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 "components/gcm_driver/gcm_driver.h"
13 #include "components/pref_registry/pref_registry_syncable.h"
15 #if defined(OS_ANDROID)
16 #include "components/gcm_driver/gcm_driver_android.h"
18 #include "base/bind.h"
19 #include "base/files/file_path.h"
20 #include "base/memory/weak_ptr.h"
21 #include "chrome/browser/services/gcm/gcm_account_tracker.h"
22 #include "chrome/browser/services/gcm/gcm_desktop_utils.h"
23 #include "chrome/browser/signin/profile_identity_provider.h"
24 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
25 #include "chrome/browser/signin/signin_manager_factory.h"
26 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
27 #include "chrome/common/chrome_constants.h"
28 #include "components/gcm_driver/gcm_channel_status_syncer.h"
29 #include "components/gcm_driver/gcm_client_factory.h"
30 #include "components/gcm_driver/gcm_driver_desktop.h"
31 #include "components/signin/core/browser/signin_manager.h"
32 #include "google_apis/gaia/account_tracker.h"
33 #include "google_apis/gaia/identity_provider.h"
34 #include "net/url_request/url_request_context_getter.h"
39 #if !defined(OS_ANDROID)
40 // Identity observer only has actual work to do when the user is actually signed
41 // in. It ensures that account tracker is taking
42 class GCMProfileService::IdentityObserver
: public IdentityProvider::Observer
{
44 IdentityObserver(Profile
* profile
, GCMDriver
* driver
);
45 ~IdentityObserver() override
;
47 // IdentityProvider::Observer:
48 void OnActiveAccountLogin() override
;
49 void OnActiveAccountLogout() override
;
52 void StartAccountTracker();
56 scoped_ptr
<IdentityProvider
> identity_provider_
;
57 scoped_ptr
<GCMAccountTracker
> gcm_account_tracker_
;
59 // The account ID that this service is responsible for. Empty when the service
61 std::string account_id_
;
63 base::WeakPtrFactory
<GCMProfileService::IdentityObserver
> weak_ptr_factory_
;
65 DISALLOW_COPY_AND_ASSIGN(IdentityObserver
);
68 GCMProfileService::IdentityObserver::IdentityObserver(Profile
* profile
,
70 : profile_(profile
), driver_(driver
), weak_ptr_factory_(this) {
71 identity_provider_
.reset(new ProfileIdentityProvider(
72 SigninManagerFactory::GetForProfile(profile
),
73 ProfileOAuth2TokenServiceFactory::GetForProfile(profile
),
74 LoginUIServiceFactory::GetForProfile(profile
)));
75 identity_provider_
->AddObserver(this);
77 OnActiveAccountLogin();
78 StartAccountTracker();
81 GCMProfileService::IdentityObserver::~IdentityObserver() {
82 if (gcm_account_tracker_
)
83 gcm_account_tracker_
->Shutdown();
84 identity_provider_
->RemoveObserver(this);
87 void GCMProfileService::IdentityObserver::OnActiveAccountLogin() {
88 // This might be called multiple times when the password changes.
89 const std::string account_id
= identity_provider_
->GetActiveAccountId();
90 if (account_id
== account_id_
)
92 account_id_
= account_id
;
94 // Still need to notify GCMDriver for UMA purpose.
95 driver_
->OnSignedIn();
98 void GCMProfileService::IdentityObserver::OnActiveAccountLogout() {
101 // Still need to notify GCMDriver for UMA purpose.
102 driver_
->OnSignedOut();
105 void GCMProfileService::IdentityObserver::StartAccountTracker() {
106 if (gcm_account_tracker_
)
109 scoped_ptr
<gaia::AccountTracker
> gaia_account_tracker(
110 new gaia::AccountTracker(identity_provider_
.get(),
111 profile_
->GetRequestContext()));
113 gcm_account_tracker_
.reset(
114 new GCMAccountTracker(gaia_account_tracker
.Pass(), driver_
));
116 gcm_account_tracker_
->Start();
119 #endif // !defined(OS_ANDROID)
122 bool GCMProfileService::IsGCMEnabled(Profile
* profile
) {
123 #if defined(OS_ANDROID)
126 return profile
->GetPrefs()->GetBoolean(gcm::prefs::kGCMChannelStatus
);
127 #endif // defined(OS_ANDROID)
130 #if defined(OS_ANDROID)
131 static GCMProfileService
* debug_instance
= nullptr;
133 GCMProfileService::GCMProfileService(Profile
* profile
)
134 : profile_(profile
) {
135 CHECK(!profile
->IsOffTheRecord());
137 // TODO(johnme): Remove debug_instance and this logging code once
138 // crbug.com/437827 is fixed.
139 if (debug_instance
!= nullptr) {
140 LOG(FATAL
) << "An instance of GCMProfileService already exists!"
141 << " Old profile: " << debug_instance
->profile_
<< " "
142 << debug_instance
->profile_
->GetDebugName() << " "
143 << debug_instance
->profile_
->GetProfileType() << " "
144 << debug_instance
->profile_
->IsSupervised() << " "
145 << debug_instance
->profile_
->IsNewProfile() << " "
146 << debug_instance
->profile_
->GetStartTime().ToInternalValue()
147 << ", new profile: " << profile
<< " "
148 << profile
->GetDebugName() << " "
149 << profile
->GetProfileType() << " "
150 << profile
->IsSupervised() << " "
151 << profile
->IsNewProfile() << " "
152 << profile
->GetStartTime().ToInternalValue();
154 debug_instance
= this;
156 driver_
.reset(new GCMDriverAndroid
);
159 GCMProfileService::GCMProfileService(
161 scoped_ptr
<GCMClientFactory
> gcm_client_factory
)
162 : profile_(profile
) {
163 DCHECK(!profile
->IsOffTheRecord());
165 driver_
= CreateGCMDriverDesktop(
166 gcm_client_factory
.Pass(),
167 profile_
->GetPrefs(),
168 profile_
->GetPath().Append(chrome::kGCMStoreDirname
),
169 profile_
->GetRequestContext());
171 identity_observer_
.reset(new IdentityObserver(profile
, driver_
.get()));
173 #endif // defined(OS_ANDROID)
175 GCMProfileService::GCMProfileService()
179 GCMProfileService::~GCMProfileService() {
180 #if defined(OS_ANDROID)
181 debug_instance
= nullptr;
185 void GCMProfileService::Shutdown() {
186 #if !defined(OS_ANDROID)
187 identity_observer_
.reset();
188 #endif // !defined(OS_ANDROID)
195 void GCMProfileService::SetDriverForTesting(GCMDriver
* driver
) {
196 driver_
.reset(driver
);
197 #if !defined(OS_ANDROID)
198 if (identity_observer_
)
199 identity_observer_
.reset(new IdentityObserver(profile_
, driver
));
200 #endif // !defined(OS_ANDROID)