1 // Copyright 2012 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 #ifndef IOS_CHROME_BROWSER_SYNC_SYNC_SETUP_SERVICE_H_
6 #define IOS_CHROME_BROWSER_SYNC_SYNC_SETUP_SERVICE_H_
7 
8 #include <memory>
9 
10 #include "base/macros.h"
11 #include "components/keyed_service/core/keyed_service.h"
12 #include "components/sync/base/model_type.h"
13 #include "components/sync/driver/sync_user_settings.h"
14 
15 namespace syncer {
16 class SyncService;
17 class SyncSetupInProgressHandle;
18 }  // namespace syncer
19 
20 // Class that allows configuring sync. It handles enabling and disabling it, as
21 // well as choosing datatypes. Most actions are delayed until a commit is done,
22 // to allow the complex sync setup flow on iOS.
23 class SyncSetupService : public KeyedService {
24  public:
25   using SyncServiceState = enum {
26     kNoSyncServiceError,
27     kSyncServiceSignInNeedsUpdate,
28     kSyncServiceCouldNotConnect,
29     kSyncServiceServiceUnavailable,
30     kSyncServiceNeedsPassphrase,
31     kSyncServiceNeedsTrustedVaultKey,
32     kSyncServiceUnrecoverableError,
33     kSyncSettingsNotConfirmed,
34     kLastSyncServiceError = kSyncServiceUnrecoverableError
35   };
36 
37   // The set of user-selectable datatypes handled by Chrome for iOS.
38   using SyncableDatatype = enum {
39     kSyncBookmarks,
40     kSyncOmniboxHistory,
41     kSyncPasswords,
42     kSyncOpenTabs,
43     kSyncAutofill,
44     kSyncPreferences,
45     kSyncReadingList,
46     kNumberOfSyncableDatatypes
47   };
48 
49   explicit SyncSetupService(syncer::SyncService* sync_service);
50   ~SyncSetupService() override;
51 
52   // Returns the |syncer::ModelType| associated to the given
53   // |SyncableDatatypes|.
54   syncer::ModelType GetModelType(SyncableDatatype datatype);
55 
56   // Returns whether sync is enabled.
57   virtual bool IsSyncEnabled() const;
58   // Enables or disables sync. Changes won't take effect in the sync backend
59   // before the next call to |CommitChanges|.
60   virtual void SetSyncEnabled(bool sync_enabled);
61 
62   // Returns all currently enabled datatypes.
63   syncer::ModelTypeSet GetPreferredDataTypes() const;
64   // Returns whether the given datatype has been enabled for sync and its
65   // initialization is complete (SyncEngineHost::OnEngineInitialized has been
66   // called).
67   virtual bool IsDataTypeActive(syncer::ModelType datatype) const;
68   // Returns whether the given datatype is enabled by the user.
69   virtual bool IsDataTypePreferred(syncer::ModelType datatype) const;
70   // Enables or disables the given datatype. To be noted: this can be called at
71   // any time, but will only be meaningful if |IsSyncEnabled| is true and
72   // |IsSyncingAllDataTypes| is false. Changes won't take effect in the sync
73   // backend before the next call to |CommitChanges|.
74   void SetDataTypeEnabled(syncer::ModelType datatype, bool enabled);
75 
76   // Returns whether the user needs to enter a passphrase or enable sync to make
77   // tab sync work.
78   bool UserActionIsRequiredToHaveTabSyncWork();
79 
80   // Returns whether all datatypes are being synced.
81   virtual bool IsSyncingAllDataTypes() const;
82   // Sets whether all datatypes should be synced or not. Changes won't take
83   // effect before the next call to |CommitChanges|.
84   virtual void SetSyncingAllDataTypes(bool sync_all);
85 
86   // Returns the current sync service state.
87   virtual SyncServiceState GetSyncServiceState();
88 
89   // Returns whether all sync data is being encrypted.
90   virtual bool IsEncryptEverythingEnabled() const;
91 
92   // Returns true if the user has gone through the initial sync configuration.
93   // This method is guaranteed not to start the sync backend so it can be
94   // called at start-up.
95   // TODO(crbug.com/951313): This method has to be remove when UnifiedConsent
96   // flag is cleaned up.
97   virtual bool HasFinishedInitialSetup();
98 
99   // Pauses sync allowing the user to configure what data to sync before
100   // actually starting to sync data with the server.
101   virtual void PrepareForFirstSyncSetup();
102 
103   // Sets the first setup complete flag. This method doesn't commit sync
104   // changes. PrepareForFirstSyncSetup() needs to be called before. This flag is
105   // not set if the user didn't turn on sync.
106   // This method should only be used with UnifiedConsent flag.
107   virtual void SetFirstSetupComplete(
108       syncer::SyncFirstSetupCompleteSource source);
109 
110   // Returns true if the user finished the Sync setup flow.
111   bool IsFirstSetupComplete() const;
112 
113   // Commits all the pending configuration changes to Sync.
114   // This method should only be used with UnifiedConsent flag.
115   void CommitSyncChanges();
116 
117   // Returns true if there are uncommitted sync changes;
118   bool HasUncommittedChanges();
119 
120  private:
121   // Enables or disables sync. Changes won't take effect in the sync backend
122   // before the next call to |CommitChanges|. No changes are made to the
123   // currently selected datatypes.
124   void SetSyncEnabledWithoutChangingDatatypes(bool sync_enabled);
125 
126   syncer::SyncService* const sync_service_;
127 
128   // Prevents Sync from running until configuration is complete.
129   std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_;
130 
131   DISALLOW_COPY_AND_ASSIGN(SyncSetupService);
132 };
133 
134 #endif  // IOS_CHROME_BROWSER_SYNC_SYNC_SETUP_SERVICE_H_
135