Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / services / gcm / gcm_profile_service.cc
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 <map>
8
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/pref_registry/pref_registry_syncable.h"
14
15 #if defined(OS_ANDROID)
16 #include "components/gcm_driver/gcm_driver_android.h"
17 #else
18 #include "base/bind.h"
19 #if defined(OS_CHROMEOS)
20 #include "chrome/browser/services/gcm/chromeos_gcm_connection_observer.h"
21 #endif
22 #include "base/files/file_path.h"
23 #include "base/memory/weak_ptr.h"
24 #include "chrome/browser/services/gcm/gcm_account_tracker.h"
25 #include "chrome/browser/services/gcm/gcm_desktop_utils.h"
26 #include "chrome/browser/signin/profile_identity_provider.h"
27 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
28 #include "chrome/browser/signin/signin_manager_factory.h"
29 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
30 #include "chrome/common/chrome_constants.h"
31 #include "components/gcm_driver/gcm_client_factory.h"
32 #include "components/gcm_driver/gcm_driver_desktop.h"
33 #include "components/signin/core/browser/signin_manager.h"
34 #include "google_apis/gaia/account_tracker.h"
35 #include "google_apis/gaia/identity_provider.h"
36 #include "net/url_request/url_request_context_getter.h"
37 #endif
38
39 namespace gcm {
40
41 #if !defined(OS_ANDROID)
42 // Identity observer only has actual work to do when the user is actually signed
43 // in. It ensures that account tracker is taking
44 class GCMProfileService::IdentityObserver : public IdentityProvider::Observer {
45  public:
46   IdentityObserver(Profile* profile, GCMDriverDesktop* driver);
47   virtual ~IdentityObserver();
48
49   // IdentityProvider::Observer:
50   virtual void OnActiveAccountLogin() OVERRIDE;
51   virtual void OnActiveAccountLogout() OVERRIDE;
52
53   std::string SignedInUserName() const;
54
55   // Called to inform IdentityObserver that a list of accounts was updated.
56   // |account_tokens| maps email addresses to OAuth2 access tokens.
57   void AccountsUpdated(
58       const std::map<std::string, std::string>& account_tokens);
59
60  private:
61   Profile* profile_;
62   GCMDriverDesktop* driver_;
63   scoped_ptr<IdentityProvider> identity_provider_;
64   scoped_ptr<GCMAccountTracker> gcm_account_tracker_;
65
66   // The account ID that this service is responsible for. Empty when the service
67   // is not running.
68   std::string account_id_;
69
70   base::WeakPtrFactory<GCMProfileService::IdentityObserver> weak_ptr_factory_;
71
72   DISALLOW_COPY_AND_ASSIGN(IdentityObserver);
73 };
74
75 GCMProfileService::IdentityObserver::IdentityObserver(Profile* profile,
76                                                       GCMDriverDesktop* driver)
77     : profile_(profile), driver_(driver), weak_ptr_factory_(this) {
78   identity_provider_.reset(new ProfileIdentityProvider(
79       SigninManagerFactory::GetForProfile(profile),
80       ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
81       LoginUIServiceFactory::GetForProfile(profile)));
82   identity_provider_->AddObserver(this);
83
84   OnActiveAccountLogin();
85 }
86
87 GCMProfileService::IdentityObserver::~IdentityObserver() {
88   if (gcm_account_tracker_)
89     gcm_account_tracker_->Shutdown();
90   identity_provider_->RemoveObserver(this);
91 }
92
93 void GCMProfileService::IdentityObserver::OnActiveAccountLogin() {
94   // This might be called multiple times when the password changes.
95   const std::string account_id = identity_provider_->GetActiveAccountId();
96   if (account_id == account_id_)
97     return;
98   account_id_ = account_id;
99
100   driver_->OnSignedIn();
101
102   if (!gcm_account_tracker_) {
103     scoped_ptr<gaia::AccountTracker> gaia_account_tracker(
104         new gaia::AccountTracker(identity_provider_.get(),
105                                  profile_->GetRequestContext()));
106
107     gcm_account_tracker_.reset(new GCMAccountTracker(
108         gaia_account_tracker.Pass(),
109         base::Bind(&GCMProfileService::IdentityObserver::AccountsUpdated,
110                    weak_ptr_factory_.GetWeakPtr())));
111   }
112
113   gcm_account_tracker_->Start();
114 }
115
116 void GCMProfileService::IdentityObserver::OnActiveAccountLogout() {
117   account_id_.clear();
118
119   // Check is necessary to not crash browser_tests.
120   if (gcm_account_tracker_)
121     gcm_account_tracker_->Stop();
122   // TODO(fgorski): If we purge here, what should happen when we get
123   // OnActiveAccountLogin() right after that?
124   driver_->Purge();
125 }
126
127 std::string GCMProfileService::IdentityObserver::SignedInUserName() const {
128   return driver_->IsStarted() ? account_id_ : std::string();
129 }
130
131 void GCMProfileService::IdentityObserver::AccountsUpdated(
132     const std::map<std::string, std::string>& account_tokens) {
133   driver_->SetAccountsForCheckin(account_tokens);
134 }
135 #endif  // !defined(OS_ANDROID)
136
137 // static
138 bool GCMProfileService::IsGCMEnabled(Profile* profile) {
139   return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled);
140 }
141
142 // static
143 void GCMProfileService::RegisterProfilePrefs(
144     user_prefs::PrefRegistrySyncable* registry) {
145   registry->RegisterBooleanPref(
146       prefs::kGCMChannelEnabled,
147       true,
148       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
149   PushMessagingServiceImpl::RegisterProfilePrefs(registry);
150 }
151
152 #if defined(OS_ANDROID)
153 GCMProfileService::GCMProfileService(Profile* profile)
154     : profile_(profile),
155       push_messaging_service_(this, profile) {
156   DCHECK(!profile->IsOffTheRecord());
157
158   driver_.reset(new GCMDriverAndroid);
159 }
160 #else
161 GCMProfileService::GCMProfileService(
162     Profile* profile,
163     scoped_ptr<GCMClientFactory> gcm_client_factory)
164     : profile_(profile),
165       push_messaging_service_(this, profile) {
166   DCHECK(!profile->IsOffTheRecord());
167
168   driver_ = CreateGCMDriverDesktop(
169       gcm_client_factory.Pass(),
170       profile_->GetPrefs(),
171       profile_->GetPath().Append(chrome::kGCMStoreDirname),
172       profile_->GetRequestContext());
173
174 #if defined(OS_CHROMEOS)
175   chromeos_connection_observer_.reset(new gcm::ChromeOSGCMConnectionObserver);
176   driver_->AddConnectionObserver(chromeos_connection_observer_.get());
177 #endif
178
179   identity_observer_.reset(new IdentityObserver(
180       profile, static_cast<gcm::GCMDriverDesktop*>(driver_.get())));
181 }
182 #endif  // defined(OS_ANDROID)
183
184 GCMProfileService::GCMProfileService()
185     : profile_(NULL),
186       push_messaging_service_(this, NULL) {
187 }
188
189 GCMProfileService::~GCMProfileService() {
190 }
191
192 void GCMProfileService::AddAppHandler(const std::string& app_id,
193                                       GCMAppHandler* handler) {
194   if (driver_)
195     driver_->AddAppHandler(app_id, handler);
196 }
197
198 void GCMProfileService::RemoveAppHandler(const std::string& app_id) {
199   if (driver_)
200     driver_->RemoveAppHandler(app_id);
201 }
202
203 void GCMProfileService::Register(const std::string& app_id,
204                                  const std::vector<std::string>& sender_ids,
205                                  const GCMDriver::RegisterCallback& callback) {
206   if (driver_)
207     driver_->Register(app_id, sender_ids, callback);
208 }
209
210 void GCMProfileService::Shutdown() {
211 #if !defined(OS_ANDROID)
212   identity_observer_.reset();
213 #endif  // !defined(OS_ANDROID)
214   if (driver_) {
215 #if defined(OS_CHROMEOS)
216     driver_->RemoveConnectionObserver(chromeos_connection_observer_.get());
217     chromeos_connection_observer_.reset();
218 #endif
219     driver_->Shutdown();
220     driver_.reset();
221   }
222 }
223
224 std::string GCMProfileService::SignedInUserName() const {
225 #if defined(OS_ANDROID)
226   return std::string();
227 #else
228   return identity_observer_ ? identity_observer_->SignedInUserName()
229                             : std::string();
230 #endif  // defined(OS_ANDROID)
231 }
232
233 void GCMProfileService::SetDriverForTesting(GCMDriver* driver) {
234   driver_.reset(driver);
235 }
236
237 }  // namespace gcm