OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/gdata/gdata_contacts_service.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_contacts_service.h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 #include <string> | 8 #include <string> |
9 #include <map> | 9 #include <map> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/json/json_value_converter.h" | 12 #include "base/json/json_value_converter.h" |
13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/string_util.h" |
17 #include "base/time.h" | 18 #include "base/time.h" |
18 #include "base/timer.h" | 19 #include "base/timer.h" |
19 #include "base/values.h" | 20 #include "base/values.h" |
20 #include "chrome/browser/chromeos/contacts/contact.pb.h" | 21 #include "chrome/browser/chromeos/contacts/contact.pb.h" |
21 #include "chrome/browser/chromeos/gdata/gdata_operation_registry.h" | 22 #include "chrome/browser/chromeos/gdata/gdata_operation_registry.h" |
22 #include "chrome/browser/chromeos/gdata/gdata_operation_runner.h" | 23 #include "chrome/browser/chromeos/gdata/gdata_operation_runner.h" |
23 #include "chrome/browser/chromeos/gdata/gdata_operations.h" | 24 #include "chrome/browser/chromeos/gdata/gdata_operations.h" |
24 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 25 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
25 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
26 | 27 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 "http://schemas.google.com/contacts/2008/rel#photo"; | 132 "http://schemas.google.com/contacts/2008/rel#photo"; |
132 | 133 |
133 // Returns a string containing a pretty-printed JSON representation of |value|. | 134 // Returns a string containing a pretty-printed JSON representation of |value|. |
134 std::string PrettyPrintValue(const base::Value& value) { | 135 std::string PrettyPrintValue(const base::Value& value) { |
135 std::string out; | 136 std::string out; |
136 base::JSONWriter::WriteWithOptions( | 137 base::JSONWriter::WriteWithOptions( |
137 &value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &out); | 138 &value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &out); |
138 return out; | 139 return out; |
139 } | 140 } |
140 | 141 |
| 142 // Assigns the value at |path| within |dict| to |out|, returning false if the |
| 143 // path wasn't present. Unicode byte order marks are removed from the string. |
| 144 bool GetCleanedString(const DictionaryValue& dict, |
| 145 const std::string& path, |
| 146 std::string* out) { |
| 147 if (!dict.GetString(path, out)) |
| 148 return false; |
| 149 |
| 150 // The Unicode byte order mark, U+FEFF, is useless in UTF-8 strings (which are |
| 151 // interpreted one byte at a time). |
| 152 ReplaceSubstringsAfterOffset(out, 0, "\xEF\xBB\xBF", ""); |
| 153 return true; |
| 154 } |
| 155 |
141 // Returns whether an address is primary, given a dictionary representing a | 156 // Returns whether an address is primary, given a dictionary representing a |
142 // single address. | 157 // single address. |
143 bool IsAddressPrimary(const DictionaryValue& address_dict) { | 158 bool IsAddressPrimary(const DictionaryValue& address_dict) { |
144 std::string primary; | 159 std::string primary; |
145 address_dict.GetString(kAddressPrimaryField, &primary); | 160 address_dict.GetString(kAddressPrimaryField, &primary); |
146 return primary == kAddressPrimaryTrueValue; | 161 return primary == kAddressPrimaryTrueValue; |
147 } | 162 } |
148 | 163 |
149 // Initializes an AddressType message given a dictionary representing a single | 164 // Initializes an AddressType message given a dictionary representing a single |
150 // address. | 165 // address. |
151 void InitAddressType(const DictionaryValue& address_dict, | 166 void InitAddressType(const DictionaryValue& address_dict, |
152 contacts::Contact_AddressType* type) { | 167 contacts::Contact_AddressType* type) { |
153 DCHECK(type); | 168 DCHECK(type); |
154 type->Clear(); | 169 type->Clear(); |
155 | 170 |
156 std::string rel; | 171 std::string rel; |
157 address_dict.GetString(kAddressRelField, &rel); | 172 address_dict.GetString(kAddressRelField, &rel); |
158 if (rel == kAddressRelHomeValue) | 173 if (rel == kAddressRelHomeValue) |
159 type->set_relation(contacts::Contact_AddressType_Relation_HOME); | 174 type->set_relation(contacts::Contact_AddressType_Relation_HOME); |
160 else if (rel == kAddressRelWorkValue) | 175 else if (rel == kAddressRelWorkValue) |
161 type->set_relation(contacts::Contact_AddressType_Relation_WORK); | 176 type->set_relation(contacts::Contact_AddressType_Relation_WORK); |
162 else if (rel == kAddressRelMobileValue) | 177 else if (rel == kAddressRelMobileValue) |
163 type->set_relation(contacts::Contact_AddressType_Relation_MOBILE); | 178 type->set_relation(contacts::Contact_AddressType_Relation_MOBILE); |
164 else | 179 else |
165 type->set_relation(contacts::Contact_AddressType_Relation_OTHER); | 180 type->set_relation(contacts::Contact_AddressType_Relation_OTHER); |
166 | 181 |
167 address_dict.GetString(kAddressLabelField, type->mutable_label()); | 182 GetCleanedString(address_dict, kAddressLabelField, type->mutable_label()); |
168 } | 183 } |
169 | 184 |
170 // Maps the protocol from a dictionary representing a contact's IM address to a | 185 // Maps the protocol from a dictionary representing a contact's IM address to a |
171 // contacts::Contact_InstantMessagingAddress_Protocol value. | 186 // contacts::Contact_InstantMessagingAddress_Protocol value. |
172 contacts::Contact_InstantMessagingAddress_Protocol | 187 contacts::Contact_InstantMessagingAddress_Protocol |
173 GetInstantMessagingProtocol(const DictionaryValue& im_dict) { | 188 GetInstantMessagingProtocol(const DictionaryValue& im_dict) { |
174 std::string protocol; | 189 std::string protocol; |
175 im_dict.GetString(kInstantMessagingProtocolField, &protocol); | 190 im_dict.GetString(kInstantMessagingProtocolField, &protocol); |
176 if (protocol == kInstantMessagingProtocolAimValue) | 191 if (protocol == kInstantMessagingProtocolAimValue) |
177 return contacts::Contact_InstantMessagingAddress_Protocol_AIM; | 192 return contacts::Contact_InstantMessagingAddress_Protocol_AIM; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 return false; | 256 return false; |
242 } | 257 } |
243 contact->set_update_time(update_time.ToInternalValue()); | 258 contact->set_update_time(update_time.ToInternalValue()); |
244 } | 259 } |
245 | 260 |
246 const base::Value* deleted_value = NULL; | 261 const base::Value* deleted_value = NULL; |
247 contact->set_deleted(dict.Get(kDeletedField, &deleted_value)); | 262 contact->set_deleted(dict.Get(kDeletedField, &deleted_value)); |
248 if (contact->deleted()) | 263 if (contact->deleted()) |
249 return true; | 264 return true; |
250 | 265 |
251 dict.GetString(kFullNameField, contact->mutable_full_name()); | 266 GetCleanedString(dict, kFullNameField, contact->mutable_full_name()); |
252 dict.GetString(kGivenNameField, contact->mutable_given_name()); | 267 GetCleanedString(dict, kGivenNameField, contact->mutable_given_name()); |
253 dict.GetString(kAdditionalNameField, contact->mutable_additional_name()); | 268 GetCleanedString( |
254 dict.GetString(kFamilyNameField, contact->mutable_family_name()); | 269 dict, kAdditionalNameField, contact->mutable_additional_name()); |
255 dict.GetString(kNamePrefixField, contact->mutable_name_prefix()); | 270 GetCleanedString(dict, kFamilyNameField, contact->mutable_family_name()); |
256 dict.GetString(kNameSuffixField, contact->mutable_name_suffix()); | 271 GetCleanedString(dict, kNamePrefixField, contact->mutable_name_prefix()); |
| 272 GetCleanedString(dict, kNameSuffixField, contact->mutable_name_suffix()); |
257 | 273 |
258 const ListValue* email_list = NULL; | 274 const ListValue* email_list = NULL; |
259 if (dict.GetList(kEmailField, &email_list)) { | 275 if (dict.GetList(kEmailField, &email_list)) { |
260 for (size_t i = 0; i < email_list->GetSize(); ++i) { | 276 for (size_t i = 0; i < email_list->GetSize(); ++i) { |
261 const DictionaryValue* email_dict = NULL; | 277 const DictionaryValue* email_dict = NULL; |
262 if (!email_list->GetDictionary(i, &email_dict)) | 278 if (!email_list->GetDictionary(i, &email_dict)) |
263 return false; | 279 return false; |
264 | 280 |
265 contacts::Contact_EmailAddress* email = contact->add_email_addresses(); | 281 contacts::Contact_EmailAddress* email = contact->add_email_addresses(); |
266 if (!email_dict->GetString(kEmailAddressField, email->mutable_address())) | 282 if (!GetCleanedString(*email_dict, |
| 283 kEmailAddressField, |
| 284 email->mutable_address())) { |
267 return false; | 285 return false; |
| 286 } |
268 email->set_primary(IsAddressPrimary(*email_dict)); | 287 email->set_primary(IsAddressPrimary(*email_dict)); |
269 InitAddressType(*email_dict, email->mutable_type()); | 288 InitAddressType(*email_dict, email->mutable_type()); |
270 } | 289 } |
271 } | 290 } |
272 | 291 |
273 const ListValue* phone_list = NULL; | 292 const ListValue* phone_list = NULL; |
274 if (dict.GetList(kPhoneField, &phone_list)) { | 293 if (dict.GetList(kPhoneField, &phone_list)) { |
275 for (size_t i = 0; i < phone_list->GetSize(); ++i) { | 294 for (size_t i = 0; i < phone_list->GetSize(); ++i) { |
276 const DictionaryValue* phone_dict = NULL; | 295 const DictionaryValue* phone_dict = NULL; |
277 if (!phone_list->GetDictionary(i, &phone_dict)) | 296 if (!phone_list->GetDictionary(i, &phone_dict)) |
278 return false; | 297 return false; |
279 | 298 |
280 contacts::Contact_PhoneNumber* phone = contact->add_phone_numbers(); | 299 contacts::Contact_PhoneNumber* phone = contact->add_phone_numbers(); |
281 if (!phone_dict->GetString(kPhoneNumberField, phone->mutable_number())) | 300 if (!GetCleanedString(*phone_dict, |
| 301 kPhoneNumberField, |
| 302 phone->mutable_number())) { |
282 return false; | 303 return false; |
| 304 } |
283 phone->set_primary(IsAddressPrimary(*phone_dict)); | 305 phone->set_primary(IsAddressPrimary(*phone_dict)); |
284 InitAddressType(*phone_dict, phone->mutable_type()); | 306 InitAddressType(*phone_dict, phone->mutable_type()); |
285 } | 307 } |
286 } | 308 } |
287 | 309 |
288 const ListValue* address_list = NULL; | 310 const ListValue* address_list = NULL; |
289 if (dict.GetList(kPostalAddressField, &address_list)) { | 311 if (dict.GetList(kPostalAddressField, &address_list)) { |
290 for (size_t i = 0; i < address_list->GetSize(); ++i) { | 312 for (size_t i = 0; i < address_list->GetSize(); ++i) { |
291 const DictionaryValue* address_dict = NULL; | 313 const DictionaryValue* address_dict = NULL; |
292 if (!address_list->GetDictionary(i, &address_dict)) | 314 if (!address_list->GetDictionary(i, &address_dict)) |
293 return false; | 315 return false; |
294 | 316 |
295 contacts::Contact_PostalAddress* address = | 317 contacts::Contact_PostalAddress* address = |
296 contact->add_postal_addresses(); | 318 contact->add_postal_addresses(); |
297 if (!address_dict->GetString(kPostalAddressFormattedField, | 319 if (!GetCleanedString(*address_dict, |
298 address->mutable_address())) { | 320 kPostalAddressFormattedField, |
| 321 address->mutable_address())) { |
299 return false; | 322 return false; |
300 } | 323 } |
301 address->set_primary(IsAddressPrimary(*address_dict)); | 324 address->set_primary(IsAddressPrimary(*address_dict)); |
302 InitAddressType(*address_dict, address->mutable_type()); | 325 InitAddressType(*address_dict, address->mutable_type()); |
303 } | 326 } |
304 } | 327 } |
305 | 328 |
306 const ListValue* im_list = NULL; | 329 const ListValue* im_list = NULL; |
307 if (dict.GetList(kInstantMessagingField, &im_list)) { | 330 if (dict.GetList(kInstantMessagingField, &im_list)) { |
308 for (size_t i = 0; i < im_list->GetSize(); ++i) { | 331 for (size_t i = 0; i < im_list->GetSize(); ++i) { |
309 const DictionaryValue* im_dict = NULL; | 332 const DictionaryValue* im_dict = NULL; |
310 if (!im_list->GetDictionary(i, &im_dict)) | 333 if (!im_list->GetDictionary(i, &im_dict)) |
311 return false; | 334 return false; |
312 | 335 |
313 contacts::Contact_InstantMessagingAddress* im = | 336 contacts::Contact_InstantMessagingAddress* im = |
314 contact->add_instant_messaging_addresses(); | 337 contact->add_instant_messaging_addresses(); |
315 if (!im_dict->GetString(kInstantMessagingAddressField, | 338 if (!GetCleanedString(*im_dict, |
316 im->mutable_address())) { | 339 kInstantMessagingAddressField, |
| 340 im->mutable_address())) { |
317 return false; | 341 return false; |
318 } | 342 } |
319 im->set_primary(IsAddressPrimary(*im_dict)); | 343 im->set_primary(IsAddressPrimary(*im_dict)); |
320 InitAddressType(*im_dict, im->mutable_type()); | 344 InitAddressType(*im_dict, im->mutable_type()); |
321 im->set_protocol(GetInstantMessagingProtocol(*im_dict)); | 345 im->set_protocol(GetInstantMessagingProtocol(*im_dict)); |
322 } | 346 } |
323 } | 347 } |
324 | 348 |
325 return true; | 349 return true; |
326 } | 350 } |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
783 DCHECK(request); | 807 DCHECK(request); |
784 VLOG(1) << "Download request " << request << " complete"; | 808 VLOG(1) << "Download request " << request << " complete"; |
785 if (!request->my_contacts_group_id().empty()) | 809 if (!request->my_contacts_group_id().empty()) |
786 cached_my_contacts_group_id_ = request->my_contacts_group_id(); | 810 cached_my_contacts_group_id_ = request->my_contacts_group_id(); |
787 requests_.erase(request); | 811 requests_.erase(request); |
788 delete request; | 812 delete request; |
789 } | 813 } |
790 | 814 |
791 } // namespace contacts | 815 } // namespace contacts |
OLD | NEW |