summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sessions/tab_restore_service_helper.h
blob: c34220d86d7d05c6ef7e840171b2d093e7f43a60 (plain)
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 (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_
#define CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_

#include <set>
#include <vector>

#include "base/basictypes.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "chrome/browser/sessions/session_id.h"
#include "chrome/browser/sessions/session_types.h"
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/ui/host_desktop.h"

class Profile;
class TabRestoreService;
class TabRestoreServiceDelegate;
class TabRestoreServiceObserver;
class TimeFactory;

namespace content {
class NavigationController;
class WebContents;
}

// Helper class used to implement InMemoryTabRestoreService and
// PersistentTabRestoreService. See tab_restore_service.h for method-level
// comments.
class TabRestoreServiceHelper {
 public:
  typedef TabRestoreService::Entries Entries;
  typedef TabRestoreService::Entry Entry;
  typedef TabRestoreService::Tab Tab;
  typedef TabRestoreService::TimeFactory TimeFactory;
  typedef TabRestoreService::Window Window;

  // 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 before the entry is restored. |entry_iterator| points to the
    // entry corresponding to the session identified by |id|.
    virtual void OnRestoreEntryById(SessionID::id_type 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.
    kMaxEntries = 25,
  };

  // 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,
                          Observer* observer,
                          Profile* profile,
                          TimeFactory* time_factory);

  ~TabRestoreServiceHelper();

  // Helper methods used to implement TabRestoreService.
  void AddObserver(TabRestoreServiceObserver* observer);
  void RemoveObserver(TabRestoreServiceObserver* observer);
  void CreateHistoricalTab(content::WebContents* contents, int index);
  void BrowserClosing(TabRestoreServiceDelegate* delegate);
  void BrowserClosed(TabRestoreServiceDelegate* delegate);
  void ClearEntries();
  const Entries& entries() const;
  std::vector<content::WebContents*> RestoreMostRecentEntry(
      TabRestoreServiceDelegate* delegate,
      chrome::HostDesktopType host_desktop_type);
  Tab* RemoveTabEntryById(SessionID::id_type id);
  std::vector<content::WebContents*> RestoreEntryById(
      TabRestoreServiceDelegate* delegate,
      SessionID::id_type id,
      chrome::HostDesktopType host_desktop_type,
      WindowOpenDisposition disposition);

  // Notifies observers the tabs have changed.
  void NotifyTabsChanged();

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

  // Adds |entry| to the list of entries and takes ownership. 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(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 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_type id);

  // Calls either ValidateTab or ValidateWindow as appropriate.
  static bool ValidateEntry(Entry* entry);

 private:
  friend class PersistentTabRestoreService;

  // Populates the tab's navigations from the NavigationController, and its
  // browser_id and pinned state from the browser.
  void PopulateTab(Tab* tab,
                   int index,
                   TabRestoreServiceDelegate* delegate,
                   content::NavigationController* controller);

  // This is a helper function for RestoreEntryById() for restoring a single
  // tab. If |delegate| is NULL, this creates a new window for the entry. This
  // returns the TabRestoreServiceDelegate 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 browser needs to be
  // created for this tab, it will be created on the desktop specified by
  // |host_desktop_type|. If present, |contents| will be populated with the
  // WebContents of the restored tab.
  TabRestoreServiceDelegate* RestoreTab(
      const Tab& tab,
      TabRestoreServiceDelegate* delegate,
      chrome::HostDesktopType host_desktop_type,
      WindowOpenDisposition disposition,
      content::WebContents** contents);

  // Returns true if |tab| has more than one navigation. If |tab| has more
  // than one navigation |tab->current_navigation_index| is constrained based
  // on the number of navigations.
  static bool ValidateTab(Tab* tab);

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

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

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

  // Validates and checks |entry| for interesting.
  static bool FilterEntry(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::id_type new_id);

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

  TabRestoreService* const tab_restore_service_;

  Observer* const observer_;

  Profile* const profile_;

  // 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_;

  ObserverList<TabRestoreServiceObserver> observer_list_;

  // Set of delegates that we've received a BrowserClosing method for but no
  // corresponding BrowserClosed. We cache the set of delegates closing to
  // avoid creating historical tabs for them.
  std::set<TabRestoreServiceDelegate*> closing_delegates_;

  TimeFactory* const time_factory_;

  DISALLOW_COPY_AND_ASSIGN(TabRestoreServiceHelper);
};

#endif  // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_HELPER_H_