Index: chrome/browser/autocomplete/contact_provider_chromeos.cc |
diff --git a/chrome/browser/autocomplete/contact_provider_chromeos.cc b/chrome/browser/autocomplete/contact_provider_chromeos.cc |
deleted file mode 100644 |
index 7a37bf0717e59c5a949b11786ace4052810e0d5f..0000000000000000000000000000000000000000 |
--- a/chrome/browser/autocomplete/contact_provider_chromeos.cc |
+++ /dev/null |
@@ -1,236 +0,0 @@ |
-// Copyright (c) 2012 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. |
- |
-#include "chrome/browser/autocomplete/contact_provider_chromeos.h" |
- |
-#include <algorithm> |
-#include <cmath> |
- |
-#include "base/i18n/break_iterator.h" |
-#include "base/i18n/string_search.h" |
-#include "base/strings/string16.h" |
-#include "base/strings/string_split.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "chrome/browser/autocomplete/autocomplete_input.h" |
-#include "chrome/browser/chromeos/contacts/contact.pb.h" |
-#include "chrome/browser/chromeos/contacts/contact_manager.h" |
-#include "chrome/browser/profiles/profile.h" |
- |
-namespace { |
- |
-// Default affinity assigned to contacts whose |affinity| field is unset. |
-// TODO(derat): Set this to something reasonable (probably 0.0) once we're |
-// getting affinity for contacts. |
-float kDefaultAffinity = 1.0; |
- |
-// Base match relevance assigned to a contact with an affinity of 0.0. |
-int kBaseRelevance = 1300; |
- |
-// Maximum boost to relevance for a contact with an affinity of 1.0. |
-int kAffinityRelevanceBoost = 200; |
- |
-// Returns true if |word_to_find| is a prefix of |name_to_search| and marks the |
-// matching text in |classifications| (which corresponds to the contact's full |
-// name). |name_index_in_full_name| contains |name_to_search|'s index within |
-// the full name or base::string16::npos if it doesn't appear in it. |
-bool WordIsNamePrefix(const base::string16& word_to_find, |
- const base::string16& name_to_search, |
- size_t name_index_in_full_name, |
- size_t full_name_length, |
- ACMatchClassifications* classifications) { |
- DCHECK(classifications); |
- |
- size_t match_index = 0; |
- size_t match_length = 0; |
- if (!base::i18n::StringSearchIgnoringCaseAndAccents(word_to_find, |
- name_to_search, &match_index, &match_length) || (match_index != 0)) |
- return false; |
- |
- if (name_index_in_full_name != base::string16::npos) { |
- AutocompleteMatch::ACMatchClassifications new_class; |
- AutocompleteMatch::ClassifyLocationInString(name_index_in_full_name, |
- match_length, full_name_length, 0, &new_class); |
- *classifications = AutocompleteMatch::MergeClassifications( |
- *classifications, new_class); |
- } |
- |
- return true; |
-} |
- |
-} // namespace |
- |
-// static |
-const char ContactProvider::kMatchContactIdKey[] = "contact_id"; |
- |
-// Cached information about a contact. |
-struct ContactProvider::ContactData { |
- ContactData(const base::string16& full_name, |
- const base::string16& given_name, |
- const base::string16& family_name, |
- const std::string& contact_id, |
- float affinity) |
- : full_name(full_name), |
- given_name(given_name), |
- family_name(family_name), |
- given_name_index(base::string16::npos), |
- family_name_index(base::string16::npos), |
- contact_id(contact_id), |
- affinity(affinity) { |
- base::i18n::StringSearchIgnoringCaseAndAccents( |
- given_name, full_name, &given_name_index, NULL); |
- base::i18n::StringSearchIgnoringCaseAndAccents( |
- family_name, full_name, &family_name_index, NULL); |
- } |
- |
- base::string16 full_name; |
- base::string16 given_name; |
- base::string16 family_name; |
- |
- // Indices into |full_name| where |given_name| and |family_name| first appear, |
- // or base::string16::npos if they don't appear in it. |
- size_t given_name_index; |
- size_t family_name_index; |
- |
- // Unique ID used to look up additional contact information. |
- std::string contact_id; |
- |
- // Affinity between the user and this contact, in the range [0.0, 1.0]. |
- float affinity; |
-}; |
- |
-ContactProvider::ContactProvider( |
- AutocompleteProviderListener* listener, |
- Profile* profile, |
- base::WeakPtr<contacts::ContactManagerInterface> contact_manager) |
- : AutocompleteProvider(listener, profile, TYPE_CONTACT), |
- contact_manager_(contact_manager) { |
- contact_manager_->AddObserver(this, profile); |
- RefreshContacts(); |
-} |
- |
-void ContactProvider::Start(const AutocompleteInput& input, |
- bool minimal_changes) { |
- if (minimal_changes) |
- return; |
- |
- matches_.clear(); |
- |
- if (input.type() != AutocompleteInput::UNKNOWN && |
- input.type() != AutocompleteInput::QUERY && |
- input.type() != AutocompleteInput::FORCED_QUERY) |
- return; |
- |
- std::vector<base::string16> input_words; |
- base::i18n::BreakIterator break_iterator( |
- input.text(), |
- base::i18n::BreakIterator::BREAK_WORD); |
- if (break_iterator.Init()) { |
- while (break_iterator.Advance()) { |
- if (break_iterator.IsWord()) |
- input_words.push_back(break_iterator.GetString()); |
- } |
- } |
- |
- // |contacts_| is ordered by descending affinity. Since affinity is currently |
- // the only signal used for computing relevance, we can stop after we've found |
- // kMaxMatches results. |
- for (ContactDataVector::const_iterator it = contacts_.begin(); |
- it != contacts_.end() && matches_.size() < kMaxMatches; ++it) |
- AddContactIfMatched(input, input_words, *it); |
-} |
- |
-void ContactProvider::OnContactsUpdated(Profile* profile) { |
- DCHECK_EQ(profile, profile_); |
- RefreshContacts(); |
-} |
- |
-ContactProvider::~ContactProvider() { |
- // Like ContactProvider, ContactManager gets destroyed at profile destruction. |
- // Make sure that this class doesn't try to access ContactManager after |
- // ContactManager is gone. |
- if (contact_manager_.get()) |
- contact_manager_->RemoveObserver(this, profile_); |
-} |
- |
-// static |
-bool ContactProvider::CompareAffinity(const ContactData& a, |
- const ContactData& b) { |
- return a.affinity > b.affinity; |
-} |
- |
-void ContactProvider::RefreshContacts() { |
- if (!contact_manager_.get()) |
- return; |
- |
- scoped_ptr<contacts::ContactPointers> contacts = |
- contact_manager_->GetAllContacts(profile_); |
- |
- contacts_.clear(); |
- contacts_.reserve(contacts->size()); |
- for (contacts::ContactPointers::const_iterator it = contacts->begin(); |
- it != contacts->end(); ++it) { |
- const contacts::Contact& contact = **it; |
- base::string16 full_name = AutocompleteMatch::SanitizeString( |
- base::UTF8ToUTF16(contact.full_name())); |
- base::string16 given_name = AutocompleteMatch::SanitizeString( |
- base::UTF8ToUTF16(contact.given_name())); |
- base::string16 family_name = AutocompleteMatch::SanitizeString( |
- base::UTF8ToUTF16(contact.family_name())); |
- float affinity = |
- contact.has_affinity() ? contact.affinity() : kDefaultAffinity; |
- |
- if (!full_name.empty()) { |
- contacts_.push_back( |
- ContactData(full_name, given_name, family_name, contact.contact_id(), |
- affinity)); |
- } |
- } |
- std::sort(contacts_.begin(), contacts_.end(), CompareAffinity); |
-} |
- |
-void ContactProvider::AddContactIfMatched( |
- const AutocompleteInput& input, |
- const std::vector<base::string16>& input_words, |
- const ContactData& contact) { |
- // First, check if the whole input string is a prefix of the full name. |
- // TODO(derat): Consider additionally segmenting the full name so we can match |
- // e.g. middle names or initials even when they aren't typed as a prefix of |
- // the full name. |
- ACMatchClassifications classifications; |
- if (!WordIsNamePrefix(input.text(), contact.full_name, 0, |
- contact.full_name.size(), &classifications)) { |
- // If not, check whether every search term is a prefix of the given name |
- // or the family name. |
- if (input_words.empty()) |
- return; |
- |
- // TODO(derat): Check new matches against previous ones to make sure they |
- // don't overlap (e.g. the query "bob b" against a contact with full name |
- // "Bob G. Bryson", given name "Bob", and family name "Bryson" should result |
- // in classifications "_Bob_ G. _B_ryson" rather than "_Bob_ G. Bryson". |
- for (std::vector<base::string16>::const_iterator it = input_words.begin(); |
- it != input_words.end(); ++it) { |
- if (!WordIsNamePrefix(*it, contact.given_name, contact.given_name_index, |
- contact.full_name.size(), &classifications) && |
- !WordIsNamePrefix(*it, contact.family_name, contact.family_name_index, |
- contact.full_name.size(), &classifications)) |
- return; |
- } |
- } |
- |
- matches_.push_back(CreateAutocompleteMatch(input, contact)); |
- matches_.back().contents_class = classifications; |
-} |
- |
-AutocompleteMatch ContactProvider::CreateAutocompleteMatch( |
- const AutocompleteInput& input, |
- const ContactData& contact) { |
- AutocompleteMatch match(this, 0, false, AutocompleteMatchType::CONTACT); |
- match.contents = contact.full_name; |
- match.fill_into_edit = match.contents; |
- match.relevance = kBaseRelevance + |
- static_cast<int>(roundf(kAffinityRelevanceBoost * contact.affinity)); |
- match.RecordAdditionalInfo(kMatchContactIdKey, contact.contact_id); |
- return match; |
-} |