assistant_web_ui_controller.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright 2019 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. #include "ash/assistant/assistant_web_ui_controller.h"
  5. #include "ash/assistant/ui/assistant_web_container_view.h"
  6. #include "ash/assistant/util/deep_link_util.h"
  7. #include "ash/multi_user/multi_user_window_manager_impl.h"
  8. #include "ash/session/session_controller_impl.h"
  9. #include "ash/shell.h"
  10. #include "ui/aura/client/aura_constants.h"
  11. #include "ui/events/event_observer.h"
  12. #include "ui/views/event_monitor.h"
  13. namespace ash {
  14. // -----------------------------------------------------------------------------
  15. // AssistantWebContainerEventObserver:
  16. class AssistantWebContainerEventObserver : public ui::EventObserver {
  17. public:
  18. AssistantWebContainerEventObserver(AssistantWebUiController* owner,
  19. views::Widget* widget)
  20. : owner_(owner),
  21. widget_(widget),
  22. event_monitor_(
  23. views::EventMonitor::CreateWindowMonitor(this,
  24. widget->GetNativeWindow(),
  25. {ui::ET_KEY_PRESSED})) {}
  26. AssistantWebContainerEventObserver(
  27. const AssistantWebContainerEventObserver&) = delete;
  28. AssistantWebContainerEventObserver& operator=(
  29. const AssistantWebContainerEventObserver&) = delete;
  30. ~AssistantWebContainerEventObserver() override = default;
  31. // ui::EventObserver:
  32. void OnEvent(const ui::Event& event) override {
  33. DCHECK(event.type() == ui::ET_KEY_PRESSED);
  34. const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
  35. switch (key_event.key_code()) {
  36. case ui::VKEY_BROWSER_BACK:
  37. owner_->OnBackButtonPressed();
  38. break;
  39. case ui::VKEY_W:
  40. if (!key_event.IsControlDown())
  41. break;
  42. event_monitor_.reset();
  43. widget_->Close();
  44. break;
  45. default:
  46. // No action necessary.
  47. break;
  48. }
  49. }
  50. private:
  51. AssistantWebUiController* owner_ = nullptr;
  52. views::Widget* widget_ = nullptr;
  53. std::unique_ptr<views::EventMonitor> event_monitor_;
  54. };
  55. // -----------------------------------------------------------------------------
  56. // AssistantWebUiController:
  57. AssistantWebUiController::AssistantWebUiController() {
  58. assistant_controller_observation_.Observe(AssistantController::Get());
  59. }
  60. AssistantWebUiController::~AssistantWebUiController() {
  61. CloseUi();
  62. CHECK(!views::WidgetObserver::IsInObserverList());
  63. }
  64. void AssistantWebUiController::OnWidgetDestroying(views::Widget* widget) {
  65. ResetWebContainerView();
  66. }
  67. void AssistantWebUiController::OnAssistantControllerConstructed() {
  68. AssistantState::Get()->AddObserver(this);
  69. }
  70. void AssistantWebUiController::OnAssistantControllerDestroying() {
  71. AssistantState::Get()->RemoveObserver(this);
  72. }
  73. void AssistantWebUiController::OnDeepLinkReceived(
  74. assistant::util::DeepLinkType type,
  75. const std::map<std::string, std::string>& params) {
  76. if (assistant::util::IsWebDeepLinkType(type, params))
  77. ShowUi(assistant::util::GetWebUrl(type, params).value());
  78. }
  79. void AssistantWebUiController::OnAssistantSettingsEnabled(bool enabled) {
  80. if (!enabled)
  81. CloseUi();
  82. }
  83. void AssistantWebUiController::ShowUi(const GURL& url) {
  84. if (!web_container_view_)
  85. CreateWebContainerView();
  86. web_container_view_->GetWidget()->Show();
  87. web_container_view_->OpenUrl(url);
  88. }
  89. void AssistantWebUiController::CloseUi() {
  90. if (!web_container_view_)
  91. return;
  92. web_container_view_->GetWidget()->CloseNow();
  93. DCHECK_EQ(nullptr, web_container_view_);
  94. }
  95. void AssistantWebUiController::OnBackButtonPressed() {
  96. DCHECK(web_container_view_);
  97. web_container_view_->GoBack();
  98. }
  99. AssistantWebContainerView* AssistantWebUiController::GetViewForTest() {
  100. return web_container_view_;
  101. }
  102. void AssistantWebUiController::CreateWebContainerView() {
  103. DCHECK(!web_container_view_);
  104. web_container_view_ = new AssistantWebContainerView(&view_delegate_);
  105. auto* widget = web_container_view_->GetWidget();
  106. widget->AddObserver(this);
  107. event_observer_ =
  108. std::make_unique<AssistantWebContainerEventObserver>(this, widget);
  109. // Associate the window for Assistant Web UI with the active user in order to
  110. // not leak across user sessions.
  111. auto* window_manager = MultiUserWindowManagerImpl::Get();
  112. if (!window_manager)
  113. return;
  114. const UserSession* active_user_session =
  115. Shell::Get()->session_controller()->GetUserSession(0);
  116. if (!active_user_session)
  117. return;
  118. auto* native_window = widget->GetNativeWindow();
  119. native_window->SetProperty(aura::client::kCreatedByUserGesture, true);
  120. window_manager->SetWindowOwner(native_window,
  121. active_user_session->user_info.account_id);
  122. }
  123. void AssistantWebUiController::ResetWebContainerView() {
  124. DCHECK(web_container_view_);
  125. event_observer_.reset();
  126. web_container_view_->GetWidget()->RemoveObserver(this);
  127. web_container_view_ = nullptr;
  128. }
  129. } // namespace ash