File: tab_hover_card_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (193 lines) | stat: -rw-r--r-- 7,714 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_CONTROLLER_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_CONTROLLER_H_

#include <memory>

#include "base/callback_list.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/performance_controls/tab_resource_usage_collector.h"
#include "chrome/browser/ui/views/tabs/tab_slot_controller.h"
#include "components/prefs/pref_change_registrar.h"
#include "ui/events/event.h"
#include "ui/views/animation/bubble_slide_animator.h"
#include "ui/views/animation/widget_fade_animator.h"
#include "ui/views/view.h"
#include "ui/views/view_observer.h"

namespace gfx {
class ImageSkia;
}

class TabHoverCardBubbleView;
class TabHoverCardThumbnailObserver;
class Tab;
class TabStrip;

// Controls how hover cards are shown and hidden for tabs.
class TabHoverCardController : public views::ViewObserver,
                               public TabResourceUsageCollector::Observer {
 public:
  explicit TabHoverCardController(TabStrip* tab_strip);
  ~TabHoverCardController() override;

  bool IsHoverCardVisible() const;
  bool IsHoverCardShowingForTab(Tab* tab) const;
  void UpdateHoverCard(Tab* tab,
                       TabSlotController::HoverCardUpdateType update_type);
  void PreventImmediateReshow();

  TabHoverCardBubbleView* hover_card_for_testing() { return hover_card_.get(); }

  size_t hover_cards_seen_count_for_testing() const {
    return hover_cards_seen_count_;
  }

  static void set_disable_animations_for_testing(
      bool disable_animations_for_testing) {
    disable_animations_for_testing_ = disable_animations_for_testing;
  }

 private:
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, ShowWrongTabDoesntCrash);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest,
                           SetPreviewWithNoHoverCardDoesntCrash);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, ShowPreviewsForTab);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, DisablePreviewsForTab);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardFadeFooterInteractiveUiTest,
                           HoverCardFooterMemoryUsagePrefEnabled);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardFadeFooterInteractiveUiTest,
                           HoverCardFooterMemoryUsagePrefDisabled);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest,
                           HidePreviewsForDiscardedTab);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest,
                           DisableMemoryUsageForTab);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest,
                           ShowPreviewsForDiscardedTabWithThumbnail);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest,
                           DontCaptureUnderCriticalMemoryPressure);
  FRIEND_TEST_ALL_PREFIXES(TabHoverCardPreviewsEnabledPrefTest, DefaultState);
  class EventSniffer;

  enum ThumbnailWaitState {
    kNotWaiting,
    kWaitingWithPlaceholder,
    kWaitingWithoutPlaceholder
  };

  // Returns whether the hover card preview images feature is enabled.
  static bool AreHoverCardImagesEnabled();

  // Returns whether hover card animations should be shown on the current
  // device.
  static bool UseAnimations();

  // views::ViewObserver:
  void OnViewIsDeleting(views::View* observed_view) override;
  void OnViewVisibilityChanged(views::View* observed_view,
                               views::View* starting_view) override;

  // TabResourceUsageCollector::Observer:
  void OnTabResourceMetricsRefreshed() override;

  bool ArePreviewsEnabled() const;

  void CreateHoverCard(Tab* tab);
  void UpdateCardContent(Tab* tab);
  void MaybeStartThumbnailObservation(Tab* tab, bool is_initial_show);
  void StartThumbnailObservation(Tab* tab);

  void UpdateOrShowCard(Tab* tab,
                        TabSlotController::HoverCardUpdateType update_type);
  void ShowHoverCard(bool is_initial, const Tab* intended_tab);
  void HideHoverCard();

  bool ShouldShowImmediately(const Tab* tab) const;

  const views::View* GetTargetAnchorView() const;

  // Determines if `target_tab_` is still valid. Call this when entering
  // TabHoverCardController from an asynchronous callback.
  bool TargetTabIsValid() const;

  // Helper for recording when a card becomes fully visible to the user.
  void OnCardFullyVisible();

  // Helper for resetting the cards seen count for testing.
  void ResetCardsSeenCount();

  // Animator events:
  void OnFadeAnimationEnded(views::WidgetFadeAnimator* animator,
                            views::WidgetFadeAnimator::FadeType fade_type);
  void OnSlideAnimationProgressed(views::BubbleSlideAnimator* animator,
                                  double value);
  void OnSlideAnimationComplete(views::BubbleSlideAnimator* animator);

  void OnPreviewImageAvailable(TabHoverCardThumbnailObserver* observer,
                               gfx::ImageSkia thumbnail_image);

  void OnHovercardImagesEnabledChanged();
  void OnHovercardMemoryUsageEnabledChanged();

  bool waiting_for_preview() const {
    return thumbnail_wait_state_ != ThumbnailWaitState::kNotWaiting;
  }

  // Timestamp of the last time the hover card is hidden by the mouse leaving
  // the tab strip. This is used for reshowing the hover card without delay if
  // the mouse reenters within a given amount of time.
  base::TimeTicks last_mouse_exit_timestamp_;

  raw_ptr<Tab> target_tab_ = nullptr;
  const raw_ptr<TabStrip> tab_strip_;
  raw_ptr<TabHoverCardBubbleView> hover_card_ = nullptr;
  base::ScopedObservation<views::View, views::ViewObserver>
      hover_card_observation_{this};
  base::ScopedObservation<views::View, views::ViewObserver>
      target_tab_observation_{this};
  std::unique_ptr<EventSniffer> event_sniffer_;

  // These are used to track when a hover card is shown on a new tab for
  // testing purposes. Counts cards seen from the time the first card is shown
  // to a tab is selected, or the hover card is shown from scratch again.
  raw_ptr<const void> hover_card_last_seen_on_tab_ = nullptr;
  size_t hover_cards_seen_count_ = 0;

  // Fade animations interfere with browser tests so we disable them in tests.
  static bool disable_animations_for_testing_;
  std::unique_ptr<views::WidgetFadeAnimator> fade_animator_;

  // Used to animate the tab hover card's movement between tabs.
  std::unique_ptr<views::BubbleSlideAnimator> slide_animator_;

  std::unique_ptr<TabHoverCardThumbnailObserver> thumbnail_observer_;
  base::CallbackListSubscription thumbnail_subscription_;
  ThumbnailWaitState thumbnail_wait_state_ = ThumbnailWaitState::kNotWaiting;

  base::CallbackListSubscription fade_complete_subscription_;
  base::CallbackListSubscription slide_progressed_subscription_;
  base::CallbackListSubscription slide_complete_subscription_;

  // Ensure that an instance of the TabResourceUsageCollector exists so
  // resources are up to date when we eventually show the hover card.
  raw_ptr<TabResourceUsageCollector> tab_resource_usage_collector_;

  // Tracks changes to the hover card preferences
  PrefChangeRegistrar pref_change_registrar_;
  bool hover_card_image_previews_enabled_ = false;
  bool hover_card_memory_usage_enabled_ = false;

  // Ensure that this timer is destroyed before anything else is cleaned up.
  base::OneShotTimer delayed_show_timer_;
  base::WeakPtrFactory<TabHoverCardController> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_CONTROLLER_H_