OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 #include "chrome/browser/sync/glue/synced_device_tracker.h" | |
6 | |
7 #include "base/strings/stringprintf.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "chrome/browser/sync/glue/device_info.h" | |
10 #include "sync/internal_api/public/base/model_type.h" | |
11 #include "sync/internal_api/public/read_node.h" | |
12 #include "sync/internal_api/public/read_transaction.h" | |
13 #include "sync/internal_api/public/user_share.h" | |
14 #include "sync/internal_api/public/write_node.h" | |
15 #include "sync/internal_api/public/write_transaction.h" | |
16 #include "sync/util/time.h" | |
17 | |
18 namespace browser_sync { | |
19 | |
20 namespace { | |
21 | |
22 // Return the DeviceInfo UNIQUE_CLIENT_TAG value for the given sync cache_guid. | |
23 std::string DeviceInfoLookupString(const std::string& cache_guid) { | |
24 return base::StringPrintf("DeviceInfo_%s", cache_guid.c_str()); | |
25 } | |
26 | |
27 } // namespace | |
28 | |
29 SyncedDeviceTracker::SyncedDeviceTracker(syncer::UserShare* user_share, | |
30 const std::string& cache_guid) | |
31 : ChangeProcessor(NULL), | |
32 user_share_(user_share), | |
33 cache_guid_(cache_guid), | |
34 local_device_info_tag_(DeviceInfoLookupString(cache_guid)), | |
35 weak_factory_(this) { | |
36 observers_ = new ObserverListThreadSafe<Observer>; | |
37 } | |
38 | |
39 SyncedDeviceTracker::~SyncedDeviceTracker() { | |
40 } | |
41 | |
42 void SyncedDeviceTracker::StartImpl() { } | |
43 | |
44 void SyncedDeviceTracker::ApplyChangesFromSyncModel( | |
45 const syncer::BaseTransaction* trans, | |
46 int64 model_version, | |
47 const syncer::ImmutableChangeRecordList& changes) { | |
48 // If desired, we could maintain a cache of device info. This method will be | |
49 // called with a transaction every time the device info is modified, so this | |
50 // would be the right place to update the cache. | |
51 } | |
52 | |
53 void SyncedDeviceTracker::CommitChangesFromSyncModel() { | |
54 observers_->Notify(&Observer::OnDeviceInfoChange); | |
55 } | |
56 | |
57 scoped_ptr<DeviceInfo> SyncedDeviceTracker::ReadLocalDeviceInfo() const { | |
58 syncer::ReadTransaction trans(FROM_HERE, user_share_); | |
59 return ReadLocalDeviceInfo(trans); | |
60 } | |
61 | |
62 scoped_ptr<DeviceInfo> SyncedDeviceTracker::ReadLocalDeviceInfo( | |
63 const syncer::BaseTransaction& trans) const { | |
64 syncer::ReadNode node(&trans); | |
65 if (node.InitByClientTagLookup(syncer::DEVICE_INFO, local_device_info_tag_) != | |
66 syncer::BaseNode::INIT_OK) { | |
67 return scoped_ptr<DeviceInfo>(); | |
68 } | |
69 | |
70 const sync_pb::DeviceInfoSpecifics& specifics = node.GetDeviceInfoSpecifics(); | |
71 return scoped_ptr<DeviceInfo>( | |
72 new DeviceInfo(specifics.cache_guid(), | |
73 specifics.client_name(), | |
74 specifics.chrome_version(), | |
75 specifics.sync_user_agent(), | |
76 specifics.device_type(), | |
77 specifics.signin_scoped_device_id())); | |
78 } | |
79 | |
80 scoped_ptr<DeviceInfo> SyncedDeviceTracker::ReadDeviceInfo( | |
81 const std::string& client_id) const { | |
82 syncer::ReadTransaction trans(FROM_HERE, user_share_); | |
83 syncer::ReadNode node(&trans); | |
84 std::string lookup_string = DeviceInfoLookupString(client_id); | |
85 if (node.InitByClientTagLookup(syncer::DEVICE_INFO, lookup_string) != | |
86 syncer::BaseNode::INIT_OK) { | |
87 return scoped_ptr<DeviceInfo>(); | |
88 } | |
89 | |
90 const sync_pb::DeviceInfoSpecifics& specifics = node.GetDeviceInfoSpecifics(); | |
91 return scoped_ptr<DeviceInfo>( | |
92 new DeviceInfo(specifics.cache_guid(), | |
93 specifics.client_name(), | |
94 specifics.chrome_version(), | |
95 specifics.sync_user_agent(), | |
96 specifics.device_type(), | |
97 specifics.signin_scoped_device_id())); | |
98 } | |
99 | |
100 void SyncedDeviceTracker::GetAllSyncedDeviceInfo( | |
101 ScopedVector<DeviceInfo>* device_info) const { | |
102 if (device_info == NULL) | |
103 return; | |
104 | |
105 device_info->clear(); | |
106 | |
107 syncer::ReadTransaction trans(FROM_HERE, user_share_); | |
108 syncer::ReadNode root_node(&trans); | |
109 | |
110 if (root_node.InitTypeRoot(syncer::DEVICE_INFO) != | |
111 syncer::BaseNode::INIT_OK) { | |
112 return; | |
113 } | |
114 | |
115 // Get all the children of the root node and use the child id to read | |
116 // device info for devices. | |
117 std::vector<int64> children; | |
118 root_node.GetChildIds(&children); | |
119 | |
120 for (std::vector<int64>::const_iterator it = children.begin(); | |
121 it != children.end(); ++it) { | |
122 syncer::ReadNode node(&trans); | |
123 if (node.InitByIdLookup(*it) != syncer::BaseNode::INIT_OK) | |
124 return; | |
125 | |
126 const sync_pb::DeviceInfoSpecifics& specifics = | |
127 node.GetDeviceInfoSpecifics(); | |
128 device_info->push_back(new DeviceInfo(specifics.cache_guid(), | |
129 specifics.client_name(), | |
130 specifics.chrome_version(), | |
131 specifics.sync_user_agent(), | |
132 specifics.device_type(), | |
133 specifics.signin_scoped_device_id())); | |
134 } | |
135 } | |
136 | |
137 std::string SyncedDeviceTracker::cache_guid() const { | |
138 return cache_guid_; | |
139 } | |
140 | |
141 void SyncedDeviceTracker::AddObserver(Observer* observer) { | |
142 observers_->AddObserver(observer); | |
143 } | |
144 | |
145 void SyncedDeviceTracker::RemoveObserver(Observer* observer) { | |
146 observers_->RemoveObserver(observer); | |
147 } | |
148 | |
149 void SyncedDeviceTracker::InitLocalDeviceInfo( | |
150 const std::string& signin_scoped_device_id, | |
151 const base::Closure& callback) { | |
152 DeviceInfo::CreateLocalDeviceInfo( | |
153 cache_guid_, | |
154 signin_scoped_device_id, | |
155 base::Bind(&SyncedDeviceTracker::InitLocalDeviceInfoContinuation, | |
156 weak_factory_.GetWeakPtr(), | |
157 callback)); | |
158 } | |
159 | |
160 void SyncedDeviceTracker::InitLocalDeviceInfoContinuation( | |
161 const base::Closure& callback, const DeviceInfo& local_info) { | |
162 WriteLocalDeviceInfo(local_info); | |
163 callback.Run(); | |
164 } | |
165 | |
166 void SyncedDeviceTracker::WriteLocalDeviceInfo(const DeviceInfo& info) { | |
167 DCHECK_EQ(cache_guid_, info.guid()); | |
168 WriteDeviceInfo(info, local_device_info_tag_); | |
169 } | |
170 | |
171 void SyncedDeviceTracker::WriteDeviceInfo(const DeviceInfo& info, | |
172 const std::string& tag) { | |
173 syncer::WriteTransaction trans(FROM_HERE, user_share_); | |
174 syncer::WriteNode node(&trans); | |
175 | |
176 sync_pb::DeviceInfoSpecifics specifics; | |
177 specifics.set_cache_guid(info.guid()); | |
178 specifics.set_client_name(info.client_name()); | |
179 specifics.set_chrome_version(info.chrome_version()); | |
180 specifics.set_sync_user_agent(info.sync_user_agent()); | |
181 specifics.set_device_type(info.device_type()); | |
182 specifics.set_signin_scoped_device_id(info.signin_scoped_device_id()); | |
183 | |
184 if (node.InitByClientTagLookup(syncer::DEVICE_INFO, tag) == | |
185 syncer::BaseNode::INIT_OK) { | |
186 const sync_pb::DeviceInfoSpecifics& sync_specifics = | |
187 node.GetDeviceInfoSpecifics(); | |
188 if (sync_specifics.has_backup_timestamp()) | |
189 specifics.set_backup_timestamp(sync_specifics.backup_timestamp()); | |
190 node.SetDeviceInfoSpecifics(specifics); | |
191 node.SetTitle(specifics.client_name()); | |
192 } else { | |
193 syncer::ReadNode type_root(&trans); | |
194 syncer::BaseNode::InitByLookupResult type_root_lookup_result = | |
195 type_root.InitTypeRoot(syncer::DEVICE_INFO); | |
196 DCHECK_EQ(syncer::BaseNode::INIT_OK, type_root_lookup_result); | |
197 | |
198 syncer::WriteNode new_node(&trans); | |
199 syncer::WriteNode::InitUniqueByCreationResult create_result = | |
200 new_node.InitUniqueByCreation(syncer::DEVICE_INFO, | |
201 type_root, | |
202 tag); | |
203 DCHECK_EQ(syncer::WriteNode::INIT_SUCCESS, create_result); | |
204 new_node.SetDeviceInfoSpecifics(specifics); | |
205 new_node.SetTitle(specifics.client_name()); | |
206 } | |
207 } | |
208 | |
209 void SyncedDeviceTracker::UpdateLocalDeviceBackupTime(base::Time backup_time) { | |
210 syncer::WriteTransaction trans(FROM_HERE, user_share_); | |
211 syncer::WriteNode node(&trans); | |
212 | |
213 if (node.InitByClientTagLookup(syncer::DEVICE_INFO, local_device_info_tag_) | |
214 == syncer::BaseNode::INIT_OK) { | |
215 sync_pb::DeviceInfoSpecifics specifics = node.GetDeviceInfoSpecifics(); | |
216 int64 new_backup_timestamp = syncer::TimeToProtoTime(backup_time); | |
217 if (!specifics.has_backup_timestamp() || | |
218 specifics.backup_timestamp() != new_backup_timestamp) { | |
219 specifics.set_backup_timestamp(new_backup_timestamp); | |
220 node.SetDeviceInfoSpecifics(specifics); | |
221 } | |
222 } | |
223 } | |
224 | |
225 base::Time SyncedDeviceTracker::GetLocalDeviceBackupTime() const { | |
226 syncer::ReadTransaction trans(FROM_HERE, user_share_); | |
227 syncer::ReadNode node(&trans); | |
228 if (node.InitByClientTagLookup(syncer::DEVICE_INFO, local_device_info_tag_) | |
229 == syncer::BaseNode::INIT_OK && | |
230 node.GetDeviceInfoSpecifics().has_backup_timestamp()) { | |
231 return syncer::ProtoTimeToTime( | |
232 node.GetDeviceInfoSpecifics().backup_timestamp()); | |
233 } else { | |
234 return base::Time(); | |
235 } | |
236 } | |
237 | |
238 } // namespace browser_sync | |
OLD | NEW |