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