• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ash/screensaver/screensaver_view.h"
6 
7 #include "ash/shell.h"
8 #include "ash/shell_delegate.h"
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/web_contents.h"
14 #include "ui/aura/window_event_dispatcher.h"
15 #include "ui/gfx/screen.h"
16 #include "ui/views/controls/webview/webview.h"
17 #include "ui/views/layout/fill_layout.h"
18 #include "ui/views/widget/widget.h"
19 
20 using content::BrowserThread;
21 
22 namespace {
23 
24 ash::ScreensaverView* g_instance = NULL;
25 
26 // Do not restart the screensaver again if it has
27 // terminated kMaxTerminations times already.
28 const int kMaxTerminations = 3;
29 
30 }  // namespace
31 
32 namespace ash {
33 
ShowScreensaver(const GURL & url)34 void ShowScreensaver(const GURL& url) { ScreensaverView::ShowScreensaver(url); }
35 
CloseScreensaver()36 void CloseScreensaver() { ScreensaverView::CloseScreensaver(); }
37 
IsScreensaverShown()38 bool IsScreensaverShown() { return ScreensaverView::IsScreensaverShown(); }
39 
40 // static
ShowScreensaver(const GURL & url)41 void ScreensaverView::ShowScreensaver(const GURL& url) {
42   if (!g_instance) {
43     g_instance = new ScreensaverView(url);
44     g_instance->Show();
45   }
46 }
47 
48 // static
CloseScreensaver()49 void ScreensaverView::CloseScreensaver() {
50   if (g_instance) {
51     g_instance->Close();
52     g_instance = NULL;
53   }
54 }
55 
56 // static
IsScreensaverShown()57 bool ScreensaverView::IsScreensaverShown() {
58   return g_instance && g_instance->IsScreensaverShowingURL(g_instance->url_);
59 }
60 
IsScreensaverShowingURL(const GURL & url)61 bool ScreensaverView::IsScreensaverShowingURL(const GURL& url) {
62   return screensaver_webview_ &&
63       screensaver_webview_->web_contents() &&
64       (screensaver_webview_->web_contents()->GetURL() == url);
65 }
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 // ScreensaverView, views::WidgetDelegateView implementation.
GetContentsView()69 views::View* ScreensaverView::GetContentsView() {
70   return this;
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 // ScreensaverView, content::WebContentsObserver implementation.
RenderProcessGone(base::TerminationStatus status)75 void ScreensaverView::RenderProcessGone(
76     base::TerminationStatus status) {
77   LOG(ERROR) << "Screensaver terminated with status " << status;
78   termination_count_++;
79 
80   if (termination_count_ < kMaxTerminations) {
81     LOG(ERROR) << termination_count_
82                << " terminations is under the threshold of "
83                << kMaxTerminations
84                << "; reloading Screensaver.";
85     LoadScreensaver();
86   } else {
87     LOG(ERROR) << "Exceeded termination threshold, closing Screensaver.";
88     ScreensaverView::CloseScreensaver();
89   }
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 // ScreensaverView private methods.
ScreensaverView(const GURL & url)94 ScreensaverView::ScreensaverView(const GURL& url)
95     : url_(url),
96       termination_count_(0),
97       screensaver_webview_(NULL),
98       container_window_(NULL) {
99 }
100 
~ScreensaverView()101 ScreensaverView::~ScreensaverView() {
102 }
103 
Show()104 void ScreensaverView::Show() {
105   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
106   // Add the WebView to our view.
107   AddChildWebContents();
108   // Show the window.
109   ShowWindow();
110 }
111 
Close()112 void ScreensaverView::Close() {
113   DCHECK(GetWidget());
114   GetWidget()->Close();
115 }
116 
AddChildWebContents()117 void ScreensaverView::AddChildWebContents() {
118   content::BrowserContext* context =
119       Shell::GetInstance()->delegate()->GetActiveBrowserContext();
120   screensaver_webview_ = new views::WebView(context);
121   SetLayoutManager(new views::FillLayout);
122   AddChildView(screensaver_webview_);
123 
124   LoadScreensaver();
125   content::WebContentsObserver::Observe(
126       screensaver_webview_->GetWebContents());
127 }
128 
LoadScreensaver()129 void ScreensaverView::LoadScreensaver() {
130   screensaver_webview_->GetWebContents()->GetController().LoadURL(
131         url_,
132         content::Referrer(),
133         content::PAGE_TRANSITION_AUTO_TOPLEVEL,
134         std::string());
135 }
136 
ShowWindow()137 void ScreensaverView::ShowWindow() {
138   aura::Window* root_window = ash::Shell::GetPrimaryRootWindow();
139   gfx::Rect screen_rect =
140       Shell::GetScreen()->GetDisplayNearestWindow(root_window).bounds();
141 
142   // We want to be the fullscreen topmost child of the root window.
143   // There should be nothing ever really that should show up on top of us.
144   container_window_ = new views::Widget();
145   views::Widget::InitParams params(
146       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
147   params.delegate = this;
148   params.parent = root_window;
149   container_window_->Init(params);
150 
151   container_window_->StackAtTop();
152   container_window_->SetBounds(screen_rect);
153   container_window_->Show();
154 }
155 
156 // static
GetInstance()157 ScreensaverView* ScreensaverView::GetInstance() {
158   return g_instance;
159 }
160 
161 }  // namespace ash
162