summaryrefslogtreecommitdiffstats
path: root/ash/screensaver
diff options
context:
space:
mode:
Diffstat (limited to 'ash/screensaver')
-rw-r--r--ash/screensaver/DEPS3
-rw-r--r--ash/screensaver/screensaver_view.cc140
-rw-r--r--ash/screensaver/screensaver_view.h86
-rw-r--r--ash/screensaver/screensaver_view_unittest.cc93
4 files changed, 322 insertions, 0 deletions
diff --git a/ash/screensaver/DEPS b/ash/screensaver/DEPS
new file mode 100644
index 0000000..1c35d9c
--- /dev/null
+++ b/ash/screensaver/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+content/public/browser",
+]
diff --git a/ash/screensaver/screensaver_view.cc b/ash/screensaver/screensaver_view.cc
new file mode 100644
index 0000000..858ae9c
--- /dev/null
+++ b/ash/screensaver/screensaver_view.cc
@@ -0,0 +1,140 @@
+// 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 "ui/gfx/screen.h"
+#include "ui/aura/root_window.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/controls/webview/webview.h"
+#include "ui/views/widget/widget.h"
+
+using content::BrowserThread;
+
+namespace {
+
+ash::internal::ScreensaverView* g_instance = NULL;
+
+} // namespace
+
+namespace ash {
+
+void ShowScreensaver(const GURL& url) {
+ internal::ScreensaverView::ShowScreensaver(url);
+}
+
+void CloseScreensaver() {
+ internal::ScreensaverView::CloseScreensaver();
+}
+
+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;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScreensaverView, views::WidgetDelegateView implementation.
+views::View* ScreensaverView::GetContentsView() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScreensaverView, content::WebContentsObserver implementation.
+void ScreensaverView::RenderViewGone(
+ base::TerminationStatus status) {
+ LOG(ERROR) << "Screensaver terminated with status " << status
+ << ", reloading.";
+ // Reload the screensaver url into the webcontents.
+ LoadScreensaver();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScreensaverView private methods.
+ScreensaverView::ScreensaverView(const GURL& url)
+ : url_(url),
+ 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_START_PAGE,
+ std::string());
+}
+
+void ScreensaverView::ShowWindow() {
+ aura::RootWindow* root_window = ash::Shell::GetRootWindow();
+ gfx::Rect screen_rect =
+ gfx::Screen::GetMonitorNearestWindow(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
diff --git a/ash/screensaver/screensaver_view.h b/ash/screensaver/screensaver_view.h
new file mode 100644
index 0000000..0835f9b
--- /dev/null
+++ b/ash/screensaver/screensaver_view.h
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef ASH_SCREENSAVER_SCREENSAVER_VIEW_H_
+#define ASH_SCREENSAVER_SCREENSAVER_VIEW_H_
+#pragma once
+
+#include "base/callback.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "googleurl/src/gurl.h"
+#include "ui/views/widget/widget_delegate.h"
+
+namespace content {
+class BrowserContent;
+}
+
+namespace views {
+class WebView;
+}
+
+namespace ash {
+
+namespace test {
+class ScreensaverViewTest;
+}
+
+void ShowScreensaver(const GURL& url);
+void CloseScreensaver();
+
+typedef
+ base::Callback<views::WebView*(content::BrowserContext*)> WebViewFactory;
+
+namespace internal {
+
+// Shows a URL as a screensaver. The screensaver window is fullscreen,
+// always on top of every other window and will reload the URL if the
+// renderer crashes for any reason.
+class ScreensaverView : public views::WidgetDelegateView,
+ public content::WebContentsObserver {
+ public:
+ static void ShowScreensaver(const GURL& url);
+ static void CloseScreensaver();
+
+ private:
+ friend class test::ScreensaverViewTest;
+
+ explicit ScreensaverView(const GURL& url);
+ virtual ~ScreensaverView();
+
+ // views::WidgetDelegate overrides.
+ virtual views::View* GetContentsView() OVERRIDE;
+
+ // content::WebContentsObserver overrides.
+ virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE;
+
+ void Show();
+ void Close();
+
+ // Creates and adds web contents to our view.
+ void AddChildWebContents();
+ // Load the screensaver in the WebView's webcontent. If the webcontents
+ // don't exist, they'll be created by WebView.
+ void LoadScreensaver();
+ // Creates and shows a frameless full screen window containing our view.
+ void ShowWindow();
+
+ // For testing purposes.
+ static ScreensaverView* GetInstance();
+
+ // URL to show in the screensaver.
+ GURL url_;
+
+ // Host for the extension that implements this dialog.
+ views::WebView* screensaver_webview_;
+
+ // Window that holds the screensaver webview.
+ views::Widget* container_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreensaverView);
+};
+
+} // namespace internal
+} // namespace ash
+
+#endif // ASH_SCREENSAVER_SCREENSAVER_VIEW_H_
diff --git a/ash/screensaver/screensaver_view_unittest.cc b/ash/screensaver/screensaver_view_unittest.cc
new file mode 100644
index 0000000..47a19e2
--- /dev/null
+++ b/ash/screensaver/screensaver_view_unittest.cc
@@ -0,0 +1,93 @@
+// 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/test/ash_test_base.h"
+#include "base/bind.h"
+#include "content/public/browser/browser_context.h"
+#include "ui/views/controls/webview/webview.h"
+#include "ui/views/test/test_views_delegate.h"
+#include "ui/views/test/webview_test_helper.h"
+
+namespace ash {
+namespace test {
+
+class ScreensaverViewTest : public ash::test::AshTestBase {
+ public:
+ ScreensaverViewTest() {
+ url_ = GURL("http://www.google.com");
+ views_delegate_.reset(new views::TestViewsDelegate);
+ webview_test_helper_.reset(new views::WebViewTestHelper(message_loop()));
+ }
+
+ virtual ~ScreensaverViewTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ AshTestBase::SetUp();
+ RunAllPendingInMessageLoop();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ AshTestBase::TearDown();
+ }
+
+ void ExpectOpenScreensaver() {
+ internal::ScreensaverView* screensaver =
+ internal::ScreensaverView::GetInstance();
+ EXPECT_TRUE(screensaver != NULL);
+ if (!screensaver) return;
+
+ EXPECT_TRUE(screensaver->screensaver_webview_ != NULL);
+ if (!screensaver->screensaver_webview_) return;
+
+ EXPECT_TRUE(screensaver->screensaver_webview_->web_contents() != NULL);
+ if (!screensaver->screensaver_webview_->web_contents()) return;
+
+ EXPECT_EQ(screensaver->screensaver_webview_->web_contents()->GetURL(),
+ url_);
+ }
+
+ void ExpectClosedScreensaver() {
+ EXPECT_TRUE(internal::ScreensaverView::GetInstance() == NULL);
+ }
+
+ protected:
+ GURL url_;
+
+ private:
+ scoped_ptr<views::TestViewsDelegate> views_delegate_;
+ scoped_ptr<views::WebViewTestHelper> webview_test_helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreensaverViewTest);
+};
+
+TEST_F(ScreensaverViewTest, ShowScreensaverAndClose) {
+ ash::ShowScreensaver(url_);
+ RunAllPendingInMessageLoop();
+ ExpectOpenScreensaver();
+
+ ash::CloseScreensaver();
+ ExpectClosedScreensaver();
+}
+
+TEST_F(ScreensaverViewTest, OutOfOrderMultipleShowAndClose) {
+ ash::CloseScreensaver();
+ ExpectClosedScreensaver();
+
+ ash::ShowScreensaver(url_);
+ ExpectOpenScreensaver();
+ RunAllPendingInMessageLoop();
+ ash::ShowScreensaver(url_);
+ ExpectOpenScreensaver();
+ RunAllPendingInMessageLoop();
+
+ ash::CloseScreensaver();
+ ExpectClosedScreensaver();
+ ash::CloseScreensaver();
+ ExpectClosedScreensaver();
+}
+
+} // namespace test
+} // namespace ash