1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_CHROMEOS_TAB_CLOSEABLE_STATE_WATCHER_H_
6 #define CHROME_BROWSER_CHROMEOS_TAB_CLOSEABLE_STATE_WATCHER_H_
11 #include "base/compiler_specific.h"
12 #include "chrome/browser/tab_closeable_state_watcher.h"
13 #include "chrome/browser/tabs/tab_strip_model_observer.h"
14 #include "chrome/browser/ui/browser_list.h"
15 #include "content/public/browser/notification_registrar.h"
19 // This class overrides ::TabCloseableStateWatcher to allow or disallow tabs or
20 // browsers to be closed based on increase or decrease in number of tabs or
21 // browsers. We only do this on Chromeos and only for non-tests.
24 // 1) A tab, and hence its containing browser, is not closeable if the tab is
25 // the last NewTabPage in the last normal non-incognito browser and user is not
27 // 2) Otherwise, if user closes a normal non-incognito browser or the last tab
28 // in it, the browser stays open, the existing tabs are closed, and a new
29 // NewTabPage is opened.
30 // 3) Or, if user closes a normal incognito browser or the last tab in it, the
31 // browser closes, a new non-incognito normal browser is opened with a
32 // NewTabPage (which, by rule 1, will not be closeable).
34 // BWSI session (all browsers are incognito):
35 // Almost the same as in the normal session, but
36 // 1) A tab, and hence its containing browser, is not closeable if the tab is
37 // the last NewTabPage in the last browser (again, all browsers are incognito
39 // 2-3) Otherwise, if user closes a normal incognito browser or the last tab in
40 // it, the browser stays open, the existing tabs are closed, and a new
41 // NewTabPage is open.
43 class TabCloseableStateWatcher
: public ::TabCloseableStateWatcher
,
44 public BrowserList::Observer
,
45 public content::NotificationObserver
{
47 TabCloseableStateWatcher();
48 virtual ~TabCloseableStateWatcher();
50 // TabCloseableStateWatcher implementation:
51 virtual bool CanCloseTab(const Browser
* browser
) const OVERRIDE
;
52 virtual bool CanCloseTabs(const Browser
* browser
,
53 std::vector
<int>* indices
) const OVERRIDE
;
54 virtual bool CanCloseBrowser(Browser
* browser
) OVERRIDE
;
55 virtual void OnWindowCloseCanceled(Browser
* browser
) OVERRIDE
;
58 enum BrowserActionType
{
59 NONE
= 0, // Nothing to do.
60 OPEN_WINDOW
= 1, // Opens a regular (i.e. non-incognito) normal browser.
61 OPEN_NTP
= 2, // Opens a NewTabPage.
64 // BrowserList::Observer implementation:
65 virtual void OnBrowserAdded(const Browser
* browser
) OVERRIDE
;
66 virtual void OnBrowserRemoved(const Browser
* browser
) OVERRIDE
;
68 // NotificationObserver implementation:
69 virtual void Observe(int type
, const content::NotificationSource
& source
,
70 const content::NotificationDetails
& details
) OVERRIDE
;
72 // Called by private class TabStripWatcher for TabStripModelObserver
74 // |closing_last_tab| is true if the tab strip is closing the last tab.
75 void OnTabStripChanged(const Browser
* browser
, bool closing_last_tab
);
79 // Checks the closeable state of tab. If it has changed, updates it and
80 // notifies all normal browsers.
81 // |browser_to_check| is the browser whose closeable state the caller is
82 // interested in; can be NULL if caller is interested in all browsers, e.g.
83 // when a browser is being removed and there's no specific browser to check.
84 void CheckAndUpdateState(const Browser
* browser_to_check
);
86 // Sets the new closeable state and fires notification.
87 void SetCloseableState(bool closeable
);
89 // Returns true if closing of |browser| is permitted.
90 // |action_type| is the action to take regardless if browser is closeable.
91 bool CanCloseBrowserImpl(const Browser
* browser
,
92 BrowserActionType
* action_type
);
96 // This is true if tab can be closed; it's updated in CheckAndUpdateState and
97 // when sign-off notification is received.
100 // This is true when sign-off notification is received; it lets us know to
101 // allow closing of all tabs and browsers in this situation.
104 // Is in guest session?
107 // Set to true if we're waiting for a new browser to be created. When true we
108 // uncoditionally allow everything as we know a browser is in the process of
110 bool waiting_for_browser_
;
112 content::NotificationRegistrar notification_registrar_
;
114 // TabStripWatcher is a TabStripModelObserver that funnels all interesting
115 // methods to TabCloseableStateWatcher::OnTabStripChanged. TabStripWatcher is
116 // needed so we know which browser the TabStripModelObserver method relates
118 class TabStripWatcher
: public TabStripModelObserver
{
120 TabStripWatcher(TabCloseableStateWatcher
* main_watcher
,
121 const Browser
* browser
);
122 virtual ~TabStripWatcher();
124 // TabStripModelObserver implementation:
125 virtual void TabInsertedAt(TabContentsWrapper
* contents
, int index
,
126 bool foreground
) OVERRIDE
;
127 virtual void TabClosingAt(TabStripModel
* tab_strip_model
,
128 TabContentsWrapper
* contents
,
130 virtual void TabDetachedAt(TabContentsWrapper
* contents
,
132 virtual void TabChangedAt(TabContentsWrapper
* contents
, int index
,
133 TabChangeType change_type
) OVERRIDE
;
135 const Browser
* browser() const {
140 TabCloseableStateWatcher
* main_watcher_
;
141 const Browser
* browser_
;
143 DISALLOW_COPY_AND_ASSIGN(TabStripWatcher
);
146 friend class TabStripWatcher
;
148 std::vector
<TabStripWatcher
*> tabstrip_watchers_
;
150 DISALLOW_COPY_AND_ASSIGN(TabCloseableStateWatcher
);
153 } // namespace chromeos
155 #endif // CHROME_BROWSER_CHROMEOS_TAB_CLOSEABLE_STATE_WATCHER_H_