#include "components/live_caption/views/caption_bubble.h"
#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/i18n/rtl.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "components/live_caption/caption_bubble_context.h"
#include "components/live_caption/pref_names.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "media/base/media_switches.h"
#include "third_party/re2/src/re2/re2.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_mode_observer.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/buildflags.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/dialog_button.mojom.h"
#include "ui/color/color_id.h"
#include "ui/compositor/layer.h"
#include "ui/events/event.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/event_monitor.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/box_layout_view.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_types.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/layout/layout_types.h"
#include "ui/views/style/typography.h"
#include "ui/views/vector_icons.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/widget/widget.h"
#if BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY() && !BUILDFLAG(IS_MAC)
#define NEED_FOCUS_FOR_ACCESSIBILITY
#endif
#if defined(NEED_FOCUS_FOR_ACCESSIBILITY)
#include "base/scoped_observation.h"
#include "ui/accessibility/platform/ax_platform.h"
#endif
namespace {
static constexpr int kLineHeightDip = …;
static constexpr int kLiveTranslateLabelLineHeightDip = …;
static constexpr int kLiveTranslateImageWidthDip = …;
static constexpr int kLanguageButtonImageLabelSpacing = …;
static constexpr int kNumLinesCollapsed = …;
static constexpr int kNumLinesExpanded = …;
static constexpr int kCornerRadiusDip = …;
static constexpr int kSidePaddingDip = …;
static constexpr int kButtonDip = …;
static constexpr int kButtonCircleHighlightPaddingDip = …;
static constexpr int kMaxWidthDip = …;
static constexpr int kMinAnchorMarginDip = …;
static constexpr char kPrimaryFont[] = …;
static constexpr char kSecondaryFont[] = …;
static constexpr char kTertiaryFont[] = …;
static constexpr int kFontSizePx = …;
static constexpr int kLiveTranslateLabelFontSizePx = …;
static constexpr double kDefaultRatioInParentX = …;
static constexpr double kDefaultRatioInParentY = …;
static constexpr int kErrorImageSizeDip = …;
static constexpr int kErrorMessageBetweenChildSpacingDip = …;
static constexpr int kNoActivityIntervalSeconds = …;
constexpr base::TimeDelta kAnimationDuration = …;
std::unique_ptr<views::ImageButton> BuildImageButton(
views::Button::PressedCallback callback,
const int tooltip_text_id) { … }
std::string MaybeRemoveCSSImportant(std::string css_string) { … }
bool ParseNonTransparentRGBACSSColorString(
std::string css_string,
SkColor* sk_color,
const ui::ColorProvider* color_provider) { … }
class CaptionBubbleEventObserver : public ui::EventObserver { … };
}
namespace captions {
#if BUILDFLAG(IS_CHROMEOS_ASH)
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsCaptionBubbleKey, false)
#endif
#if BUILDFLAG(IS_WIN)
class MediaFoundationRendererErrorMessageView : public views::StyledLabel {
METADATA_HEADER(MediaFoundationRendererErrorMessageView, views::StyledLabel)
public:
explicit MediaFoundationRendererErrorMessageView(
CaptionBubble* caption_bubble)
: caption_bubble_(caption_bubble) {}
bool HandleAccessibleAction(const ui::AXActionData& action_data) override {
switch (action_data.action) {
case ax::mojom::Action::kDoDefault:
caption_bubble_->OnContentSettingsLinkClicked();
return true;
default:
break;
}
return views::StyledLabel::HandleAccessibleAction(action_data);
}
private:
const raw_ptr<CaptionBubble> caption_bubble_;
};
BEGIN_METADATA(MediaFoundationRendererErrorMessageView)
END_METADATA
#endif
class CaptionBubbleFrameView : public views::BubbleFrameView { … };
BEGIN_METADATA(…)
class CaptionBubbleLabelAXModeObserver;
class CaptionBubbleLabel : public views::Label { … };
BEGIN_METADATA(…)
class LanguageLabelButton : public views::LabelButton { … };
BEGIN_METADATA(…)
#if defined(NEED_FOCUS_FOR_ACCESSIBILITY)
class CaptionBubbleLabelAXModeObserver : public ui::AXModeObserver { … };
#endif
CaptionBubble::CaptionBubble(PrefService* profile_prefs,
const std::string& application_locale,
base::OnceClosure destroyed_callback)
: … { … }
CaptionBubble::~CaptionBubble() { … }
gfx::Rect CaptionBubble::GetBubbleBounds() { … }
void CaptionBubble::Init() { … }
void CaptionBubble::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params,
views::Widget* widget) const { … }
bool CaptionBubble::ShouldShowCloseButton() const { … }
std::unique_ptr<views::NonClientFrameView>
CaptionBubble::CreateNonClientFrameView(views::Widget* widget) { … }
void CaptionBubble::OnWidgetBoundsChanged(views::Widget* widget,
const gfx::Rect& new_bounds) { … }
void CaptionBubble::OnWidgetActivationChanged(views::Widget* widget,
bool active) { … }
void CaptionBubble::OnLiveTranslateEnabledChanged() { … }
void CaptionBubble::OnLiveCaptionLanguageChanged() { … }
void CaptionBubble::OnLiveTranslateTargetLanguageChanged() { … }
void CaptionBubble::GetAccessibleNodeData(ui::AXNodeData* node_data) { … }
std::u16string CaptionBubble::GetAccessibleWindowTitle() const { … }
void CaptionBubble::OnThemeChanged() { … }
void CaptionBubble::BackToTabButtonPressed() { … }
void CaptionBubble::CloseButtonPressed() { … }
void CaptionBubble::ExpandOrCollapseButtonPressed() { … }
void CaptionBubble::PinOrUnpinButtonPressed() { … }
void CaptionBubble::SwapButtons(views::Button* first_button,
views::Button* second_button,
bool show_first_button) { … }
void CaptionBubble::CaptionSettingsButtonPressed() { … }
void CaptionBubble::SetModel(CaptionBubbleModel* model) { … }
void CaptionBubble::AnimationProgressed(const gfx::Animation* animation) { … }
void CaptionBubble::OnTextChanged() { … }
void CaptionBubble::OnDownloadProgressTextChanged() { … }
void CaptionBubble::OnLanguagePackInstalled() { … }
void CaptionBubble::OnAutoDetectedLanguageChanged() { … }
bool CaptionBubble::ThemeColorsChanged() { … }
void CaptionBubble::OnErrorChanged(
CaptionBubbleErrorType error_type,
OnErrorClickedCallback callback,
OnDoNotShowAgainClickedCallback error_silenced_callback) { … }
#if BUILDFLAG(IS_WIN)
void CaptionBubble::OnContentSettingsLinkClicked() {
if (error_clicked_callback_) {
error_clicked_callback_.Run();
}
}
#endif
void CaptionBubble::UpdateControlsVisibility(bool show_controls) { … }
void CaptionBubble::OnMouseEnteredOrExitedWindow(bool entered) { … }
void CaptionBubble::UpdateBubbleAndTitleVisibility() { … }
void CaptionBubble::UpdateBubbleVisibility() { … }
void CaptionBubble::UpdateCaptionStyle(
std::optional<ui::CaptionStyle> caption_style) { … }
size_t CaptionBubble::GetTextIndexOfLineInLabel(size_t line) const { … }
size_t CaptionBubble::GetNumLinesInLabel() const { … }
int CaptionBubble::GetNumLinesVisible() { … }
double CaptionBubble::GetTextScaleFactor() { … }
const gfx::FontList CaptionBubble::GetFontList(int font_size) { … }
void CaptionBubble::SetTextSizeAndFontFamily() { … }
void CaptionBubble::SetTextColor() { … }
void CaptionBubble::SetBackgroundColor() { … }
void CaptionBubble::OnLanguageChanged() { … }
void CaptionBubble::UpdateLanguageLabelText() { … }
void CaptionBubble::RepositionInContextRect(CaptionBubbleModel::Id model_id,
const gfx::Rect& context_rect) { … }
void CaptionBubble::UpdateContentSize() { … }
void CaptionBubble::Redraw() { … }
void CaptionBubble::ShowInactive() { … }
void CaptionBubble::Hide() { … }
void CaptionBubble::OnInactivityTimeout() { … }
void CaptionBubble::ResetInactivityTimer() { … }
void CaptionBubble::MediaFoundationErrorCheckboxPressed() { … }
bool CaptionBubble::HasMediaFoundationError() { … }
void CaptionBubble::LogSessionEvent(SessionEvent event) { … }
std::vector<raw_ptr<views::View, VectorExperimental>>
CaptionBubble::GetButtons() { … }
bool CaptionBubble::HasActivity() { … }
views::Label* CaptionBubble::GetLabelForTesting() { … }
views::Label* CaptionBubble::GetDownloadProgressLabelForTesting() { … }
views::Label* CaptionBubble::GetLanguageLabelForTesting() { … }
bool CaptionBubble::IsGenericErrorMessageVisibleForTesting() const { … }
void CaptionBubble::SetCaptionBubbleStyle() { … }
base::RetainingOneShotTimer* CaptionBubble::GetInactivityTimerForTesting() { … }
views::Button* CaptionBubble::GetCloseButtonForTesting() { … }
views::Button* CaptionBubble::GetBackToTabButtonForTesting() { … }
views::View* CaptionBubble::GetHeaderForTesting() { … }
BEGIN_METADATA(…)
}