1 // Copyright 2014 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.
5 #ifndef CHROME_BROWSER_SYNC_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
6 #define CHROME_BROWSER_SYNC_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/sequenced_task_runner.h"
11 #include "sync/internal_api/public/base/model_type.h"
12 #include "sync/internal_api/public/sync_core_proxy.h"
15 class NonBlockingTypeProcessor;
18 namespace browser_sync {
20 // Lives on the UI thread and manages the interactions between many sync
23 // There are three main parts to this controller:
24 // - The SyncCoreProxy, represening the sync thread.
25 // - The NonBlockingTypeProcessor, representing the model type thread.
26 // - The user-set state for this type (prefs), which lives on the UI thread.
28 // The NonBlockingSyncTypeProcessor can exist in three different states. Those
30 // - Enabled: Changes are being synced.
31 // - Disconnected: Changes would be synced, but there is no connection between
32 // the sync thread and the model thread.
33 // - Disabled: Syncing is intentionally disabled. The processor may clear any
34 // of its local state associated with sync when this happens, since
35 // this is expected to last a while.
37 // This controller is responsible for transitioning the processor into and out
38 // of these states. It does this by posting tasks to the model type thread.
40 // The processor is enabled when the user has indicated a desire to sync this
41 // type, and the NonBlockingTypeProcessor and SyncCoreProxy are available.
43 // The processor is disconnected during initialization, or when either the
44 // NonBlockingDataTypeController or SyncCoreProxy have not yet registered. It
45 // can also be disconnected later on if the sync backend becomes unavailable.
47 // The processor is disabled if the user has disabled sync for this type. The
48 // signal indicating this state will be sent to the processor when the pref is
49 // first changed, or when the processor first connects to the controller.
51 // This class is structured using some state machine patterns. It's a bit
52 // awkward at times, but this seems to be the clearest way to express the
53 // behaviors this class must implement.
54 class NonBlockingDataTypeController {
56 NonBlockingDataTypeController(syncer::ModelType type, bool is_preferred);
57 ~NonBlockingDataTypeController();
59 // Connects the NonBlockingTypeProcessor to this controller.
61 // There is no "undo" for this operation. The NonBlockingDataTypeController
62 // will only ever deal with a single processor.
63 void InitializeProcessor(
64 scoped_refptr<base::SequencedTaskRunner> task_runner,
65 base::WeakPtr<syncer::NonBlockingTypeProcessor> processor);
67 // Initialize the connection to the SyncCoreProxy.
69 // This process may be reversed with ClearSyncCoreProxy().
70 void InitializeSyncCoreProxy(scoped_ptr<syncer::SyncCoreProxy> proxy);
72 // Disconnect from the current SyncCoreProxy.
73 void ClearSyncCoreProxy();
75 // Sets the current preferred state.
77 // Represents a choice to sync or not sync this type. This is expected to
78 // last a long time, so local state may be deleted if this setting is toggled
80 void SetIsPreferred(bool is_preferred);
83 enum TypeProcessorState { ENABLED, DISABLED, DISCONNECTED };
85 // Figures out which signals need to be sent then send then sends them.
88 // Sends an enable signal to the NonBlockingTypeProcessor.
89 void SendEnableSignal();
91 // Sends a disable signal to the NonBlockingTypeProcessor.
92 void SendDisableSignal();
94 // Sends a disconnect signal to the NonBlockingTypeProcessor.
95 void SendDisconnectSignal();
97 // Returns true if this type should be synced.
98 bool IsPreferred() const;
100 // Returns true if this object has access to the NonBlockingTypeProcessor.
101 bool IsTypeProcessorConnected() const;
103 // Returns true if this object has access to the SyncCoreProxy.
104 bool IsSyncBackendConnected() const;
106 // Returns the state that the processor *should* be in.
107 TypeProcessorState GetDesiredState() const;
109 // The ModelType we're controlling. Kept mainly for debugging.
110 const syncer::ModelType type_;
112 // Returns the state that the processor is actually in, from this class'
115 // This state is inferred based on the most recently sent signals, and is
116 // intended to represent the state the processor will be in by the time any
117 // tasks we post to it now will be run. Due to threading / queueing effects,
118 // this may or may not be the actual state at this point in time.
119 TypeProcessorState current_state_;
121 // Whether or not the user wants to sync this type.
124 // The NonBlockingTypeProcessor and its associated thread. May be NULL.
125 scoped_refptr<base::SequencedTaskRunner> task_runner_;
126 base::WeakPtr<syncer::NonBlockingTypeProcessor> processor_;
128 // The SyncCoreProxy that connects to the current sync backend. May be NULL.
129 scoped_ptr<syncer::SyncCoreProxy> proxy_;
131 DISALLOW_COPY_AND_ASSIGN(NonBlockingDataTypeController);
134 } // namespace browser_sync
136 #endif // CHROME_BROWSER_SYNC_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_