From 5241024004177ab2f312c513c79078bd9199cd08 Mon Sep 17 00:00:00 2001 From: Cici Ruan Date: Mon, 6 Dec 2021 19:54:12 +0000 Subject: [PATCH] arc: Add display overlay with input mapping view Display overlay is added as exo/surface overlay. Once the window is unregistered, the display overlay is removed too. The UIs still need to be polished according to the UX requirement when it's ready. This is simple version and the overlay structure. And then it can add other components like menu and education dialog. Since display overlay is added on exo/surface, rewrote some unit_tests depending on exo::test::ExoTestBase and added class to create test window with exo/surface. DisplayOverlayControllerTest*/TouchInjectorTest* Bug: b:188452744 Test: unit_tests--gtest_filter=ArcInputOverlayManagerTest*/ Change-Id: I8620cf054fe5025282b34099236971184cf2826d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3273312 Reviewed-by: Yuichiro Hanada Auto-Submit: Cici Ruan Commit-Queue: Cici Ruan Cr-Commit-Position: refs/heads/main@{#948633} --- .../ash/arc/input_overlay/actions/action.cc | 16 ++- .../ash/arc/input_overlay/actions/action.h | 9 ++ .../arc/input_overlay/actions/action_label.cc | 48 +++++++ .../arc/input_overlay/actions/action_label.h | 34 +++++ .../input_overlay/actions/action_move_key.cc | 19 +++ .../input_overlay/actions/action_move_key.h | 3 + .../input_overlay/actions/action_tap_key.cc | 18 +++ .../input_overlay/actions/action_tap_key.h | 3 + .../arc_input_overlay_manager.cc | 50 +++++-- .../input_overlay/arc_input_overlay_manager.h | 13 +- .../arc_input_overlay_manager_unittest.cc | 134 +++++++++--------- .../display_overlay_controller.cc | 118 +++++++++++++++ .../display_overlay_controller.h | 46 ++++++ .../display_overlay_controller_unittest.cc | 83 +++++++++++ .../arc/input_overlay/test/arc_test_window.cc | 57 ++++++++ .../arc/input_overlay/test/arc_test_window.h | 41 ++++++ .../ash/arc/input_overlay/touch_injector.cc | 8 +- .../ash/arc/input_overlay/touch_injector.h | 2 + chrome/browser/chromeos/BUILD.gn | 7 + 19 files changed, 626 insertions(+), 83 deletions(-) create mode 100644 chrome/browser/ash/arc/input_overlay/actions/action_label.cc create mode 100644 chrome/browser/ash/arc/input_overlay/actions/action_label.h create mode 100644 chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc create mode 100644 chrome/browser/ash/arc/input_overlay/display_overlay_controller.h create mode 100644 chrome/browser/ash/arc/input_overlay/display_overlay_controller_unittest.cc create mode 100644 chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc create mode 100644 chrome/browser/ash/arc/input_overlay/test/arc_test_window.h diff --git a/chrome/browser/ash/arc/input_overlay/actions/action.cc b/chrome/browser/ash/arc/input_overlay/actions/action.cc index aa98a9c096f7d..2ee8f6bf37c90 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/action.cc @@ -9,6 +9,7 @@ #include "ui/events/base_event_utils.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/keycode_converter.h" +#include "ui/views/controls/label.h" namespace arc { namespace input_overlay { @@ -35,7 +36,7 @@ void LogEvent(const ui::Event& event) { << "}. Pointer detail {" << touch_event.pointer_details().ToString() << "}, TouchID {" << touch_event.pointer_details().id << "}."; } - // TODO (cuicuiruan): Add logging other events as needed. + // TODO(cuicuiruan): Add logging other events as needed. } void LogTouchEvents(const std::list& events) { @@ -43,6 +44,19 @@ void LogTouchEvents(const std::list& events) { LogEvent(event); } +std::string GetDisplayText(const std::string& dom_code_string) { + if (base::StartsWith(dom_code_string, "Key", base::CompareCase::SENSITIVE)) + return dom_code_string.substr(3); + if (base::StartsWith(dom_code_string, "Digit", base::CompareCase::SENSITIVE)) + return dom_code_string.substr(5); + auto lower = base::ToLowerASCII(dom_code_string); + if (lower == "escape") + return "esc"; + // TODO(cuicuiruan): adjust more display text according to UX design + // requirement. + return lower; +} + Action::Action(aura::Window* window) : target_window_(window) {} Action::~Action() = default; diff --git a/chrome/browser/ash/arc/input_overlay/actions/action.h b/chrome/browser/ash/arc/input_overlay/actions/action.h index 17ffdce2db4ce..d31c6093ec1ed 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action.h +++ b/chrome/browser/ash/arc/input_overlay/actions/action.h @@ -11,6 +11,7 @@ #include #include "base/values.h" +#include "chrome/browser/ash/arc/input_overlay/actions/action_label.h" #include "chrome/browser/ash/arc/input_overlay/actions/position.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" @@ -21,6 +22,10 @@ namespace input_overlay { // Log events for debugging. void LogEvent(const ui::Event& event); void LogTouchEvents(const std::list& events); +// TODO(cuicuiruan): Currently, it shows the dom_code. +// Will replace it with showing the result of dom_key / keyboard key depending +// on different keyboard layout. +std::string GetDisplayText(const std::string& dom_code_string); // This is the base touch action which converts other events to touch // events for input overlay. @@ -41,6 +46,10 @@ class Action { virtual bool RewriteEvent(const ui::Event& origin, std::list& touch_events, const gfx::RectF& content_bounds) = 0; + // Get the UI location in the content view. + virtual gfx::PointF GetUIPosition(const gfx::RectF& content_bounds) = 0; + virtual std::unique_ptr CreateView( + const gfx::RectF& content_bounds) = 0; const std::string& name() { return name_; } const std::vector>& locations() const { diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_label.cc b/chrome/browser/ash/arc/input_overlay/actions/action_label.cc new file mode 100644 index 0000000000000..eb720544d3363 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/actions/action_label.cc @@ -0,0 +1,48 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/arc/input_overlay/actions/action_label.h" + +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/color_palette.h" +#include "ui/views/background.h" + +namespace arc { +namespace input_overlay { + +constexpr int kWidthPadding = 10; +constexpr int kMinimumLabelWidth = 20; + +ActionLabel::ActionLabel() : views::Label() {} +ActionLabel::ActionLabel(const std::u16string& text) : views::Label(text) { + SetDefaultViewMode(); +} + +ActionLabel::~ActionLabel() = default; + +void ActionLabel::SetDefaultViewMode() { + // TODO(cuicuiruan): Replace it with required color once UI/UX specs are + // confirmed. + SetBackground(views::CreateSolidBackground(gfx::kGoogleGrey400)); +} + +void ActionLabel::SetPositionFromCenterPosition(gfx::PointF& center_position) { + auto size = GetPreferredSize(); + SetSize(size); + int left = std::max(0, (int)(center_position.x() - size.width() / 2)); + int top = std::max(0, (int)(center_position.y() - size.height() / 2)); + // SetPosition function needs the top-left position. + SetPosition(gfx::Point(left, top)); +} + +gfx::Size ActionLabel::CalculatePreferredSize() const { + auto size = Label::CalculatePreferredSize(); + size.set_width(size.width() + kWidthPadding); + if (size.width() < kMinimumLabelWidth) + size.set_width(kMinimumLabelWidth); + return size; +} + +} // namespace input_overlay +} // namespace arc diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_label.h b/chrome/browser/ash/arc/input_overlay/actions/action_label.h new file mode 100644 index 0000000000000..3843217d704b7 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/actions/action_label.h @@ -0,0 +1,34 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_ACTIONS_ACTION_LABEL_H_ +#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_ACTIONS_ACTION_LABEL_H_ + +#include "ui/views/controls/label.h" + +namespace arc { +namespace input_overlay { +// ActionLabel is the basic UI label for the action. It can set default view +// mode and edit mode. +class ActionLabel : public views::Label { + public: + ActionLabel(); + explicit ActionLabel(const std::u16string& text); + + ActionLabel(const ActionLabel&) = delete; + ActionLabel& operator=(const ActionLabel&) = delete; + ~ActionLabel() override; + + // Set it with default view mode. + void SetDefaultViewMode(); + // Set position from its center position. + void SetPositionFromCenterPosition(gfx::PointF& center_position); + + // views::View: + gfx::Size CalculatePreferredSize() const override; +}; +} // namespace input_overlay +} // namespace arc + +#endif // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_ACTIONS_ACTION_LABEL_H_ diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_move_key.cc b/chrome/browser/ash/arc/input_overlay/actions/action_move_key.cc index ae1e96f8531e5..c3bceae375af1 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action_move_key.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/action_move_key.cc @@ -91,6 +91,25 @@ bool ActionMoveKey::RewriteEvent(const ui::Event& origin, return rewritten; } +gfx::PointF ActionMoveKey::GetUIPosition(const gfx::RectF& content_bounds) { + // TODO(cuicuiruan): will update the UI position according to design specs. + auto* position = locations().front().get(); + return position->CalculatePosition(content_bounds); +} + +std::unique_ptr ActionMoveKey::CreateView( + const gfx::RectF& content_bounds) { + // TODO(cuicuiruan): will update the view according to design specs. + std::string text; + for (auto key : keys_) { + text += GetDisplayText(ui::KeycodeConverter::DomCodeToCodeString(key)); + } + auto view = std::make_unique(base::UTF8ToUTF16(text)); + auto center_pos = GetUIPosition(content_bounds); + view->SetPositionFromCenterPosition(center_pos); + return view; +} + bool ActionMoveKey::RewriteKeyEvent(const ui::KeyEvent& key_event, std::list& rewritten_events, const gfx::RectF& content_bounds) { diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_move_key.h b/chrome/browser/ash/arc/input_overlay/actions/action_move_key.h index f808e360d4db3..c47da0dd19690 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action_move_key.h +++ b/chrome/browser/ash/arc/input_overlay/actions/action_move_key.h @@ -40,6 +40,9 @@ class ActionMoveKey : public Action { bool RewriteEvent(const ui::Event& origin, std::list& touch_events, const gfx::RectF& content_bounds) override; + gfx::PointF GetUIPosition(const gfx::RectF& content_bounds) override; + std::unique_ptr CreateView( + const gfx::RectF& content_bounds) override; const std::vector& keys() const { return keys_; } diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.cc b/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.cc index 9b237fe99c934..465085a4840cc 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.cc +++ b/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.cc @@ -10,6 +10,8 @@ #include "ui/events/base_event_utils.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/keycode_converter.h" +#include "ui/gfx/geometry/size.h" +#include "ui/views/controls/label.h" namespace arc { namespace input_overlay { @@ -111,5 +113,21 @@ bool ActionTapKey::RewriteKeyEvent(const ui::KeyEvent& key_event, return true; } +gfx::PointF ActionTapKey::GetUIPosition(const gfx::RectF& content_bounds) { + // TODO(cuicuiruan): will update the UI position according to design specs. + auto* position = locations().front().get(); + return position->CalculatePosition(content_bounds); +} + +std::unique_ptr ActionTapKey::CreateView( + const gfx::RectF& content_bounds) { + // TODO(cuicuiruan): will update the view according to design specs. + auto text = GetDisplayText(ui::KeycodeConverter::DomCodeToCodeString(key_)); + auto view = std::make_unique(base::UTF8ToUTF16(text)); + auto center_pos = GetUIPosition(content_bounds); + view->SetPositionFromCenterPosition(center_pos); + return view; +} + } // namespace input_overlay } // namespace arc diff --git a/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.h b/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.h index 5ea526fb56a5b..a627bdd3b0800 100644 --- a/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.h +++ b/chrome/browser/ash/arc/input_overlay/actions/action_tap_key.h @@ -34,6 +34,9 @@ class ActionTapKey : public Action { bool RewriteEvent(const ui::Event& origin, std::list& touch_events, const gfx::RectF& content_bounds) override; + gfx::PointF GetUIPosition(const gfx::RectF& content_bounds) override; + std::unique_ptr CreateView( + const gfx::RectF& content_bounds) override; ui::DomCode key() { return key_; } diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc index ce7d8ac0a5979..1374d21900360 100644 --- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc +++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.cc @@ -138,16 +138,19 @@ void ArcInputOverlayManager::RemoveObserverFromInputMethod() { input_method_ = nullptr; } -void ArcInputOverlayManager::RegisterWindow(aura::Window* top_level_window) { - if (!top_level_window || registered_top_level_window_ == top_level_window) +void ArcInputOverlayManager::RegisterWindow(aura::Window* window) { + if (!window || window != window->GetToplevelWindow() || + registered_top_level_window_ == window) { return; - auto it = input_overlay_enabled_windows_.find(top_level_window); + } + auto it = input_overlay_enabled_windows_.find(window); if (it == input_overlay_enabled_windows_.end()) return; DCHECK(!registered_top_level_window_); it->second->RegisterEventRewriter(); - registered_top_level_window_ = top_level_window; + registered_top_level_window_ = window; AddObserverToInputMethod(); + AddDisplayOverlayController(); // If the window is on the extended window, it turns out only primary root // window catches the key event. So it needs to forward the key event from // primary root window to extended root window event source. @@ -158,11 +161,9 @@ void ArcInputOverlayManager::RegisterWindow(aura::Window* top_level_window) { } } -void ArcInputOverlayManager::UnRegisterWindow(aura::Window* top_level_window) { - if (!registered_top_level_window_ || - registered_top_level_window_ != top_level_window) { +void ArcInputOverlayManager::UnRegisterWindow(aura::Window* window) { + if (!registered_top_level_window_ || registered_top_level_window_ != window) return; - } auto it = input_overlay_enabled_windows_.find(registered_top_level_window_); DCHECK(it != input_overlay_enabled_windows_.end()); if (it == input_overlay_enabled_windows_.end()) @@ -170,8 +171,26 @@ void ArcInputOverlayManager::UnRegisterWindow(aura::Window* top_level_window) { if (key_event_source_rewriter_) key_event_source_rewriter_.reset(); it->second->UnRegisterEventRewriter(); - registered_top_level_window_ = nullptr; + RemoveDisplayOverlayController(); RemoveObserverFromInputMethod(); + registered_top_level_window_ = nullptr; +} + +void ArcInputOverlayManager::AddDisplayOverlayController() { + if (!registered_top_level_window_) + return; + DCHECK(!display_overlay_controller_); + auto it = input_overlay_enabled_windows_.find(registered_top_level_window_); + DCHECK(it != input_overlay_enabled_windows_.end()); + display_overlay_controller_ = + std::make_unique(it->second.get()); +} + +void ArcInputOverlayManager::RemoveDisplayOverlayController() { + if (!registered_top_level_window_) + return; + DCHECK(display_overlay_controller_); + display_overlay_controller_.reset(); } //////////////////////////////////////////////////////////////////////////////// @@ -211,7 +230,7 @@ void ArcInputOverlayManager::OnWindowDestroying(aura::Window* window) { void ArcInputOverlayManager::OnWindowAddedToRootWindow(aura::Window* window) { if (!window) return; - RegisterWindow(window->GetToplevelWindow()); + RegisterWindow(window); } void ArcInputOverlayManager::OnWindowRemovingFromRootWindow( @@ -224,6 +243,17 @@ void ArcInputOverlayManager::OnWindowRemovingFromRootWindow( UnRegisterWindow(window); } +void ArcInputOverlayManager::OnWindowBoundsChanged( + aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) { + if (!window || window != registered_top_level_window_) + return; + if (display_overlay_controller_) + display_overlay_controller_->OnWindowBoundsChanged(); +} + //////////////////////////////////////////////////////////////////////////////// // KeyedService: void ArcInputOverlayManager::Shutdown() { diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h index 20a4d1c45bda3..6d941af92a1ca 100644 --- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h +++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h @@ -9,6 +9,7 @@ #include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h" #include "base/strings/string_util.h" +#include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" #include "chrome/browser/ash/arc/input_overlay/key_event_source_rewriter.h" #include "chrome/browser/ash/arc/input_overlay/touch_injector.h" #include "components/keyed_service/core/keyed_service.h" @@ -56,6 +57,10 @@ class ArcInputOverlayManager : public KeyedService, void OnWindowAddedToRootWindow(aura::Window* window) override; void OnWindowRemovingFromRootWindow(aura::Window* window, aura::Window* new_root) override; + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) override; // KeyedService overrides: void Shutdown() override; @@ -84,14 +89,18 @@ class ArcInputOverlayManager : public KeyedService, // each time. aura::Window* registered_top_level_window_ = nullptr; std::unique_ptr key_event_source_rewriter_; + std::unique_ptr display_overlay_controller_; void ReadData(const std::string& package_name, aura::Window* top_level_window); void NotifyTextInputState(); void AddObserverToInputMethod(); void RemoveObserverFromInputMethod(); - void RegisterWindow(aura::Window* top_level_window); - void UnRegisterWindow(aura::Window* top_level_window); + // Only top level window will be registered successfully. + void RegisterWindow(aura::Window* window); + void UnRegisterWindow(aura::Window* window); + void AddDisplayOverlayController(); + void RemoveDisplayOverlayController(); base::WeakPtrFactory weak_ptr_factory_{this}; }; diff --git a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc index 5de3f82fce83d..0507d11df6f70 100644 --- a/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc +++ b/chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc @@ -4,10 +4,11 @@ #include "chrome/browser/ash/arc/input_overlay/arc_input_overlay_manager.h" -#include "ash/public/cpp/window_properties.h" #include "ash/shell.h" -#include "ash/test/ash_test_base.h" +#include "chrome/browser/ash/arc/input_overlay/test/arc_test_window.h" #include "chrome/browser/ash/arc/input_overlay/test/event_capturer.h" +#include "components/exo/test/exo_test_base.h" +#include "components/exo/test/exo_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h" @@ -16,26 +17,7 @@ #include "ui/views/widget/widget.h" namespace arc { -namespace { - -std::unique_ptr CreateArcWindowWithRootAndPackage( - aura::Window* root, - const std::string& package_name) { - views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); - params.bounds = gfx::Rect(); - params.context = root; - views::Widget* widget = new views::Widget(); - widget->Init(std::move(params)); - widget->GetNativeWindow()->SetTitle(u"foo"); - widget->GetNativeWindow()->SetProperty(ash::kArcPackageNameKey, package_name); - widget->Show(); - widget->Activate(); - return base::WrapUnique(widget->GetNativeWindow()); -} - -} // namespace - -class ArcInputOverlayManagerTest : public ash::AshTestBase { +class ArcInputOverlayManagerTest : public exo::test::ExoTestBase { public: ArcInputOverlayManagerTest() = default; @@ -76,6 +58,14 @@ class ArcInputOverlayManagerTest : public ash::AshTestBase { return arc_test_input_overlay_manager_->key_event_source_rewriter_.get(); } + DisplayOverlayController* GetDisplayOverlayController() { + return arc_test_input_overlay_manager_->display_overlay_controller_.get(); + } + + void WindowFocus(aura::Window* gain_focus, aura::Window* lost_focus) { + arc_test_input_overlay_manager_->OnWindowFocused(gain_focus, lost_focus); + } + protected: std::unique_ptr arc_test_input_overlay_manager_; @@ -83,7 +73,7 @@ class ArcInputOverlayManagerTest : public ash::AshTestBase { aura::test::TestWindowDelegate dummy_delegate_; void SetUp() override { - ash::AshTestBase::SetUp(); + exo::test::ExoTestBase::SetUp(); arc_test_input_overlay_manager_ = base::WrapUnique(new ArcInputOverlayManager(nullptr, nullptr)); } @@ -91,33 +81,40 @@ class ArcInputOverlayManagerTest : public ash::AshTestBase { void TearDown() override { arc_test_input_overlay_manager_->Shutdown(); arc_test_input_overlay_manager_.reset(); - ash::AshTestBase::TearDown(); + exo::test::ExoTestBase::TearDown(); } }; TEST_F(ArcInputOverlayManagerTest, TestPropertyChangeAndWindowDestroy) { // Test app with input overlay data. - auto arc_window = CreateArcWindowWithRootAndPackage( - nullptr, "org.chromium.arc.testapp.inputoverlay"); - EXPECT_TRUE(IsInputOverlayEnabled(arc_window.get())); + auto arc_window = std::make_unique( + exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), + "org.chromium.arc.testapp.inputoverlay"); + EXPECT_TRUE(IsInputOverlayEnabled(arc_window->GetWindow())); + EXPECT_FALSE(GetRegisteredWindow()); + WindowFocus(arc_window->GetWindow(), nullptr); + EXPECT_TRUE(GetRegisteredWindow()); // Test app with input overlay data when window is destroyed. + auto* arc_window_ptr = arc_window->GetWindow(); arc_window.reset(); - EXPECT_FALSE(IsInputOverlayEnabled(arc_window.get())); + EXPECT_FALSE(IsInputOverlayEnabled(arc_window_ptr)); // Test app without input overlay data. - auto arc_window_no_data = CreateArcWindowWithRootAndPackage( - nullptr, "org.chromium.arc.testapp.inputoverlay_no_data"); - EXPECT_FALSE(IsInputOverlayEnabled(arc_window_no_data.get())); + auto arc_window_no_data = + std::make_unique( + exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), + "org.chromium.arc.testapp.inputoverlay_no_data"); + EXPECT_FALSE(IsInputOverlayEnabled(arc_window_no_data->GetWindow())); } TEST_F(ArcInputOverlayManagerTest, TestInputMethodObsever) { ASSERT_FALSE(GetInputMethod()); ASSERT_FALSE(IsTextInputActive()); - auto arc_window = CreateArcWindowWithRootAndPackage( - ash::Shell::GetPrimaryRootWindow(), + auto arc_window = std::make_unique( + exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), "org.chromium.arc.testapp.inputoverlay"); - arc_test_input_overlay_manager_->OnWindowFocused(arc_window.get(), nullptr); + WindowFocus(arc_window->GetWindow(), nullptr); ui::InputMethod* input_method = GetInputMethod(); EXPECT_TRUE(GetInputMethod()); input_method->SetFocusedTextInputClient(nullptr); @@ -133,26 +130,27 @@ TEST_F(ArcInputOverlayManagerTest, TestInputMethodObsever) { } TEST_F(ArcInputOverlayManagerTest, TestWindowFocusChange) { - auto arc_window = CreateArcWindowWithRootAndPackage( - ash::Shell::GetPrimaryRootWindow(), + auto arc_window = std::make_unique( + exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), "org.chromium.arc.testapp.inputoverlay"); - auto arc_window_no_data = CreateArcWindowWithRootAndPackage( - ash::Shell::GetPrimaryRootWindow(), - "org.chromium.arc.testapp.inputoverlay_no_data"); + auto arc_window_no_data = + std::make_unique( + exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), + "org.chromium.arc.testapp.inputoverlay_no_data"); EXPECT_EQ(1, EnabledWindows()); - auto* injector = GetTouchInjector(arc_window.get()); + auto* injector = GetTouchInjector(arc_window->GetWindow()); EXPECT_TRUE(injector); // The action number should be adjusted with the data in the // org.chromium.arc.testapp.inputoverlay.json. EXPECT_EQ(2, (int)injector->actions().size()); - EXPECT_TRUE(!GetRegisteredWindow()); - arc_test_input_overlay_manager_->OnWindowFocused(arc_window.get(), nullptr); - EXPECT_EQ(arc_window.get(), GetRegisteredWindow()); - arc_test_input_overlay_manager_->OnWindowFocused(arc_window_no_data.get(), - arc_window.get()); - EXPECT_TRUE(!GetRegisteredWindow()); + EXPECT_TRUE(!GetRegisteredWindow() && !GetDisplayOverlayController()); + WindowFocus(arc_window->GetWindow(), nullptr); + EXPECT_EQ(arc_window->GetWindow(), GetRegisteredWindow()); + EXPECT_TRUE(GetDisplayOverlayController()); + WindowFocus(arc_window_no_data->GetWindow(), arc_window->GetWindow()); + EXPECT_TRUE(!GetRegisteredWindow() && !GetDisplayOverlayController()); } TEST_F(ArcInputOverlayManagerTest, TestKeyEventSourceRewriterForMultiDisplay) { @@ -167,9 +165,11 @@ TEST_F(ArcInputOverlayManagerTest, TestKeyEventSourceRewriterForMultiDisplay) { // should be |key_event_source_rewriter_| registered on the primary root // window. EXPECT_FALSE(GetKeyEventSourceRewriter()); - auto arc_window = CreateArcWindowWithRootAndPackage( - root_windows[1], "org.chromium.arc.testapp.inputoverlay"); - arc_window->SetBoundsInScreen(gfx::Rect(1010, 910, 100, 100), display1); + auto arc_window = std::make_unique( + exo_test_helper(), root_windows[1], + "org.chromium.arc.testapp.inputoverlay"); + // arc_window->SetBounds(display1, gfx::Rect(1010, 910, 100, 100)); + WindowFocus(arc_window->GetWindow(), nullptr); EXPECT_TRUE(GetKeyEventSourceRewriter()); // Simulate the fact that key events are only sent to primary root window // when there is no text input focus. Make sure the input overlay window can @@ -187,31 +187,35 @@ TEST_F(ArcInputOverlayManagerTest, TestKeyEventSourceRewriterForMultiDisplay) { event_capturer.Clear(); root_windows[1]->RemovePostTargetHandler(&event_capturer); // Move to the primary display. - arc_window->SetBoundsInScreen(gfx::Rect(10, 10, 100, 100), display0); + arc_window->SetBounds(display0, gfx::Rect(10, 10, 100, 100)); EXPECT_FALSE(GetKeyEventSourceRewriter()); // Move back to the secondary display. - arc_window->SetBoundsInScreen(gfx::Rect(1010, 910, 100, 100), display1); + arc_window->SetBounds(display1, gfx::Rect(1010, 910, 100, 100)); EXPECT_TRUE(GetKeyEventSourceRewriter()); arc_window.reset(); // Test when launching input overlay window on the primary display, there // shouldn't be |key_event_source_rewriter_|. EXPECT_FALSE(GetKeyEventSourceRewriter()); - arc_window = CreateArcWindowWithRootAndPackage( - root_windows[0], "org.chromium.arc.testapp.inputoverlay"); + arc_window = std::make_unique( + exo_test_helper(), root_windows[0], + "org.chromium.arc.testapp.inputoverlay"); EXPECT_FALSE(GetKeyEventSourceRewriter()); // Move to the secondary display. - arc_window->SetBoundsInScreen(gfx::Rect(1010, 910, 100, 100), display1); + arc_window->SetBounds(display1, gfx::Rect(10, 10, 100, 100)); EXPECT_TRUE(GetKeyEventSourceRewriter()); // When losing focus, |key_event_source_rewriter_| should be destroyed too. - arc_test_input_overlay_manager_->OnWindowFocused(nullptr, arc_window.get()); + WindowFocus(nullptr, arc_window->GetWindow()); EXPECT_FALSE(GetKeyEventSourceRewriter()); arc_window.reset(); // Test when this is non input overlay window launched on the secondry // display, there shouldn't be |key_event_source_rewriter_|. - auto arc_window_no_data = CreateArcWindowWithRootAndPackage( - root_windows[1], "org.chromium.arc.testapp.inputoverlay_no_data"); + auto arc_window_no_data = + std::make_unique( + exo_test_helper(), root_windows[1], + "org.chromium.arc.testapp.inputoverlay_no_data"); + WindowFocus(arc_window_no_data->GetWindow(), nullptr); EXPECT_FALSE(GetKeyEventSourceRewriter()); arc_window_no_data.reset(); @@ -220,20 +224,20 @@ TEST_F(ArcInputOverlayManagerTest, TestKeyEventSourceRewriterForMultiDisplay) { // events. When input overlay window on the secondary root window is not // registered/not focused, primary window should receive key events. root_windows[0]->AddPostTargetHandler(&event_capturer); - arc_window = CreateArcWindowWithRootAndPackage( - root_windows[1], "org.chromium.arc.testapp.inputoverlay"); - arc_window_no_data = CreateArcWindowWithRootAndPackage( - root_windows[0], "org.chromium.arc.testapp.inputoverlay_no_data"); + arc_window = std::make_unique( + exo_test_helper(), root_windows[1], + "org.chromium.arc.testapp.inputoverlay"); + arc_window_no_data = std::make_unique( + exo_test_helper(), root_windows[0], + "org.chromium.arc.testapp.inputoverlay_no_data"); // Focus on window without input overlay. - arc_test_input_overlay_manager_->OnWindowFocused(arc_window_no_data.get(), - nullptr); + WindowFocus(arc_window_no_data->GetWindow(), nullptr); event_generator->PressKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); event_generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); EXPECT_TRUE(event_capturer.key_events().size() == 2); event_capturer.Clear(); // Focus input overlay window. - arc_test_input_overlay_manager_->OnWindowFocused(arc_window.get(), - arc_window_no_data.get()); + WindowFocus(arc_window->GetWindow(), arc_window_no_data->GetWindow()); EXPECT_TRUE(GetKeyEventSourceRewriter()); event_generator->PressKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); event_generator->ReleaseKey(ui::VKEY_A, ui::EF_NONE, 1 /* keyboard id */); diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc new file mode 100644 index 0000000000000..e1414028ff719 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc @@ -0,0 +1,118 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" + +#include "ash/frame/non_client_frame_view_ash.h" +#include "components/exo/shell_surface_base.h" +#include "components/exo/shell_surface_util.h" + +namespace arc { + +class DisplayOverlayController::InputMappingView : public views::View { + public: + explicit InputMappingView(DisplayOverlayController* owner) : owner_(owner) { + auto content_bounds = input_overlay::CalculateWindowContentBounds( + owner_->touch_injector_->target_window()); + auto& actions = owner_->touch_injector_->actions(); + SetBounds(content_bounds.x(), content_bounds.y(), content_bounds.width(), + content_bounds.height()); + for (auto& action : actions) { + auto view = action->CreateView(content_bounds); + AddChildView(std::move(view)); + } + } + InputMappingView(const InputMappingView&) = delete; + InputMappingView& operator=(const InputMappingView&) = delete; + ~InputMappingView() override = default; + + private: + DisplayOverlayController* const owner_; +}; + +DisplayOverlayController::DisplayOverlayController( + TouchInjector* touch_injector) { + touch_injector_ = touch_injector; + AddOverlay(); + AddInputMappingView(); +} + +DisplayOverlayController::~DisplayOverlayController() { + RemoveOverlayIfAny(); +} + +void DisplayOverlayController::OnWindowBoundsChanged() { + RemoveInputMappingView(); + AddInputMappingView(); +} + +// For test: +gfx::Rect DisplayOverlayController::GetInputMappingViewBoundsForTesting() { + if (!input_mapping_view_) + return gfx::Rect(); + return input_mapping_view_->bounds(); +} + +void DisplayOverlayController::AddOverlay() { + RemoveOverlayIfAny(); + auto* shell_surface_base = + exo::GetShellSurfaceBaseForWindow(touch_injector_->target_window()); + if (!shell_surface_base) + return; + + exo::ShellSurfaceBase::OverlayParams params(std::make_unique()); + params.translucent = true; + params.overlaps_frame = false; + shell_surface_base->AddOverlay(std::move(params)); + views::Widget* overlay_widget = + static_cast(shell_surface_base->GetFocusTraversable()); + // TODO(cuicuiruan): split below to the view mode. For the edit mode, display + // overlay should take the event. + overlay_widget->GetNativeWindow()->SetEventTargetingPolicy( + aura::EventTargetingPolicy::kNone); +} + +void DisplayOverlayController::RemoveOverlayIfAny() { + auto* shell_surface_base = + exo::GetShellSurfaceBaseForWindow(touch_injector_->target_window()); + if (shell_surface_base && shell_surface_base->HasOverlay()) { + shell_surface_base->RemoveOverlay(); + } +} + +void DisplayOverlayController::AddInputMappingView() { + if (input_mapping_view_) + return; + auto* overlay_widget = GetOverlayWidget(); + DCHECK(overlay_widget); + if (!overlay_widget) + return; + input_mapping_view_ = overlay_widget->GetContentsView()->AddChildView( + std::make_unique(this)); + input_mapping_view_->SetPosition(gfx::Point()); +} + +void DisplayOverlayController::RemoveInputMappingView() { + if (!input_mapping_view_) + return; + auto* overlay_widget = GetOverlayWidget(); + DCHECK(overlay_widget); + if (!overlay_widget) + return; + overlay_widget->GetContentsView()->RemoveChildView(input_mapping_view_); + input_mapping_view_ = nullptr; +} + +views::Widget* DisplayOverlayController::GetOverlayWidget() { + auto* shell_surface_base = + exo::GetShellSurfaceBaseForWindow(touch_injector_->target_window()); + DCHECK(shell_surface_base); + if (!shell_surface_base) + return nullptr; + views::Widget* overlay_widget = + static_cast(shell_surface_base->GetFocusTraversable()); + return overlay_widget; +} + +} // namespace arc diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h new file mode 100644 index 0000000000000..72ea946100306 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h @@ -0,0 +1,46 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_DISPLAY_OVERLAY_CONTROLLER_H_ +#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_DISPLAY_OVERLAY_CONTROLLER_H_ + +#include "chrome/browser/ash/arc/input_overlay/actions/action.h" +#include "chrome/browser/ash/arc/input_overlay/touch_injector.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_observer.h" + +namespace arc { +// DisplayOverlayController manages the input mapping view, view and edit mode, +// menu, and educational dialog. +class DisplayOverlayController { + public: + explicit DisplayOverlayController(TouchInjector* touch_injector); + DisplayOverlayController(const DisplayOverlayController&) = delete; + DisplayOverlayController& operator=(const DisplayOverlayController&) = delete; + ~DisplayOverlayController(); + + void OnWindowBoundsChanged(); + + // For test: + gfx::Rect GetInputMappingViewBoundsForTesting(); + + private: + friend class DisplayOverlayControllerTest; + + // InputMappingView is the whole view of the input mappings. + class InputMappingView; + + void AddOverlay(); + void RemoveOverlayIfAny(); + void AddInputMappingView(); + void RemoveInputMappingView(); + views::Widget* GetOverlayWidget(); + + TouchInjector* touch_injector_; + InputMappingView* input_mapping_view_ = nullptr; +}; + +} // namespace arc + +#endif // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_DISPLAY_OVERLAY_CONTROLLER_H_ diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller_unittest.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller_unittest.cc new file mode 100644 index 0000000000000..c0dbdd95b796b --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller_unittest.cc @@ -0,0 +1,83 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" + +#include "ash/shell.h" +#include "base/json/json_reader.h" +#include "chrome/browser/ash/arc/input_overlay/test/arc_test_window.h" +#include "chrome/browser/ash/arc/input_overlay/touch_injector.h" +#include "components/exo/test/exo_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { +namespace { + +constexpr const char kValidJson[] = + R"json({ + "tap": { + "keyboard": [ + { + "name": "Run", + "key": "KeyB", + "location": [ + { + "type": "position", + "anchor_to_target": [ + 0.8, + 0.8 + ] + } + ] + } + ] + } + })json"; +} // namespace + +class DisplayOverlayControllerTest : public exo::test::ExoTestBase { + public: + DisplayOverlayControllerTest() = default; + + protected: + std::unique_ptr arc_test_window_; + std::unique_ptr controller_; + + private: + void SetUp() override { + exo::test::ExoTestBase::SetUp(); + arc_test_window_ = std::make_unique( + exo_test_helper(), ash::Shell::GetPrimaryRootWindow(), + "org.chromium.arc.testapp.inputoverlay"); + injector_ = std::make_unique(arc_test_window_->GetWindow()); + base::JSONReader::ValueWithError json_value = + base::JSONReader::ReadAndReturnValueWithError(kValidJson); + injector_->ParseActions(json_value.value.value()); + controller_ = std::make_unique(injector_.get()); + } + + void TearDown() override { + controller_.reset(); + injector_.reset(); + arc_test_window_.reset(); + exo::test::ExoTestBase::TearDown(); + } + + std::unique_ptr injector_; +}; + +TEST_F(DisplayOverlayControllerTest, TestWindowBoundsChange) { + auto original_bounds = controller_->GetInputMappingViewBoundsForTesting(); + auto new_bounds = gfx::Rect(original_bounds); + new_bounds.set_width(new_bounds.size().width() + 50); + new_bounds.set_height(new_bounds.size().height() + 50); + + display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); + arc_test_window_->SetBounds(display, new_bounds); + controller_->OnWindowBoundsChanged(); + auto updated_bounds = controller_->GetInputMappingViewBoundsForTesting(); + EXPECT_NE(original_bounds, updated_bounds); +} + +} // namespace arc diff --git a/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc new file mode 100644 index 0000000000000..134addfd0f7d5 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.cc @@ -0,0 +1,57 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/arc/input_overlay/test/arc_test_window.h" +#include "ash/constants/app_types.h" +#include "ash/public/cpp/window_properties.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/display/screen.h" + +namespace arc { +namespace input_overlay { +namespace test { + +ArcTestWindow::ArcTestWindow(exo::test::ExoTestHelper* helper, + aura::Window* root, + const std::string& package_name) { + surface_ = std::make_unique(); + buffer_ = std::make_unique( + helper->CreateGpuMemoryBuffer(gfx::Size(100, 100))); + shell_surface_ = + helper->CreateClientControlledShellSurface(surface_.get(), false); + surface_->Attach(buffer_.get()); + + auto display_id = + display::Screen::GetScreen()->GetDisplayNearestWindow(root).id(); + shell_surface_->SetBounds(display_id, gfx::Rect(10, 10, 100, 100)); + surface_->Commit(); + shell_surface_->GetWidget()->Show(); + shell_surface_->GetWidget()->Activate(); + surface_->SetApplicationId(package_name.c_str()); + shell_surface_->GetWidget()->GetNativeWindow()->SetProperty( + aura::client::kAppType, static_cast(ash::AppType::ARC_APP)); + shell_surface_->GetWidget()->GetNativeWindow()->SetProperty( + ash::kArcPackageNameKey, package_name); +} + +ArcTestWindow::~ArcTestWindow() = default; + +aura::Window* ArcTestWindow::GetWindow() { + return shell_surface_->GetWidget()->GetNativeWindow(); +} + +void ArcTestWindow::SetMinimized() { + shell_surface_->SetMinimized(); + surface_->Commit(); +} + +void ArcTestWindow::SetBounds(display::Display& display, gfx::Rect bounds) { + auto display_id = display.id(); + shell_surface_->SetBounds(display_id, bounds); + surface_->Commit(); +} + +} // namespace test +} // namespace input_overlay +} // namespace arc diff --git a/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h new file mode 100644 index 0000000000000..26afa72e39cb2 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/test/arc_test_window.h @@ -0,0 +1,41 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_TEST_ARC_TEST_WINDOW_H_ +#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_TEST_ARC_TEST_WINDOW_H_ + +#include "components/exo/shell_surface_util.h" +#include "components/exo/surface.h" +#include "components/exo/test/exo_test_helper.h" + +namespace arc { +namespace input_overlay { +namespace test { + +// ArcTestWindow creates window with exo/surface. +class ArcTestWindow { + public: + ArcTestWindow(exo::test::ExoTestHelper* helper, + aura::Window* root, + const std::string& package_name); + ArcTestWindow(const ArcTestWindow&) = delete; + ArcTestWindow& operator=(const ArcTestWindow&) = delete; + ~ArcTestWindow(); + + aura::Window* GetWindow(); + void SetMinimized(); + // Set bounds in |display|. |bounds| is the local bounds in the display. + void SetBounds(display::Display& display, gfx::Rect bounds); + + private: + std::unique_ptr buffer_; + std::unique_ptr surface_; + std::unique_ptr shell_surface_; +}; + +} // namespace test +} // namespace input_overlay +} // namespace arc + +#endif // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_TEST_ARC_TEST_WINDOW_H_ diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.cc b/chrome/browser/ash/arc/input_overlay/touch_injector.cc index 591ace8f2dd4b..6154639343e35 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.cc +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.cc @@ -8,15 +8,14 @@ #include "base/task/thread_pool.h" #include "chrome/browser/ash/arc/input_overlay/actions/action.h" #include "chrome/browser/ash/arc/input_overlay/input_overlay_resources_util.h" +#include "ui/views/controls/label.h" #include "ui/views/widget/widget.h" #include "ui/views/window/non_client_view.h" namespace arc { -namespace { - // Calculate the window content bounds (excluding caption if it exists) in the // root window. -gfx::RectF CalculateWindowContentBounds(aura::Window* window) { +gfx::RectF input_overlay::CalculateWindowContentBounds(aura::Window* window) { DCHECK(window); auto* widget = views::Widget::GetWidgetForNativeView(window); DCHECK(widget->non_client_view()); @@ -27,7 +26,6 @@ gfx::RectF CalculateWindowContentBounds(aura::Window* window) { bounds.Inset(0, height, 0, 0); return bounds; } -} // namespace TouchInjector::TouchInjector(aura::Window* top_level_window) : target_window_(top_level_window) {} @@ -93,7 +91,7 @@ ui::EventDispatchDetails TouchInjector::RewriteEvent( if (text_input_active_) return SendEvent(continuation, &event); - auto bounds = CalculateWindowContentBounds(target_window_); + auto bounds = input_overlay::CalculateWindowContentBounds(target_window_); std::list touch_events; for (auto& action : actions_) { diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.h b/chrome/browser/ash/arc/input_overlay/touch_injector.h index db7d266fac13d..5d56fdbbf9951 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.h +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.h @@ -16,6 +16,8 @@ namespace input_overlay { // event. constexpr base::TimeDelta kSendTouchMoveDelay = base::Milliseconds(50); +gfx::RectF CalculateWindowContentBounds(aura::Window* window); + } // namespace input_overlay // TouchInjector includes all the touch actions related to the specific window diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 52df858d908ad..47ff00b7c7de0 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn @@ -846,6 +846,8 @@ source_set("chromeos") { "../ash/arc/input_method_manager/input_method_prefs.h", "../ash/arc/input_overlay/actions/action.cc", "../ash/arc/input_overlay/actions/action.h", + "../ash/arc/input_overlay/actions/action_label.cc", + "../ash/arc/input_overlay/actions/action_label.h", "../ash/arc/input_overlay/actions/action_move_key.cc", "../ash/arc/input_overlay/actions/action_move_key.h", "../ash/arc/input_overlay/actions/action_tap_key.cc", @@ -856,6 +858,8 @@ source_set("chromeos") { "../ash/arc/input_overlay/actions/position.h", "../ash/arc/input_overlay/arc_input_overlay_manager.cc", "../ash/arc/input_overlay/arc_input_overlay_manager.h", + "../ash/arc/input_overlay/display_overlay_controller.cc", + "../ash/arc/input_overlay/display_overlay_controller.h", "../ash/arc/input_overlay/input_overlay_resources_util.cc", "../ash/arc/input_overlay/input_overlay_resources_util.h", "../ash/arc/input_overlay/key_event_source_rewriter.cc", @@ -3924,7 +3928,10 @@ source_set("unit_tests") { "../ash/arc/input_overlay/actions/dependent_position_unittest.cc", "../ash/arc/input_overlay/actions/position_unittest.cc", "../ash/arc/input_overlay/arc_input_overlay_manager_unittest.cc", + "../ash/arc/input_overlay/display_overlay_controller_unittest.cc", "../ash/arc/input_overlay/input_overlay_resources_util_unittest.cc", + "../ash/arc/input_overlay/test/arc_test_window.cc", + "../ash/arc/input_overlay/test/arc_test_window.h", "../ash/arc/input_overlay/test/event_capturer.cc", "../ash/arc/input_overlay/test/event_capturer.h", "../ash/arc/input_overlay/touch_id_manager_unittest.cc",