summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/glue/preference_model_associator.h
blob: 5c661b298b1d74b8b899897dc862b5399578fe12 (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
// Copyright (c) 2011 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 CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
#define CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
#pragma once

#include <map>
#include <set>
#include <string>

#include "base/basictypes.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/sync/glue/model_associator.h"
#include "chrome/browser/sync/unrecoverable_error_handler.h"

class ProfileSyncService;
class Value;

namespace sync_api {
class WriteNode;
class WriteTransaction;
}

namespace browser_sync {

class PreferenceChangeProcessor;

static const char kPreferencesTag[] = "google_chrome_preferences";

// Contains all model association related logic:
// * Algorithm to associate preferences model and sync model.
class PreferenceModelAssociator
    : public PerDataTypeAssociatorInterface<PrefService::Preference,
                                            std::string> {
 public:
  static syncable::ModelType model_type() { return syncable::PREFERENCES; }
  explicit PreferenceModelAssociator(ProfileSyncService* sync_service);
  virtual ~PreferenceModelAssociator();

  // Returns the list of preference names that should be monitored for
  // changes.  Only preferences that are registered will be in this
  // list.
  const std::set<std::string>& synced_preferences() {
    return synced_preferences_;
  }

  // Create an association for a given preference. A sync node is created if
  // necessary and the value is read from or written to the node as appropriate.
  bool InitPrefNodeAndAssociate(sync_api::WriteTransaction* trans,
                                const sync_api::BaseNode& root,
                                const PrefService::Preference* pref);

  // PerDataTypeAssociatorInterface implementation.
  //
  // Iterates through the sync model looking for matched pairs of items.
  virtual bool AssociateModels();

  // Clears all associations.
  virtual bool DisassociateModels();

  // Returns whether the sync model has nodes other than the permanent tagged
  // nodes.
  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);

  virtual void AbortAssociation() {
    // No implementation needed, this associator runs on the main
    // thread.
  }

  // See ModelAssociator interface.
  virtual bool CryptoReadyIfNecessary();

  // Not implemented.
  virtual const PrefService::Preference* GetChromeNodeFromSyncId(int64 sync_id);

  // Not implemented.
  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
                                        sync_api::BaseNode* sync_node);

  // Returns the sync id for the given preference name, or sync_api::kInvalidId
  // if the preference name is not associated to any sync id.
  virtual int64 GetSyncIdFromChromeId(const std::string& node_id);

  // Associates the given preference name with the given sync id.
  virtual void Associate(const PrefService::Preference* node, int64 sync_id);

  // Remove the association that corresponds to the given sync id.
  virtual void Disassociate(int64 sync_id);

  // Returns whether a node with the given permanent tag was found and update
  // |sync_id| with that node's id.
  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);

  // Merges the value of local_pref into the supplied server_value and
  // returns the result (caller takes ownership).  If there is a
  // conflict, the server value always takes precedence.  Note that
  // only certain preferences will actually be merged, all others will
  // return a copy of the server value.  See the method's
  // implementation for details.
  static Value* MergePreference(const PrefService::Preference& local_pref,
                                const Value& server_value);

  // Writes the value of pref into the specified node.  Returns true
  // upon success.
  static bool WritePreferenceToNode(const std::string& name,
                                    const Value& value,
                                    sync_api::WriteNode* node);

  // Perform any additional operations that need to happen after a preference
  // has been updated.
  void AfterUpdateOperations(const std::string& pref_name);

 private:
  typedef std::map<std::string, int64> PreferenceNameToSyncIdMap;
  typedef std::map<int64, std::string> SyncIdToPreferenceNameMap;

  static Value* MergeListValues(const Value& from_value, const Value& to_value);
  static Value* MergeDictionaryValues(const Value& from_value,
                                      const Value& to_value);

  ProfileSyncService* sync_service_;
  std::set<std::string> synced_preferences_;
  int64 preferences_node_id_;

  PreferenceNameToSyncIdMap id_map_;
  SyncIdToPreferenceNameMap id_map_inverse_;

  DISALLOW_COPY_AND_ASSIGN(PreferenceModelAssociator);
};

}  // namespace browser_sync

#endif  // CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_