hung_renderer_view.h revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Use of this source code is governed by a BSD-style license that can be
3845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com// found in the LICENSE file.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#ifndef CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_
6845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com#define CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "base/memory/scoped_vector.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "chrome/browser/favicon/favicon_tab_helper.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/web_contents_observer.h"
118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "ui/base/models/table_model.h"
128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "ui/views/controls/button/button.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/views/controls/table/table_grouper.h"
141202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com#include "ui/views/controls/table/table_view.h"
15c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include "ui/views/window/dialog_delegate.h"
1631b3044af4e97c662076147d119ba233a163b769reed@google.com
1731b3044af4e97c662076147d119ba233a163b769reed@google.comnamespace content {
1843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass WebContents;
1943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
2043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
2143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comnamespace views {
2243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass LabelButton;
2343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
2443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
2543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com// Provides functionality to display information about a hung renderer.
268b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.comclass HungPagesTableModel : public ui::TableModel, public views::TableGrouper {
2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com public:
2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // The Delegate is notified any time a WebContents the model is listening to
2943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // is destroyed.
3043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  class Delegate {
3143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com   public:
328b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual void TabDestroyed() = 0;
3343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
341447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com   protected:
358b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual ~Delegate() {}
368b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  };
378b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
388b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  explicit HungPagesTableModel(Delegate* delegate);
39fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com  virtual ~HungPagesTableModel();
40bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com
4143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  void InitForWebContents(content::WebContents* hung_contents);
4243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
4343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // Returns the first RenderProcessHost, or NULL if there aren't any
4443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // WebContents.
4543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  content::RenderProcessHost* GetRenderProcessHost();
4643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
4743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // Returns the first RenderViewHost, or NULL if there aren't any WebContents.
4843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  content::RenderViewHost* GetRenderViewHost();
4943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
5043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // Overridden from ui::TableModel:
5143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  virtual int RowCount() OVERRIDE;
5243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  virtual string16 GetText(int row, int column_id) OVERRIDE;
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  virtual gfx::ImageSkia GetIcon(int row) OVERRIDE;
54bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com  virtual void SetObserver(ui::TableModelObserver* observer) OVERRIDE;
558b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
568b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  // Overridden from views::TableGrouper:
57fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com  virtual void GetGroupRange(int model_index,
588b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com                             views::GroupRange* range) OVERRIDE;
59bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com
608b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com private:
618b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  // Used to track a single WebContents. If the WebContents is destroyed
62fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com  // TabDestroyed() is invoked on the model.
638b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  class WebContentsObserverImpl : public content::WebContentsObserver {
648b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com   public:
658b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    WebContentsObserverImpl(HungPagesTableModel* model,
668b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com                            content::WebContents* tab);
67fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
688b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    content::WebContents* web_contents() const {
69bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com      return content::WebContentsObserver::web_contents();
708b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    }
71fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
728b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    FaviconTabHelper* favicon_tab_helper() {
738b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com      return FaviconTabHelper::FromWebContents(web_contents());
74fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    }
758b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
768b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    // WebContentsObserver overrides:
778b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
788b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com    virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
800f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org   private:
811202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com    HungPagesTableModel* model_;
821202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com
831202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com    DISALLOW_COPY_AND_ASSIGN(WebContentsObserverImpl);
841202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com  };
851202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com
861202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com  // Invoked when a WebContents is destroyed. Cleans up |tab_observers_| and
871202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com  // notifies the observer and delegate.
881202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com  void TabDestroyed(WebContentsObserverImpl* tab);
89a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
90a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  typedef ScopedVector<WebContentsObserverImpl> TabObservers;
91a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  TabObservers tab_observers_;
928b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
9343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  ui::TableModelObserver* observer_;
9443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  Delegate* delegate_;
958b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org
961447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com  DISALLOW_COPY_AND_ASSIGN(HungPagesTableModel);
97c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com};
98c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// This class displays a dialog which contains information about a hung
1001447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com// renderer process.
1018b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgclass HungRendererDialogView : public views::DialogDelegateView,
102c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                               public views::ButtonListener,
103c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                               public HungPagesTableModel::Delegate {
104c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org public:
105c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org  // Factory function for creating an instance of the HungRendererDialogView
106c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org  // class. At any given point only one instance can be active.
107c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org  static HungRendererDialogView* Create(gfx::NativeView context);
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
109845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com  // Returns a pointer to the singleton instance if any.
11043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  static HungRendererDialogView* GetInstance();
11143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
11243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com  // Platform specific function to kill the renderer process identified by the
1138b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  // handle passed in.
1148b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  static void KillRendererProcess(base::ProcessHandle process_handle);
1158b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
1168b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  // Returns true if the frame is in the foreground.
117fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com  static bool IsFrameActive(content::WebContents* contents);
1188b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
1198b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  virtual void ShowForWebContents(content::WebContents* contents);
1208b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  virtual void EndForWebContents(content::WebContents* contents);
1218b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com
1228b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com  // views::DialogDelegateView overrides:
123fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com  virtual string16 GetWindowTitle() const OVERRIDE;
1241447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com  virtual void WindowClosing() OVERRIDE;
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  virtual int GetDialogButtons() const OVERRIDE;
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com  virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE;
127a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  virtual views::View* CreateExtraView() OVERRIDE;
128a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  virtual bool Accept(bool window_closing)  OVERRIDE;
129a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
130a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // views::ButtonListener overrides:
131a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  virtual void ButtonPressed(views::Button* sender,
132a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                             const ui::Event& event) OVERRIDE;
133a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
134a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // HungPagesTableModel::Delegate overrides:
135a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  virtual void TabDestroyed() OVERRIDE;
136a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
137a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org protected:
138a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  HungRendererDialogView();
139a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  virtual ~HungRendererDialogView();
140a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
141a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // views::View overrides:
142a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  virtual void ViewHierarchyChanged(
143a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org      const ViewHierarchyChangedDetails& details) OVERRIDE;
144a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
145a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  static HungRendererDialogView* g_instance_;
146a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
147a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org private:
14888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org  // Initialize the controls in this dialog.
149a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  void Init();
150a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
151a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // Returns the bounds the dialog should be displayed at to be meaningfully
152a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // associated with the specified WebContents.
153a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  gfx::Rect GetDisplayBounds(content::WebContents* contents);
154a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
155a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  static void InitClass();
156a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
157a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // Controls within the dialog box.
158a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  views::TableView* hung_pages_table_;
159a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
160a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // The extra button inserted into the ClientView to kill the errant process.
161a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  views::LabelButton* kill_button_;
162a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
163a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // The model that provides the contents of the table that shows a list of
164a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // pages affected by the hang.
165a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  scoped_ptr<HungPagesTableModel> hung_pages_table_model_;
166a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
167a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // Whether or not we've created controls for ourself.
168a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  bool initialized_;
169a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
170a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  // An amusing icon image.
171a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  static gfx::ImageSkia* frozen_icon_;
172a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
173a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org  DISALLOW_COPY_AND_ASSIGN(HungRendererDialogView);
174a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org};
175a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org
176a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#endif  // CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_
177a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org