| 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;
 | 
| -}
 | 
| 
 |