| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/ui/webui_login_view.h" | 5 #include "chrome/browser/chromeos/login/ui/webui_login_view.h" |
| 6 | 6 |
| 7 #include "ash/common/focus_cycler.h" | 7 #include "ash/common/focus_cycler.h" |
| 8 #include "ash/common/system/status_area_widget_delegate.h" | |
| 9 #include "ash/common/system/tray/system_tray.h" | 8 #include "ash/common/system/tray/system_tray.h" |
| 10 #include "ash/common/wm_shell.h" | 9 #include "ash/common/wm_shell.h" |
| 11 #include "ash/shell.h" | 10 #include "ash/shell.h" |
| 12 #include "base/bind.h" | 11 #include "base/bind.h" |
| 13 #include "base/callback.h" | 12 #include "base/callback.h" |
| 14 #include "base/i18n/rtl.h" | 13 #include "base/i18n/rtl.h" |
| 15 #include "base/logging.h" | 14 #include "base/logging.h" |
| 16 #include "base/macros.h" | 15 #include "base/macros.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #include "content/public/browser/render_widget_host.h" | 52 #include "content/public/browser/render_widget_host.h" |
| 54 #include "content/public/browser/render_widget_host_view.h" | 53 #include "content/public/browser/render_widget_host_view.h" |
| 55 #include "content/public/browser/web_contents.h" | 54 #include "content/public/browser/web_contents.h" |
| 56 #include "content/public/browser/web_ui.h" | 55 #include "content/public/browser/web_ui.h" |
| 57 #include "content/public/common/renderer_preferences.h" | 56 #include "content/public/common/renderer_preferences.h" |
| 58 #include "extensions/browser/view_type_utils.h" | 57 #include "extensions/browser/view_type_utils.h" |
| 59 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 58 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
| 60 #include "ui/gfx/geometry/rect.h" | 59 #include "ui/gfx/geometry/rect.h" |
| 61 #include "ui/gfx/geometry/size.h" | 60 #include "ui/gfx/geometry/size.h" |
| 62 #include "ui/views/controls/webview/webview.h" | 61 #include "ui/views/controls/webview/webview.h" |
| 63 #include "ui/views/focus/focus_manager.h" | |
| 64 #include "ui/views/focus/focus_search.h" | |
| 65 #include "ui/views/widget/widget.h" | 62 #include "ui/views/widget/widget.h" |
| 66 | 63 |
| 67 using content::NativeWebKeyboardEvent; | 64 using content::NativeWebKeyboardEvent; |
| 68 using content::RenderViewHost; | 65 using content::RenderViewHost; |
| 69 using content::WebContents; | 66 using content::WebContents; |
| 70 using web_modal::WebContentsModalDialogManager; | 67 using web_modal::WebContentsModalDialogManager; |
| 71 | 68 |
| 72 namespace { | 69 namespace { |
| 73 | 70 |
| 74 // These strings must be kept in sync with handleAccelerator() | 71 // These strings must be kept in sync with handleAccelerator() |
| (...skipping 26 matching lines...) Expand all Loading... |
| 101 ~ScopedArrowKeyTraversal() { | 98 ~ScopedArrowKeyTraversal() { |
| 102 views::FocusManager::set_arrow_key_traversal_enabled( | 99 views::FocusManager::set_arrow_key_traversal_enabled( |
| 103 previous_arrow_key_traversal_enabled_); | 100 previous_arrow_key_traversal_enabled_); |
| 104 } | 101 } |
| 105 | 102 |
| 106 private: | 103 private: |
| 107 const bool previous_arrow_key_traversal_enabled_; | 104 const bool previous_arrow_key_traversal_enabled_; |
| 108 DISALLOW_COPY_AND_ASSIGN(ScopedArrowKeyTraversal); | 105 DISALLOW_COPY_AND_ASSIGN(ScopedArrowKeyTraversal); |
| 109 }; | 106 }; |
| 110 | 107 |
| 111 // A helper method returns status area widget delegate if exists, | |
| 112 // otherwise nullptr. | |
| 113 ash::StatusAreaWidgetDelegate* GetStatusAreaWidgetDelegate() { | |
| 114 ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray(); | |
| 115 return tray ? static_cast<ash::StatusAreaWidgetDelegate*>( | |
| 116 tray->GetWidget()->GetContentsView()) | |
| 117 : nullptr; | |
| 118 } | |
| 119 | |
| 120 } // namespace | 108 } // namespace |
| 121 | 109 |
| 122 namespace chromeos { | 110 namespace chromeos { |
| 123 | 111 |
| 124 // static | 112 // static |
| 125 const char WebUILoginView::kViewClassName[] = | 113 const char WebUILoginView::kViewClassName[] = |
| 126 "browser/chromeos/login/WebUILoginView"; | 114 "browser/chromeos/login/WebUILoginView"; |
| 127 | 115 |
| 128 // WebUILoginView::CycleFocusTraversable --------------------------------------- | |
| 129 class WebUILoginView::CycleFocusTraversable : public views::FocusTraversable { | |
| 130 public: | |
| 131 explicit CycleFocusTraversable(WebUILoginView* webui_login_view) | |
| 132 : cycle_focus_search_(webui_login_view, true, false) {} | |
| 133 ~CycleFocusTraversable() override {} | |
| 134 | |
| 135 // views::FocusTraversable | |
| 136 views::FocusSearch* GetFocusSearch() override { return &cycle_focus_search_; } | |
| 137 | |
| 138 views::FocusTraversable* GetFocusTraversableParent() override { | |
| 139 return nullptr; | |
| 140 } | |
| 141 | |
| 142 views::View* GetFocusTraversableParentView() override { return nullptr; } | |
| 143 | |
| 144 private: | |
| 145 views::FocusSearch cycle_focus_search_; | |
| 146 | |
| 147 DISALLOW_COPY_AND_ASSIGN(CycleFocusTraversable); | |
| 148 }; | |
| 149 | |
| 150 // WebUILoginView::StatusAreaFocusTraversable ---------------------------------- | |
| 151 class WebUILoginView::StatusAreaFocusTraversable | |
| 152 : public views::FocusTraversable { | |
| 153 public: | |
| 154 StatusAreaFocusTraversable( | |
| 155 ash::StatusAreaWidgetDelegate* status_area_widget_delegate, | |
| 156 WebUILoginView* webui_login_view) | |
| 157 : webui_login_view_(webui_login_view), | |
| 158 status_area_focus_search_(status_area_widget_delegate, false, false) {} | |
| 159 ~StatusAreaFocusTraversable() override {} | |
| 160 | |
| 161 // views::FocusTraversable | |
| 162 views::FocusSearch* GetFocusSearch() override { | |
| 163 return &status_area_focus_search_; | |
| 164 } | |
| 165 | |
| 166 views::FocusTraversable* GetFocusTraversableParent() override { | |
| 167 return webui_login_view_->cycle_focus_traversable_.get(); | |
| 168 } | |
| 169 | |
| 170 views::View* GetFocusTraversableParentView() override { | |
| 171 return webui_login_view_->status_area_widget_host_; | |
| 172 } | |
| 173 | |
| 174 private: | |
| 175 WebUILoginView* const webui_login_view_; | |
| 176 views::FocusSearch status_area_focus_search_; | |
| 177 | |
| 178 DISALLOW_COPY_AND_ASSIGN(StatusAreaFocusTraversable); | |
| 179 }; | |
| 180 | |
| 181 // WebUILoginView public: ------------------------------------------------------ | 116 // WebUILoginView public: ------------------------------------------------------ |
| 182 | 117 |
| 183 WebUILoginView::WebUILoginView(const WebViewSettings& settings) | 118 WebUILoginView::WebUILoginView(const WebViewSettings& settings) |
| 184 : settings_(settings) { | 119 : settings_(settings) { |
| 185 registrar_.Add(this, | 120 registrar_.Add(this, |
| 186 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, | 121 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, |
| 187 content::NotificationService::AllSources()); | 122 content::NotificationService::AllSources()); |
| 188 registrar_.Add(this, | 123 registrar_.Add(this, |
| 189 chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN, | 124 chrome::NOTIFICATION_LOGIN_NETWORK_ERROR_SHOWN, |
| 190 content::NotificationService::AllSources()); | 125 content::NotificationService::AllSources()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 for (AccelMap::iterator i(accel_map_.begin()); i != accel_map_.end(); ++i) | 175 for (AccelMap::iterator i(accel_map_.begin()); i != accel_map_.end(); ++i) |
| 241 AddAccelerator(i->first); | 176 AddAccelerator(i->first); |
| 242 } | 177 } |
| 243 | 178 |
| 244 WebUILoginView::~WebUILoginView() { | 179 WebUILoginView::~WebUILoginView() { |
| 245 for (auto& observer : observer_list_) | 180 for (auto& observer : observer_list_) |
| 246 observer.OnHostDestroying(); | 181 observer.OnHostDestroying(); |
| 247 | 182 |
| 248 if (!chrome::IsRunningInMash() && | 183 if (!chrome::IsRunningInMash() && |
| 249 ash::Shell::GetInstance()->HasPrimaryStatusArea()) { | 184 ash::Shell::GetInstance()->HasPrimaryStatusArea()) { |
| 250 views::Widget* tray_widget = | 185 ash::Shell::GetInstance()->GetPrimarySystemTray()->SetNextFocusableView( |
| 251 ash::Shell::GetInstance()->GetPrimarySystemTray()->GetWidget(); | 186 nullptr); |
| 252 ash::StatusAreaWidgetDelegate* status_area_widget_delegate = | |
| 253 static_cast<ash::StatusAreaWidgetDelegate*>( | |
| 254 tray_widget->GetContentsView()); | |
| 255 status_area_widget_delegate->set_custom_focus_traversable(nullptr); | |
| 256 status_area_widget_delegate->set_default_last_focusable_child(false); | |
| 257 } else { | 187 } else { |
| 258 NOTIMPLEMENTED(); | 188 NOTIMPLEMENTED(); |
| 259 } | 189 } |
| 260 | 190 |
| 261 // Clear any delegates we have set on the WebView. | 191 // Clear any delegates we have set on the WebView. |
| 262 WebContents* web_contents = web_view()->GetWebContents(); | 192 WebContents* web_contents = web_view()->GetWebContents(); |
| 263 WebContentsModalDialogManager::FromWebContents(web_contents) | 193 WebContentsModalDialogManager::FromWebContents(web_contents) |
| 264 ->SetDelegate(nullptr); | 194 ->SetDelegate(nullptr); |
| 265 web_contents->SetDelegate(nullptr); | 195 web_contents->SetDelegate(nullptr); |
| 266 } | 196 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 WebContents* web_contents = web_view()->GetWebContents(); | 248 WebContents* web_contents = web_view()->GetWebContents(); |
| 319 if (!is_reusing_webview_) | 249 if (!is_reusing_webview_) |
| 320 InitializeWebView(web_view(), settings_.web_view_title); | 250 InitializeWebView(web_view(), settings_.web_view_title); |
| 321 | 251 |
| 322 web_view()->set_allow_accelerators(true); | 252 web_view()->set_allow_accelerators(true); |
| 323 AddChildView(web_view()); | 253 AddChildView(web_view()); |
| 324 | 254 |
| 325 WebContentsModalDialogManager::FromWebContents(web_contents) | 255 WebContentsModalDialogManager::FromWebContents(web_contents) |
| 326 ->SetDelegate(this); | 256 ->SetDelegate(this); |
| 327 web_contents->SetDelegate(this); | 257 web_contents->SetDelegate(this); |
| 328 | |
| 329 status_area_widget_host_ = new views::View; | |
| 330 AddChildView(status_area_widget_host_); | |
| 331 } | 258 } |
| 332 | 259 |
| 333 const char* WebUILoginView::GetClassName() const { | 260 const char* WebUILoginView::GetClassName() const { |
| 334 return kViewClassName; | 261 return kViewClassName; |
| 335 } | 262 } |
| 336 | 263 |
| 337 void WebUILoginView::RequestFocus() { | 264 void WebUILoginView::RequestFocus() { |
| 338 web_view()->RequestFocus(); | 265 web_view()->RequestFocus(); |
| 339 } | 266 } |
| 340 | 267 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 } | 320 } |
| 394 | 321 |
| 395 void WebUILoginView::LoadURL(const GURL& url) { | 322 void WebUILoginView::LoadURL(const GURL& url) { |
| 396 if (!is_reusing_webview_) | 323 if (!is_reusing_webview_) |
| 397 web_view()->LoadInitialURL(url); | 324 web_view()->LoadInitialURL(url); |
| 398 web_view()->RequestFocus(); | 325 web_view()->RequestFocus(); |
| 399 | 326 |
| 400 // There is no Shell instance while running in mash. | 327 // There is no Shell instance while running in mash. |
| 401 if (chrome::IsRunningInMash()) | 328 if (chrome::IsRunningInMash()) |
| 402 return; | 329 return; |
| 403 | |
| 404 ash::StatusAreaWidgetDelegate* status_area_widget_delegate = | |
| 405 GetStatusAreaWidgetDelegate(); | |
| 406 DCHECK(status_area_widget_delegate); | |
| 407 cycle_focus_traversable_.reset(new CycleFocusTraversable(this)); | |
| 408 status_area_focus_traversable_.reset( | |
| 409 new StatusAreaFocusTraversable(status_area_widget_delegate, this)); | |
| 410 status_area_widget_delegate->set_custom_focus_traversable( | |
| 411 status_area_focus_traversable_.get()); | |
| 412 } | 330 } |
| 413 | 331 |
| 414 content::WebUI* WebUILoginView::GetWebUI() { | 332 content::WebUI* WebUILoginView::GetWebUI() { |
| 415 return web_view()->web_contents()->GetWebUI(); | 333 return web_view()->web_contents()->GetWebUI(); |
| 416 } | 334 } |
| 417 | 335 |
| 418 content::WebContents* WebUILoginView::GetWebContents() { | 336 content::WebContents* WebUILoginView::GetWebContents() { |
| 419 return web_view()->web_contents(); | 337 return web_view()->web_contents(); |
| 420 } | 338 } |
| 421 | 339 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 // In case of blocked UI (ex.: sign in is in progress) | 457 // In case of blocked UI (ex.: sign in is in progress) |
| 540 // we should not process focus change events. | 458 // we should not process focus change events. |
| 541 if (!forward_keyboard_event_) | 459 if (!forward_keyboard_event_) |
| 542 return false; | 460 return false; |
| 543 | 461 |
| 544 // Focus is accepted, but the Ash system tray is not available in Mash, so | 462 // Focus is accepted, but the Ash system tray is not available in Mash, so |
| 545 // exit early. | 463 // exit early. |
| 546 if (chrome::IsRunningInMash()) | 464 if (chrome::IsRunningInMash()) |
| 547 return true; | 465 return true; |
| 548 | 466 |
| 549 ash::StatusAreaWidgetDelegate* status_area_widget_delegate = | 467 ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray(); |
| 550 GetStatusAreaWidgetDelegate(); | 468 if (tray && tray->GetWidget()->IsVisible()) { |
| 551 if (status_area_widget_delegate && | 469 tray->SetNextFocusableView(this); |
| 552 status_area_widget_delegate->GetWidget()->IsVisible()) { | |
| 553 status_area_widget_delegate->set_default_last_focusable_child(reverse); | |
| 554 ash::WmShell::Get()->focus_cycler()->RotateFocus( | 470 ash::WmShell::Get()->focus_cycler()->RotateFocus( |
| 555 reverse ? ash::FocusCycler::BACKWARD : ash::FocusCycler::FORWARD); | 471 reverse ? ash::FocusCycler::BACKWARD : ash::FocusCycler::FORWARD); |
| 556 } | 472 } |
| 557 | 473 |
| 558 return true; | 474 return true; |
| 559 } | 475 } |
| 560 | 476 |
| 561 void WebUILoginView::RequestMediaAccessPermission( | 477 void WebUILoginView::RequestMediaAccessPermission( |
| 562 WebContents* web_contents, | 478 WebContents* web_contents, |
| 563 const content::MediaStreamRequest& request, | 479 const content::MediaStreamRequest& request, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 if (should_emit_login_prompt_visible_) { | 547 if (should_emit_login_prompt_visible_) { |
| 632 VLOG(1) << "Login WebUI >> login-prompt-visible"; | 548 VLOG(1) << "Login WebUI >> login-prompt-visible"; |
| 633 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> | 549 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> |
| 634 EmitLoginPromptVisible(); | 550 EmitLoginPromptVisible(); |
| 635 } | 551 } |
| 636 | 552 |
| 637 webui_visible_ = true; | 553 webui_visible_ = true; |
| 638 } | 554 } |
| 639 | 555 |
| 640 } // namespace chromeos | 556 } // namespace chromeos |
| OLD | NEW |