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
29 namespace gcm {
30
31 #if !defined(OS_ANDROID)
32 class 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
IdentityObserver(Profile * profile,GCMDriver * driver)54 GCMProfileService::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
~IdentityObserver()66 GCMProfileService::IdentityObserver::~IdentityObserver() {
67 identity_provider_->RemoveObserver(this);
68 }
69
OnActiveAccountLogin()70 void 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
OnActiveAccountLogout()80 void GCMProfileService::IdentityObserver::OnActiveAccountLogout() {
81 driver_->Purge();
82 }
83
SignedInUserName() const84 std::string GCMProfileService::IdentityObserver::SignedInUserName() const {
85 return driver_->IsStarted() ? account_id_ : std::string();
86 }
87 #endif // !defined(OS_ANDROID)
88
89 // static
IsGCMEnabled(Profile * profile)90 bool GCMProfileService::IsGCMEnabled(Profile* profile) {
91 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled);
92 }
93
94 // static
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)95 void 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)
GCMProfileService(Profile * profile)105 GCMProfileService::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
GCMProfileService(Profile * profile,scoped_ptr<GCMClientFactory> gcm_client_factory)113 GCMProfileService::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
GCMProfileService()129 GCMProfileService::GCMProfileService()
130 : profile_(NULL),
131 push_messaging_service_(this, NULL) {
132 }
133
~GCMProfileService()134 GCMProfileService::~GCMProfileService() {
135 }
136
AddAppHandler(const std::string & app_id,GCMAppHandler * handler)137 void GCMProfileService::AddAppHandler(const std::string& app_id,
138 GCMAppHandler* handler) {
139 if (driver_)
140 driver_->AddAppHandler(app_id, handler);
141 }
142
RemoveAppHandler(const std::string & app_id)143 void GCMProfileService::RemoveAppHandler(const std::string& app_id) {
144 if (driver_)
145 driver_->RemoveAppHandler(app_id);
146 }
147
Register(const std::string & app_id,const std::vector<std::string> & sender_ids,const GCMDriver::RegisterCallback & callback)148 void 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
Shutdown()155 void 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
SignedInUserName() const166 std::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
SetDriverForTesting(GCMDriver * driver)175 void GCMProfileService::SetDriverForTesting(GCMDriver* driver) {
176 driver_.reset(driver);
177 }
178
179 } // namespace gcm
180