15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/hung_renderer_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/platform_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_view.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/result_codes.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/label_button.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/client_view.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContents;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These functions allow certain chrome platforms to override the default hung
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// renderer dialog. For e.g. Chrome on Windows 8 metro
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformShowCustomHungRendererDialog(WebContents* contents);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformHideCustomHungRendererDialog(WebContents* contents);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformShowCustomHungRendererDialog(WebContents* contents) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformHideCustomHungRendererDialog(WebContents* contents) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungRendererDialogView* HungRendererDialogView::g_instance_ = NULL;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungPagesTableModel, public:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungPagesTableModel::HungPagesTableModel(Delegate* delegate)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : observer_(NULL),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungPagesTableModel::~HungPagesTableModel() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::RenderProcessHost* HungPagesTableModel::GetRenderProcessHost() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tab_observers_.empty() ? NULL :
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_observers_[0]->web_contents()->GetRenderProcessHost();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::RenderViewHost* HungPagesTableModel::GetRenderViewHost() {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tab_observers_.empty() ? NULL :
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_observers_[0]->web_contents()->GetRenderViewHost();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungPagesTableModel::InitForWebContents(WebContents* hung_contents) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_observers_.clear();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hung_contents) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Force hung_contents to be first.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (hung_contents) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_observers_.push_back(new WebContentsObserverImpl(this,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                           hung_contents));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (TabContentsIterator it; !it.done(); it.Next()) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (*it != hung_contents &&
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          it->GetRenderProcessHost() == hung_contents->GetRenderProcessHost())
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tab_observers_.push_back(new WebContentsObserverImpl(this, *it));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The world is different.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnModelChanged();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HungPagesTableModel, ui::TableModel implementation:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HungPagesTableModel::RowCount() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<int>(tab_observers_.size());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 HungPagesTableModel::GetText(int row, int column_id) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(row >= 0 && row < RowCount());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 title = tab_observers_[row]->web_contents()->GetTitle();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (title.empty())
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    title = CoreTabHelper::GetDefaultTitle();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(xji): Consider adding a special case if the title text is a URL,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since those should always have LTR directionality. Please refer to
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://crbug.com/6726 for more information.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::i18n::AdjustStringForLocaleDirection(&title);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return title;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia HungPagesTableModel::GetIcon(int row) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(row >= 0 && row < RowCount());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FaviconTabHelper::FromWebContents(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_observers_[row]->web_contents())->GetFavicon().AsImageSkia();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungPagesTableModel::SetObserver(ui::TableModelObserver* observer) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_ = observer;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HungPagesTableModel::GetGroupRange(int model_index,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        views::GroupRange* range) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(range);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  range->start = 0;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  range->length = RowCount();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungPagesTableModel::TabDestroyed(WebContentsObserverImpl* tab) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clean up tab_observers_ and notify our observer.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabObservers::iterator i = std::find(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_observers_.begin(), tab_observers_.end(), tab);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(i != tab_observers_.end());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int index = static_cast<int>(i - tab_observers_.begin());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_observers_.erase(i);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnItemsRemoved(index, 1);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the delegate.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->TabDestroyed();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WARNING: we've likely been deleted.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungPagesTableModel::WebContentsObserverImpl::WebContentsObserverImpl(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HungPagesTableModel* model, WebContents* tab)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : content::WebContentsObserver(tab),
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      model_(model) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HungPagesTableModel::WebContentsObserverImpl::RenderProcessGone(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TerminationStatus status) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->TabDestroyed(this);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungPagesTableModel::WebContentsObserverImpl::WebContentsDestroyed(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* tab) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model_->TabDestroyed(this);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia* HungRendererDialogView::frozen_icon_ = NULL;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The distance in pixels from the top of the relevant contents to place the
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// warning window.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kOverlayContentsOffsetY = 50;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The dimensions of the hung pages list table view, in pixels.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kTableViewWidth = 300;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kTableViewHeight = 100;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Padding space in pixels between frozen icon to the info label, hung pages
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// list table view and the Kill pages button.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kCentralColumnPadding =
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::kUnrelatedControlLargeHorizontalSpacing;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView, public:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)HungRendererDialogView* HungRendererDialogView::Create(
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gfx::NativeView context) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_instance_) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_instance_ = new HungRendererDialogView;
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    views::DialogDelegate::CreateDialogWidget(g_instance_, context, NULL);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_instance_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungRendererDialogView* HungRendererDialogView::GetInstance() {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_instance_;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HungRendererDialogView::IsFrameActive(WebContents* contents) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView frame_view =
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      platform_util::GetTopLevel(contents->GetView()->GetNativeView());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return platform_util::IsWindowActive(frame_view);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::KillRendererProcess(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessHandle process_handle) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::KillProcess(process_handle, content::RESULT_CODE_HUNG, false);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungRendererDialogView::HungRendererDialogView()
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : hung_pages_table_(NULL),
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kill_button_(NULL),
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      initialized_(false) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitClass();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HungRendererDialogView::~HungRendererDialogView() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hung_pages_table_->SetModel(NULL);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::ShowForWebContents(WebContents* contents) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(contents && GetWidget());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't show the warning unless the foreground window is the frame, or this
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // window (but still invisible). If the user has another window or
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // application selected, activating ourselves is rude.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsFrameActive(contents) &&
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !platform_util::IsWindowActive(GetWidget()->GetNativeWindow()))
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetWidget()->IsActive()) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect bounds = GetDisplayBounds(contents);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::NativeView frame_view =
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        platform_util::GetTopLevel(contents->GetView()->GetNativeView());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Widget* insert_after =
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        views::Widget::GetWidgetForNativeView(frame_view);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetWidget()->SetBoundsConstrained(bounds);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (insert_after)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetWidget()->StackAboveWidget(insert_after);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We only do this if the window isn't active (i.e. hasn't been shown yet,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // or is currently shown but deactivated for another WebContents). This is
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // because this window is a singleton, and it's possible another active
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // renderer may hang while this one is showing, and we don't want to reset
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the list of hung pages for a potentially unrelated renderer while this
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one is showing.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hung_pages_table_model_->InitForWebContents(contents);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetWidget()->Show();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::EndForWebContents(WebContents* contents) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(contents);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hung_pages_table_model_->RowCount() == 0 ||
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hung_pages_table_model_->GetRenderProcessHost() ==
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents->GetRenderProcessHost()) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetWidget()->Close();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Close is async, make sure we drop our references to the tab immediately
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (it may be going away).
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hung_pages_table_model_->InitForWebContents(NULL);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView, views::DialogDelegate implementation:
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 HungRendererDialogView::GetWindowTitle() const {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_TITLE);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::WindowClosing() {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are going to be deleted soon, so make sure our instance is destroyed.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_instance_ = NULL;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HungRendererDialogView::GetDialogButtons() const {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We specifically don't want a CANCEL button here because that code path is
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // also called when the window is closed by the user clicking the X button in
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the window's titlebar, and also if we call Window::Close. Rather, we want
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the OK button to wait for responsiveness (and close the dialog) and our
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // additional button (which we create) to kill the process (which will result
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the dialog being destroyed).
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::DIALOG_BUTTON_OK;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 HungRendererDialogView::GetDialogButtonLabel(
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::DialogButton button) const {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button == ui::DIALOG_BUTTON_OK)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_WAIT);
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return views::DialogDelegateView::GetDialogButtonLabel(button);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)views::View* HungRendererDialogView::CreateExtraView() {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!kill_button_);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kill_button_ = new views::LabelButton(this,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END));
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kill_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kill_button_;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HungRendererDialogView::Accept(bool window_closing) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't do anything if we're being called only because the dialog is being
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed and we don't supply a Cancel function...
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_closing)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start waiting again for responsiveness.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hung_pages_table_model_->GetRenderViewHost())
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hung_pages_table_model_->GetRenderViewHost()->RestartHangMonitorTimeout();
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView, views::ButtonListener implementation:
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::ButtonPressed(
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Button* sender, const ui::Event& event) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sender == kill_button_ &&
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hung_pages_table_model_->GetRenderProcessHost()) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessHandle process_handle =
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hung_pages_table_model_->GetRenderProcessHost()->GetHandle();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KillRendererProcess(process_handle);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView, HungPagesTableModel::Delegate overrides:
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::TabDestroyed() {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Close();
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView, views::View overrides:
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
353a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void HungRendererDialogView::ViewHierarchyChanged(
354a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const ViewHierarchyChangedDetails& details) {
355a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!initialized_ && details.is_add && details.child == this && GetWidget())
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Init();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HungRendererDialogView, private:
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::Init() {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::ImageView* frozen_icon_view = new views::ImageView;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frozen_icon_view->SetImage(frozen_icon_);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* info_label = new views::Label(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_label->SetMultiLine(true);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hung_pages_table_model_.reset(new HungPagesTableModel(this));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ui::TableColumn> columns;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns.push_back(ui::TableColumn());
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hung_pages_table_ = new views::TableView(
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      hung_pages_table_model_.get(), columns, views::ICON_AND_TEXT, true);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hung_pages_table_->SetGrouper(hung_pages_table_model_.get());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  using views::GridLayout;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  using views::ColumnSet;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GridLayout* layout = GridLayout::CreatePanel(this);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(layout);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int double_column_set_id = 0;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* column_set = layout->AddColumnSet(double_column_set_id);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        GridLayout::FIXED, frozen_icon_->width(), 0);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddPaddingColumn(0, kCentralColumnPadding);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        GridLayout::USE_PREF, 0, 0);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, double_column_set_id);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(frozen_icon_view, 1, 3);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the label with a preferred width of 1, this way it doesn't effect the
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overall preferred size of the dialog.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info_label, 1, 1, GridLayout::FILL, GridLayout::LEADING, 1, 0);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, double_column_set_id);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->SkipColumns(1);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(hung_pages_table_->CreateParentIfNecessary(), 1, 1,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  views::GridLayout::FILL,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  views::GridLayout::FILL, kTableViewWidth, kTableViewHeight);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initialized_ = true;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect HungRendererDialogView::GetDisplayBounds(
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* contents) {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect contents_bounds(
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents->GetView()->GetNativeView()->GetBoundsInRootWindow());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND contents_hwnd = contents->GetView()->GetNativeView();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RECT contents_bounds_rect;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWindowRect(contents_hwnd, &contents_bounds_rect);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect contents_bounds(contents_bounds_rect);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect window_bounds = GetWidget()->GetWindowBoundsInScreen();
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_x = contents_bounds.x() +
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (contents_bounds.width() - window_bounds.width()) / 2;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_y = contents_bounds.y() + kOverlayContentsOffsetY;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(window_x, window_y, window_bounds.width(),
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   window_bounds.height());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HungRendererDialogView::InitClass() {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool initialized = false;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frozen_icon_ = rb.GetImageSkiaNamed(IDR_FROZEN_TAB_ICON);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    initialized = true;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowHungRendererDialog(WebContents* contents) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!logging::DialogsAreSuppressed() &&
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !PlatformShowCustomHungRendererDialog(contents)) {
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    HungRendererDialogView* view = HungRendererDialogView::Create(
44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        platform_util::GetTopLevel(contents->GetView()->GetNativeView()));
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view->ShowForWebContents(contents);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HideHungRendererDialog(WebContents* contents) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!logging::DialogsAreSuppressed() &&
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !PlatformHideCustomHungRendererDialog(contents) &&
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HungRendererDialogView::GetInstance())
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HungRendererDialogView::GetInstance()->EndForWebContents(contents);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
459