Home | History | Annotate | Download | only in chromeos
      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.
      4 
      5 #ifndef CHROME_BROWSER_CHROMEOS_TAB_CLOSEABLE_STATE_WATCHER_H_
      6 #define CHROME_BROWSER_CHROMEOS_TAB_CLOSEABLE_STATE_WATCHER_H_
      7 #pragma once
      8 
      9 #include <vector>
     10 
     11 #include "chrome/browser/tab_closeable_state_watcher.h"
     12 #include "chrome/browser/tabs/tab_strip_model_observer.h"
     13 #include "chrome/browser/ui/browser_list.h"
     14 #include "content/common/notification_registrar.h"
     15 
     16 namespace chromeos {
     17 
     18 // This class overrides ::TabCloseableStateWatcher to allow or disallow tabs or
     19 // browsers to be closed based on increase or decrease in number of tabs or
     20 // browsers.  We only do this on Chromeos and only for non-tests.
     21 //
     22 // Normal session:
     23 // 1) A tab, and hence its containing browser, is not closeable if the tab is
     24 // the last NewTabPage in the last normal non-incognito browser and user is not
     25 // signing off.
     26 // 2) Otherwise, if user closes a normal non-incognito browser or the last tab
     27 // in it, the browser stays open, the existing tabs are closed, and a new
     28 // NewTabPage is opened.
     29 // 3) Or, if user closes a normal incognito browser or the last tab in it, the
     30 // browser closes, a new non-incognito normal browser is opened with a
     31 // NewTabPage (which, by rule 1, will not be closeable).
     32 //
     33 // BWSI session (all browsers are incognito):
     34 // Almost the same as in the normal session, but
     35 // 1) A tab, and hence its containing browser, is not closeable if the tab is
     36 // the last NewTabPage in the last browser (again, all browsers are incognito
     37 // browsers).
     38 // 2-3) Otherwise, if user closes a normal incognito browser or the last tab in
     39 // it, the browser stays open, the existing tabs are closed, and a new
     40 // NewTabPage is open.
     41 
     42 class TabCloseableStateWatcher : public ::TabCloseableStateWatcher,
     43                                  public BrowserList::Observer,
     44                                  public NotificationObserver {
     45  public:
     46   TabCloseableStateWatcher();
     47   virtual ~TabCloseableStateWatcher();
     48 
     49   // TabCloseableStateWatcher implementation:
     50   virtual bool CanCloseTab(const Browser* browser) const;
     51   virtual bool CanCloseBrowser(Browser* browser);
     52   virtual void OnWindowCloseCanceled(Browser* browser);
     53 
     54  private:
     55   enum BrowserActionType {
     56     NONE = 0,         // Nothing to do.
     57     OPEN_WINDOW = 1,  // Opens a regular (i.e. non-incognito) normal browser.
     58     OPEN_NTP = 2,     // Opens a NewTabPage.
     59   };
     60 
     61   // BrowserList::Observer implementation:
     62   virtual void OnBrowserAdded(const Browser* browser);
     63   virtual void OnBrowserRemoved(const Browser* browser);
     64 
     65   // NotificationObserver implementation:
     66   virtual void Observe(NotificationType type, const NotificationSource& source,
     67                        const NotificationDetails& details);
     68 
     69   // Called by private class TabStripWatcher for TabStripModelObserver
     70   // notifications.
     71   // |closing_last_tab| is true if the tab strip is closing the last tab.
     72   virtual void OnTabStripChanged(const Browser* browser, bool closing_last_tab);
     73 
     74   // Utility functions.
     75 
     76   // Checks the closeable state of tab.  If it has changed, updates it and
     77   // notifies all normal browsers.
     78   // |browser_to_check| is the browser whose closeable state the caller is
     79   // interested in; can be NULL if caller is interested in all browsers, e.g.
     80   // when a browser is being removed and there's no specific browser to check.
     81   void CheckAndUpdateState(const Browser* browser_to_check);
     82 
     83   // Sets the new closeable state and fires notification.
     84   void SetCloseableState(bool closeable);
     85 
     86   // Returns true if closing of |browser| is permitted.
     87   // |action_type| is the action to take regardless if browser is closeable.
     88   bool CanCloseBrowserImpl(const Browser* browser,
     89                            BrowserActionType* action_type);
     90 
     91   // Data members.
     92 
     93   // This is true if tab can be closed; it's updated in CheckAndUpdateState and
     94   // when sign-off notification is received.
     95   bool can_close_tab_;
     96 
     97   // This is true when sign-off notification is received; it lets us know to
     98   // allow closing of all tabs and browsers in this situation.
     99   bool signing_off_;
    100 
    101   // Is in guest session?
    102   bool guest_session_;
    103 
    104   // Set to true if we're waiting for a new browser to be created. When true we
    105   // uncoditionally allow everything as we know a browser is in the process of
    106   // being created.
    107   bool waiting_for_browser_;
    108 
    109   NotificationRegistrar notification_registrar_;
    110 
    111   // TabStripWatcher is a TabStripModelObserver that funnels all interesting
    112   // methods to TabCloseableStateWatcher::OnTabStripChanged. TabStripWatcher is
    113   // needed so we know which browser the TabStripModelObserver method relates
    114   // to.
    115   class TabStripWatcher : public TabStripModelObserver {
    116    public:
    117     TabStripWatcher(TabCloseableStateWatcher* main_watcher,
    118                     const Browser* browser);
    119     virtual ~TabStripWatcher();
    120 
    121     // TabStripModelObserver implementation:
    122     virtual void TabInsertedAt(TabContentsWrapper* contents, int index,
    123                                bool foreground);
    124     virtual void TabClosingAt(TabStripModel* tab_strip_model,
    125                               TabContentsWrapper* contents,
    126                               int index);
    127     virtual void TabDetachedAt(TabContentsWrapper* contents, int index);
    128     virtual void TabChangedAt(TabContentsWrapper* contents, int index,
    129                               TabChangeType change_type);
    130 
    131     const Browser* browser() const {
    132       return browser_;
    133     }
    134 
    135    private:
    136     TabCloseableStateWatcher* main_watcher_;
    137     const Browser* browser_;
    138 
    139     DISALLOW_COPY_AND_ASSIGN(TabStripWatcher);
    140   };
    141 
    142   friend class TabStripWatcher;
    143 
    144   std::vector<TabStripWatcher*> tabstrip_watchers_;
    145 
    146   DISALLOW_COPY_AND_ASSIGN(TabCloseableStateWatcher);
    147 };
    148 
    149 }  // namespace chromeos
    150 
    151 #endif  // CHROME_BROWSER_CHROMEOS_TAB_CLOSEABLE_STATE_WATCHER_H_
    152