File: tab_declutter_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 (172 lines) | stat: -rw-r--r-- 6,131 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
// Copyright 2024 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_TABS_ORGANIZATION_TAB_DECLUTTER_CONTROLLER_H_
#define CHROME_BROWSER_UI_TABS_ORGANIZATION_TAB_DECLUTTER_CONTROLLER_H_

#include <memory>
#include <optional>
#include <set>

#include "base/callback_list.h"
#include "base/containers/span.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/types/pass_key.h"
#include "chrome/browser/ui/tabs/organization/tab_declutter_observer.h"
#include "chrome/browser/ui/tabs/organization/trigger_policies.h"
#include "chrome/browser/ui/webui/tab_search/tab_search.mojom-forward.h"
#include "url/gurl.h"

class TabStripActionContainer;
class TabStripModel;
class TabSearchContainer;
class BrowserWindowInterface;

namespace tabs {

class TabInterface;

// Controller that computes the tabs to be decluttered, tied to a specific
// browser.
class TabDeclutterController {
 public:
  static void EmitEntryPointHistogram(
      tab_search::mojom::TabDeclutterEntryPoint entry_point);

  explicit TabDeclutterController(
      BrowserWindowInterface* browser_window_interface);
  TabDeclutterController(const TabDeclutterController&) = delete;
  TabDeclutterController& operator=(const TabDeclutterController& other) =
      delete;
  virtual ~TabDeclutterController();

  void AddObserver(TabDeclutterObserver* observer) {
    observers_.AddObserver(observer);
  }

  void RemoveObserver(TabDeclutterObserver* observer) {
    observers_.RemoveObserver(observer);
  }

  bool HasObserver(TabDeclutterObserver* observer) {
    return observers_.HasObserver(observer);
  }

  base::TimeDelta stale_tab_threshold_duration() const {
    return stale_tab_threshold_duration_;
  }

  base::RepeatingTimer* GetDeclutterTimerForTesting() const {
    return declutter_timer_.get();
  }

  base::TimeDelta declutter_timer_interval() const {
    return declutter_timer_interval_;
  }

  base::TimeTicks next_nudge_valid_time_ticks() const {
    return next_nudge_valid_time_ticks_;
  }

  void set_next_nudge_valid_time_ticks_for_testing(
      base::TimeTicks next_nudge_valid_time_ticks) {
    next_nudge_valid_time_ticks_ = next_nudge_valid_time_ticks;
  }

  base::TimeDelta nudge_timer_interval() const { return nudge_timer_interval_; }

  void OnActionUIDismissed(base::PassKey<TabSearchContainer>);
  void OnActionUIDismissed(base::PassKey<TabStripActionContainer>);

  void SetTimerForTesting(const base::TickClock* tick_clock,
                          scoped_refptr<base::SequencedTaskRunner> task_runner);

  virtual std::vector<tabs::TabInterface*> GetStaleTabs();

  virtual std::map<GURL, std::vector<tabs::TabInterface*>> GetDuplicateTabs();

  TabStripModel* tab_strip_model() { return tab_strip_model_; }

  void ExcludeFromStaleTabs(tabs::TabInterface* tabs);

  void ExcludeFromDuplicateTabs(GURL url);

  void DidBecomeActive(BrowserWindowInterface* browser_window_interface);

  void DidBecomeInactive(BrowserWindowInterface* browser_window_interface);

  // Closes the tabs from the tabstrip if they are present.
  void DeclutterTabs(std::vector<tabs::TabInterface*> tabs,
                     const std::vector<GURL>& urls);

 private:
  void StartDeclutterTimer();

  // Returns whether the nudge should be shown in the tabstrip for declutter.
  // Note: The calculation for stale tabs and duplicate tabs are considered
  // independent of each other from the perspective of the controller. This
  // means that the expected unused tabs for nudge might be different from that
  // of the webUI in certain edge cases where a duplicate tab is also a stale
  // tab.
  bool DeclutterNudgeCriteriaMet(
      base::span<tabs::TabInterface*> stale_tabs,
      std::map<GURL, std::vector<tabs::TabInterface*>> duplicate_tabs);

  bool DeclutterStaleTabsNudgeCriteriaMet(
      base::span<tabs::TabInterface*> stale_tabs);

  bool DeclutterDuplicateTabsNudgeCriteriaMet(
      std::map<GURL, std::vector<tabs::TabInterface*>> duplicate_tabs);

  // Helper for computing `DeclutterNudgeCriteriaMet()` by calculating if there
  // is a new unused tab from the previous nudge.
  bool HasNewUnusedTabsForNudge(
      base::span<tabs::TabInterface*> stale_tabs,
      std::map<GURL, std::vector<tabs::TabInterface*>> duplicate_tabs) const;

  // Returns if `tabs` has an element not present in `tabs_previous_nudge_`.
  bool IsNewTabDetectedForNudge(base::span<tabs::TabInterface*> tabs) const;
  void ProcessTabs();

  void StartNudgeTimer();

  void LogExcludedDuplicateTabMetrics();

  bool IsTabExcluded(tabs::TabInterface* tab) const;

  void ResetAndDoubleNudgeTimer();

  // Duration of inactivity after which a tab is considered stale.
  base::TimeDelta stale_tab_threshold_duration_;
  // Interval between a recomputation of stale tabs.
  base::TimeDelta declutter_timer_interval_;
  // Interval after showing a nudge to prevent another nudge from being shown.
  base::TimeDelta nudge_timer_interval_;
  // The timer that is responsible for calculating stale tabs on getting
  // triggered.
  std::unique_ptr<base::RepeatingTimer> declutter_timer_;
  // The usage tick clock that is used for setting
  // `next_nudge_valid_time_ticks_` and comparing time ticks with
  // `next_nudge_valid_time_ticks_` to show the nudge.
  std::unique_ptr<UsageTickClock> usage_tick_clock_;
  // The timer that is responsible for blocking the nudge from showing.
  base::TimeTicks next_nudge_valid_time_ticks_;
  // The list of tabs shown previously in a nudge.
  std::set<tabs::TabInterface*> tabs_previous_nudge_;

  base::ObserverList<TabDeclutterObserver> observers_;
  raw_ptr<TabStripModel> tab_strip_model_;
  std::set<tabs::TabInterface*> excluded_tabs_;
  std::set<GURL> excluded_urls_;

  bool is_active_;
  // Holds subscriptions for BrowserWindowInterface callbacks.
  std::vector<base::CallbackListSubscription> browser_subscriptions_;
};

}  // namespace tabs

#endif  // CHROME_BROWSER_UI_TABS_ORGANIZATION_TAB_DECLUTTER_CONTROLLER_H_