File: tab_restore_service_helper.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 (269 lines) | stat: -rw-r--r-- 11,078 bytes parent folder | download | duplicates (5)
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SESSIONS_CORE_TAB_RESTORE_SERVICE_HELPER_H_
#define COMPONENTS_SESSIONS_CORE_TAB_RESTORE_SERVICE_HELPER_H_

#include <optional>
#include <set>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/trace_event/memory_dump_provider.h"
#include "build/build_config.h"
#include "components/sessions/core/session_id.h"
#include "components/sessions/core/session_types.h"
#include "components/sessions/core/sessions_export.h"
#include "components/sessions/core/tab_restore_service.h"
#include "components/sessions/core/tab_restore_types.h"

namespace sessions {

class TabRestoreServiceImpl;
class TabRestoreServiceClient;
class LiveTabContext;
class TabRestoreServiceObserver;
class TimeFactory;

// Helper class used to implement TabRestoreService. See tab_restore_service.h
// for method-level comments.
class SESSIONS_EXPORT TabRestoreServiceHelper
    : public base::trace_event::MemoryDumpProvider {
 public:
  typedef TabRestoreService::DeletionPredicate DeletionPredicate;
  typedef TabRestoreService::Entries Entries;
  typedef tab_restore::Entry Entry;
  typedef tab_restore::Tab Tab;
  typedef tab_restore::TimeFactory TimeFactory;
  typedef tab_restore::Window Window;
  typedef tab_restore::Group Group;

  // Provides a way for the client to add behavior to the tab restore service
  // helper (e.g. implementing tabs persistence).
  class Observer {
   public:
    // Invoked before the entries are cleared.
    virtual void OnClearEntries();

    // Invoked when navigations from entries have been deleted.
    virtual void OnNavigationEntriesDeleted();

    // Invoked before the entry is restored. |entry_iterator| points to the
    // entry corresponding to the session identified by |id|.
    virtual void OnRestoreEntryById(SessionID id,
                                    Entries::const_iterator entry_iterator);

    // Invoked after an entry was added.
    virtual void OnAddEntry();

   protected:
    virtual ~Observer();
  };

  enum {
  // Max number of entries we'll keep around.
#if BUILDFLAG(IS_ANDROID)
    // Android keeps at most 5 recent tabs.
    kMaxEntries = 5,
#else
    kMaxEntries = 25,
#endif
  };

  // Creates a new TabRestoreServiceHelper and provides an object that provides
  // the current time. The TabRestoreServiceHelper does not take ownership of
  // |time_factory| and |observer|. Note that |observer| can also be NULL.
  TabRestoreServiceHelper(TabRestoreService* tab_restore_service,
                          TabRestoreServiceClient* client,
                          TimeFactory* time_factory);

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

  ~TabRestoreServiceHelper() override;

  void SetHelperObserver(Observer* observer);

  // Creates a mapping of local to saved ids for groups that have a
  // saved_group_id. Take in a window's group storage type, and outputs a type
  // usable for UpdateSavedGroupIDsForTabEntries.
  static std::map<tab_groups::TabGroupId, base::Uuid>
  CreateLocalSavedGroupIDMapping(
      const std::map<tab_groups::TabGroupId, std::unique_ptr<Group>>& groups);

  // Updates the saved group IDs for tabs based on the provided group mapping.
  // Used by RestoreEntryByID.
  static void UpdateSavedGroupIDsForTabEntries(
      std::vector<std::unique_ptr<tab_restore::Tab>>& tabs,
      const std::map<tab_groups::TabGroupId, base::Uuid>& group_mapping);

  // Helper methods used to implement TabRestoreService.
  void AddObserver(TabRestoreServiceObserver* observer);
  void RemoveObserver(TabRestoreServiceObserver* observer);
  std::optional<SessionID> CreateHistoricalTab(LiveTab* live_tab, int index);
  void BrowserClosing(LiveTabContext* context);
  void BrowserClosed(LiveTabContext* context);
  void CreateHistoricalGroup(LiveTabContext* context,
                             const tab_groups::TabGroupId& id);
  void GroupClosed(const tab_groups::TabGroupId& group);
  void GroupCloseStopped(const tab_groups::TabGroupId& group);
  void ClearEntries();
  void DeleteNavigationEntries(const DeletionPredicate& predicate);

  const Entries& entries() const;
  std::vector<LiveTab*> RestoreMostRecentEntry(LiveTabContext* context);
  void RemoveEntryById(SessionID id);
  std::vector<LiveTab*> RestoreEntryById(LiveTabContext* context,
                                         SessionID id,
                                         WindowOpenDisposition disposition);
  bool IsRestoring() const;

  // Notifies observers the entries have changed.
  void NotifyEntriesChanged();

  // Notifies observers the service has loaded.
  void NotifyLoaded();

  // Adds |entry| to the list of entries. If |prune| is true |PruneAndNotify| is
  // invoked. If |to_front| is true the entry is added to the front, otherwise
  // the back. Normal closes go to the front, but tab/window closes from the
  // previous session are added to the back.
  void AddEntry(std::unique_ptr<Entry> entry, bool prune, bool to_front);

  // Prunes |entries_| to contain only kMaxEntries, and removes uninteresting
  // entries.
  void PruneEntries();

  // Returns an iterator into |entries_| whose id or original_id matches |id|.
  // If |id| identifies a Window, then its iterator position will be returned.
  // If it identifies a tab, then the iterator position of the Window in which
  // the Tab resides is returned.
  Entries::iterator GetEntryIteratorById(SessionID id);

  // From base::trace_event::MemoryDumpProvider
  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                    base::trace_event::ProcessMemoryDump* pmd) override;

  // Calls ValidateTab, ValidateWindow, or ValidateGroup as appropriate.
  static bool ValidateEntry(const Entry& entry);

 private:
  friend class TabRestoreServiceImpl;

  // Populates the tab's navigations from the LiveTab, and its browser_id and
  // pinned state from the context.
  void PopulateTab(Tab* tab,
                   int index,
                   LiveTabContext* context,
                   LiveTab* live_tab);

  // This is a helper function for RestoreEntryById() for restoring a single
  // tab. If |context| is NULL, this creates a new window for the entry. This
  // returns the LiveTabContext into which the tab was restored. |disposition|
  // will be respected, but if it is UNKNOWN then the tab's original attributes
  // will be respected instead. If a new LiveTabContext needs to be created for
  // this tab, If present, |live_tab| will be populated with the LiveTab of the
  // restored tab.
  // |original_session_type| indicates the type of session entry the tab
  // belongs to.
  // |is_restoring_group_or_window| indicates if the tab is being restored
  // alongside other tabs inside the same group or window.
  LiveTabContext* RestoreTab(const Tab& tab,
                             LiveTabContext* context,
                             WindowOpenDisposition disposition,
                             sessions::tab_restore::Type session_restore_type,
                             LiveTab** live_tab,
                             bool is_restoring_group_or_window);

  // This is a helper function for RestoreEntryById(). Restores a single entry
  // from the `window`. The entry to restore is denoted by `id` and can either
  // be a single tab or an entire group.
  LiveTabContext* RestoreTabOrGroupFromWindow(Window& window,
                                              SessionID id,
                                              LiveTabContext* context,
                                              WindowOpenDisposition disposition,
                                              std::vector<LiveTab*>* live_tabs);

  // Helper function for CreateHistoricalGroup. Returns a Group populated with
  // metadta for the tab group `id`.
  std::unique_ptr<Group> CreateHistoricalGroupImpl(
      LiveTabContext* context,
      const tab_groups::TabGroupId& id);

  // Returns true if |tab| has at least one navigation and
  // |tab->current_navigation_index| is in bounds.
  static bool ValidateTab(const Tab& tab);

  // Validates all the tabs in a window, plus the window's active tab index.
  static bool ValidateWindow(const Window& window);

  // Validates all the tabs in a group.
  static bool ValidateGroup(const Group& group);

  // Removes all navigation entries matching |predicate| from |tab|.
  // Returns true if |tab| should be deleted because it is empty.
  static bool DeleteFromTab(const DeletionPredicate& predicate, Tab* tab);

  // Removes all navigation entries matching |predicate| from tabs in |window|.
  // Returns true if |window| should be deleted because it is empty.
  static bool DeleteFromWindow(const DeletionPredicate& predicate,
                               Window* window);

  // Removes all navigation entries matching |predicate| from tabs in |group|.
  // Returns true if |group| should be deleted because it is empty.
  static bool DeleteFromGroup(const DeletionPredicate& predicate, Group* group);

  // Returns true if |tab| is one we care about restoring.
  bool IsTabInteresting(const Tab& tab);

  // Checks whether |window| is interesting --- if it only contains a single,
  // uninteresting tab, it's not interesting.
  bool IsWindowInteresting(const Window& window);

  // Checks whether |group| is interesting -- as long as it contains tabs,
  // it is.
  bool IsGroupInteresting(const Group& group);

  // Validates and checks |entry| for interesting.
  bool FilterEntry(const Entry& entry);

  // Finds tab entries with the old browser_id and sets it to the new one.
  void UpdateTabBrowserIDs(SessionID::id_type old_id, SessionID new_id);

  // Gets the current time. This uses the time_factory_ if there is one.
  base::Time TimeNow() const;

  const raw_ptr<TabRestoreService> tab_restore_service_;

  raw_ptr<Observer> observer_;

  raw_ptr<TabRestoreServiceClient> client_;

  // Set of entries. They are ordered from most to least recent.
  Entries entries_;

  // Are we restoring a tab? If this is true we ignore requests to create a
  // historical tab.
  bool restoring_;

  base::ObserverList<TabRestoreServiceObserver>::Unchecked observer_list_;

  // Set of contexts that we've received a BrowserClosing method for but no
  // corresponding BrowserClosed. We cache the set of contexts closing to
  // avoid creating historical tabs for them.
  std::set<raw_ptr<LiveTabContext, SetExperimental>> closing_contexts_;

  // Set of groups that we've received a CreateHistoricalGroup method for but no
  // corresponding GroupClosed. We cache the set of groups closing to avoid
  // creating historical tabs for them.
  std::set<tab_groups::TabGroupId> closing_groups_;

  const raw_ptr<TimeFactory> time_factory_;
};

}  // namespace sessions

#endif  // COMPONENTS_SESSIONS_CORE_TAB_RESTORE_SERVICE_HELPER_H_