| // Copyright 2013 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 "components/omnibox/browser/omnibox_controller.h" | 
 |  | 
 | #include "base/bind.h" | 
 | #include "base/metrics/histogram.h" | 
 | #include "components/omnibox/browser/autocomplete_classifier.h" | 
 | #include "components/omnibox/browser/autocomplete_match.h" | 
 | #include "components/omnibox/browser/omnibox_client.h" | 
 | #include "components/omnibox/browser/omnibox_controller_emitter.h" | 
 | #include "components/omnibox/browser/omnibox_edit_controller.h" | 
 | #include "components/omnibox/browser/omnibox_edit_model.h" | 
 | #include "components/omnibox/browser/omnibox_popup_model.h" | 
 | #include "components/omnibox/browser/omnibox_popup_view.h" | 
 | #include "ui/gfx/geometry/rect.h" | 
 |  | 
 | OmniboxController::OmniboxController(OmniboxEditModel* omnibox_edit_model, | 
 |                                      OmniboxClient* client) | 
 |     : omnibox_edit_model_(omnibox_edit_model), | 
 |       client_(client), | 
 |       popup_(nullptr), | 
 |       autocomplete_controller_(new AutocompleteController( | 
 |           client_->CreateAutocompleteProviderClient(), | 
 |           AutocompleteClassifier::DefaultOmniboxProviders())) { | 
 |   autocomplete_controller_->AddObserver(this); | 
 |  | 
 |   OmniboxControllerEmitter* emitter = client_->GetOmniboxControllerEmitter(); | 
 |   if (emitter) | 
 |     autocomplete_controller_->AddObserver(emitter); | 
 | } | 
 |  | 
 | OmniboxController::~OmniboxController() { | 
 | } | 
 |  | 
 | void OmniboxController::StartAutocomplete( | 
 |     const AutocompleteInput& input) const { | 
 |   ClearPopupKeywordMode(); | 
 |  | 
 |   // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as | 
 |   // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. | 
 |   autocomplete_controller_->Start(input); | 
 | } | 
 |  | 
 | void OmniboxController::OnResultChanged(AutocompleteController* controller, | 
 |                                         bool default_match_changed) { | 
 |   DCHECK(controller == autocomplete_controller_.get()); | 
 |  | 
 |   const bool was_open = popup_ && popup_->IsOpen(); | 
 |   if (default_match_changed) { | 
 |     // The default match has changed, we need to let the OmniboxEditModel know | 
 |     // about new inline autocomplete text (blue highlight). | 
 |     if (auto* match = result().default_match()) { | 
 |       current_match_ = *match; | 
 |       omnibox_edit_model_->OnCurrentMatchChanged(); | 
 |     } else { | 
 |       InvalidateCurrentMatch(); | 
 |       if (popup_) | 
 |         popup_->OnResultChanged(); | 
 |       omnibox_edit_model_->OnPopupDataChanged(base::string16(), | 
 |                                               /*is_temporary_text=*/false, | 
 |                                               base::string16(), false); | 
 |     } | 
 |   } else if (popup_) { | 
 |     popup_->OnResultChanged(); | 
 |   } | 
 |  | 
 |   if (was_open && !popup_->IsOpen()) { | 
 |     // Accept the temporary text as the user text, because it makes little sense | 
 |     // to have temporary text when the popup is closed. | 
 |     omnibox_edit_model_->AcceptTemporaryTextAsUserText(); | 
 |   } | 
 |  | 
 |   // Note: The client outlives |this|, so bind a weak pointer to the callback | 
 |   // passed in to eliminate the potential for crashes on shutdown. | 
 |   client_->OnResultChanged( | 
 |       result(), default_match_changed, | 
 |       base::BindRepeating(&OmniboxController::SetRichSuggestionBitmap, | 
 |                           weak_ptr_factory_.GetWeakPtr())); | 
 | } | 
 |  | 
 | void OmniboxController::InvalidateCurrentMatch() { | 
 |   current_match_ = AutocompleteMatch(); | 
 | } | 
 |  | 
 | void OmniboxController::ClearPopupKeywordMode() const { | 
 |   // |popup_| can be nullptr in tests. | 
 |   if (popup_ && popup_->IsOpen() && | 
 |       popup_->selected_line_state() == OmniboxPopupModel::KEYWORD) { | 
 |     popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL); | 
 |   } | 
 | } | 
 |  | 
 | void OmniboxController::SetRichSuggestionBitmap(int result_index, | 
 |                                                 const SkBitmap& bitmap) { | 
 |   popup_->SetRichSuggestionBitmap(result_index, bitmap); | 
 | } |