File: tab_model_test_helper.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (220 lines) | stat: -rw-r--r-- 8,671 bytes parent folder | download | duplicates (4)
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// 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_ANDROID_TAB_MODEL_TAB_MODEL_TEST_HELPER_H_
#define CHROME_BROWSER_UI_ANDROID_TAB_MODEL_TAB_MODEL_TEST_HELPER_H_

#include <memory>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/sequence_checker.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/flags/android/chrome_session_state.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "content/public/test/browser_test_utils.h"
#include "url/gurl.h"

namespace content {
class WebContents;
}

class TabModelObserver;

// TestTabModel is a thin TabModel that can be used for testing Android tab
// behavior. It holds pointers to WebContents that are owned elsewhere. Many
// functions are unimplemented. Use OwningTestTabModel for a more complete
// TabModel implementation.
// TODO(crbug.com/415309796): Convert tests using this to OwningTestTabModel and
// remove it.
class TestTabModel : public TabModel {
 public:
  explicit TestTabModel(Profile* profile,
                        chrome::android::ActivityType activity_type =
                            chrome::android::ActivityType::kTabbed);
  ~TestTabModel() override;

  // TabModel:
  // Returns tab_count_ if not 0. Otherwise, returns size of web_contents_list_.
  int GetTabCount() const override;
  int GetActiveIndex() const override;
  content::WebContents* GetWebContentsAt(int index) const override;
  base::android::ScopedJavaLocalRef<jobject> GetJavaObject() const override;
  void CreateTab(TabAndroid* parent,
                 content::WebContents* web_contents,
                 bool select) override;
  void HandlePopupNavigation(TabAndroid* parent,
                             NavigateParams* params) override;
  content::WebContents* CreateNewTabForDevTools(const GURL& url,
                                                bool new_window) override;
  bool IsSessionRestoreInProgress() const override;

  bool IsActiveModel() const override;
  void SetIsActiveModel(bool is_active);

  TabAndroid* GetTabAt(int index) const override;
  void SetActiveIndex(int index) override;
  void ForceCloseAllTabs() override;
  void CloseTabAt(int index) override;
  void AddObserver(TabModelObserver* observer) override;
  void RemoveObserver(TabModelObserver* observer) override;

  TabModelObserver* GetObserver();
  void SetTabCount(int tab_count);
  void SetWebContentsList(
      const std::vector<raw_ptr<content::WebContents>>& web_contents_list);
  int GetTabCountNavigatedInTimeWindow(
      const base::Time& begin_time,
      const base::Time& end_time) const override;
  void CloseTabsNavigatedInTimeWindow(const base::Time& begin_time,
                                      const base::Time& end_time) override;

  // TODO(crbug.com/415351293): Implement these.
  // TabListInterface implementation.
  void OpenTab(const GURL& url, int index) override;
  void DiscardTab(int index) override;
  void DuplicateTab(int index) override;
  tabs::TabInterface* GetTab(int index) override;
  void HighlightTabs(std::set<int> indicies) override;
  void MoveTab(int from_index, int to_index) override;
  void CloseTab(int index) override;
  std::vector<tabs::TabInterface*> GetAllTabs() override;
  void PinTab(int index) override;
  void UnpinTab(int index) override;
  std::optional<tab_groups::TabGroupId> CreateGroup(
      std::set<int> indicies) override;
  void MoveGroupTo(tab_groups::TabGroupId group_id, int index) override;

 private:
  // A fake value for the current number of tabs.
  int tab_count_ = 0;
  bool is_active_ = false;

  raw_ptr<TabModelObserver> observer_ = nullptr;
  std::vector<raw_ptr<content::WebContents>> web_contents_list_;
};

// A TabModel that owns the WebContents for each tab and simulates many of the
// operations that are provided by the JNI bridge in the production TabModel.
class OwningTestTabModel : public TabModel {
 public:
  // Creates a TabModel that starts empty. The model will automatically be added
  // to the TabModelList, and removed when it's destroyed.
  explicit OwningTestTabModel(Profile* profile,
                              chrome::android::ActivityType activity_type =
                                  chrome::android::ActivityType::kTabbed);

  ~OwningTestTabModel() override;

  OwningTestTabModel(const OwningTestTabModel&) = delete;
  OwningTestTabModel& operator=(const OwningTestTabModel&) = delete;

  // TabModel:

  int GetTabCount() const override;
  int GetActiveIndex() const override;
  content::WebContents* GetWebContentsAt(int index) const override;
  TabAndroid* GetTabAt(int index) const override;
  void SetActiveIndex(int index) override;
  void ForceCloseAllTabs() override;
  void CloseTabAt(int index) override;
  void CreateTab(TabAndroid* parent,
                 content::WebContents* web_contents,
                 bool select) override;
  bool IsActiveModel() const override;
  void AddObserver(TabModelObserver* observer) override;
  void RemoveObserver(TabModelObserver* observer) override;

  // Unimplemented methods.
  base::android::ScopedJavaLocalRef<jobject> GetJavaObject() const override;
  void HandlePopupNavigation(TabAndroid* parent,
                             NavigateParams* params) override;
  content::WebContents* CreateNewTabForDevTools(const GURL& url,
                                                bool new_window) override;
  bool IsSessionRestoreInProgress() const override;
  int GetTabCountNavigatedInTimeWindow(
      const base::Time& begin_time,
      const base::Time& end_time) const override;
  void CloseTabsNavigatedInTimeWindow(const base::Time& begin_time,
                                      const base::Time& end_time) override;

  // Test accessors:

  // Adds a new tab containing an empty `web_contents` at `index`. If `select`
  // is true the new tab will become active.
  TabAndroid* AddEmptyTab(size_t index,
                          bool select = false,
                          TabModel::TabLaunchType launch_type =
                              TabModel::TabLaunchType::FROM_CHROME_UI);

  // Adds a new tab containing `web_contents` at `index`. If `select` is true
  // the new tab will become active.
  TabAndroid* AddTabFromWebContents(
      std::unique_ptr<content::WebContents> web_contents,
      size_t index,
      bool select = false,
      TabModel::TabLaunchType launch_type =
          TabModel::TabLaunchType::FROM_CHROME_UI);

  void SetIsActiveModel(bool is_active);

  // TODO(crbug.com/415351293): Implement these.
  // TabListInterface implementation.
  void OpenTab(const GURL& url, int index) override;
  void DiscardTab(int index) override;
  void DuplicateTab(int index) override;
  tabs::TabInterface* GetTab(int index) override;
  void HighlightTabs(std::set<int> indicies) override;
  void MoveTab(int from_index, int to_index) override;
  void CloseTab(int index) override;
  std::vector<tabs::TabInterface*> GetAllTabs() override;
  void PinTab(int index) override;
  void UnpinTab(int index) override;
  std::optional<tab_groups::TabGroupId> CreateGroup(
      std::set<int> indicies) override;
  void MoveGroupTo(tab_groups::TabGroupId group_id, int index) override;

 private:
  void SelectTab(TabAndroid* tab, TabModel::TabSelectionType selection_type);

  SEQUENCE_CHECKER(sequence_checker_);

  base::ObserverList<TabModelObserver>::Unchecked observer_list_
      GUARDED_BY_CONTEXT(sequence_checker_);

  std::vector<std::unique_ptr<TabAndroid>> owned_tabs_
      GUARDED_BY_CONTEXT(sequence_checker_);

  raw_ptr<TabAndroid> active_tab_ GUARDED_BY_CONTEXT(sequence_checker_) =
      nullptr;

  bool is_active_model_ GUARDED_BY_CONTEXT(sequence_checker_) = false;

  int next_tab_id_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
};

// Waits until a TabAndroid has a WebContents assigned that's finished loading.
class TabAndroidLoadedWaiter final : public TabAndroid::Observer {
 public:
  explicit TabAndroidLoadedWaiter(TabAndroid* tab);
  ~TabAndroidLoadedWaiter() final;

  TabAndroidLoadedWaiter(const TabAndroidLoadedWaiter&) = delete;
  TabAndroidLoadedWaiter& operator=(const TabAndroidLoadedWaiter&) = delete;

  bool Wait();

  // TabAndroid::Observer:
  void OnInitWebContents(TabAndroid* tab) final;

 private:
  content::WaiterHelper waiter_helper_;
  bool load_succeeded_ = false;
  base::ScopedObservation<TabAndroid, TabAndroid::Observer> tab_observation_{
      this};
};

#endif  // CHROME_BROWSER_UI_ANDROID_TAB_MODEL_TAB_MODEL_TEST_HELPER_H_