summaryrefslogtreecommitdiffstats
path: root/components/sync_driver/non_blocking_data_type_controller.h
blob: eeeaeb94f6a99ea52465701a387d9d1c6c6869f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
#define COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_

#include <string>

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/sync_driver/data_type_controller.h"
#include "sync/internal_api/public/base/model_type.h"

namespace sync_driver {
class SyncClient;
}

namespace syncer_v2 {
struct ActivationContext;
class SharedModelTypeProcessor;
}

namespace sync_driver_v2 {

// Base class for DataType controllers for Unified Sync and Storage datatypes.
// Derived types must implement the following methods:
// - RunOnModelThread
// - RunOnUIThread
class NonBlockingDataTypeController : public sync_driver::DataTypeController {
 public:
  NonBlockingDataTypeController(
      const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
      const base::Closure& error_callback,
      syncer::ModelType model_type,
      sync_driver::SyncClient* sync_client);

  // Connects the ModelTypeProcessor to this controller.
  // TODO(stanisc): replace this with a proper initialization mechanism similar
  // to how directory DTC obtain SyncableService.
  void InitializeType(
      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
      const base::WeakPtr<syncer_v2::SharedModelTypeProcessor>& type_processor);

  // DataTypeErrorHandler interface.
  void OnSingleDataTypeUnrecoverableError(
      const syncer::SyncError& error) override;

  // DataTypeController interface.
  bool ShouldLoadModelBeforeConfigure() const override;
  void LoadModels(const ModelLoadCallback& model_load_callback) override;
  void StartAssociating(const StartCallback& start_callback) override;
  void ActivateDataType(
      sync_driver::BackendDataTypeConfigurer* configurer) override;
  void DeactivateDataType(
      sync_driver::BackendDataTypeConfigurer* configurer) override;
  void Stop() override;
  std::string name() const override;
  State state() const override;
  syncer::ModelType type() const override;

 protected:
  // DataTypeController is RefCounted.
  ~NonBlockingDataTypeController() override;

  // Returns SharedModelTypeProcessor associated with the controller.
  // The weak pointer should be used only on the model thread.
  base::WeakPtr<syncer_v2::SharedModelTypeProcessor> type_processor() const;

  // Returns true if the call is made on UI thread.
  bool BelongsToUIThread() const;

  // Posts the given task to the model thread, i.e. the thread the
  // datatype lives on.  Return value: True if task posted successfully,
  // false otherwise.
  virtual bool RunOnModelThread(const tracked_objects::Location& from_here,
                                const base::Closure& task) = 0;

  // Post the given task on the UI thread. If the call is made on UI thread
  // already, make a direct call without posting.
  virtual void RunOnUIThread(const tracked_objects::Location& from_here,
                             const base::Closure& task) = 0;

  // The function will create SharedModelTypeProcessor on model thread.
  void InitializeProcessor();

 private:
  void RecordStartFailure(ConfigureResult result) const;
  void RecordUnrecoverableError();
  void ReportLoadModelError(ConfigureResult result,
                            const syncer::SyncError& error);
  void InitializeProcessorOnModelThread();

  // If the DataType controller is waiting for models to load, once the models
  // are loaded this function should be called to let the base class
  // implementation know that it is safe to continue with the activation.
  // The error indicates whether the loading completed successfully.
  void LoadModelsDone(ConfigureResult result, const syncer::SyncError& error);

  // Callback passed to the processor to be invoked when the processor has
  // started. This is called on the model thread.
  void OnProcessorStarted(
      syncer::SyncError error,
      scoped_ptr<syncer_v2::ActivationContext> activation_context);

  // The function will do the real work when OnProcessorStarted got called. This
  // is called on the UI thread.
  void OnProcessorStartedOnUIThread(
      syncer::SyncError error,
      scoped_ptr<syncer_v2::ActivationContext> activation_context);

  // Model Type for this controller
  syncer::ModelType model_type_;

  // Sync client
  sync_driver::SyncClient* const sync_client_;

  // State of this datatype controller.
  State state_;

  // Callbacks for use when starting the datatype.
  ModelLoadCallback model_load_callback_;

  // Controller receives |activation_context_| from SharedModelTypeProcessor
  // callback and must temporarily own it until ActivateDataType is called.
  scoped_ptr<syncer_v2::ActivationContext> activation_context_;

  // A weak pointer to the actual SharedModelTypeProcessor
  base::WeakPtr<syncer_v2::SharedModelTypeProcessor> type_processor_;

  DISALLOW_COPY_AND_ASSIGN(NonBlockingDataTypeController);
};

}  // namespace sync_driver_v2

#endif  // COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_