1 // Copyright (c) 2006-2008 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_BROWSER_H_
6 #define CHROME_BROWSER_BROWSER_H_
8 #include "chrome/browser/controller.h"
9 #include "chrome/browser/hang_monitor/hung_plugin_action.h"
10 #include "chrome/browser/hang_monitor/hung_window_detector.h"
11 #include "chrome/browser/shell_dialogs.h"
12 #include "chrome/browser/browser_type.h"
13 #include "chrome/browser/session_id.h"
14 #include "chrome/browser/tab_contents_delegate.h"
15 #include "chrome/browser/tabs/tab_strip_model.h"
16 #include "chrome/browser/toolbar_model.h"
17 #include "chrome/common/notification_service.h"
18 #include "chrome/common/pref_member.h"
20 class BrowserIdleTimer
;
24 class LocationBarView
;
32 class Browser
: public TabStripModelDelegate
,
33 public TabStripModelObserver
,
34 public TabContentsDelegate
,
35 public CommandHandler
,
36 public NotificationObserver
,
37 public SelectFileDialog::Listener
{
39 // TODO(beng): (Cleanup) This is a hack. Right now the |initial_bounds|
40 // parameter to Browser's ctor specifies the size of the frame, not the size
41 // of the contents that will be displayed within it. So this flag exists,
42 // which can be passed instead of a typical value for |show_command| that
43 // tells the Browser to create its window, and then use the |initial_bounds|
44 // parameter as the size of the contents, resizing the frame to fit. See
45 // SizeToContents method on chrome_frame.h
47 SIZE_TO_CONTENTS
= 9999
50 // Creates a new browser with the given bounds. If the bounds are empty, the
51 // system will try to find a saved size from a previous session, if none
52 // exists, the operating system will be allowed to size the window.
53 // |type| defines the kind of browser to create.
55 // Creating a browser does NOT show the window. You must manually call Show()
56 // to display the window.
57 Browser(const gfx::Rect
& initial_bounds
,
60 BrowserType::Type browser_type
,
61 const std::wstring
& app_name
);
64 // Shows the browser window. It is initially created hidden. It will be shown
65 // with the show command passed to the constructor, or possibly another state
66 // if it was overridden in the preferences.
68 // Ideally, this function is called after everything in the window is
69 // initialized so that we do not have to repaint again.
70 void Show() { ShowAndFit(false); }
72 // Like Show, but the window is optionally resized and moved to be on the
74 void ShowAndFit(bool resize_to_fit
);
76 // Returns the Browser which contains the tab with the given
77 // NavigationController, also filling in |index| (if valid) with the tab's
78 // index in the tab strip.
79 // Returns NULL if not found.
80 // This call is O(N) in the number of tabs.
81 static Browser
* GetBrowserForController(
82 const NavigationController
* controller
, int* index
);
84 static void OpenNewBrowserWindow(Profile
* profile
, int show_command
);
86 static void RegisterPrefs(PrefService
* prefs
);
87 static void RegisterUserPrefs(PrefService
* prefs
);
89 // Initialize the receiver with the provided bounds which
90 // is in the screen coordinate system.
91 void InitWithBounds(CRect
* bounds
, int show_command
);
99 // "Stars" or (book)marks the contents of the current tab.
100 void StarCurrentTabContents();
102 // Opens the FindInPage window for the currently open tab.
103 void OpenFindInPageWindow();
104 // Becomes the parent window of the Find window of the specified tab. This is
105 // useful, for example, when tabs are dragged out of (or in to) the tab strip
106 // to make sure the Find window shows up in the right Browser window.
107 void AdoptFindWindow(TabContents
* tab_contents
);
110 void OpenDebuggerWindow();
112 // Advance the find selection by one. Direction is either forward or backwards
113 // depending on parameter passed in. If selection cannot be advanced (for
114 // example because no search has been issued, then the function returns false
115 // and caller can call OpenFindInPageWindow to show the search window.
116 bool AdvanceFindSelection(bool forward_direction
);
118 Profile
* profile() const { return profile_
; }
120 BrowserWindow
* window() const { return window_
; }
122 ToolbarModel
* toolbar_model() { return &toolbar_model_
; }
124 // Returns the HWND of the top-level system window for this Browser.
125 HWND
GetTopLevelHWND() const;
127 // Update commands that drive the NavigationController to reflect changes in
128 // the NavigationController's state (Back, Forward, etc).
129 void UpdateNavigationCommands();
131 // CommandHandler interface method implementation
132 bool GetContextualLabel(int id
, std::wstring
* out
) const;
133 void ExecuteCommand(int id
);
135 // Please fix the incestuous nest that is */controller.h and eliminate the
136 // need for this retarded hack.
137 bool SupportsCommand(int id
) const;
138 bool IsCommandEnabled(int id
) const;
140 // Sets focus on the location bar's text field.
141 void FocusLocationBar();
143 // Notification that some of our content has animated. If the source
144 // is the current tab, this invokes the same method on the frame.
145 void ToolbarSizeChanged(TabContents
* source
, bool is_animating
);
147 // Move the window to the front.
148 void MoveToFront(bool should_activate
);
150 // Unique identifier for this window; used for session restore.
151 const SessionID
& session_id() const { return session_id_
; }
153 // Executes a Windows WM_APPCOMMAND command id. This function translates a
154 // button-specific identifier to an id understood by our controller.
155 bool ExecuteWindowsAppCommand(int app_command_id
);
157 // Gives beforeunload handlers the chance to cancel the close.
158 bool ShouldCloseWindow();
160 // Tells us that we've finished firing this tab's beforeunload event.
161 // The proceed bool tells us whether the user chose to proceed closing the
162 // tab. Returns true if the tab can continue on firing it's unload event.
163 // If we're closing the entire browser, then we'll want to delay firing
164 // unload events until all the beforeunload events have fired.
165 void BeforeUnloadFired(TabContents
* source
,
167 bool* proceed_to_fire_unload
);
169 // Invoked when the window containing us is closing. Performs the necessary
171 void OnWindowClosing();
173 // TabStripModel pass-thrus //////////////////////////////////////////////////
175 TabStripModel
* tabstrip_model() const {
176 return const_cast<TabStripModel
*>(&tabstrip_model_
);
179 int tab_count() const { return tabstrip_model_
.count(); }
180 int selected_index() const { return tabstrip_model_
.selected_index(); }
181 int GetIndexOfController(const NavigationController
* controller
) const {
182 return tabstrip_model_
.GetIndexOfController(controller
);
184 TabContents
* GetTabContentsAt(int index
) const {
185 return tabstrip_model_
.GetTabContentsAt(index
);
187 TabContents
* GetSelectedTabContents() const {
188 return tabstrip_model_
.GetSelectedTabContents();
190 NavigationController
* GetSelectedNavigationController() const;
191 void SelectTabContentsAt(int index
, bool user_gesture
) {
192 tabstrip_model_
.SelectTabContentsAt(index
, user_gesture
);
194 TabContents
* AddBlankTab(bool foreground
) {
195 return tabstrip_model_
.AddBlankTab(foreground
);
197 void CloseAllTabs() {
198 tabstrip_model_
.CloseAllTabs();
201 // Tab Creation functions ////////////////////////////////////////////////////
203 // Add a new tab with the specified URL. If instance is not null, its process
204 // will be used to render the tab.
205 TabContents
* AddTabWithURL(
206 const GURL
& url
, PageTransition::Type transition
, bool foreground
,
207 SiteInstance
* instance
);
209 // Add a new application tab for the specified URL. If lazy is true, the tab
210 // won't be selected. Further, the initial web page load will only take place
211 // when the tab is first selected.
212 TabContents
* AddWebApplicationTab(Profile
* profile
,
216 // Add a new tab, given a NavigationController. A TabContents appropriate to
217 // display the last committed entry is created and returned.
218 TabContents
* AddTabWithNavigationController(NavigationController
* ctrl
,
219 PageTransition::Type type
);
221 // Add a tab with its session history restored from the SessionRestore
222 // system. If select is true, the tab is selected. Returns the created
223 // NavigationController.
224 NavigationController
* AddRestoredTab(
225 const std::vector
<TabNavigation
>& navigations
,
226 int selected_navigation
,
229 // Replaces the state of the currently selected tab with the session
230 // history restored from the SessionRestore system.
231 void ReplaceRestoredTab(
232 const std::vector
<TabNavigation
>& navigations
,
233 int selected_navigation
);
235 // Overridden from TabStripDelegate:
236 virtual void CreateNewStripWithContents(TabContents
* detached_contents
,
237 const gfx::Point
& drop_point
);
238 virtual int GetDragActions() const;
239 // Construct a TabContents for a given URL, profile and transition type.
240 // If instance is not null, its process will be used to render the tab.
241 virtual TabContents
* CreateTabContentsForURL(
244 PageTransition::Type transition
,
246 SiteInstance
* instance
) const;
247 virtual void ShowApplicationMenu(const gfx::Point p
);
248 virtual bool CanDuplicateContentsAt(int index
);
249 virtual void DuplicateContentsAt(int index
);
250 virtual void ValidateLoadingAnimations();
251 virtual void CloseFrameAfterDragSession();
253 // Overridden from TabStripObserver:
254 virtual void TabInsertedAt(TabContents
* contents
,
257 virtual void TabClosingAt(TabContents
* contents
, int index
);
258 virtual void TabDetachedAt(TabContents
* contents
, int index
);
259 virtual void TabSelectedAt(TabContents
* old_contents
,
260 TabContents
* new_contents
,
263 virtual void TabMoved(TabContents
* contents
,
266 virtual void TabStripEmpty();
268 // Overridden from TabContentsDelegate:
269 virtual void OpenURLFromTab(TabContents
* source
,
271 WindowOpenDisposition disposition
,
272 PageTransition::Type transition
);
273 virtual void NavigationStateChanged(const TabContents
* source
,
274 unsigned changed_flags
);
275 virtual void ReplaceContents(TabContents
* source
, TabContents
* new_contents
);
276 virtual void AddNewContents(TabContents
* source
,
277 TabContents
* new_contents
,
278 WindowOpenDisposition disposition
,
279 const gfx::Rect
& initial_pos
,
281 virtual void StartDraggingDetachedContents(TabContents
* source
,
282 TabContents
* new_contents
,
283 const gfx::Rect
& contents_bounds
,
284 const gfx::Point
& mouse_pt
,
285 int frame_component
);
286 virtual void ActivateContents(TabContents
* contents
);
287 virtual void LoadingStateChanged(TabContents
* source
);
288 virtual void CloseContents(TabContents
* source
);
289 virtual void MoveContents(TabContents
* source
, const gfx::Rect
& pos
);
290 virtual bool IsPopup(TabContents
* source
);
291 virtual void URLStarredChanged(TabContents
* source
, bool starred
);
293 virtual void WindowMoved();
294 virtual void ContentsMouseEvent(TabContents
* source
, UINT message
);
295 virtual void UpdateTargetURL(TabContents
* source
, const GURL
& url
);
297 virtual void ContentsZoomChange(bool zoom_in
);
298 virtual bool IsApplication() const;
299 virtual void ConvertContentsToApplication(TabContents
* source
);
300 virtual void ContentsStateChanged(TabContents
* source
);
301 virtual bool ShouldDisplayURLField();
303 // Return this browser type.
304 BrowserType::Type
GetType() const;
306 // Invoke the menu we use for application and popup windows at the provided
307 // point and for the provided hwnd.
308 void RunSimpleFrameMenu(const CPoint
& pt
, HWND hwnd
);
310 // Show some native UI given a URL. If a tab with the same URL is already
311 // visible in this browser, it becomes selected. Otherwise a new tab is
313 void ShowNativeUI(const GURL
& url
);
315 // Show a dialog with HTML content. |delegate| contains a pointer to the
316 // delegate who knows how to display the dialog (which file URL and JSON
317 // string input to use during initialization). |parent_hwnd| is the window
318 // that should be the parent of this dialog, or NULL for this browser's top
320 // TODO(beng): (Cleanup) this really shouldn't live here. It's not
321 // necessarily browser-related (e.g. can be called from options
323 void ShowHtmlDialog(HtmlDialogContentsDelegate
* delegate
, HWND parent_hwnd
);
325 // Overridden from SelectFileDialog::Listener:
326 virtual void FileSelected(const std::wstring
& path
, void* params
);
328 // Start an off the record session. If a window containing an off the record
329 // tab for the current profile exists, create a new off the record tab in that
330 // window. Otherwise, create a new window with an off the record tab.
331 static void OpenURLOffTheRecord(Profile
* p
, const GURL
& url
);
333 // Computes a title suitable for popups without a URL field.
334 static std::wstring
ComputePopupTitle(const GURL
& url
,
335 const std::wstring
& title
);
337 // Compute a deterministic name based on the URL. We use this pseudo name
338 // as a key to store window location per application URLs.
339 static std::wstring
ComputeApplicationNameFromURL(const GURL
& url
);
341 // Start a web application.
342 static void OpenWebApplication(Profile
* profile
,
346 // Return this browser's controller.
347 CommandController
* controller() { return &controller_
; }
349 // Returns the location bar view for this browser.
350 LocationBarView
* GetLocationBarView() const;
352 void ConvertTabToApplication(TabContents
* contents
);
354 // NEW FRAME METHODS BELOW THIS LINE ONLY... TODO(beng): clean up this file!
356 // Save and restore the window position.
357 void SaveWindowPosition(const gfx::Rect
& bounds
, bool maximized
);
358 void RestoreWindowPosition(gfx::Rect
* bounds
, bool* maximized
);
360 // Gets the FavIcon of the page in the selected tab.
361 SkBitmap
GetCurrentPageIcon() const;
363 // Gets the title of the page in the selected tab.
364 std::wstring
GetCurrentPageTitle() const;
366 // Prepares a title string for display (removes embedded newlines, etc).
367 static void FormatTitleForDisplay(std::wstring
* title
);
370 friend class XPFrame
;
371 friend class VistaFrame
;
372 friend class SimpleFrame
;
373 friend class BrowserView2
;
375 // Tracks invalidates to the UI, see the declaration in the .cc file.
377 typedef std::vector
<UIUpdate
> UpdateVector
;
379 typedef std::vector
<TabContents
*> UnloadListenerVector
;
386 // Returns the root view for this browser.
387 ChromeViews::RootView
* GetRootView() const;
389 // Returns what the user's home page is, or the new tab page if the home page
393 // Called when this window gains or loses window-manager-level activation.
394 // is_active is whether or not the Window is now active.
395 void WindowActivationChanged(bool is_active
);
397 // Initialize state for all browser commands.
398 void InitCommandState();
400 // Change the "starred" button display to starred/unstarred.
401 // TODO(evanm): migrate this to the commands framework.
402 void SetStarredButtonToggled(bool starred
);
404 GoButton
* GetGoButton();
406 // Returns the StatusBubble from the current toolbar. It is possible for
407 // this to return NULL if called before the toolbar has initialized.
408 // TODO(beng): remove this.
409 StatusBubble
* GetStatusBubble();
411 // Syncs the window title with current_tab_. This may be necessary because
412 // current_tab_'s title changed, or because current_tab_ itself has
414 void SyncWindowTitle();
416 // Saves the location of the window to the history database.
417 void SaveWindowPlacementToDatabase();
418 // Window placement memory across sessions.
419 void SaveWindowPlacement();
421 // Notifies the history database of the index for all tabs whose index is
423 void SyncHistoryWithTabs(int index
);
425 // Notification service callback.
426 virtual void Observe(NotificationType type
,
427 const NotificationSource
& source
,
428 const NotificationDetails
& details
);
430 // The Controller that updates all browser commands.
431 CommandController controller_
;
433 // Asks the toolbar (and as such the location bar) to update its state to
434 // reflect the current tab's current URL, security state, etc.
435 // If |should_restore_state| is true, we're switching (back?) to this tab and
436 // should restore any previous location bar state (such as user editing) as
438 void UpdateToolBar(bool should_restore_state
);
440 // Adds an update to the update queue and schedules an update if necessary.
441 // These are subsequently processed by ProcessPendingUIUpdates.
442 // |changed_flags| is a bitfield of TabContents::INVALIDATE_* values.
443 void ScheduleUIUpdate(const TabContents
* source
,
444 unsigned changed_flags
);
446 // Processes all pending updates to the UI that have been queued by
447 // ScheduleUIUpdate in scheduled_updates_.
448 void ProcessPendingUIUpdates();
450 // Update the current page title
453 // Opens the Keyword Editor
454 void OpenKeywordEditor();
456 // Opens the Clear Browsing Data dialog.
457 void OpenClearBrowsingDataDialog();
459 // Opens the Import settings dialog.
460 void OpenImportSettingsDialog();
462 // Opens the Bug Report dialog.
463 void OpenBugReportDialog();
465 // Removes the InfoBar and download shelf for the specified TabContents, if
466 // they are presently attached.
467 // TODO(beng): REMOVE
468 void RemoveShelvesForTabContents(TabContents
* contents
);
470 // Copy the current page URL to the clipboard.
471 void CopyCurrentURLToClipBoard();
473 // Initializes the hang monitor.
474 void InitHangMonitor();
476 // Retrieve the last active tabbed browser with the same profile as the
477 // receiving Browser. Creates a new Browser if none are available.
478 Browser
* GetOrCreateTabbedBrowser();
480 // Removes all entries from scheduled_updates_ whose source is contents.
481 void RemoveScheduledUpdatesFor(TabContents
* contents
);
483 // Called from AddRestoredTab and ReplaceRestoredTab to build a
484 // NavigationController from an incoming vector of TabNavigations.
485 // Caller takes ownership of the returned NavigationController.
486 NavigationController
* BuildRestoredNavigationController(
487 const std::vector
<TabNavigation
>& navigations
,
488 int selected_navigation
);
490 // Convert the receiving Browser to a normal browser window. This is used to
491 // convert a popup window into a normal browser window. The receiver's type
493 void ConvertToTabbedBrowser();
495 // Create a preference dictionary for the provided application name. This is
496 // done only once per application name / per session.
497 static void RegisterAppPrefs(const std::wstring
& app_name
);
499 // Creates a new popup window with its own Browser object with the
500 // incoming sizing information. |initial_pos|'s origin() is the
501 // window origin, and its size() is the size of the content area.
502 void BuildPopupWindow(TabContents
* source
,
503 TabContents
* new_contents
,
504 const gfx::Rect
& initial_pos
);
506 // Processes the next tab that needs it's beforeunload/unload event fired.
507 void ProcessPendingTabs();
509 // Whether we've completed firing all the tabs' beforeunload/unload events.
510 bool HasCompletedUnloadProcessing();
512 // Clears all the state associated with processing tabs' beforeunload/unload
513 // events since the user cancelled closing the window.
514 void CancelWindowClose();
516 // Removes the tab from the associated vector. Returns whether the tab
517 // was in the vector in the first place.
518 bool RemoveFromVector(UnloadListenerVector
* vector
, TabContents
* tab
);
520 // Cleans up state appropriately when we are trying to close the browser and
521 // the tab has finished firing it's unload handler. We also use this in the
522 // cases where a tab crashes or hangs even if the beforeunload/unload haven't
523 // successfully fired.
524 void ClearUnloadState(TabContents
* tab
);
527 BrowserWindow
* window_
;
529 // Controls how the window will appear when Show() is called. This is one
530 // of the SW_* constants passed to ShowWindow, and will be initialized in the
533 // After the first call to Show() succeeds, this is set to -1, indicating that
534 // subsequent calls to Show() should be ignored.
535 int initial_show_command_
;
537 class BrowserToolbarModel
: public ToolbarModel
{
539 explicit BrowserToolbarModel(Browser
* browser
) : browser_(browser
) { }
540 virtual ~BrowserToolbarModel() { }
542 // ToolbarModel implementation.
543 virtual NavigationController
* GetNavigationController() {
544 return browser_
->GetSelectedNavigationController();
550 DISALLOW_EVIL_CONSTRUCTORS(BrowserToolbarModel
);
553 // The model for the toolbar view.
554 BrowserToolbarModel toolbar_model_
;
556 TabStripModel tabstrip_model_
;
560 // Tracks tabs that need there beforeunload event fired before we can
561 // close the browser. Only gets populated when we try to close the browser.
562 UnloadListenerVector tabs_needing_before_unload_fired_
;
564 // Tracks tabs that need there unload event fired before we can
565 // close the browser. Only gets populated when we try to close the browser.
566 UnloadListenerVector tabs_needing_unload_fired_
;
568 // Whether we already handled the OnStripEmpty event - it can be called
570 bool handled_strip_empty_
;
572 // Whether we are processing the beforeunload and unload events of each tab
573 // in preparation for closing the browser.
574 bool is_attempting_to_close_browser_
;
576 // The following factory is used for chrome update coalescing.
577 ScopedRunnableMethodFactory
<Browser
> chrome_updater_factory_
;
579 // The following factory is used to close the frame at a later time.
580 ScopedRunnableMethodFactory
<Browser
> method_factory_
;
582 // This object is used to perform periodic actions in a worker
583 // thread. It is currently used to monitor hung plugin windows.
584 WorkerThreadTicker ticker_
;
586 // This object is initialized with the frame window HWND. This
587 // object is also passed as a tick handler with the ticker_ object.
588 // It is used to periodically monitor for hung plugin windows
589 HungWindowDetector hung_window_detector_
;
591 // This object is invoked by hung_window_detector_ when it detects a hung
593 HungPluginAction hung_plugin_action_
;
595 // This browser type.
596 BrowserType::Type type_
;
598 // Lists all UI updates that are pending. We don't update things like the
599 // URL or tab title right away to avoid flickering and extra painting.
600 // See ScheduleUIUpdate and ProcessPendingUIUpdates.
601 UpdateVector scheduled_updates_
;
603 // An optional application name which is used to retrieve and save window
605 std::wstring app_name_
;
607 // Unique identifier of this browser for session restore. This id is only
608 // unique within the current session, and is not guaranteed to be unique
610 SessionID session_id_
;
612 // Debugger Window, created lazily
613 scoped_refptr
<DebuggerWindow
> debugger_window_
;
615 // Dialog box used for opening and saving files.
616 scoped_refptr
<SelectFileDialog
> select_file_dialog_
;
618 // The browser idle task helps cleanup unused memory resources when idle.
619 scoped_ptr
<BrowserIdleTimer
> idle_task_
;
621 // Keep track of the encoding auto detect pref.
622 BooleanPrefMember encoding_auto_detect_
;
624 DISALLOW_COPY_AND_ASSIGN(Browser
);
627 #endif // CHROME_BROWSER_BROWSER_H_