summaryrefslogtreecommitdiff
path: root/chromium/ash/screensaver/screensaver_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/screensaver/screensaver_view.cc')
-rw-r--r--chromium/ash/screensaver/screensaver_view.cc170
1 files changed, 170 insertions, 0 deletions
diff --git a/chromium/ash/screensaver/screensaver_view.cc b/chromium/ash/screensaver/screensaver_view.cc
new file mode 100644
index 00000000000..6c2c1e03d7d
--- /dev/null
+++ b/chromium/ash/screensaver/screensaver_view.cc
@@ -0,0 +1,170 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/screensaver/screensaver_view.h"
+
+#include "ash/shell.h"
+#include "ash/shell_delegate.h"
+#include "base/bind.h"
+#include "base/logging.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/aura/root_window.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/controls/webview/webview.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/widget/widget.h"
+
+using content::BrowserThread;
+
+namespace {
+
+ash::internal::ScreensaverView* g_instance = NULL;
+
+// Do not restart the screensaver again if it has
+// terminated kMaxTerminations times already.
+const int kMaxTerminations = 3;
+
+} // namespace
+
+namespace ash {
+
+void ShowScreensaver(const GURL& url) {
+ internal::ScreensaverView::ShowScreensaver(url);
+}
+
+void CloseScreensaver() {
+ internal::ScreensaverView::CloseScreensaver();
+}
+
+bool IsScreensaverShown() {
+ return internal::ScreensaverView::IsScreensaverShown();
+}
+
+namespace internal {
+
+// static
+void ScreensaverView::ShowScreensaver(const GURL& url) {
+ if (!g_instance) {
+ g_instance = new ScreensaverView(url);
+ g_instance->Show();
+ }
+}
+
+// static
+void ScreensaverView::CloseScreensaver() {
+ if (g_instance) {
+ g_instance->Close();
+ g_instance = NULL;
+ }
+}
+
+// static
+bool ScreensaverView::IsScreensaverShown() {
+ return g_instance && g_instance->IsScreensaverShowingURL(g_instance->url_);
+}
+
+bool ScreensaverView::IsScreensaverShowingURL(const GURL& url) {
+ return screensaver_webview_ &&
+ screensaver_webview_->web_contents() &&
+ (screensaver_webview_->web_contents()->GetURL() == url);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScreensaverView, views::WidgetDelegateView implementation.
+views::View* ScreensaverView::GetContentsView() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScreensaverView, content::WebContentsObserver implementation.
+void ScreensaverView::RenderProcessGone(
+ base::TerminationStatus status) {
+ LOG(ERROR) << "Screensaver terminated with status " << status;
+ termination_count_++;
+
+ if (termination_count_ < kMaxTerminations) {
+ LOG(ERROR) << termination_count_
+ << " terminations is under the threshold of "
+ << kMaxTerminations
+ << "; reloading Screensaver.";
+ LoadScreensaver();
+ } else {
+ LOG(ERROR) << "Exceeded termination threshold, closing Screensaver.";
+ ScreensaverView::CloseScreensaver();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScreensaverView private methods.
+ScreensaverView::ScreensaverView(const GURL& url)
+ : url_(url),
+ termination_count_(0),
+ screensaver_webview_(NULL),
+ container_window_(NULL) {
+}
+
+ScreensaverView::~ScreensaverView() {
+}
+
+void ScreensaverView::Show() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Add the WebView to our view.
+ AddChildWebContents();
+ // Show the window.
+ ShowWindow();
+}
+
+void ScreensaverView::Close() {
+ DCHECK(GetWidget());
+ GetWidget()->Close();
+}
+
+void ScreensaverView::AddChildWebContents() {
+ content::BrowserContext* context =
+ Shell::GetInstance()->delegate()->GetCurrentBrowserContext();
+ screensaver_webview_ = new views::WebView(context);
+ SetLayoutManager(new views::FillLayout);
+ AddChildView(screensaver_webview_);
+
+ LoadScreensaver();
+ content::WebContentsObserver::Observe(
+ screensaver_webview_->GetWebContents());
+}
+
+void ScreensaverView::LoadScreensaver() {
+ screensaver_webview_->GetWebContents()->GetController().LoadURL(
+ url_,
+ content::Referrer(),
+ content::PAGE_TRANSITION_AUTO_TOPLEVEL,
+ std::string());
+}
+
+void ScreensaverView::ShowWindow() {
+ aura::RootWindow* root_window = ash::Shell::GetPrimaryRootWindow();
+ gfx::Rect screen_rect =
+ Shell::GetScreen()->GetDisplayNearestWindow(root_window).bounds();
+
+ // We want to be the fullscreen topmost child of the root window.
+ // There should be nothing ever really that should show up on top of us.
+ container_window_ = new views::Widget();
+ views::Widget::InitParams params(
+ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ params.delegate = this;
+ params.parent = root_window;
+ container_window_->Init(params);
+
+ container_window_->StackAtTop();
+ container_window_->SetBounds(screen_rect);
+ container_window_->Show();
+}
+
+// static
+ScreensaverView* ScreensaverView::GetInstance() {
+ return g_instance;
+}
+
+} // namespace internal
+} // namespace ash