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 "components/gcm_driver/gcm_profile_service.h"
6
7 #include <utility>
8 #include <vector>
9
10 #include "base/macros.h"
11 #include "build/build_config.h"
12 #include "components/gcm_driver/gcm_driver.h"
13 #include "components/gcm_driver/gcm_driver_constants.h"
14 #include "components/pref_registry/pref_registry_syncable.h"
15 #include "components/prefs/pref_service.h"
16 #include "services/network/public/cpp/shared_url_loader_factory.h"
17
18 #if BUILDFLAG(USE_GCM_FROM_PLATFORM)
19 #include "base/sequenced_task_runner.h"
20 #include "components/gcm_driver/gcm_driver_android.h"
21 #else
22 #include "base/bind.h"
23 #include "base/files/file_path.h"
24 #include "base/memory/weak_ptr.h"
25 #include "components/gcm_driver/account_tracker.h"
26 #include "components/gcm_driver/gcm_account_tracker.h"
27 #include "components/gcm_driver/gcm_client_factory.h"
28 #include "components/gcm_driver/gcm_desktop_utils.h"
29 #include "components/gcm_driver/gcm_driver_desktop.h"
30 #include "components/signin/public/identity_manager/identity_manager.h"
31 #endif
32
33 namespace gcm {
34
35 #if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
36 // Identity observer only has actual work to do when the user is actually signed
37 // in. It ensures that account tracker is taking
38 class GCMProfileService::IdentityObserver
39 : public signin::IdentityManager::Observer {
40 public:
41 IdentityObserver(
42 signin::IdentityManager* identity_manager,
43 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
44 GCMDriver* driver);
45 ~IdentityObserver() override;
46
47 // signin::IdentityManager::Observer:
48 void OnPrimaryAccountSet(
49 const CoreAccountInfo& primary_account_info) override;
50 void OnPrimaryAccountCleared(
51 const CoreAccountInfo& previous_primary_account_info) override;
52
53 private:
54 void StartAccountTracker(
55 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
56
57 GCMDriver* driver_;
58 signin::IdentityManager* identity_manager_;
59 std::unique_ptr<GCMAccountTracker> gcm_account_tracker_;
60
61 // The account ID that this service is responsible for. Empty when the service
62 // is not running.
63 CoreAccountId account_id_;
64
65 base::WeakPtrFactory<GCMProfileService::IdentityObserver> weak_ptr_factory_{
66 this};
67
68 DISALLOW_COPY_AND_ASSIGN(IdentityObserver);
69 };
70
IdentityObserver(signin::IdentityManager * identity_manager,scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,GCMDriver * driver)71 GCMProfileService::IdentityObserver::IdentityObserver(
72 signin::IdentityManager* identity_manager,
73 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
74 GCMDriver* driver)
75 : driver_(driver), identity_manager_(identity_manager) {
76 identity_manager_->AddObserver(this);
77
78 OnPrimaryAccountSet(identity_manager_->GetPrimaryAccountInfo());
79 StartAccountTracker(std::move(url_loader_factory));
80 }
81
~IdentityObserver()82 GCMProfileService::IdentityObserver::~IdentityObserver() {
83 if (gcm_account_tracker_)
84 gcm_account_tracker_->Shutdown();
85 identity_manager_->RemoveObserver(this);
86 }
87
OnPrimaryAccountSet(const CoreAccountInfo & primary_account_info)88 void GCMProfileService::IdentityObserver::OnPrimaryAccountSet(
89 const CoreAccountInfo& primary_account_info) {
90 // This might be called multiple times when the password changes.
91 if (primary_account_info.account_id == account_id_)
92 return;
93 account_id_ = primary_account_info.account_id;
94
95 // Still need to notify GCMDriver for UMA purpose.
96 driver_->OnSignedIn();
97 }
98
OnPrimaryAccountCleared(const CoreAccountInfo & previous_primary_account_info)99 void GCMProfileService::IdentityObserver::OnPrimaryAccountCleared(
100 const CoreAccountInfo& previous_primary_account_info) {
101 account_id_ = CoreAccountId();
102
103 // Still need to notify GCMDriver for UMA purpose.
104 driver_->OnSignedOut();
105 }
106
StartAccountTracker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)107 void GCMProfileService::IdentityObserver::StartAccountTracker(
108 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
109 if (gcm_account_tracker_)
110 return;
111
112 std::unique_ptr<AccountTracker> gaia_account_tracker(
113 new AccountTracker(identity_manager_));
114
115 gcm_account_tracker_.reset(new GCMAccountTracker(
116 std::move(gaia_account_tracker), identity_manager_, driver_));
117
118 gcm_account_tracker_->Start();
119 }
120
121 #endif // !BUILDFLAG(USE_GCM_FROM_PLATFORM)
122
123 #if BUILDFLAG(USE_GCM_FROM_PLATFORM)
GCMProfileService(base::FilePath path,scoped_refptr<base::SequencedTaskRunner> & blocking_task_runner)124 GCMProfileService::GCMProfileService(
125 base::FilePath path,
126 scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) {
127 driver_ = std::make_unique<GCMDriverAndroid>(
128 path.Append(gcm_driver::kGCMStoreDirname), blocking_task_runner);
129 }
130 #else
GCMProfileService(PrefService * prefs,base::FilePath path,base::RepeatingCallback<void (base::WeakPtr<GCMProfileService>,mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)> get_socket_factory_callback,scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,network::NetworkConnectionTracker * network_connection_tracker,version_info::Channel channel,const std::string & product_category_for_subtypes,signin::IdentityManager * identity_manager,std::unique_ptr<GCMClientFactory> gcm_client_factory,const scoped_refptr<base::SequencedTaskRunner> & ui_task_runner,const scoped_refptr<base::SequencedTaskRunner> & io_task_runner,scoped_refptr<base::SequencedTaskRunner> & blocking_task_runner)131 GCMProfileService::GCMProfileService(
132 PrefService* prefs,
133 base::FilePath path,
134 base::RepeatingCallback<void(
135 base::WeakPtr<GCMProfileService>,
136 mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
137 get_socket_factory_callback,
138 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
139 network::NetworkConnectionTracker* network_connection_tracker,
140 version_info::Channel channel,
141 const std::string& product_category_for_subtypes,
142 signin::IdentityManager* identity_manager,
143 std::unique_ptr<GCMClientFactory> gcm_client_factory,
144 const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner,
145 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
146 scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner)
147 : identity_manager_(identity_manager),
148 url_loader_factory_(std::move(url_loader_factory)) {
149 signin::IdentityManager::AccountIdMigrationState id_migration =
150 identity_manager_->GetAccountIdMigrationState();
151 bool remove_account_mappings_with_email_key =
152 (id_migration == signin::IdentityManager::MIGRATION_IN_PROGRESS) ||
153 (id_migration == signin::IdentityManager::MIGRATION_DONE);
154 driver_ = CreateGCMDriverDesktop(
155 std::move(gcm_client_factory), prefs,
156 path.Append(gcm_driver::kGCMStoreDirname),
157 remove_account_mappings_with_email_key,
158 base::BindRepeating(get_socket_factory_callback,
159 weak_ptr_factory_.GetWeakPtr()),
160 url_loader_factory_, network_connection_tracker, channel,
161 product_category_for_subtypes, ui_task_runner, io_task_runner,
162 blocking_task_runner);
163
164 identity_observer_.reset(new IdentityObserver(
165 identity_manager_, url_loader_factory_, driver_.get()));
166 }
167 #endif // BUILDFLAG(USE_GCM_FROM_PLATFORM)
168
GCMProfileService()169 GCMProfileService::GCMProfileService() {}
170
~GCMProfileService()171 GCMProfileService::~GCMProfileService() {}
172
Shutdown()173 void GCMProfileService::Shutdown() {
174 #if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
175 identity_observer_.reset();
176 #endif // !BUILDFLAG(USE_GCM_FROM_PLATFORM)
177 if (driver_) {
178 driver_->Shutdown();
179 driver_.reset();
180 }
181 }
182
SetDriverForTesting(std::unique_ptr<GCMDriver> driver)183 void GCMProfileService::SetDriverForTesting(std::unique_ptr<GCMDriver> driver) {
184 driver_ = std::move(driver);
185
186 #if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
187 if (identity_observer_) {
188 identity_observer_ = std::make_unique<IdentityObserver>(
189 identity_manager_, url_loader_factory_, driver.get());
190 }
191 #endif // !BUILDFLAG(USE_GCM_FROM_PLATFORM)
192 }
193
194 } // namespace gcm
195