1 // Copyright 2015 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 "ios/chrome/browser/sync/profile_sync_service_factory.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/no_destructor.h"
11 #include "base/task/post_task.h"
12 #include "base/time/time.h"
13 #include "components/autofill/core/browser/personal_data_manager.h"
14 #include "components/invalidation/impl/profile_invalidation_provider.h"
15 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
16 #include "components/network_time/network_time_tracker.h"
17 #include "components/policy/core/common/policy_map.h"
18 #include "components/sync/base/sync_util.h"
19 #include "components/sync/driver/profile_sync_service.h"
20 #include "components/sync/driver/sync_driver_switches.h"
21 #include "components/sync/driver/sync_service.h"
22 #include "ios/chrome/browser/application_context.h"
23 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
24 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
25 #include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h"
26 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
27 #include "ios/chrome/browser/favicon/favicon_service_factory.h"
28 #include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h"
29 #include "ios/chrome/browser/history/history_service_factory.h"
30 #include "ios/chrome/browser/invalidation/ios_chrome_profile_invalidation_provider_factory.h"
31 #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
32 #include "ios/chrome/browser/policy/browser_state_policy_connector.h"
33 #include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
34 #include "ios/chrome/browser/search_engines/template_url_service_factory.h"
35 #include "ios/chrome/browser/signin/about_signin_internals_factory.h"
36 #include "ios/chrome/browser/signin/identity_manager_factory.h"
37 #include "ios/chrome/browser/sync/consent_auditor_factory.h"
38 #include "ios/chrome/browser/sync/device_info_sync_service_factory.h"
39 #include "ios/chrome/browser/sync/ios_chrome_sync_client.h"
40 #include "ios/chrome/browser/sync/ios_user_event_service_factory.h"
41 #include "ios/chrome/browser/sync/model_type_store_service_factory.h"
42 #include "ios/chrome/browser/sync/session_sync_service_factory.h"
43 #include "ios/chrome/browser/sync/sync_invalidations_service_factory.h"
44 #include "ios/chrome/browser/undo/bookmark_undo_service_factory.h"
45 #include "ios/chrome/browser/webdata_services/web_data_service_factory.h"
46 #include "ios/chrome/common/channel_info.h"
47 #include "ios/web/public/thread/web_task_traits.h"
48 #include "ios/web/public/thread/web_thread.h"
49 #include "services/network/public/cpp/shared_url_loader_factory.h"
50 #include "url/gurl.h"
51
52 namespace {
53
UpdateNetworkTimeOnUIThread(base::Time network_time,base::TimeDelta resolution,base::TimeDelta latency,base::TimeTicks post_time)54 void UpdateNetworkTimeOnUIThread(base::Time network_time,
55 base::TimeDelta resolution,
56 base::TimeDelta latency,
57 base::TimeTicks post_time) {
58 GetApplicationContext()->GetNetworkTimeTracker()->UpdateNetworkTime(
59 network_time, resolution, latency, post_time);
60 }
61
UpdateNetworkTime(const base::Time & network_time,const base::TimeDelta & resolution,const base::TimeDelta & latency)62 void UpdateNetworkTime(const base::Time& network_time,
63 const base::TimeDelta& resolution,
64 const base::TimeDelta& latency) {
65 base::PostTask(FROM_HERE, {web::WebThread::UI},
66 base::BindOnce(&UpdateNetworkTimeOnUIThread, network_time,
67 resolution, latency, base::TimeTicks::Now()));
68 }
69
70 } // namespace
71
72 // static
GetInstance()73 ProfileSyncServiceFactory* ProfileSyncServiceFactory::GetInstance() {
74 static base::NoDestructor<ProfileSyncServiceFactory> instance;
75 return instance.get();
76 }
77
78 // static
GetForBrowserState(ChromeBrowserState * browser_state)79 syncer::SyncService* ProfileSyncServiceFactory::GetForBrowserState(
80 ChromeBrowserState* browser_state) {
81 if (!switches::IsSyncAllowedByFlag())
82 return nullptr;
83
84 return static_cast<syncer::SyncService*>(
85 GetInstance()->GetServiceForBrowserState(browser_state, true));
86 }
87
88 // static
GetForBrowserStateIfExists(ChromeBrowserState * browser_state)89 syncer::SyncService* ProfileSyncServiceFactory::GetForBrowserStateIfExists(
90 ChromeBrowserState* browser_state) {
91 if (!switches::IsSyncAllowedByFlag())
92 return nullptr;
93
94 return static_cast<syncer::SyncService*>(
95 GetInstance()->GetServiceForBrowserState(browser_state, false));
96 }
97
98 // static
99 syncer::ProfileSyncService*
GetAsProfileSyncServiceForBrowserState(ChromeBrowserState * browser_state)100 ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
101 ChromeBrowserState* browser_state) {
102 return static_cast<syncer::ProfileSyncService*>(
103 GetForBrowserState(browser_state));
104 }
105
106 // static
107 syncer::ProfileSyncService*
GetAsProfileSyncServiceForBrowserStateIfExists(ChromeBrowserState * browser_state)108 ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserStateIfExists(
109 ChromeBrowserState* browser_state) {
110 return static_cast<syncer::ProfileSyncService*>(
111 GetForBrowserStateIfExists(browser_state));
112 }
113
ProfileSyncServiceFactory()114 ProfileSyncServiceFactory::ProfileSyncServiceFactory()
115 : BrowserStateKeyedServiceFactory(
116 "ProfileSyncService",
117 BrowserStateDependencyManager::GetInstance()) {
118 // The ProfileSyncService depends on various SyncableServices being around
119 // when it is shut down. Specify those dependencies here to build the proper
120 // destruction order.
121 DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
122 DependsOn(ConsentAuditorFactory::GetInstance());
123 DependsOn(DeviceInfoSyncServiceFactory::GetInstance());
124 DependsOn(ios::AboutSigninInternalsFactory::GetInstance());
125 DependsOn(ios::BookmarkModelFactory::GetInstance());
126 DependsOn(ios::BookmarkSyncServiceFactory::GetInstance());
127 DependsOn(ios::BookmarkUndoServiceFactory::GetInstance());
128 DependsOn(ios::FaviconServiceFactory::GetInstance());
129 DependsOn(ios::HistoryServiceFactory::GetInstance());
130 DependsOn(ios::TemplateURLServiceFactory::GetInstance());
131 DependsOn(ios::WebDataServiceFactory::GetInstance());
132 DependsOn(IdentityManagerFactory::GetInstance());
133 DependsOn(IOSChromeGCMProfileServiceFactory::GetInstance());
134 DependsOn(IOSChromePasswordStoreFactory::GetInstance());
135 DependsOn(IOSChromeProfileInvalidationProviderFactory::GetInstance());
136 DependsOn(IOSUserEventServiceFactory::GetInstance());
137 DependsOn(ModelTypeStoreServiceFactory::GetInstance());
138 DependsOn(ReadingListModelFactory::GetInstance());
139 DependsOn(SessionSyncServiceFactory::GetInstance());
140 DependsOn(SyncInvalidationsServiceFactory::GetInstance());
141 }
142
~ProfileSyncServiceFactory()143 ProfileSyncServiceFactory::~ProfileSyncServiceFactory() {}
144
145 std::unique_ptr<KeyedService>
BuildServiceInstanceFor(web::BrowserState * context) const146 ProfileSyncServiceFactory::BuildServiceInstanceFor(
147 web::BrowserState* context) const {
148 ChromeBrowserState* browser_state =
149 ChromeBrowserState::FromBrowserState(context);
150
151 // Always create the GCMProfileService instance such that we can listen to
152 // the profile notifications and purge the GCM store when the profile is
153 // being signed out.
154 IOSChromeGCMProfileServiceFactory::GetForBrowserState(browser_state);
155
156 // TODO(crbug.com/171406): Change AboutSigninInternalsFactory to load on
157 // startup once bug has been fixed.
158 ios::AboutSigninInternalsFactory::GetForBrowserState(browser_state);
159
160 syncer::ProfileSyncService::InitParams init_params;
161 init_params.identity_manager =
162 IdentityManagerFactory::GetForBrowserState(browser_state);
163 init_params.start_behavior = syncer::ProfileSyncService::MANUAL_START;
164 init_params.sync_client =
165 std::make_unique<IOSChromeSyncClient>(browser_state);
166 init_params.network_time_update_callback =
167 base::BindRepeating(&UpdateNetworkTime);
168 init_params.url_loader_factory = browser_state->GetSharedURLLoaderFactory();
169 init_params.network_connection_tracker =
170 GetApplicationContext()->GetNetworkConnectionTracker();
171 init_params.channel = ::GetChannel();
172 init_params.debug_identifier = browser_state->GetDebugName();
173 auto* policy_connector = browser_state->GetPolicyConnector();
174 init_params.policy_service =
175 policy_connector ? policy_connector->GetPolicyService() : nullptr;
176
177 auto* fcm_invalidation_provider =
178 IOSChromeProfileInvalidationProviderFactory::GetForBrowserState(
179 browser_state);
180 if (fcm_invalidation_provider) {
181 init_params.invalidations_identity_provider =
182 fcm_invalidation_provider->GetIdentityProvider();
183 }
184
185 auto pss =
186 std::make_unique<syncer::ProfileSyncService>(std::move(init_params));
187 pss->Initialize();
188
189 // Hook PSS into PersonalDataManager (a circular dependency).
190 autofill::PersonalDataManager* pdm =
191 autofill::PersonalDataManagerFactory::GetForBrowserState(browser_state);
192 pdm->OnSyncServiceInitialized(pss.get());
193
194 return pss;
195 }
196