Commit message: None
CVE: CVE-2016-5220
CWE: CWE-200
Vulnerability description: PDFium in Google Chrome prior to 55.0.2883.75 for Mac, Windows and Linux, and 55.0.2883.84 for Android incorrectly handled navigation within PDFs, which allowed a remote attacker to read local files via a crafted PDF file.

Project: Chrome

void OmniboxViewViews::ApplyCaretVisibility() {
  SetCursorEnabled(model()->is_caret_visible());

  if (location_bar_view_)
    location_bar_view_->OnOmniboxFocused();
}

Project: Chrome

void OmniboxViewViews::ClearAccessibilityLabel() {
  friendly_suggestion_text_.clear();
  friendly_suggestion_text_prefix_length_ = 0;
}

Project: Chrome

bool OmniboxViewViews::DirectionAwareSelectionAtEnd() const {
  return TextAndUIDirectionMatch() ? SelectionAtEnd() : SelectionAtBeginning();
}

Project: Chrome

void OmniboxViewViews::DoInsertChar(base::char16 ch) {
  if ((model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE) &&
      base::IsUnicodeWhitespace(ch)) {
    return;
  }

  if (insert_char_time_.is_null()) {
    DCHECK_EQ(latency_histogram_state_, NOT_ACTIVE);
    latency_histogram_state_ = CHAR_TYPED;
    insert_char_time_ = base::TimeTicks::Now();
  }
  Textfield::DoInsertChar(ch);
}

Project: Chrome

void OmniboxViewViews::EmphasizeURLComponents() {
  if (!location_bar_view_)
    return;

  if (path_fade_animation_)
    path_fade_animation_->Stop();

  bool text_is_url = model()->CurrentTextIsURL();
  GetRenderText()->SetDirectionalityMode(
      text_is_url ? gfx::DIRECTIONALITY_AS_URL : gfx::DIRECTIONALITY_FROM_TEXT);
  SetStyle(gfx::TEXT_STYLE_STRIKE, false);

  base::string16 text = GetText();
  bool path_eligible_for_fading = UpdateTextStyle(
      text, text_is_url, model()->client()->GetSchemeClassifier());

  if (path_fade_animation_ && path_eligible_for_fading && !HasFocus() &&
      !model()->user_input_in_progress()) {
    url::Component scheme, host;
    AutocompleteInput::ParseForEmphasizeComponents(
        text, model()->client()->GetSchemeClassifier(), &scheme, &host);
    gfx::Range path_bounds(host.end(), text.size());

    path_fade_animation_->Start(path_bounds);
  }
}

Project: Chrome

void OmniboxViewViews::EnterKeywordModeForDefaultSearchProvider() {
  model()->EnterKeywordModeForDefaultSearchProvider(
      OmniboxEventProto::KEYBOARD_SHORTCUT);
}

Project: Chrome

void OmniboxViewViews::ExecuteCommand(int command_id, int event_flags) {
  DestroyTouchSelection();
  switch (command_id) {
    case IDC_PASTE_AND_GO:
      model()->PasteAndGo(GetClipboardText());
      return;
    case IDS_SHOW_URL:
      model()->Unelide(true /* exit_query_in_omnibox */);
      return;
    case IDC_EDIT_SEARCH_ENGINES:
      location_bar_view_->command_updater()->ExecuteCommand(command_id);
      return;
    case IDC_SEND_TAB_TO_SELF:
      send_tab_to_self::RecordSendTabToSelfClickResult(
          send_tab_to_self::kOmniboxMenu, SendTabToSelfClickResult::kClickItem);
      send_tab_to_self::CreateNewEntry(location_bar_view_->GetWebContents());
      return;

    case IDS_APP_PASTE:
      ExecuteTextEditCommand(ui::TextEditCommand::PASTE);
      return;
    default:
      if (Textfield::IsCommandIdEnabled(command_id)) {
        Textfield::ExecuteCommand(command_id, event_flags);
        return;
      }
      OnBeforePossibleChange();
      location_bar_view_->command_updater()->ExecuteCommand(command_id);
      OnAfterPossibleChange(true);
      return;
  }
}

Project: Chrome

void OmniboxViewViews::ExecuteTextEditCommand(ui::TextEditCommand command) {
  DestroyTouchSelection();

  if (!IsTextEditCommandEnabled(command))
    return;

  switch (command) {
    case ui::TextEditCommand::MOVE_UP:
      model()->OnUpOrDownKeyPressed(-1);
      break;
    case ui::TextEditCommand::MOVE_DOWN:
      model()->OnUpOrDownKeyPressed(1);
      break;
    case ui::TextEditCommand::PASTE:
      OnPaste();
      break;
    default:
      Textfield::ExecuteTextEditCommand(command);
      break;
  }
 }

Project: Chrome

base::string16 OmniboxViewViews::GetLabelForCommandId(int command_id) const {
  DCHECK_EQ(IDC_PASTE_AND_GO, command_id);

  constexpr size_t kMaxSelectionTextLength = 50;
  const base::string16 clipboard_text = GetClipboardText();

  base::string16 selection_text = gfx::TruncateString(
      clipboard_text, kMaxSelectionTextLength, gfx::WORD_BREAK);

  if (model()->ClassifiesAsSearch(clipboard_text))
    return l10n_util::GetStringFUTF16(IDS_PASTE_AND_SEARCH, selection_text);

  const float kMaxSelectionPixelWidth = GetStringWidthF(
      selection_text, Textfield::GetFontList(), gfx::Typesetter::BROWSER);
  base::string16 url = url_formatter::ElideUrl(
      GURL(clipboard_text), Textfield::GetFontList(), kMaxSelectionPixelWidth,
      gfx::Typesetter::BROWSER);

  return l10n_util::GetStringFUTF16(IDS_PASTE_AND_GO, url);
}

Project: Chrome

ui::TextInputType OmniboxViewViews::GetTextInputType() const {
  ui::TextInputType input_type = views::Textfield::GetTextInputType();
#if defined(OS_WIN)
  if (input_type != ui::TEXT_INPUT_TYPE_NONE && location_bar_view_) {
    ui::InputMethod* input_method =
        location_bar_view_->GetWidget()->GetInputMethod();
    if (input_method && input_method->IsInputLocaleCJK())
      return ui::TEXT_INPUT_TYPE_SEARCH;
  }
#endif
  return input_type;
}

Project: Chrome

int OmniboxViewViews::GetWidth() const {
  return location_bar_view_ ? location_bar_view_->width() : 0;
}

Project: Chrome

bool OmniboxViewViews::HandleAccessibleAction(
    const ui::AXActionData& action_data) {
  if (read_only())
    return Textfield::HandleAccessibleAction(action_data);

  if (action_data.action == ax::mojom::Action::kSetValue) {
    SetUserText(base::UTF8ToUTF16(action_data.value), true);
    return true;
  } else if (action_data.action == ax::mojom::Action::kReplaceSelectedText) {
    model()->SetInputInProgress(true);
    if (saved_selection_for_focus_change_.IsValid()) {
      SelectRange(saved_selection_for_focus_change_);
      saved_selection_for_focus_change_ = gfx::Range::InvalidRange();
    }
    InsertOrReplaceText(base::UTF8ToUTF16(action_data.value));
    TextChanged();
    return true;
  } else if (action_data.action == ax::mojom::Action::kSetSelection) {
    ui::AXActionData set_selection_action_data;
    set_selection_action_data.action = ax::mojom::Action::kSetSelection;
    set_selection_action_data.anchor_node_id = action_data.anchor_node_id;
    set_selection_action_data.focus_offset =
        action_data.focus_offset - friendly_suggestion_text_prefix_length_;
    set_selection_action_data.anchor_offset =
        action_data.anchor_offset - friendly_suggestion_text_prefix_length_;
    return Textfield::HandleAccessibleAction(set_selection_action_data);
  }

  return Textfield::HandleAccessibleAction(action_data);
}

Project: Chrome

bool OmniboxViewViews::HandleEarlyTabActions(const ui::KeyEvent& event) {
  if (!views::FocusManager::IsTabTraversalKeyEvent(event))
    return false;

  if (model()->is_keyword_hint() && !event.IsShiftDown())
    return model()->AcceptKeyword(OmniboxEventProto::TAB);

  if (!model()->popup_model()->IsOpen())
    return false;

  if (event.IsShiftDown() && (model()->popup_model()->selected_line_state() ==
                              OmniboxPopupModel::KEYWORD)) {
    model()->ClearKeyword();
    return true;
  }

  if (!event.IsShiftDown()) {
    if (MaybeFocusTabButton())
      return true;
  }

  if (event.IsShiftDown()) {
    if (MaybeUnfocusTabButton())
      return true;

    if (model()->popup_model()->selected_line() == 0)
      return false;
  }

  model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1);
  if (event.IsShiftDown() &&
      model()->popup_model()->SelectedLineHasButton()) {
    model()->popup_model()->SetSelectedLineState(
        OmniboxPopupModel::BUTTON_FOCUSED);
    popup_view_->ProvideButtonFocusHint(
        model()->popup_model()->selected_line());
  }

  return true;
}

Project: Chrome

bool OmniboxViewViews::HandleKeyEvent(views::Textfield* textfield,
                                      const ui::KeyEvent& event) {
  if (event.type() == ui::ET_KEY_RELEASED) {
    if (event.key_code() == ui::VKEY_CONTROL)
      model()->OnControlKeyChanged(false);

    return false;
  }

  if (event.IsUnicodeKeyCode())
    return false;

  const bool shift = event.IsShiftDown();
  const bool control = event.IsControlDown();
  const bool alt = event.IsAltDown() || event.IsAltGrDown();
  const bool command = event.IsCommandDown();
  switch (event.key_code()) {
    case ui::VKEY_RETURN:
      if (model()->popup_model()->selected_line_state() ==
          OmniboxPopupModel::BUTTON_FOCUSED) {
        if (!(OmniboxFieldTrial::IsTabSwitchLogicReversed() &&
              model()->popup_model()->SelectedLineHasTabMatch())) {
          popup_view_->OpenMatch(WindowOpenDisposition::SWITCH_TO_TAB,
                                 event.time_stamp());
        } else {
          popup_view_->OpenMatch(WindowOpenDisposition::CURRENT_TAB,
                                 event.time_stamp());
        }
      } else {
        if (alt || (shift && command)) {
          model()->AcceptInput(WindowOpenDisposition::NEW_FOREGROUND_TAB, false,
                               event.time_stamp());
        } else if (command) {
          model()->AcceptInput(WindowOpenDisposition::NEW_BACKGROUND_TAB, false,
                               event.time_stamp());
        } else if (shift) {
          model()->AcceptInput(WindowOpenDisposition::NEW_WINDOW, false,
                               event.time_stamp());
        } else {
          if (!(OmniboxFieldTrial::IsTabSwitchLogicReversed() &&
                model()->popup_model()->SelectedLineHasTabMatch())) {
            model()->AcceptInput(WindowOpenDisposition::CURRENT_TAB, false,
                                 event.time_stamp());
          } else {
            model()->AcceptInput(WindowOpenDisposition::SWITCH_TO_TAB, false,
                                 event.time_stamp());
          }
        }
      }
      return true;

    case ui::VKEY_ESCAPE:
      return model()->OnEscapeKeyPressed();

    case ui::VKEY_CONTROL:
      model()->OnControlKeyChanged(true);
      break;

    case ui::VKEY_DELETE:
      if (shift && model()->popup_model()->IsOpen()) {
        model()->popup_model()->TryDeletingLine(
            model()->popup_model()->selected_line());
      }
      break;

    case ui::VKEY_UP:
      if (shift)
        return false;

      if (IsTextEditCommandEnabled(ui::TextEditCommand::MOVE_UP)) {
        ExecuteTextEditCommand(ui::TextEditCommand::MOVE_UP);
        return true;
      }
      break;

    case ui::VKEY_DOWN:
      if (shift)
        return false;

      if (IsTextEditCommandEnabled(ui::TextEditCommand::MOVE_DOWN)) {
        ExecuteTextEditCommand(ui::TextEditCommand::MOVE_DOWN);
        return true;
      }
      break;

    case ui::VKEY_PRIOR:
      if (control || alt || shift || read_only())
        return false;
      model()->OnUpOrDownKeyPressed(-1 * model()->result().size());
      return true;

    case ui::VKEY_NEXT:
      if (control || alt || shift || read_only())
        return false;
      model()->OnUpOrDownKeyPressed(model()->result().size());
      return true;

    case ui::VKEY_RIGHT:
    case ui::VKEY_LEFT:
      if (control || alt || shift)
        return false;

      if (base::i18n::IsRTL() == (event.key_code() == ui::VKEY_LEFT)) {
        if (!DirectionAwareSelectionAtEnd())
          return false;

        if (OmniboxFieldTrial::IsExperimentalKeywordModeEnabled() &&
            model()->is_keyword_hint()) {
          OnBeforePossibleChange();
          model()->AcceptKeyword(OmniboxEventProto::SELECT_SUGGESTION);
          OnAfterPossibleChange(true);
          return true;
        } else if (MaybeFocusTabButton()) {
          return true;
        }
      } else if (MaybeUnfocusTabButton()) {
        return true;
      }
      break;

    case ui::VKEY_V:
      if (control && !alt &&
          IsTextEditCommandEnabled(ui::TextEditCommand::PASTE)) {
        ExecuteTextEditCommand(ui::TextEditCommand::PASTE);
        return true;
      }
      break;

    case ui::VKEY_INSERT:
      if (shift && !control &&
          IsTextEditCommandEnabled(ui::TextEditCommand::PASTE)) {
        ExecuteTextEditCommand(ui::TextEditCommand::PASTE);
        return true;
      }
      break;

    case ui::VKEY_BACK:
      if (model()->is_keyword_hint() || model()->keyword().empty() ||
          HasSelection() || GetCursorPosition() != 0)
        return false;
      model()->ClearKeyword();
      return true;

    case ui::VKEY_HOME:
      if (UnapplySteadyStateElisions(UnelisionGesture::HOME_KEY_PRESSED)) {
        if (shift) {
          size_t start, end;
          GetSelectionBounds(&start, &end);
          SelectRange(gfx::Range(start, 0));
        } else {
          SetCaretPos(0);
        }

        TextChanged();
        return true;
      }
      break;

    case ui::VKEY_SPACE:
      if (!(control || alt || shift)) {
        if (SelectionAtEnd() &&
            model()->popup_model()->selected_line_state() ==
                OmniboxPopupModel::BUTTON_FOCUSED) {
          popup_view_->OpenMatch(WindowOpenDisposition::SWITCH_TO_TAB,
                                 event.time_stamp());
          return true;
        }
      }
      break;

    default:
      break;
  }

  return HandleEarlyTabActions(event);
}

Project: Chrome

void OmniboxViewViews::HideImeIfNeeded() {
  if (auto* input_method = GetInputMethod()) {
    if (auto* keyboard = input_method->GetInputMethodKeyboardController())
      keyboard->DismissVirtualKeyboard();
  }
}

Project: Chrome

void OmniboxViewViews::Init() {
  set_controller(this);
  SetTextInputType(ui::TEXT_INPUT_TYPE_URL);
  GetRenderText()->SetElideBehavior(gfx::ELIDE_TAIL);
  GetRenderText()->set_symmetric_selection_visual_bounds(true);

  if (popup_window_mode_)
    SetReadOnly(true);

  if (location_bar_view_) {
    InstallPlaceholderText();
    scoped_template_url_service_observer_.Add(
        model()->client()->GetTemplateURLService());

    popup_view_.reset(
        new OmniboxPopupContentsView(this, model(), location_bar_view_));
  }

  constexpr gfx::Insets kTextfieldInsets(3);
  SetBorder(views::CreateEmptyBorder(kTextfieldInsets));

#if defined(OS_CHROMEOS)
  chromeos::input_method::InputMethodManager::Get()->
      AddCandidateWindowObserver(this);
#endif
}

Project: Chrome

void OmniboxViewViews::InstallPlaceholderText() {
  set_placeholder_text_color(
      location_bar_view_->GetColor(OmniboxPart::LOCATION_BAR_TEXT_DIMMED));

  const TemplateURL* const default_provider =
      model()->client()->GetTemplateURLService()->GetDefaultSearchProvider();
  if (default_provider) {
    set_placeholder_text(l10n_util::GetStringFUTF16(
        IDS_OMNIBOX_PLACEHOLDER_TEXT, default_provider->short_name()));
  } else {
    set_placeholder_text(base::string16());
  }
}

Project: Chrome

bool OmniboxViewViews::IsCommandIdEnabled(int command_id) const {
  if (command_id == IDS_APP_PASTE)
    return !read_only() && !GetClipboardText().empty();
  if (command_id == IDC_PASTE_AND_GO)
    return !read_only() && model()->CanPasteAndGo(GetClipboardText());

  if (command_id == IDS_SHOW_URL)
    return true;

  return Textfield::IsCommandIdEnabled(command_id) ||
         location_bar_view_->command_updater()->IsCommandEnabled(command_id);
}

Project: Chrome

bool OmniboxViewViews::IsDropCursorForInsertion() const {
  return HasTextBeingDragged();
}

Project: Chrome

bool OmniboxViewViews::IsItemForCommandIdDynamic(int command_id) const {
  return command_id == IDC_PASTE_AND_GO;
}

Project: Chrome

bool OmniboxViewViews::IsSelectAll() const {
  return !text().empty() && text() == GetSelectedText();
}

Project: Chrome

bool OmniboxViewViews::IsTextEditCommandEnabled(
    ui::TextEditCommand command) const {
  switch (command) {
    case ui::TextEditCommand::MOVE_UP:
    case ui::TextEditCommand::MOVE_DOWN:
      return !read_only();
    case ui::TextEditCommand::PASTE:
      return !read_only() && !GetClipboardText().empty();
    default:
      return Textfield::IsTextEditCommandEnabled(command);
  }
}

Project: Chrome

bool OmniboxViewViews::MaybeUnfocusTabButton() {
  if (SelectedSuggestionHasTabMatch() &&
      model()->popup_model()->selected_line_state() ==
          OmniboxPopupModel::BUTTON_FOCUSED) {
    model()->popup_model()->SetSelectedLineState(OmniboxPopupModel::NORMAL);
    return true;
  }
  return false;
}

Project: Chrome

OmniboxViewViews::OmniboxViewViews(OmniboxEditController* controller,
                                   std::unique_ptr<OmniboxClient> client,
                                   bool popup_window_mode,
                                   LocationBarView* location_bar,
                                   const gfx::FontList& font_list)
    : OmniboxView(controller, std::move(client)),
      popup_window_mode_(popup_window_mode),
      saved_selection_for_focus_change_(gfx::Range::InvalidRange()),
      location_bar_view_(location_bar),
      latency_histogram_state_(NOT_ACTIVE),
      friendly_suggestion_text_prefix_length_(0),
      scoped_compositor_observer_(this),
      scoped_template_url_service_observer_(this) {
  set_id(VIEW_ID_OMNIBOX);
  SetFontList(font_list);

  if (base::FeatureList::IsEnabled(
          omnibox::kHideSteadyStateUrlPathQueryAndRef)) {
    SkColor starting_color =
        location_bar_view_->GetColor(OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
    path_fade_animation_ =
        std::make_unique<PathFadeAnimation>(this, starting_color);
  }
}

Project: Chrome

void OmniboxViewViews::OnAfterCutOrCopy(ui::ClipboardType clipboard_type) {
  ui::Clipboard* cb = ui::Clipboard::GetForCurrentThread();
  base::string16 selected_text;
  cb->ReadText(clipboard_type, &selected_text);
  GURL url;
  bool write_url = false;
  model()->AdjustTextForCopy(GetSelectedRange().GetMin(), &selected_text, &url,
                             &write_url);
  if (IsSelectAll())
    UMA_HISTOGRAM_COUNTS_1M(OmniboxEditModel::kCutOrCopyAllTextHistogram, 1);

  ui::ScopedClipboardWriter scoped_clipboard_writer(clipboard_type);
  scoped_clipboard_writer.WriteText(selected_text);

  if (write_url &&
      base::FeatureList::IsEnabled(kOmniboxCanCopyHyperlinksToClipboard)) {
    scoped_clipboard_writer.WriteHyperlink(selected_text, url.spec());
  }
}

Project: Chrome

bool OmniboxViewViews::OnAfterPossibleChange(bool allow_keyword_ui_change) {
  State new_state;
  GetState(&new_state);
  OmniboxView::StateChanges state_changes =
      GetStateChanges(state_before_change_, new_state);

  state_changes.text_differs =
      state_changes.text_differs ||
      (ime_composing_before_change_ != IsIMEComposing());

  bool something_changed = model()->OnAfterPossibleChange(
      state_changes, allow_keyword_ui_change && !IsIMEComposing());

  if (state_changes.selection_differs && !is_mouse_pressed_ &&
      UnapplySteadyStateElisions(UnelisionGesture::OTHER)) {
    something_changed = true;
    state_changes.text_differs = true;
  }

  if (something_changed &&
      (state_changes.text_differs || state_changes.keyword_differs))
    TextChanged();
  else if (state_changes.selection_differs)
    EmphasizeURLComponents();

  return something_changed;
}

Project: Chrome

void OmniboxViewViews::OnBlur() {
  saved_selection_for_focus_change_ = GetSelectedRange();

  OmniboxPopupModel* popup_model = model()->popup_model();
  bool popup_closes_on_blur = true;
  if (popup_model)
    popup_closes_on_blur = popup_model->popup_closes_on_blur();

  if (GetWidget() && GetWidget()->IsActive() && popup_closes_on_blur &&
      ((!model()->user_input_in_progress() &&
        text() != model()->GetPermanentDisplayText()) ||
       (model()->user_input_in_progress() &&
        text() == model()->GetPermanentDisplayText()))) {
    RevertAll();
  }

  views::Textfield::OnBlur();
  model()->OnWillKillFocus();

  if (!model()->user_input_in_progress() && popup_model &&
      popup_model->IsOpen() && text() != model()->GetPermanentDisplayText()) {
    RevertAll();
  } else if (popup_closes_on_blur) {
    CloseOmniboxPopup();
  }

  model()->OnKillFocus();

  SelectRange(gfx::Range(0));

  gfx::RenderText* render_text = GetRenderText();
  render_text->SetElideBehavior(gfx::ELIDE_TAIL);
  render_text->SetDisplayOffset(0);

  if (location_bar_view_) {
    if (model()->is_keyword_hint())
      location_bar_view_->Layout();

    location_bar_view_->OnOmniboxBlurred();

    location_bar_view_->SchedulePaint();
  }

  ClearAccessibilityLabel();
}

Project: Chrome

void OmniboxViewViews::OnCompositingDidCommit(ui::Compositor* compositor) {
  if (latency_histogram_state_ == ON_PAINT_CALLED) {
    latency_histogram_state_ = COMPOSITING_COMMIT;
  } else if (latency_histogram_state_ == COMPOSITING_COMMIT) {
    insert_char_time_ = base::TimeTicks();
    latency_histogram_state_ = NOT_ACTIVE;
  }
}

Project: Chrome

void OmniboxViewViews::OnCompositingStarted(ui::Compositor* compositor,
                                            base::TimeTicks start_time) {
  if (latency_histogram_state_ == COMPOSITING_COMMIT)
    latency_histogram_state_ = COMPOSITING_STARTED;
}

Project: Chrome

int OmniboxViewViews::OnDrop(const ui::OSExchangeData& data) {
  if (HasTextBeingDragged())
    return ui::DragDropTypes::DRAG_NONE;

  base::string16 text;
  if (data.HasURL(ui::OSExchangeData::CONVERT_FILENAMES)) {
    GURL url;
    base::string16 title;
    if (data.GetURLAndTitle(ui::OSExchangeData::CONVERT_FILENAMES, &url,
                            &title)) {
      text = StripJavascriptSchemas(base::UTF8ToUTF16(url.spec()));
    }
  } else if (data.HasString() && data.GetString(&text)) {
    text = StripJavascriptSchemas(base::CollapseWhitespace(text, true));
  } else {
    return ui::DragDropTypes::DRAG_NONE;
  }

  SetUserText(text);
  if (!HasFocus())
    RequestFocus();
  SelectAll(false);
  return ui::DragDropTypes::DRAG_COPY;
}

Project: Chrome

void OmniboxViewViews::OnFocus() {
  views::Textfield::OnFocus();
  model()->ResetDisplayTexts();
  model()->OnSetFocus(false);

  if (saved_selection_for_focus_change_.IsValid()) {
    SelectRange(saved_selection_for_focus_change_);
    saved_selection_for_focus_change_ = gfx::Range::InvalidRange();
  }

  GetRenderText()->SetElideBehavior(gfx::NO_ELIDE);

  if (location_bar_view_ && model()->is_keyword_hint())
    location_bar_view_->Layout();

#if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
  if (location_bar_view_ &&
      controller()->GetLocationBarModel()->ShouldDisplayURL()) {
    feature_engagement::NewTabTrackerFactory::GetInstance()
        ->GetForProfile(location_bar_view_->profile())
        ->OnOmniboxFocused();
  }
#endif

  if (location_bar_view_)
    location_bar_view_->OnOmniboxFocused();
}

Project: Chrome

void OmniboxViewViews::OnGetDragOperationsForTextfield(int* drag_operations) {
  base::string16 selected_text = GetSelectedText();
  GURL url;
  bool write_url;
  model()->AdjustTextForCopy(GetSelectedRange().GetMin(), &selected_text, &url,
                             &write_url);
  if (write_url)
    *drag_operations |= ui::DragDropTypes::DRAG_LINK;
}

Project: Chrome

void OmniboxViewViews::OnInlineAutocompleteTextCleared() {
  if (location_bar_view_)
    location_bar_view_->SetImeInlineAutocompletion(base::string16());
}

Project: Chrome

bool OmniboxViewViews::OnInlineAutocompleteTextMaybeChanged(
    const base::string16& display_text,
    size_t user_text_length) {
  if (display_text == text())
    return false;

  if (!IsIMEComposing()) {
    gfx::Range range(display_text.size(), user_text_length);
    SetTextAndSelectedRange(display_text, range);
  } else if (location_bar_view_) {
    location_bar_view_->SetImeInlineAutocompletion(
        display_text.substr(user_text_length));
  }
  TextChanged();
  return true;
}

Project: Chrome

bool OmniboxViewViews::OnMouseDragged(const ui::MouseEvent& event) {
  if (filter_drag_events_for_unelision_ &&
      !ExceededDragThreshold(event.root_location() -
                             GetLastClickRootLocation())) {
    return true;
  }

  if (HasTextBeingDragged())
    CloseOmniboxPopup();

  bool handled = views::Textfield::OnMouseDragged(event);

  if (HasSelection() || ExceededDragThreshold(event.root_location() -
                                              GetLastClickRootLocation())) {
    select_all_on_mouse_release_ = false;
  }

  return handled;
}

Project: Chrome

void OmniboxViewViews::OnMouseExited(const ui::MouseEvent& event) {
  if (location_bar_view_)
    location_bar_view_->OnOmniboxHovered(false);
}

Project: Chrome

void OmniboxViewViews::OnMouseMoved(const ui::MouseEvent& event) {
  if (location_bar_view_)
    location_bar_view_->OnOmniboxHovered(true);
}

Project: Chrome

bool OmniboxViewViews::OnMousePressed(const ui::MouseEvent& event) {
  if (model()->popup_model() &&  // Can be null in tests.
      model()->popup_model()->selected_line_state() ==
          OmniboxPopupModel::BUTTON_FOCUSED) {
    model()->popup_model()->SetSelectedLineState(OmniboxPopupModel::NORMAL);
  }
  is_mouse_pressed_ = true;

  select_all_on_mouse_release_ =
      (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) &&
      (!HasFocus() || (model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE));
  if (select_all_on_mouse_release_) {
    model()->SetCaretVisibility(true);

    saved_selection_for_focus_change_ = gfx::Range::InvalidRange();
  }

  bool handled = views::Textfield::OnMousePressed(event);

  if (!select_all_on_mouse_release_ &&
      UnapplySteadyStateElisions(UnelisionGesture::OTHER)) {
    TextChanged();
    filter_drag_events_for_unelision_ = true;
  }

  return handled;
}

Project: Chrome

void OmniboxViewViews::OnMouseReleased(const ui::MouseEvent& event) {
  views::Textfield::OnMouseReleased(event);
  if ((event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) &&
      select_all_on_mouse_release_) {
    SelectAllForUserGesture();
    if (location_bar_view_)
      location_bar_view_->omnibox_page_action_icon_container_view()
          ->UpdatePageActionIcon(PageActionIconType::kSendTabToSelf);
  }
  select_all_on_mouse_release_ = false;

  is_mouse_pressed_ = false;
  filter_drag_events_for_unelision_ = false;

  if (UnapplySteadyStateElisions(UnelisionGesture::MOUSE_RELEASE))
    TextChanged();
}

Project: Chrome

void OmniboxViewViews::OnPaint(gfx::Canvas* canvas) {
  if (latency_histogram_state_ == CHAR_TYPED) {
    DCHECK(!insert_char_time_.is_null());
    UMA_HISTOGRAM_TIMES("Omnibox.CharTypedToRepaintLatency.ToPaint",
                        base::TimeTicks::Now() - insert_char_time_);
    latency_histogram_state_ = ON_PAINT_CALLED;
  }

  {
    SCOPED_UMA_HISTOGRAM_TIMER("Omnibox.PaintTime");
    Textfield::OnPaint(canvas);
  }
}

Project: Chrome

void OmniboxViewViews::OnPaste() {
  const base::string16 text(GetClipboardText());

  if (text.empty() ||
      (model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE &&
       std::all_of(text.begin(), text.end(), base::IsUnicodeWhitespace))) {
    return;
  }

  OnBeforePossibleChange();
  model()->OnPaste();
  state_before_change_.text.clear();
  InsertOrReplaceText(text);
  OnAfterPossibleChange(true);
}

Project: Chrome

void OmniboxViewViews::OnRevertTemporaryText(const base::string16& display_text,
                                             const AutocompleteMatch& match) {
  SetAccessibilityLabel(display_text, match);
  SelectRange(saved_temporary_selection_);
}

Project: Chrome

void OmniboxViewViews::OnTabChanged(const content::WebContents* web_contents) {
  const OmniboxState* state = static_cast<OmniboxState*>(
      web_contents->GetUserData(&OmniboxState::kKey));
  model()->RestoreState(state ? &state->model_state : nullptr);
  if (state) {
    SelectRange(state->selection);
    saved_selection_for_focus_change_ = state->saved_selection_for_focus_change;
  }

  ClearEditHistory();
}

Project: Chrome

void OmniboxViewViews::OnTemplateURLServiceChanged() {
  InstallPlaceholderText();
}

Project: Chrome

void OmniboxViewViews::OnTemporaryTextMaybeChanged(
    const base::string16& display_text,
    const AutocompleteMatch& match,
    bool save_original_selection,
    bool notify_text_changed) {
  if (save_original_selection)
    saved_temporary_selection_ = GetSelectedRange();
  SetAccessibilityLabel(display_text, match);
  int caret_pos = TextAndUIDirectionMatch() ? display_text.length() : 0;
  SetWindowTextAndCaretPos(display_text, caret_pos, false, notify_text_changed);
}

Project: Chrome

void OmniboxViewViews::OnWriteDragData(ui::OSExchangeData* data) {
  GURL url;
  bool write_url;
  base::string16 selected_text = GetSelectedText();
  model()->AdjustTextForCopy(GetSelectedRange().GetMin(), &selected_text, &url,
                             &write_url);
  data->SetString(selected_text);
  if (write_url) {
    gfx::Image favicon;
    base::string16 title = selected_text;
    if (IsSelectAll())
      model()->GetDataForURLExport(&url, &title, &favicon);
    button_drag_utils::SetURLAndDragImage(url, title, favicon.AsImageSkia(),
                                          nullptr, *GetWidget(), data);
    data->SetURL(url, title);
  }
}

Project: Chrome

  PathFadeAnimation(OmniboxViewViews* view, SkColor starting_color)
      : view_(view),
        starting_color_(starting_color),
        animation_(
            {
                gfx::MultiAnimation::Part(4000, gfx::Tween::ZERO),
                gfx::MultiAnimation::Part(300, gfx::Tween::FAST_OUT_SLOW_IN),
            },

Project: Chrome

void OmniboxViewViews::RemovedFromWidget() {
  views::Textfield::RemovedFromWidget();
  scoped_compositor_observer_.RemoveAll();
}

Project: Chrome

void OmniboxViewViews::ResetTabState(content::WebContents* web_contents) {
  web_contents->SetUserData(OmniboxState::kKey, nullptr);
}

Project: Chrome

void OmniboxViewViews::SaveStateToTab(content::WebContents* tab) {
  DCHECK(tab);

  if (IsIMEComposing()) {
    ConfirmCompositionText();
    GetInputMethod()->CancelComposition(this);
  }

  OmniboxEditModel::State state = model()->GetStateForTabSwitch();
  tab->SetUserData(OmniboxState::kKey, std::make_unique<OmniboxState>(
                                           state, GetSelectedRange(),
                                           saved_selection_for_focus_change_));
}

Project: Chrome

void OmniboxViewViews::SelectAllForUserGesture() {
  if (base::FeatureList::IsEnabled(omnibox::kOneClickUnelide) &&
      UnapplySteadyStateElisions(UnelisionGesture::OTHER)) {
    TextChanged();
  }

  SelectAll(true);
}

Project: Chrome

bool OmniboxViewViews::SelectedSuggestionHasTabMatch() const {
  return model()->popup_model() &&  // Can be null in tests.
         model()->popup_model()->SelectedLineHasButton();
}

Project: Chrome

bool OmniboxViewViews::SelectionAtBeginning() const {
  const gfx::Range sel = GetSelectedRange();
  return sel.GetMax() == 0;
}

Project: Chrome

bool OmniboxViewViews::SelectionAtEnd() const {
  const gfx::Range sel = GetSelectedRange();
  return sel.GetMin() == text().size();
}

Project: Chrome

void OmniboxViewViews::SetAccessibilityLabel(const base::string16& display_text,
                                             const AutocompleteMatch& match) {
  bool is_tab_switch_button_focused =
      model()->popup_model()->selected_line_state() ==
      OmniboxPopupModel::BUTTON_FOCUSED;
  friendly_suggestion_text_ = AutocompleteMatchType::ToAccessibilityLabel(
      match, display_text, model()->popup_model()->selected_line(),
      model()->result().size(), is_tab_switch_button_focused,
      &friendly_suggestion_text_prefix_length_);

#if defined(OS_MACOSX)
  GetViewAccessibility().AnnounceText(friendly_suggestion_text_);
#endif
}

Project: Chrome

void OmniboxViewViews::SetEmphasis(bool emphasize, const gfx::Range& range) {
  SkColor color = location_bar_view_->GetColor(
      emphasize ? OmniboxPart::LOCATION_BAR_TEXT_DEFAULT
                : OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
  if (range.IsValid())
    ApplyColor(color, range);
  else
    SetColor(color);
}

Project: Chrome

void OmniboxViewViews::SetFocus() {
  std::unique_ptr<ImmersiveRevealedLock> focus_reveal_lock;
  if (location_bar_view_) {
    focus_reveal_lock.reset(
        BrowserView::GetBrowserViewForBrowser(location_bar_view_->browser())
            ->immersive_mode_controller()
            ->GetRevealedLock(ImmersiveModeController::ANIMATE_REVEAL_YES));
  }

  RequestFocus();
  model()->SetCaretVisibility(true);
  model()->ConsumeCtrlKey();
}

Project: Chrome

void OmniboxViewViews::SetUserText(const base::string16& text,
                                   bool update_popup) {
  saved_selection_for_focus_change_ = gfx::Range::InvalidRange();
  OmniboxView::SetUserText(text, update_popup);
}

Project: Chrome

bool OmniboxViewViews::ShouldDoLearning() {
  return location_bar_view_ && !location_bar_view_->profile()->IsOffTheRecord();
}

Project: Chrome

bool OmniboxViewViews::SkipDefaultKeyEventProcessing(
    const ui::KeyEvent& event) {
  if (views::FocusManager::IsTabTraversalKeyEvent(event) &&
      ((model()->is_keyword_hint() && !event.IsShiftDown()) ||
       model()->popup_model()->IsOpen())) {
    return true;
  }
  if (event.key_code() == ui::VKEY_ESCAPE)
    return model()->WillHandleEscapeKey();
  return Textfield::SkipDefaultKeyEventProcessing(event);
}

Project: Chrome

  void Start(const gfx::Range& path_bounds) {
    path_bounds_ = path_bounds;
    animation_.Start();
  }

Project: Chrome

bool OmniboxViewViews::UnapplySteadyStateElisions(UnelisionGesture gesture) {
  if (IsSelectAll() && gesture != UnelisionGesture::HOME_KEY_PRESSED)
    return false;

  size_t start, end;
  GetSelectionBounds(&start, &end);

  base::string16 original_text = GetText();
  base::string16 original_selected_text = GetSelectedText();
  if (!model()->Unelide(false /* exit_query_in_omnibox */))
    return false;

  size_t offset = GetText().find(original_text);
  if (offset != base::string16::npos) {
    if (start != end && gesture == UnelisionGesture::MOUSE_RELEASE &&
        !model()->ClassifiesAsSearch(original_selected_text)) {
      if (start != 0)
        start += offset;
      if (end != 0)
        end += offset;
    } else {
      start += offset;
      end += offset;
    }

    OffsetDoubleClickWord(offset);
  }

  SelectRange(gfx::Range(start, end));
  return true;
}

Project: Chrome

void OmniboxViewViews::Update() {
  if (model()->ResetDisplayTexts()) {
    RevertAll();

    if (model()->has_focus()) {
      SelectAllForUserGesture();
    }
  } else {
    EmphasizeURLComponents();
  }
}

Project: Chrome

void OmniboxViewViews::UpdateContextMenu(ui::SimpleMenuModel* menu_contents) {
  if (send_tab_to_self::ShouldOfferFeature(
          location_bar_view_->GetWebContents())) {
    send_tab_to_self::RecordSendTabToSelfClickResult(
        send_tab_to_self::kOmniboxMenu, SendTabToSelfClickResult::kShowItem);
    int index = menu_contents->GetIndexOfCommandId(IDS_APP_UNDO);
    if (index)
      menu_contents->InsertSeparatorAt(index++, ui::NORMAL_SEPARATOR);
    menu_contents->InsertItemWithStringIdAt(index, IDC_SEND_TAB_TO_SELF,
                                            IDS_CONTEXT_MENU_SEND_TAB_TO_SELF);
    menu_contents->SetIcon(index,
                           gfx::Image(*send_tab_to_self::GetImageSkia()));
    menu_contents->InsertSeparatorAt(++index, ui::NORMAL_SEPARATOR);
  }

  int paste_position = menu_contents->GetIndexOfCommandId(IDS_APP_PASTE);
  DCHECK_GE(paste_position, 0);
  menu_contents->InsertItemWithStringIdAt(paste_position + 1, IDC_PASTE_AND_GO,
                                          IDS_PASTE_AND_GO);

  if (base::FeatureList::IsEnabled(omnibox::kQueryInOmnibox)) {
    if (!read_only() && !model()->user_input_in_progress() &&
        text() != controller()->GetLocationBarModel()->GetFormattedFullURL()) {
      menu_contents->AddItemWithStringId(IDS_SHOW_URL, IDS_SHOW_URL);
    }
  }

  menu_contents->AddSeparator(ui::NORMAL_SEPARATOR);

  menu_contents->AddItemWithStringId(IDC_EDIT_SEARCH_ENGINES,
                                     IDS_EDIT_SEARCH_ENGINES);
}

Project: Chrome

void OmniboxViewViews::UpdatePopup() {
  const gfx::Range sel = GetSelectedRange();
  model()->UpdateInput(!sel.is_empty(), !SelectionAtEnd());
}

Project: Chrome

void OmniboxViewViews::UpdateSchemeStyle(const gfx::Range& range) {
  DCHECK(range.IsValid());
  DCHECK(!model()->user_input_in_progress());

  security_state::SecurityLevel security_level =
      controller()->GetLocationBarModel()->GetSecurityLevel();

  if (security_level == security_state::NONE ||
      security_level == security_state::HTTP_SHOW_WARNING)
    return;
  ApplyColor(location_bar_view_->GetSecurityChipColor(security_level), range);
  if (security_level == security_state::DANGEROUS)
    ApplyStyle(gfx::TEXT_STYLE_STRIKE, true, range);
}