summaryrefslogtreecommitdiffstats
path: root/components/sync_driver/device_info_service.h
blob: bc32e1740f2b96c9638ac0597f61efb868b3c205 (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2015 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_DEVICE_INFO_SERVICE_H_
#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_

#include <stdint.h>

#include <map>
#include <string>
#include <vector>

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "components/sync_driver/device_info_tracker.h"
#include "components/sync_driver/local_device_info_provider.h"
#include "sync/api/model_type_service.h"
#include "sync/api/model_type_store.h"
#include "sync/internal_api/public/simple_metadata_change_list.h"

namespace syncer {
class SyncError;
}  // namespace syncer

namespace syncer_v2 {
class ModelTypeChangeProcessor;
}  // namespace syncer_v2

namespace sync_pb {
class DeviceInfoSpecifics;
}  // namespace sync_pb

namespace sync_driver_v2 {

// USS service implementation for DEVICE_INFO model type. Handles storage of
// device info and associated sync metadata, applying/merging foreign changes,
// and allows public read access.
class DeviceInfoService : public syncer_v2::ModelTypeService,
                          public sync_driver::DeviceInfoTracker {
 public:
  typedef base::Callback<void(syncer_v2::ModelTypeStore::InitCallback callback)>
      StoreFactoryFunction;

  DeviceInfoService(
      sync_driver::LocalDeviceInfoProvider* local_device_info_provider,
      const StoreFactoryFunction& callback,
      const ChangeProcessorFactory& change_processor_factory);
  ~DeviceInfoService() override;

  // ModelTypeService implementation.
  scoped_ptr<syncer_v2::MetadataChangeList> CreateMetadataChangeList() override;
  syncer::SyncError MergeSyncData(
      scoped_ptr<syncer_v2::MetadataChangeList> metadata_change_list,
      syncer_v2::EntityDataMap entity_data_map) override;
  syncer::SyncError ApplySyncChanges(
      scoped_ptr<syncer_v2::MetadataChangeList> metadata_change_list,
      syncer_v2::EntityChangeList entity_changes) override;
  void GetData(ClientTagList client_tags, DataCallback callback) override;
  void GetAllData(DataCallback callback) override;
  std::string GetClientTag(const syncer_v2::EntityData& entity_data) override;
  void OnChangeProcessorSet() override;

  // DeviceInfoTracker implementation.
  bool IsSyncing() const override;
  scoped_ptr<sync_driver::DeviceInfo> GetDeviceInfo(
      const std::string& client_id) const override;
  ScopedVector<sync_driver::DeviceInfo> GetAllDeviceInfo() const override;
  void AddObserver(Observer* observer) override;
  void RemoveObserver(Observer* observer) override;
  int CountActiveDevices() const override;

 private:
  friend class DeviceInfoServiceTest;

  scoped_ptr<sync_pb::DeviceInfoSpecifics> CreateLocalSpecifics();
  static scoped_ptr<sync_pb::DeviceInfoSpecifics> CreateSpecifics(
      const sync_driver::DeviceInfo& info);

  // Allocate new DeviceInfo from SyncData.
  static scoped_ptr<sync_driver::DeviceInfo> CreateDeviceInfo(
      const sync_pb::DeviceInfoSpecifics& specifics);
  // Conversion as we prepare to hand data to the processor.
  static scoped_ptr<syncer_v2::EntityData> CopyIntoNewEntityData(
      const sync_pb::DeviceInfoSpecifics& specifics);

  // Store SyncData in the cache and durable storage.
  void StoreSpecifics(scoped_ptr<sync_pb::DeviceInfoSpecifics> specifics,
                      syncer_v2::ModelTypeStore::WriteBatch* batch);
  // Delete SyncData from the cache and durable storage, returns true if there
  // was actually anything at the given tag.
  bool DeleteSpecifics(const std::string& tag,
                       syncer_v2::ModelTypeStore::WriteBatch* batch);

  // Notify all registered observers.
  void NotifyObservers();

  // Used as callback given to LocalDeviceInfoProvider.
  void OnProviderInitialized();

  // Methods used as callbacks given to DataTypeStore.
  void OnStoreCreated(syncer_v2::ModelTypeStore::Result result,
                      scoped_ptr<syncer_v2::ModelTypeStore> store);
  void OnReadAllData(
      syncer_v2::ModelTypeStore::Result result,
      scoped_ptr<syncer_v2::ModelTypeStore::RecordList> record_list);
  void OnReadAllMetadata(
      syncer_v2::ModelTypeStore::Result result,
      scoped_ptr<syncer_v2::ModelTypeStore::RecordList> metadata_records,
      const std::string& global_metadata);
  void OnCommit(syncer_v2::ModelTypeStore::Result result);

  // Checks if conditions have been met to perform reconciliation between the
  // locally provide device info and the stored device info data. If conditions
  // are met and the sets of data differ, than we condier this a local change
  // and we send it to the processor.
  void TryReconcileLocalAndStored();

  // Checks if conditions have been met to load and report metadata to our
  // current processor if able.
  void TryLoadAllMetadata();

  // |local_device_info_provider_| isn't owned.
  const sync_driver::LocalDeviceInfoProvider* const local_device_info_provider_;

  // Cache of all syncable and local data, stored by device cache guid.
  using ClientIdToSpecifics =
      std::map<std::string, scoped_ptr<sync_pb::DeviceInfoSpecifics>>;
  ClientIdToSpecifics all_data_;

  // Registered observers, not owned.
  base::ObserverList<Observer, true> observers_;

  // Used to listen for provider initialization. If the provider is already
  // initialized during our constructor then the subscription is never used.
  scoped_ptr<sync_driver::LocalDeviceInfoProvider::Subscription> subscription_;

  // In charge of actually persiting changes to disk, or loading previous data.
  scoped_ptr<syncer_v2::ModelTypeStore> store_;

  // If |store_| has invoked |LoadAllDataCallback|.
  bool has_data_loaded_ = false;
  // If |local_device_info_provider_| has initialized.
  bool has_provider_initialized_ = false;

  // Should always be last member.
  base::WeakPtrFactory<DeviceInfoService> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(DeviceInfoService);
};

}  // namespace sync_driver_v2

#endif  // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_