- add sources.
[platform/framework/web/crosswalk.git] / src / ash / screensaver / screensaver_view.cc
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/root_window.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::internal::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
34 void ShowScreensaver(const GURL& url) {
35   internal::ScreensaverView::ShowScreensaver(url);
36 }
37
38 void CloseScreensaver() {
39   internal::ScreensaverView::CloseScreensaver();
40 }
41
42 bool IsScreensaverShown() {
43   return internal::ScreensaverView::IsScreensaverShown();
44 }
45
46 namespace internal {
47
48 // static
49 void ScreensaverView::ShowScreensaver(const GURL& url) {
50   if (!g_instance) {
51     g_instance = new ScreensaverView(url);
52     g_instance->Show();
53   }
54 }
55
56 // static
57 void ScreensaverView::CloseScreensaver() {
58   if (g_instance) {
59     g_instance->Close();
60     g_instance = NULL;
61   }
62 }
63
64 // static
65 bool ScreensaverView::IsScreensaverShown() {
66   return g_instance && g_instance->IsScreensaverShowingURL(g_instance->url_);
67 }
68
69 bool ScreensaverView::IsScreensaverShowingURL(const GURL& url) {
70   return screensaver_webview_ &&
71       screensaver_webview_->web_contents() &&
72       (screensaver_webview_->web_contents()->GetURL() == url);
73 }
74
75 ////////////////////////////////////////////////////////////////////////////////
76 // ScreensaverView, views::WidgetDelegateView implementation.
77 views::View* ScreensaverView::GetContentsView() {
78   return this;
79 }
80
81 ////////////////////////////////////////////////////////////////////////////////
82 // ScreensaverView, content::WebContentsObserver implementation.
83 void ScreensaverView::RenderProcessGone(
84     base::TerminationStatus status) {
85   LOG(ERROR) << "Screensaver terminated with status " << status;
86   termination_count_++;
87
88   if (termination_count_ < kMaxTerminations) {
89     LOG(ERROR) << termination_count_
90                << " terminations is under the threshold of "
91                << kMaxTerminations
92                << "; reloading Screensaver.";
93     LoadScreensaver();
94   } else {
95     LOG(ERROR) << "Exceeded termination threshold, closing Screensaver.";
96     ScreensaverView::CloseScreensaver();
97   }
98 }
99
100 ////////////////////////////////////////////////////////////////////////////////
101 // ScreensaverView private methods.
102 ScreensaverView::ScreensaverView(const GURL& url)
103     : url_(url),
104       termination_count_(0),
105       screensaver_webview_(NULL),
106       container_window_(NULL) {
107 }
108
109 ScreensaverView::~ScreensaverView() {
110 }
111
112 void ScreensaverView::Show() {
113   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
114   // Add the WebView to our view.
115   AddChildWebContents();
116   // Show the window.
117   ShowWindow();
118 }
119
120 void ScreensaverView::Close() {
121   DCHECK(GetWidget());
122   GetWidget()->Close();
123 }
124
125 void ScreensaverView::AddChildWebContents() {
126   content::BrowserContext* context =
127       Shell::GetInstance()->delegate()->GetCurrentBrowserContext();
128   screensaver_webview_ = new views::WebView(context);
129   SetLayoutManager(new views::FillLayout);
130   AddChildView(screensaver_webview_);
131
132   LoadScreensaver();
133   content::WebContentsObserver::Observe(
134       screensaver_webview_->GetWebContents());
135 }
136
137 void ScreensaverView::LoadScreensaver() {
138   screensaver_webview_->GetWebContents()->GetController().LoadURL(
139         url_,
140         content::Referrer(),
141         content::PAGE_TRANSITION_AUTO_TOPLEVEL,
142         std::string());
143 }
144
145 void ScreensaverView::ShowWindow() {
146   aura::Window* root_window = ash::Shell::GetPrimaryRootWindow();
147   gfx::Rect screen_rect =
148       Shell::GetScreen()->GetDisplayNearestWindow(root_window).bounds();
149
150   // We want to be the fullscreen topmost child of the root window.
151   // There should be nothing ever really that should show up on top of us.
152   container_window_ = new views::Widget();
153   views::Widget::InitParams params(
154       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
155   params.delegate = this;
156   params.parent = root_window;
157   container_window_->Init(params);
158
159   container_window_->StackAtTop();
160   container_window_->SetBounds(screen_rect);
161   container_window_->Show();
162 }
163
164 // static
165 ScreensaverView* ScreensaverView::GetInstance() {
166   return g_instance;
167 }
168
169 }  // namespace internal
170 }  // namespace ash