diff options
Diffstat (limited to 'chromium/ash/screensaver/screensaver_view.cc')
-rw-r--r-- | chromium/ash/screensaver/screensaver_view.cc | 170 |
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 |