blob: 8c8c132b0af116d2ae8bde5eeefabb73a7d54cf0 [file] [log] [blame]
[email protected]8643e6d2012-01-18 20:26:101// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]9cddb1a22011-11-15 15:04:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]79b18962012-03-06 06:16:155#include "chrome/browser/ui/sad_tab_helper.h"
[email protected]9cddb1a22011-11-15 15:04:276
[email protected]c47317e2012-06-20 22:35:317#include "base/logging.h"
[email protected]9cddb1a22011-11-15 15:04:278#include "chrome/browser/browser_shutdown.h"
[email protected]a506c5f2012-07-10 13:09:069#include "chrome/browser/ui/sad_tab_types.h"
[email protected]9cddb1a22011-11-15 15:04:2710#include "content/public/browser/notification_source.h"
11#include "content/public/browser/notification_types.h"
[email protected]83ff91c2012-01-05 20:54:1312#include "content/public/browser/web_contents.h"
[email protected]8643e6d2012-01-18 20:26:1013#include "content/public/browser/web_contents_view.h"
[email protected]9cddb1a22011-11-15 15:04:2714
15#if defined(OS_MACOSX)
16#include "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h"
17#elif defined(TOOLKIT_VIEWS)
18#include "chrome/browser/ui/views/sad_tab_view.h"
[email protected]79b18962012-03-06 06:16:1519#include "ui/views/widget/widget.h"
[email protected]9cddb1a22011-11-15 15:04:2720#elif defined(TOOLKIT_GTK)
[email protected]2fdcef12012-03-05 22:12:2421#include <gtk/gtk.h>
22
[email protected]9cddb1a22011-11-15 15:04:2723#include "chrome/browser/ui/gtk/sad_tab_gtk.h"
24#endif
25
[email protected]ad4c6ff2012-09-28 17:10:0526DEFINE_WEB_CONTENTS_USER_DATA_KEY(SadTabHelper)
[email protected]e81f50d2012-09-19 18:42:3827
[email protected]a506c5f2012-07-10 13:09:0628SadTabHelper::SadTabHelper(content::WebContents* web_contents)
[email protected]83ff91c2012-01-05 20:54:1329 : content::WebContentsObserver(web_contents) {
[email protected]ef9572e2012-01-04 22:14:1230 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
[email protected]a506c5f2012-07-10 13:09:0631 content::Source<content::WebContents>(web_contents));
[email protected]9cddb1a22011-11-15 15:04:2732}
33
[email protected]79b18962012-03-06 06:16:1534SadTabHelper::~SadTabHelper() {
[email protected]9cddb1a22011-11-15 15:04:2735}
36
[email protected]a506c5f2012-07-10 13:09:0637bool SadTabHelper::HasSadTab() const {
38 return sad_tab_.get() != NULL;
39}
40
[email protected]79b18962012-03-06 06:16:1541void SadTabHelper::RenderViewGone(base::TerminationStatus status) {
[email protected]3dfa7f3c2012-04-18 18:01:3242 // Only show the sad tab if we're not in browser shutdown, so that WebContents
[email protected]9cddb1a22011-11-15 15:04:2743 // objects that are not in a browser (e.g., HTML dialogs) and thus are
44 // visible do not flash a sad tab page.
45 if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID)
46 return;
47
48 if (HasSadTab())
49 return;
50
[email protected]caf7c8f82012-10-18 23:53:5851 if (status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
52 status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ||
53 status == base::TERMINATION_STATUS_PROCESS_CRASHED)
54 InstallSadTab(status);
[email protected]9cddb1a22011-11-15 15:04:2755}
56
[email protected]79b18962012-03-06 06:16:1557void SadTabHelper::Observe(int type,
58 const content::NotificationSource& source,
59 const content::NotificationDetails& details) {
[email protected]9cddb1a22011-11-15 15:04:2760 switch (type) {
[email protected]ef9572e2012-01-04 22:14:1261 case content::NOTIFICATION_WEB_CONTENTS_CONNECTED:
[email protected]9cddb1a22011-11-15 15:04:2762 if (HasSadTab()) {
[email protected]2fdcef12012-03-05 22:12:2463#if defined(OS_MACOSX)
64 sad_tab_controller_mac::RemoveSadTab(sad_tab_.get());
65#elif defined(TOOLKIT_VIEWS)
[email protected]79b18962012-03-06 06:16:1566 sad_tab_->Close();
[email protected]020add4c2012-03-20 15:23:4767 // See http://crbug.com/117668. When the Widget is being destructed, we
68 // want calls to sad_tab() to return NULL.
69 scoped_ptr<views::Widget> local_sad_tab;
70 local_sad_tab.swap(sad_tab_);
[email protected]2fdcef12012-03-05 22:12:2471#elif defined(TOOLKIT_GTK)
[email protected]b137c122012-11-20 00:12:0072 sad_tab_->Close();
[email protected]2fdcef12012-03-05 22:12:2473#else
74#error Unknown platform
75#endif
76 sad_tab_.reset();
[email protected]9cddb1a22011-11-15 15:04:2777 }
78 break;
79
80 default:
81 NOTREACHED() << "Got a notification we didn't register for.";
82 }
83}
84
[email protected]79b18962012-03-06 06:16:1585void SadTabHelper::InstallSadTab(base::TerminationStatus status) {
[email protected]a506c5f2012-07-10 13:09:0686#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK)
87 chrome::SadTabKind kind =
88 (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) ?
89 chrome::SAD_TAB_KIND_KILLED : chrome::SAD_TAB_KIND_CRASHED;
90#endif
[email protected]9cddb1a22011-11-15 15:04:2791#if defined(OS_MACOSX)
92 sad_tab_.reset(
[email protected]c85864d2011-12-26 21:18:2693 sad_tab_controller_mac::CreateSadTabController(web_contents()));
[email protected]9cddb1a22011-11-15 15:04:2794#elif defined(TOOLKIT_VIEWS)
[email protected]9cddb1a22011-11-15 15:04:2795 views::Widget::InitParams sad_tab_params(
96 views::Widget::InitParams::TYPE_CONTROL);
[email protected]6f1e8732011-12-06 06:27:4797 // It is not possible to create a native_widget_win that has no parent in
98 // and later re-parent it.
99 // TODO(avi): This is a cheat. Can this be made cleaner?
[email protected]9ad527c2012-03-07 16:39:34100 sad_tab_params.parent = web_contents()->GetView()->GetNativeView();
[email protected]b4c1725e2012-04-11 21:03:40101#if defined(OS_WIN) && !defined(USE_AURA)
102 // Crash data indicates we can get here when the parent is no longer valid.
103 // Attempting to create a child window with a bogus parent crashes. So, we
104 // don't show a sad tab in this case in hopes the tab is in the process of
105 // shutting down.
106 if (!IsWindow(sad_tab_params.parent))
107 return;
108#endif
[email protected]9cddb1a22011-11-15 15:04:27109 sad_tab_params.ownership =
110 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
111 sad_tab_.reset(new views::Widget);
112 sad_tab_->Init(sad_tab_params);
[email protected]768c5472011-12-26 19:06:17113 sad_tab_->SetContentsView(new SadTabView(web_contents(), kind));
[email protected]79b18962012-03-06 06:16:15114
115 views::Widget::ReparentNativeView(
116 sad_tab_->GetNativeView(), web_contents()->GetView()->GetNativeView());
117 gfx::Rect bounds;
118 web_contents()->GetView()->GetContainerBounds(&bounds);
119 sad_tab_->SetBounds(gfx::Rect(bounds.size()));
[email protected]9cddb1a22011-11-15 15:04:27120#elif defined(TOOLKIT_GTK)
[email protected]a506c5f2012-07-10 13:09:06121 sad_tab_.reset(new SadTabGtk(web_contents(), kind));
[email protected]b137c122012-11-20 00:12:00122 sad_tab_->Show();
[email protected]9cddb1a22011-11-15 15:04:27123#else
124#error Unknown platform
125#endif
126}