1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_STARTUP_CONTROLLER_H_
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define CHROME_BROWSER_SYNC_STARTUP_CONTROLLER_H_
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/weak_ptr.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/time/time.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ProfileOAuth2TokenService;
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass SupervisedUserSigninManagerWrapper;
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace sync_driver {
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class SyncPrefs;
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace browser_sync {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Defines the type of behavior the sync engine should use. If configured for
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// AUTO_START, the sync engine will automatically call SetSyncSetupCompleted()
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// and start downloading data types as soon as sync credentials are available.
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// If configured for MANUAL_START, sync will not start until the user
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// completes sync setup, at which point the UI makes an explicit call to
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// complete sync setup.
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)enum ProfileSyncServiceStartBehavior {
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AUTO_START,
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MANUAL_START,
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This class is used by ProfileSyncService to manage all logic and state
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// pertaining to initialization of the SyncBackendHost (colloquially referred
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// to as "the backend").
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class StartupController {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StartupController(ProfileSyncServiceStartBehavior start_behavior,
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    const ProfileOAuth2TokenService* token_service,
4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                    const sync_driver::SyncPrefs* sync_prefs,
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    const SupervisedUserSigninManagerWrapper* signin,
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    base::Closure start_backend);
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~StartupController();
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Starts up sync if it is not suppressed and preconditions are met.
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns true if these preconditions are met, although does not imply
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the backend was started.
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool TryStart();
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Called when a datatype (SyncableService) has a need for sync to start
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // ASAP, presumably because a local change event has occurred but we're
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // still in deferred start mode, meaning the SyncableService hasn't been
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // told to MergeDataAndStartSyncing yet.
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // It is expected that |type| is a currently active datatype.
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void OnDataTypeRequestsSyncStartup(syncer::ModelType type);
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Prepares this object for a new attempt to start sync, forgetting
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // whether or not preconditions were previously met.
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // NOTE: This resets internal state managed by this class, but does not
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // touch values that are explicitly set and reset by higher layers to
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // tell this class whether a setup UI dialog is being shown to the user.
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // See setup_in_progress_.
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Reset(const syncer::ModelTypeSet registered_types);
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void set_setup_in_progress(bool in_progress);
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool setup_in_progress() const { return setup_in_progress_; }
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool auto_start_enabled() const { return auto_start_enabled_; }
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::Time start_backend_time() const { return start_backend_time_; }
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string GetBackendInitializationStateString() const;
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void OverrideFallbackTimeoutForTest(const base::TimeDelta& timeout);
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum StartUpDeferredOption {
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    STARTUP_BACKEND_DEFERRED,
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    STARTUP_IMMEDIATE
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns true if all conditions to start the backend are met.
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool StartUp(StartUpDeferredOption deferred_option);
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void OnFallbackStartupTimerExpired();
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Records time spent in deferred state with UMA histograms.
8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void RecordTimeDeferred();
8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // True if we should start sync ASAP because either a SyncableService has
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // requested it, or we're done waiting for a sign and decided to go ahead.
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool received_start_request_;
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The time that StartUp() is called. This is used to calculate time spent
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // in the deferred state; that is, after StartUp and before invoking the
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // start_backend_ callback.
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::Time start_up_time_;
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If |true|, there is setup UI visible so we should not start downloading
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // data types.
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Note: this is explicitly controlled by higher layers (UI) and is meant to
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // reflect what the UI claims the setup state to be. Therefore, only set this
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // due to explicit requests to do so via set_setup_in_progress.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool setup_in_progress_;
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If true, we want to automatically start sync signin whenever we have
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // credentials (user doesn't need to go through the startup flow). This is
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // typically enabled on platforms (like ChromeOS) that have their own
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // distinct signin flow.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const bool auto_start_enabled_;
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const sync_driver::SyncPrefs* sync_prefs_;
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const ProfileOAuth2TokenService* token_service_;
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const SupervisedUserSigninManagerWrapper* signin_;
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The callback we invoke when it's time to call expensive
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // startup routines for the sync backend.
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::Closure start_backend_;
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The time at which we invoked the start_backend_ callback.
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::Time start_backend_time_;
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeDelta fallback_timeout_;
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Used to compute preferred_types from SyncPrefs as-needed.
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  syncer::ModelTypeSet registered_types_;
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // True before calling |start_backend_| for the first time. False after that.
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool first_start_;
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WeakPtrFactory<StartupController> weak_factory_;
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace browser_sync
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // CHROME_BROWSER_SYNC_STARTUP_CONTROLLER_H_
133