- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / webui_screen_locker.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 "chrome/browser/chromeos/login/webui_screen_locker.h"
6
7 #include "ash/shell.h"
8 #include "ash/wm/lock_state_controller.h"
9 #include "ash/wm/lock_state_observer.h"
10 #include "base/command_line.h"
11 #include "base/metrics/histogram.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_shutdown.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
17 #include "chrome/browser/chromeos/login/helper.h"
18 #include "chrome/browser/chromeos/login/screen_locker.h"
19 #include "chrome/browser/chromeos/login/user_manager.h"
20 #include "chrome/browser/chromeos/login/webui_login_display.h"
21 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
22 #include "chrome/common/url_constants.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/render_widget_host_view.h"
28 #include "content/public/browser/web_ui.h"
29 #include "ui/aura/client/capture_client.h"
30 #include "ui/aura/root_window.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/x/x11_util.h"
33 #include "ui/gfx/screen.h"
34 #include "ui/views/controls/webview/webview.h"
35
36 namespace {
37
38 // URL which corresponds to the login WebUI.
39 const char kLoginURL[] = "chrome://oobe/lock";
40
41 }  // namespace
42
43 namespace chromeos {
44
45 ////////////////////////////////////////////////////////////////////////////////
46 // WebUIScreenLocker implementation.
47
48 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
49     : ScreenLockerDelegate(screen_locker),
50       lock_ready_(false),
51       webui_ready_(false),
52       network_state_helper_(new login::NetworkStateHelper),
53       weak_factory_(this) {
54   set_should_emit_login_prompt_visible(false);
55   ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
56   DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
57 }
58
59 void WebUIScreenLocker::LockScreen() {
60   gfx::Rect bounds(ash::Shell::GetScreen()->GetPrimaryDisplay().bounds());
61
62   lock_time_ = base::TimeTicks::Now();
63   LockWindow* lock_window = LockWindow::Create();
64   lock_window->set_observer(this);
65   lock_window_ = lock_window->GetWidget();
66   lock_window_->AddObserver(this);
67   WebUILoginView::Init();
68   lock_window_->SetContentsView(this);
69   lock_window_->Show();
70   LoadURL(GURL(kLoginURL));
71   lock_window->Grab();
72
73   login_display_.reset(new WebUILoginDisplay(this));
74   login_display_->set_background_bounds(bounds);
75   login_display_->set_parent_window(GetNativeWindow());
76   login_display_->Init(screen_locker()->users(), false, true, false);
77
78   static_cast<OobeUI*>(GetWebUI()->GetController())->ShowSigninScreen(
79       login_display_.get(), login_display_.get());
80
81   registrar_.Add(this,
82                  chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
83                  content::NotificationService::AllSources());
84 }
85
86 void WebUIScreenLocker::ScreenLockReady() {
87   UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
88                       base::TimeTicks::Now() - lock_time_);
89   ScreenLockerDelegate::ScreenLockReady();
90   SetInputEnabled(true);
91 }
92
93 void WebUIScreenLocker::OnAuthenticate() {
94 }
95
96 void WebUIScreenLocker::SetInputEnabled(bool enabled) {
97   login_display_->SetUIEnabled(enabled);
98 }
99
100 void WebUIScreenLocker::ShowErrorMessage(
101     int error_msg_id,
102     HelpAppLauncher::HelpTopic help_topic_id) {
103   login_display_->ShowError(error_msg_id,
104                   0 /* login_attempts */,
105                   help_topic_id);
106 }
107
108 void WebUIScreenLocker::AnimateAuthenticationSuccess() {
109   GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
110 }
111
112 void WebUIScreenLocker::ClearErrors() {
113   GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
114 }
115
116 gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const {
117   return lock_window_->GetNativeWindow();
118 }
119
120 content::WebUI* WebUIScreenLocker::GetAssociatedWebUI() {
121   return GetWebUI();
122 }
123
124 void WebUIScreenLocker::FocusUserPod() {
125   if (!webui_ready_)
126     return;
127   webui_login_->RequestFocus();
128   GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
129 }
130
131 WebUIScreenLocker::~WebUIScreenLocker() {
132   DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
133   ash::Shell::GetInstance()->
134       lock_state_controller()->RemoveObserver(this);
135   // In case of shutdown, lock_window_ may be deleted before WebUIScreenLocker.
136   if (lock_window_) {
137     lock_window_->RemoveObserver(this);
138     lock_window_->Close();
139   }
140   // If LockScreen() was called, we need to clear the signin screen handler
141   // delegate set in ShowSigninScreen so that it no longer points to us.
142   if (login_display_.get()) {
143     static_cast<OobeUI*>(GetWebUI()->GetController())->
144         ResetSigninScreenHandlerDelegate();
145   }
146 }
147
148 void WebUIScreenLocker::OnLockWebUIReady() {
149   VLOG(1) << "WebUI ready; lock window is "
150           << (lock_ready_ ? "too" : "not");
151   webui_ready_ = true;
152   if (lock_ready_)
153     ScreenLockReady();
154 }
155
156 void WebUIScreenLocker::OnLockBackgroundDisplayed() {
157   UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
158                       base::TimeTicks::Now() - lock_time_);
159 }
160
161 ////////////////////////////////////////////////////////////////////////////////
162 // WebUIScreenLocker, content::NotificationObserver implementation:
163
164 void WebUIScreenLocker::Observe(
165     int type,
166     const content::NotificationSource& source,
167     const content::NotificationDetails& details) {
168   switch (type) {
169     case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
170       const User& user = *content::Details<User>(details).ptr();
171       login_display_->OnUserImageChanged(user);
172       break;
173     }
174     default:
175       WebUILoginView::Observe(type, source, details);
176   }
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
180 // WebUIScreenLocker, LoginDisplay::Delegate implementation:
181
182 void WebUIScreenLocker::CancelPasswordChangedFlow()  {
183   NOTREACHED();
184 }
185
186 void WebUIScreenLocker::CreateAccount() {
187   NOTREACHED();
188 }
189
190 void WebUIScreenLocker::CompleteLogin(const UserContext& user_context) {
191   NOTREACHED();
192 }
193
194 string16 WebUIScreenLocker::GetConnectedNetworkName() {
195   return network_state_helper_->GetCurrentNetworkName();
196 }
197
198 bool WebUIScreenLocker::IsSigninInProgress() const {
199   // The way how screen locker is implemented right now there's no
200   // GAIA sign in in progress in any case.
201   return false;
202 }
203
204 void WebUIScreenLocker::Login(const UserContext& user_context) {
205   chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
206 }
207
208 void WebUIScreenLocker::LoginAsRetailModeUser() {
209   NOTREACHED();
210 }
211
212 void WebUIScreenLocker::LoginAsGuest() {
213   NOTREACHED();
214 }
215
216 void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
217   NOTREACHED();
218 }
219
220 void WebUIScreenLocker::LoginAsPublicAccount(const std::string& username) {
221   NOTREACHED();
222 }
223
224 void WebUIScreenLocker::OnSigninScreenReady() {
225 }
226
227 void WebUIScreenLocker::OnUserSelected(const std::string& username) {
228 }
229
230 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
231   NOTREACHED();
232 }
233
234 void WebUIScreenLocker::OnStartKioskEnableScreen() {
235   NOTREACHED();
236 }
237
238 void WebUIScreenLocker::OnStartDeviceReset() {
239   NOTREACHED();
240 }
241
242 void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
243   NOTREACHED();
244 }
245
246 void WebUIScreenLocker::ShowWrongHWIDScreen() {
247   NOTREACHED();
248 }
249
250 void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
251 }
252
253 void WebUIScreenLocker::ResyncUserData() {
254   NOTREACHED();
255 }
256
257 void WebUIScreenLocker::SetDisplayEmail(const std::string& email) {
258   NOTREACHED();
259 }
260
261 void WebUIScreenLocker::Signout() {
262   chromeos::ScreenLocker::default_screen_locker()->Signout();
263 }
264
265 void WebUIScreenLocker::LoginAsKioskApp(const std::string& app_id) {
266   NOTREACHED();
267 }
268
269 ////////////////////////////////////////////////////////////////////////////////
270 // LockWindow::Observer implementation:
271
272 void WebUIScreenLocker::OnLockWindowReady() {
273   VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not");
274   lock_ready_ = true;
275   if (webui_ready_)
276     ScreenLockReady();
277 }
278
279 ////////////////////////////////////////////////////////////////////////////////
280 // SessionLockStateObserver override.
281
282 void WebUIScreenLocker::OnLockStateEvent(
283     ash::LockStateObserver::EventType event) {
284   if (event == ash::LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED) {
285     // Release capture if any.
286     aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow())->
287         SetCapture(NULL);
288     GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
289   }
290 }
291
292 ////////////////////////////////////////////////////////////////////////////////
293 // WidgetObserver override.
294
295 void WebUIScreenLocker::OnWidgetDestroying(views::Widget* widget) {
296   lock_window_->RemoveObserver(this);
297   lock_window_ = NULL;
298 }
299
300 ////////////////////////////////////////////////////////////////////////////////
301 // PowerManagerClient::Observer overrides.
302
303 void WebUIScreenLocker::LidEventReceived(bool open,
304                                          const base::TimeTicks& time) {
305   content::BrowserThread::PostTask(
306       content::BrowserThread::UI,
307       FROM_HERE,
308       base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
309 }
310
311 void WebUIScreenLocker::SystemResumed(const base::TimeDelta& sleep_duration) {
312   content::BrowserThread::PostTask(
313       content::BrowserThread::UI,
314       FROM_HERE,
315       base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
316 }
317
318 void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) {
319   if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID &&
320       status != base::TERMINATION_STATUS_NORMAL_TERMINATION) {
321     LOG(ERROR) << "Renderer crash on lock screen";
322     Signout();
323   }
324 }
325
326 }  // namespace chromeos