caption_bubble.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_LIVE_CAPTION_VIEWS_CAPTION_BUBBLE_H_
  5. #define COMPONENTS_LIVE_CAPTION_VIEWS_CAPTION_BUBBLE_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/callback.h"
  9. #include "base/callback_helpers.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "build/buildflag.h"
  12. #include "components/live_caption/views/caption_bubble_model.h"
  13. #include "components/prefs/pref_service.h"
  14. #include "ui/base/metadata/metadata_header_macros.h"
  15. #include "ui/gfx/font_list.h"
  16. #include "ui/native_theme/caption_style.h"
  17. #include "ui/views/bubble/bubble_dialog_delegate_view.h"
  18. #include "ui/views/controls/button/button.h"
  19. #include "ui/views/controls/styled_label.h"
  20. #include "ui/views/metadata/view_factory.h"
  21. namespace base {
  22. class RetainingOneShotTimer;
  23. class TickClock;
  24. }
  25. namespace views {
  26. class Checkbox;
  27. class ImageButton;
  28. class ImageView;
  29. class Label;
  30. } // namespace views
  31. namespace ui {
  32. struct AXNodeData;
  33. }
  34. namespace captions {
  35. class CaptionBubbleFrameView;
  36. class CaptionBubbleLabel;
  37. // These values are persisted to logs. Entries should not be renumbered and
  38. // numeric values should never be reused. These should be the same as
  39. // LiveCaptionSessionEvent in enums.xml.
  40. enum class SessionEvent {
  41. // We began showing captions for an audio stream.
  42. kStreamStarted = 0,
  43. // The audio stream ended and the caption bubble closes.
  44. kStreamEnded = 1,
  45. // The close button was clicked, so we stopped listening to an audio stream.
  46. kCloseButtonClicked = 2,
  47. kMaxValue = kCloseButtonClicked,
  48. };
  49. using ResetInactivityTimerCallback = base::RepeatingCallback<void()>;
  50. ///////////////////////////////////////////////////////////////////////////////
  51. // Caption Bubble
  52. //
  53. // A caption bubble that floats above all other windows and shows
  54. // automatically- generated text captions for audio and media streams. The
  55. // captions bubble's widget is a top-level window that has top z order and is
  56. // visible on all workspaces. It is draggable in and out of the tab.
  57. //
  58. class CaptionBubble : public views::BubbleDialogDelegateView {
  59. public:
  60. METADATA_HEADER(CaptionBubble);
  61. CaptionBubble(PrefService* profile_prefs,
  62. base::OnceClosure destroyed_callback);
  63. CaptionBubble(const CaptionBubble&) = delete;
  64. CaptionBubble& operator=(const CaptionBubble&) = delete;
  65. ~CaptionBubble() override;
  66. // Sets the caption bubble model currently being used for this caption bubble.
  67. // There exists one CaptionBubble per profile, but one CaptionBubbleModel per
  68. // media stream. A new CaptionBubbleModel is set when transcriptions from a
  69. // different media stream are received. A CaptionBubbleModel is owned by the
  70. // CaptionBubbleControllerViews. It is created when transcriptions from a new
  71. // media stream are received and exists until the audio stream ends for that
  72. // stream.
  73. void SetModel(CaptionBubbleModel* model);
  74. // Changes the caption style of the caption bubble.
  75. void UpdateCaptionStyle(absl::optional<ui::CaptionStyle> caption_style);
  76. // Returns whether the bubble has activity. Activity is defined as
  77. // transcription received from the speech service or user interacting with the
  78. // bubble through focus, pressing buttons, or dragging.
  79. bool HasActivity();
  80. views::Label* GetLabelForTesting();
  81. base::RetainingOneShotTimer* GetInactivityTimerForTesting();
  82. void set_tick_clock_for_testing(const base::TickClock* tick_clock) {
  83. tick_clock_ = tick_clock;
  84. }
  85. void SetCaptionBubbleStyle();
  86. #if BUILDFLAG(IS_WIN)
  87. void OnContentSettingsLinkClicked();
  88. #endif
  89. protected:
  90. // views::BubbleDialogDelegateView:
  91. void Init() override;
  92. void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params,
  93. views::Widget* widget) const override;
  94. bool ShouldShowCloseButton() const override;
  95. std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
  96. views::Widget* widget) override;
  97. gfx::Rect GetBubbleBounds() override;
  98. void OnWidgetBoundsChanged(views::Widget* widget,
  99. const gfx::Rect& new_bounds) override;
  100. void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
  101. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  102. std::u16string GetAccessibleWindowTitle() const override;
  103. void OnThemeChanged() override;
  104. private:
  105. friend class CaptionBubbleControllerViewsTest;
  106. friend class CaptionBubbleModel;
  107. void BackToTabButtonPressed();
  108. void CloseButtonPressed();
  109. void ExpandOrCollapseButtonPressed();
  110. void PinOrUnpinButtonPressed();
  111. void SwapButtons(views::Button* first_button,
  112. views::Button* second_button,
  113. bool show_first_button);
  114. // Called by CaptionBubbleModel to notify this object that the model's text
  115. // has changed. Sets the text of the caption bubble to the model's text.
  116. void OnTextChanged();
  117. // Used to prevent propagating theme changes when no theme colors have
  118. // changed. Returns whether the caption theme colors have changed since the
  119. // last time this function was called.
  120. bool ThemeColorsChanged();
  121. // Called by CaptionBubbleModel to notify this object that the model's error
  122. // state has changed. Makes the caption bubble display an error message if
  123. // the model has an error, otherwise displays the latest text.
  124. void OnErrorChanged(CaptionBubbleErrorType error_type,
  125. OnErrorClickedCallback callback,
  126. OnDoNotShowAgainClickedCallback error_silenced_callback);
  127. // The caption bubble manages its own visibility based on whether there's
  128. // space for it to be shown, and if it has an error or text to display.
  129. void UpdateBubbleVisibility();
  130. void UpdateBubbleAndTitleVisibility();
  131. // For the provided line index, gets the corresponding rendered line in the
  132. // label and returns the text position of the first character of that line.
  133. // Returns the same value regardless of whether the label is visible or not.
  134. // TODO(crbug.com/1055150): This feature is launching for English first.
  135. // Make sure this is correct for all languages.
  136. size_t GetTextIndexOfLineInLabel(size_t line) const;
  137. // Returns the number of lines in the caption bubble label that are rendered.
  138. size_t GetNumLinesInLabel() const;
  139. int GetNumLinesVisible();
  140. void UpdateContentSize();
  141. void Redraw();
  142. void ShowInactive();
  143. void Hide();
  144. // The following methods set the caption bubble style based on the user's
  145. // preferences, which are stored in `caption_style_`.
  146. double GetTextScaleFactor();
  147. const gfx::FontList GetFontList();
  148. void SetTextSizeAndFontFamily();
  149. void SetTextColor();
  150. void SetBackgroundColor();
  151. // After 5 seconds of inactivity, hide the caption bubble. Activity is defined
  152. // as transcription received from the speech service or user interacting with
  153. // the bubble through focus, pressing buttons, or dragging.
  154. void OnInactivityTimeout();
  155. void ResetInactivityTimer();
  156. void MediaFoundationErrorCheckboxPressed();
  157. bool HasMediaFoundationError();
  158. void LogSessionEvent(SessionEvent event);
  159. // Unowned. Owned by views hierarchy.
  160. raw_ptr<CaptionBubbleLabel> label_;
  161. raw_ptr<views::Label> title_;
  162. raw_ptr<views::Label> generic_error_text_;
  163. raw_ptr<views::ImageView> generic_error_icon_;
  164. raw_ptr<views::View> generic_error_message_;
  165. raw_ptr<views::ImageButton> back_to_tab_button_;
  166. raw_ptr<views::ImageButton> close_button_;
  167. raw_ptr<views::ImageButton> expand_button_;
  168. raw_ptr<views::ImageButton> collapse_button_;
  169. raw_ptr<views::ImageButton> pin_button_;
  170. raw_ptr<views::ImageButton> unpin_button_;
  171. raw_ptr<CaptionBubbleFrameView> frame_;
  172. #if BUILDFLAG(IS_WIN)
  173. raw_ptr<views::StyledLabel> media_foundation_renderer_error_text_;
  174. raw_ptr<views::ImageView> media_foundation_renderer_error_icon_;
  175. raw_ptr<views::View> media_foundation_renderer_error_message_;
  176. // Checkbox the user can use to indicate whether to silence the error message
  177. // for the origin.
  178. raw_ptr<views::Checkbox> media_foundation_renderer_error_checkbox_ = nullptr;
  179. #endif
  180. absl::optional<ui::CaptionStyle> caption_style_;
  181. raw_ptr<CaptionBubbleModel> model_ = nullptr;
  182. raw_ptr<PrefService> profile_prefs_;
  183. OnErrorClickedCallback error_clicked_callback_;
  184. OnDoNotShowAgainClickedCallback error_silenced_callback_;
  185. base::ScopedClosureRunner destroyed_callback_;
  186. // Whether the caption bubble is expanded to show more lines of text.
  187. bool is_expanded_;
  188. // Whether the caption bubble is pinned or if it should hide on inactivity.
  189. bool is_pinned_;
  190. bool has_been_shown_ = false;
  191. // Used to determine whether to propagate theme changes to the widget.
  192. SkColor text_color_ = gfx::kPlaceholderColor;
  193. SkColor icon_color_ = gfx::kPlaceholderColor;
  194. SkColor icon_disabled_color_ = gfx::kPlaceholderColor;
  195. SkColor link_color_ = gfx::kPlaceholderColor;
  196. SkColor checkbox_color_ = gfx::kPlaceholderColor;
  197. SkColor background_color_ = gfx::kPlaceholderColor;
  198. // A timer which causes the bubble to hide if there is no activity after a
  199. // specified interval.
  200. std::unique_ptr<base::RetainingOneShotTimer> inactivity_timer_;
  201. raw_ptr<const base::TickClock> tick_clock_;
  202. };
  203. BEGIN_VIEW_BUILDER(/* no export */,
  204. CaptionBubble,
  205. views::BubbleDialogDelegateView)
  206. END_VIEW_BUILDER
  207. } // namespace captions
  208. DEFINE_VIEW_BUILDER(/* no export */, captions::CaptionBubble)
  209. #endif // COMPONENTS_LIVE_CAPTION_VIEWS_CAPTION_BUBBLE_H_