1// Copyright (c) 2011 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_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
6#define CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
7#pragma once
8
9#include <map>
10#include <set>
11#include <string>
12
13#include "base/basictypes.h"
14#include "chrome/browser/prefs/pref_service.h"
15#include "chrome/browser/sync/glue/model_associator.h"
16#include "chrome/browser/sync/unrecoverable_error_handler.h"
17
18class ProfileSyncService;
19class Value;
20
21namespace sync_api {
22class WriteNode;
23class WriteTransaction;
24}
25
26namespace browser_sync {
27
28class PreferenceChangeProcessor;
29
30static const char kPreferencesTag[] = "google_chrome_preferences";
31
32// Contains all model association related logic:
33// * Algorithm to associate preferences model and sync model.
34class PreferenceModelAssociator
35    : public PerDataTypeAssociatorInterface<PrefService::Preference,
36                                            std::string> {
37 public:
38  static syncable::ModelType model_type() { return syncable::PREFERENCES; }
39  explicit PreferenceModelAssociator(ProfileSyncService* sync_service);
40  virtual ~PreferenceModelAssociator();
41
42  // Returns the list of preference names that should be monitored for
43  // changes.  Only preferences that are registered will be in this
44  // list.
45  const std::set<std::string>& synced_preferences() {
46    return synced_preferences_;
47  }
48
49  // Create an association for a given preference. A sync node is created if
50  // necessary and the value is read from or written to the node as appropriate.
51  bool InitPrefNodeAndAssociate(sync_api::WriteTransaction* trans,
52                                const sync_api::BaseNode& root,
53                                const PrefService::Preference* pref);
54
55  // PerDataTypeAssociatorInterface implementation.
56  //
57  // Iterates through the sync model looking for matched pairs of items.
58  virtual bool AssociateModels();
59
60  // Clears all associations.
61  virtual bool DisassociateModels();
62
63  // Returns whether the sync model has nodes other than the permanent tagged
64  // nodes.
65  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
66
67  virtual void AbortAssociation() {
68    // No implementation needed, this associator runs on the main
69    // thread.
70  }
71
72  // See ModelAssociator interface.
73  virtual bool CryptoReadyIfNecessary();
74
75  // Not implemented.
76  virtual const PrefService::Preference* GetChromeNodeFromSyncId(int64 sync_id);
77
78  // Not implemented.
79  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
80                                        sync_api::BaseNode* sync_node);
81
82  // Returns the sync id for the given preference name, or sync_api::kInvalidId
83  // if the preference name is not associated to any sync id.
84  virtual int64 GetSyncIdFromChromeId(const std::string& node_id);
85
86  // Associates the given preference name with the given sync id.
87  virtual void Associate(const PrefService::Preference* node, int64 sync_id);
88
89  // Remove the association that corresponds to the given sync id.
90  virtual void Disassociate(int64 sync_id);
91
92  // Returns whether a node with the given permanent tag was found and update
93  // |sync_id| with that node's id.
94  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
95
96  // Merges the value of local_pref into the supplied server_value and
97  // returns the result (caller takes ownership).  If there is a
98  // conflict, the server value always takes precedence.  Note that
99  // only certain preferences will actually be merged, all others will
100  // return a copy of the server value.  See the method's
101  // implementation for details.
102  static Value* MergePreference(const PrefService::Preference& local_pref,
103                                const Value& server_value);
104
105  // Writes the value of pref into the specified node.  Returns true
106  // upon success.
107  static bool WritePreferenceToNode(const std::string& name,
108                                    const Value& value,
109                                    sync_api::WriteNode* node);
110
111  // Perform any additional operations that need to happen after a preference
112  // has been updated.
113  void AfterUpdateOperations(const std::string& pref_name);
114
115 private:
116  typedef std::map<std::string, int64> PreferenceNameToSyncIdMap;
117  typedef std::map<int64, std::string> SyncIdToPreferenceNameMap;
118
119  static Value* MergeListValues(const Value& from_value, const Value& to_value);
120  static Value* MergeDictionaryValues(const Value& from_value,
121                                      const Value& to_value);
122
123  ProfileSyncService* sync_service_;
124  std::set<std::string> synced_preferences_;
125  int64 preferences_node_id_;
126
127  PreferenceNameToSyncIdMap id_map_;
128  SyncIdToPreferenceNameMap id_map_inverse_;
129
130  DISALLOW_COPY_AND_ASSIGN(PreferenceModelAssociator);
131};
132
133}  // namespace browser_sync
134
135#endif  // CHROME_BROWSER_SYNC_GLUE_PREFERENCE_MODEL_ASSOCIATOR_H_
136