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