blob: c3d3bff099be6761f138da75552aae54ca065366 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/omnibox/omnibox_popup_view_webui.h"
#include <memory>
#include <numeric>
#include <optional>
#include <string_view>
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/omnibox/omnibox_controller.h"
#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
#include "chrome/browser/ui/omnibox/omnibox_next_features.h"
#include "chrome/browser/ui/omnibox/omnibox_popup_state_manager.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h"
#include "chrome/browser/ui/views/omnibox/omnibox_popup_presenter_base.h"
#include "chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.h"
#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h"
#include "chrome/browser/ui/views/omnibox/omnibox_row_view.h"
#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
#include "chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h"
#include "chrome/browser/ui/views/theme_copying_widget.h"
#include "chrome/browser/ui/webui/searchbox/webui_omnibox_handler.h"
#include "components/omnibox/browser/omnibox_prefs.h"
#include "components/omnibox/common/omnibox_features.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/compositor/closure_animation_observer.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/image/image.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/cascading_property.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/views_features.h"
#include "ui/views/widget/widget.h"
OmniboxPopupViewWebUI::OmniboxPopupViewWebUI(OmniboxViewViews* omnibox_view,
OmniboxController* controller,
LocationBarView* location_bar_view)
: OmniboxPopupView(controller),
construction_time_(base::TimeTicks::Now()),
omnibox_view_(omnibox_view),
location_bar_view_(location_bar_view) {
presenter_ =
std::make_unique<OmniboxPopupPresenter>(location_bar_view, controller);
controller->edit_model()->set_popup_view(this);
edit_model_observation_.Observe(controller->edit_model());
}
OmniboxPopupViewWebUI::~OmniboxPopupViewWebUI() {
controller()->edit_model()->set_popup_view(nullptr);
}
bool OmniboxPopupViewWebUI::IsOpen() const {
return presenter_->IsShown();
}
void OmniboxPopupViewWebUI::InvalidateLine(size_t line) {}
void OmniboxPopupViewWebUI::UpdatePopupAppearance() {
const bool should_be_visible =
controller()->popup_state_manager()->popup_state() !=
OmniboxPopupState::kAim &&
!controller()->autocomplete_controller()->result().empty() &&
!omnibox_view_->IsImeShowingPopup();
if (!should_be_visible) {
presenter_->Hide();
// Update the popup state manager that the classic popup is closing.
// Do this AFTER widget operations. LocationBarView is subscribed to state
// changes and attempts to call `UpdatePopupAppearance()` again if the
// widget is open.
// Only update the state if it's currently kClassic. If it's already
// transitioning to another state (e.g., kAim), don't override it.
if (controller()->popup_state_manager()->popup_state() ==
OmniboxPopupState::kClassic) {
controller()->popup_state_manager()->SetPopupState(
OmniboxPopupState::kNone);
}
} else {
const bool was_visible = IsOpen();
presenter_->Show();
// Update the popup state manager that the classic popup is opening.
controller()->popup_state_manager()->SetPopupState(
OmniboxPopupState::kClassic);
if (!was_visible) {
if (!construction_time_.is_null()) {
const base::TimeDelta delta =
base::TimeTicks::Now() - construction_time_;
construction_time_ = base::TimeTicks();
base::UmaHistogramTimes(
"Omnibox.Popup.WebUI.ConstructionToFirstShownDuration", delta);
}
}
}
}
void OmniboxPopupViewWebUI::OnContentsChanged() {
UpdatePopupAppearance();
}
void OmniboxPopupViewWebUI::ProvideButtonFocusHint(size_t line) {
// TODO(crbug.com/40062053): Not implemented for WebUI omnibox popup yet.
}
void OmniboxPopupViewWebUI::OnDragCanceled() {}
void OmniboxPopupViewWebUI::GetPopupAccessibleNodeData(
ui::AXNodeData* node_data) const {}
raw_ptr<OmniboxPopupViewWebUI>
OmniboxPopupViewWebUI::GetOmniboxPopupViewWebUI() {
return this;
}