Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: chrome/browser/chromeos/login/webui_login_view.cc

Issue 286933002: [cros login] Split login related classes into subfolders. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix includes in new tests Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_login_view.h"
6
7 #include "ash/shell.h"
8 #include "ash/system/tray/system_tray.h"
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/debug/trace_event.h"
12 #include "base/i18n/rtl.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
17 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
18 #include "chrome/browser/chromeos/login/proxy_settings_dialog.h"
19 #include "chrome/browser/chromeos/login/webui_login_display.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
22 #include "chrome/browser/media/media_stream_infobar_delegate.h"
23 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
24 #include "chrome/browser/renderer_preferences_util.h"
25 #include "chrome/browser/sessions/session_tab_helper.h"
26 #include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h"
27 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
28 #include "chrome/common/render_messages.h"
29 #include "chromeos/dbus/dbus_thread_manager.h"
30 #include "chromeos/dbus/session_manager_client.h"
31 #include "chromeos/network/network_state.h"
32 #include "chromeos/network/network_state_handler.h"
33 #include "components/password_manager/core/browser/password_manager.h"
34 #include "components/web_modal/web_contents_modal_dialog_manager.h"
35 #include "content/public/browser/notification_service.h"
36 #include "content/public/browser/render_view_host.h"
37 #include "content/public/browser/render_widget_host_view.h"
38 #include "content/public/browser/web_contents.h"
39 #include "content/public/browser/web_ui.h"
40 #include "third_party/WebKit/public/web/WebInputEvent.h"
41 #include "ui/gfx/rect.h"
42 #include "ui/gfx/size.h"
43 #include "ui/views/controls/webview/webview.h"
44 #include "ui/views/widget/widget.h"
45
46 using content::NativeWebKeyboardEvent;
47 using content::RenderViewHost;
48 using content::WebContents;
49 using web_modal::WebContentsModalDialogManager;
50
51 namespace {
52
53 // These strings must be kept in sync with handleAccelerator()
54 // in display_manager.js.
55 const char kAccelNameCancel[] = "cancel";
56 const char kAccelNameEnrollment[] = "enrollment";
57 const char kAccelNameKioskEnable[] = "kiosk_enable";
58 const char kAccelNameVersion[] = "version";
59 const char kAccelNameReset[] = "reset";
60 const char kAccelFocusPrev[] = "focus_prev";
61 const char kAccelFocusNext[] = "focus_next";
62 const char kAccelNameDeviceRequisition[] = "device_requisition";
63 const char kAccelNameDeviceRequisitionRemora[] = "device_requisition_remora";
64 const char kAccelNameAppLaunchBailout[] = "app_launch_bailout";
65 const char kAccelNameAppLaunchNetworkConfig[] = "app_launch_network_config";
66
67 // A class to change arrow key traversal behavior when it's alive.
68 class ScopedArrowKeyTraversal {
69 public:
70 explicit ScopedArrowKeyTraversal(bool new_arrow_key_tranversal_enabled)
71 : previous_arrow_key_traversal_enabled_(
72 views::FocusManager::arrow_key_traversal_enabled()) {
73 views::FocusManager::set_arrow_key_traversal_enabled(
74 new_arrow_key_tranversal_enabled);
75 }
76 ~ScopedArrowKeyTraversal() {
77 views::FocusManager::set_arrow_key_traversal_enabled(
78 previous_arrow_key_traversal_enabled_);
79 }
80
81 private:
82 const bool previous_arrow_key_traversal_enabled_;
83 DISALLOW_COPY_AND_ASSIGN(ScopedArrowKeyTraversal);
84 };
85
86 } // namespace
87
88 namespace chromeos {
89
90 // static
91 const char WebUILoginView::kViewClassName[] =
92 "browser/chromeos/login/WebUILoginView";
93
94 // WebUILoginView public: ------------------------------------------------------
95
96 WebUILoginView::WebUILoginView()
97 : webui_login_(NULL),
98 is_hidden_(false),
99 webui_visible_(false),
100 should_emit_login_prompt_visible_(true),
101 forward_keyboard_event_(true) {
102 registrar_.Add(this,
103 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
104 content::NotificationService::AllSources());
105 registrar_.Add(this,
106 chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN,
107 content::NotificationService::AllSources());
108
109 accel_map_[ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)] =
110 kAccelNameCancel;
111 accel_map_[ui::Accelerator(ui::VKEY_E,
112 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] =
113 kAccelNameEnrollment;
114 accel_map_[ui::Accelerator(ui::VKEY_K,
115 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] =
116 kAccelNameKioskEnable;
117 accel_map_[ui::Accelerator(ui::VKEY_V, ui::EF_ALT_DOWN)] =
118 kAccelNameVersion;
119 accel_map_[ui::Accelerator(ui::VKEY_R,
120 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN)] =
121 kAccelNameReset;
122
123 accel_map_[ui::Accelerator(ui::VKEY_LEFT, ui::EF_NONE)] =
124 kAccelFocusPrev;
125 accel_map_[ui::Accelerator(ui::VKEY_RIGHT, ui::EF_NONE)] =
126 kAccelFocusNext;
127
128 // Use KEY_RELEASED because Gaia consumes KEY_PRESSED for up/down key.
129 ui::Accelerator key_up(ui::VKEY_UP, ui::EF_NONE);
130 key_up.set_type(ui::ET_KEY_RELEASED);
131 ui::Accelerator key_down(ui::VKEY_DOWN, ui::EF_NONE);
132 key_down.set_type(ui::ET_KEY_RELEASED);
133 accel_map_[key_up] = kAccelFocusPrev;
134 accel_map_[key_down] = kAccelFocusNext;
135
136 accel_map_[ui::Accelerator(
137 ui::VKEY_D, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN)] =
138 kAccelNameDeviceRequisition;
139 accel_map_[
140 ui::Accelerator(ui::VKEY_H, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] =
141 kAccelNameDeviceRequisitionRemora;
142
143 accel_map_[ui::Accelerator(ui::VKEY_S,
144 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] =
145 kAccelNameAppLaunchBailout;
146
147 accel_map_[ui::Accelerator(ui::VKEY_N,
148 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] =
149 kAccelNameAppLaunchNetworkConfig;
150
151 for (AccelMap::iterator i(accel_map_.begin()); i != accel_map_.end(); ++i)
152 AddAccelerator(i->first);
153 }
154
155 WebUILoginView::~WebUILoginView() {
156 FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver,
157 observer_list_,
158 OnHostDestroying());
159
160 if (ash::Shell::GetInstance()->HasPrimaryStatusArea()) {
161 ash::Shell::GetInstance()->GetPrimarySystemTray()->
162 SetNextFocusableView(NULL);
163 }
164 }
165
166 void WebUILoginView::Init() {
167 Profile* signin_profile = ProfileHelper::GetSigninProfile();
168 auth_extension_.reset(new ScopedGaiaAuthExtension(signin_profile));
169 webui_login_ = new views::WebView(signin_profile);
170 webui_login_->set_allow_accelerators(true);
171 AddChildView(webui_login_);
172
173 WebContents* web_contents = webui_login_->GetWebContents();
174
175 // Ensure that the login UI has a tab ID, which will allow the GAIA auth
176 // extension's background script to tell it apart from a captive portal window
177 // that may be opened on top of this UI.
178 SessionTabHelper::CreateForWebContents(web_contents);
179
180 // Create the password manager that is needed for the proxy.
181 ChromePasswordManagerClient::CreateForWebContentsWithAutofillManagerDelegate(
182 web_contents,
183 autofill::TabAutofillManagerDelegate::FromWebContents(web_contents));
184
185 // LoginHandlerViews uses a constrained window for the password manager view.
186 WebContentsModalDialogManager::CreateForWebContents(web_contents);
187 WebContentsModalDialogManager::FromWebContents(web_contents)->
188 SetDelegate(this);
189
190 web_contents->SetDelegate(this);
191 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
192 web_contents);
193 WebContentsObserver::Observe(web_contents);
194 renderer_preferences_util::UpdateFromSystemSettings(
195 web_contents->GetMutableRendererPrefs(),
196 signin_profile);
197 }
198
199 const char* WebUILoginView::GetClassName() const {
200 return kViewClassName;
201 }
202
203 web_modal::WebContentsModalDialogHost*
204 WebUILoginView::GetWebContentsModalDialogHost() {
205 return this;
206 }
207
208 gfx::NativeView WebUILoginView::GetHostView() const {
209 return GetWidget()->GetNativeView();
210 }
211
212 gfx::Point WebUILoginView::GetDialogPosition(const gfx::Size& size) {
213 // Center the widget.
214 gfx::Size widget_size = GetWidget()->GetWindowBoundsInScreen().size();
215 return gfx::Point(widget_size.width() / 2 - size.width() / 2,
216 widget_size.height() / 2 - size.height() / 2);
217 }
218
219 gfx::Size WebUILoginView::GetMaximumDialogSize() {
220 return GetWidget()->GetWindowBoundsInScreen().size();
221 }
222
223 void WebUILoginView::AddObserver(
224 web_modal::ModalDialogHostObserver* observer) {
225 if (observer && !observer_list_.HasObserver(observer))
226 observer_list_.AddObserver(observer);
227 }
228
229 void WebUILoginView::RemoveObserver(
230 web_modal::ModalDialogHostObserver* observer) {
231 observer_list_.RemoveObserver(observer);
232 }
233
234 bool WebUILoginView::AcceleratorPressed(
235 const ui::Accelerator& accelerator) {
236 AccelMap::const_iterator entry = accel_map_.find(accelerator);
237 if (entry == accel_map_.end())
238 return false;
239
240 if (!webui_login_)
241 return true;
242
243 content::WebUI* web_ui = GetWebUI();
244 if (web_ui) {
245 base::StringValue accel_name(entry->second);
246 web_ui->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
247 accel_name);
248 }
249
250 return true;
251 }
252
253 gfx::NativeWindow WebUILoginView::GetNativeWindow() const {
254 return GetWidget()->GetNativeWindow();
255 }
256
257 void WebUILoginView::LoadURL(const GURL & url) {
258 webui_login_->LoadInitialURL(url);
259 webui_login_->RequestFocus();
260
261 // TODO(nkostylev): Use WebContentsObserver::RenderViewCreated to track
262 // when RenderView is created.
263 GetWebContents()->GetRenderViewHost()->GetView()->SetBackgroundOpaque(false);
264 }
265
266 content::WebUI* WebUILoginView::GetWebUI() {
267 return webui_login_->web_contents()->GetWebUI();
268 }
269
270 content::WebContents* WebUILoginView::GetWebContents() {
271 return webui_login_->web_contents();
272 }
273
274 void WebUILoginView::OpenProxySettings() {
275 const NetworkState* network =
276 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
277 if (!network) {
278 LOG(ERROR) << "No default network found!";
279 return;
280 }
281 ProxySettingsDialog* dialog =
282 new ProxySettingsDialog(ProfileHelper::GetSigninProfile(),
283 *network, NULL, GetNativeWindow());
284 dialog->Show();
285 }
286
287 void WebUILoginView::OnPostponedShow() {
288 set_is_hidden(false);
289 OnLoginPromptVisible();
290 }
291
292 void WebUILoginView::SetStatusAreaVisible(bool visible) {
293 if (ash::Shell::GetInstance()->HasPrimaryStatusArea()) {
294 ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
295 if (visible) {
296 // Tray may have been initialized being hidden.
297 tray->SetVisible(visible);
298 tray->GetWidget()->Show();
299 } else {
300 tray->GetWidget()->Hide();
301 }
302 }
303 }
304
305 void WebUILoginView::SetUIEnabled(bool enabled) {
306 forward_keyboard_event_ = enabled;
307 ash::Shell::GetInstance()->GetPrimarySystemTray()->SetEnabled(enabled);
308 }
309
310 // WebUILoginView protected: ---------------------------------------------------
311
312 void WebUILoginView::Layout() {
313 DCHECK(webui_login_);
314 webui_login_->SetBoundsRect(bounds());
315
316 FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver,
317 observer_list_,
318 OnPositionRequiresUpdate());
319 }
320
321 void WebUILoginView::OnLocaleChanged() {
322 }
323
324 void WebUILoginView::ChildPreferredSizeChanged(View* child) {
325 Layout();
326 SchedulePaint();
327 }
328
329 void WebUILoginView::AboutToRequestFocusFromTabTraversal(bool reverse) {
330 // Return the focus to the web contents.
331 webui_login_->web_contents()->FocusThroughTabTraversal(reverse);
332 GetWidget()->Activate();
333 webui_login_->web_contents()->Focus();
334 }
335
336 void WebUILoginView::Observe(int type,
337 const content::NotificationSource& source,
338 const content::NotificationDetails& details) {
339 switch (type) {
340 case chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE:
341 case chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN: {
342 OnLoginPromptVisible();
343 registrar_.RemoveAll();
344 break;
345 }
346 default:
347 NOTREACHED() << "Unexpected notification " << type;
348 }
349 }
350
351 // WebUILoginView private: -----------------------------------------------------
352
353 bool WebUILoginView::HandleContextMenu(
354 const content::ContextMenuParams& params) {
355 // Do not show the context menu.
356 #ifndef NDEBUG
357 return false;
358 #else
359 return true;
360 #endif
361 }
362
363 void WebUILoginView::HandleKeyboardEvent(content::WebContents* source,
364 const NativeWebKeyboardEvent& event) {
365 if (forward_keyboard_event_) {
366 // Disable arrow key traversal because arrow keys are handled via
367 // accelerator when this view has focus.
368 ScopedArrowKeyTraversal arrow_key_traversal(false);
369
370 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event,
371 GetFocusManager());
372 }
373
374 // Make sure error bubble is cleared on keyboard event. This is needed
375 // when the focus is inside an iframe. Only clear on KeyDown to prevent hiding
376 // an immediate authentication error (See crbug.com/103643).
377 if (event.type == blink::WebInputEvent::KeyDown) {
378 content::WebUI* web_ui = GetWebUI();
379 if (web_ui)
380 web_ui->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
381 }
382 }
383
384 bool WebUILoginView::IsPopupOrPanel(const WebContents* source) const {
385 return true;
386 }
387
388 bool WebUILoginView::TakeFocus(content::WebContents* source, bool reverse) {
389 // In case of blocked UI (ex.: sign in is in progress)
390 // we should not process focus change events.
391 if (!forward_keyboard_event_)
392 return false;
393
394 ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
395 if (tray && tray->GetWidget()->IsVisible()) {
396 tray->SetNextFocusableView(this);
397 ash::Shell::GetInstance()->RotateFocus(reverse ? ash::Shell::BACKWARD :
398 ash::Shell::FORWARD);
399 }
400
401 return true;
402 }
403
404 void WebUILoginView::RequestMediaAccessPermission(
405 WebContents* web_contents,
406 const content::MediaStreamRequest& request,
407 const content::MediaResponseCallback& callback) {
408 if (MediaStreamInfoBarDelegate::Create(web_contents, request, callback))
409 NOTREACHED() << "Media stream not allowed for WebUI";
410 }
411
412 bool WebUILoginView::PreHandleGestureEvent(
413 content::WebContents* source,
414 const blink::WebGestureEvent& event) {
415 // Disable pinch zooming.
416 return event.type == blink::WebGestureEvent::GesturePinchBegin ||
417 event.type == blink::WebGestureEvent::GesturePinchUpdate ||
418 event.type == blink::WebGestureEvent::GesturePinchEnd;
419 }
420
421 void WebUILoginView::DidFailProvisionalLoad(
422 int64 frame_id,
423 const base::string16& frame_unique_name,
424 bool is_main_frame,
425 const GURL& validated_url,
426 int error_code,
427 const base::string16& error_description,
428 content::RenderViewHost* render_view_host) {
429 if (frame_unique_name != base::UTF8ToUTF16("gaia-frame"))
430 return;
431
432 GetWebUI()->CallJavascriptFunction("login.GaiaSigninScreen.onFrameError",
433 base::FundamentalValue(-error_code),
434 base::StringValue(validated_url.spec()));
435 }
436
437 void WebUILoginView::OnLoginPromptVisible() {
438 // If we're hidden than will generate this signal once we're shown.
439 if (is_hidden_ || webui_visible_) {
440 LOG(WARNING) << "Login WebUI >> not emitting signal, hidden: "
441 << is_hidden_;
442 return;
443 }
444 TRACE_EVENT0("chromeos", "WebUILoginView::OnLoginPromoptVisible");
445 if (should_emit_login_prompt_visible_) {
446 LOG(WARNING) << "Login WebUI >> login-prompt-visible";
447 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
448 EmitLoginPromptVisible();
449 }
450
451 webui_visible_ = true;
452 }
453
454 void WebUILoginView::ReturnFocus(bool reverse) {
455 // Return the focus to the web contents.
456 webui_login_->web_contents()->FocusThroughTabTraversal(reverse);
457 GetWidget()->Activate();
458 }
459
460 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/webui_login_view.h ('k') | chrome/browser/chromeos/login/webui_screen_locker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698