Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / sync_driver / non_blocking_data_type_controller.h
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.
4
5 #ifndef CHROME_BROWSER_SYNC_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
6 #define CHROME_BROWSER_SYNC_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
7
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"
13
14 namespace syncer {
15 class NonBlockingTypeProcessor;
16 }
17
18 namespace browser_sync {
19
20 // Lives on the UI thread and manages the interactions between many sync
21 // components.
22 //
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.
27 //
28 // The NonBlockingSyncTypeProcessor can exist in three different states.  Those
29 // states are:
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.
36 //
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.
39 //
40 // The processor is enabled when the user has indicated a desire to sync this
41 // type, and the NonBlockingTypeProcessor and SyncCoreProxy are available.
42 //
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.
46 //
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.
50 //
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 {
55  public:
56   NonBlockingDataTypeController(syncer::ModelType type, bool is_preferred);
57   ~NonBlockingDataTypeController();
58
59   // Connects the NonBlockingTypeProcessor to this controller.
60   //
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);
66
67   // Initialize the connection to the SyncCoreProxy.
68   //
69   // This process may be reversed with ClearSyncCoreProxy().
70   void InitializeSyncCoreProxy(scoped_ptr<syncer::SyncCoreProxy> proxy);
71
72   // Disconnect from the current SyncCoreProxy.
73   void ClearSyncCoreProxy();
74
75   // Sets the current preferred state.
76   //
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
79   // to false.
80   void SetIsPreferred(bool is_preferred);
81
82  private:
83   enum TypeProcessorState { ENABLED, DISABLED, DISCONNECTED };
84
85   // Figures out which signals need to be sent then send then sends them.
86   void UpdateState();
87
88   // Sends an enable signal to the NonBlockingTypeProcessor.
89   void SendEnableSignal();
90
91   // Sends a disable signal to the NonBlockingTypeProcessor.
92   void SendDisableSignal();
93
94   // Sends a disconnect signal to the NonBlockingTypeProcessor.
95   void SendDisconnectSignal();
96
97   // Returns true if this type should be synced.
98   bool IsPreferred() const;
99
100   // Returns true if this object has access to the NonBlockingTypeProcessor.
101   bool IsTypeProcessorConnected() const;
102
103   // Returns true if this object has access to the SyncCoreProxy.
104   bool IsSyncBackendConnected() const;
105
106   // Returns the state that the processor *should* be in.
107   TypeProcessorState GetDesiredState() const;
108
109   // The ModelType we're controlling.  Kept mainly for debugging.
110   const syncer::ModelType type_;
111
112   // Returns the state that the processor is actually in, from this class'
113   // point of view.
114   //
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_;
120
121   // Whether or not the user wants to sync this type.
122   bool is_preferred_;
123
124   // The NonBlockingTypeProcessor and its associated thread.  May be NULL.
125   scoped_refptr<base::SequencedTaskRunner> task_runner_;
126   base::WeakPtr<syncer::NonBlockingTypeProcessor> processor_;
127
128   // The SyncCoreProxy that connects to the current sync backend.  May be NULL.
129   scoped_ptr<syncer::SyncCoreProxy> proxy_;
130
131   DISALLOW_COPY_AND_ASSIGN(NonBlockingDataTypeController);
132 };
133
134 }  // namespace browser_sync
135
136 #endif  // CHROME_BROWSER_SYNC_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_