Commit a15346bc authored by Lloyd Pique's avatar Lloyd Pique Committed by Commit Bot

ARC Overlays: Setup test support code

Introduce TestArcOverlayManager which creates
FakeArcOverlayControllers.

This allows other unit tests to create a test overlay manager without
requiring that they actually set up a window hierarchy.

Test: payments unittests pass
Bug: b:172592701
Change-Id: I1d614ed1021628adf789bb483140c1c11f2acea1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2538139
Commit-Queue: Lloyd Pique <lpique@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828569}
parent 0993a176
......@@ -26,8 +26,14 @@ static_library("external_arc") {
"message_center/arc_notification_view.h",
"overlay/arc_overlay_controller.cc",
"overlay/arc_overlay_controller.h",
"overlay/arc_overlay_controller_impl.cc",
"overlay/arc_overlay_controller_impl.h",
"overlay/arc_overlay_manager.cc",
"overlay/arc_overlay_manager.h",
"overlay/test/fake_arc_overlay_controller_impl.cc",
"overlay/test/fake_arc_overlay_controller_impl.h",
"overlay/test/test_arc_overlay_manager.cc",
"overlay/test/test_arc_overlay_manager.h",
"toast/arc_toast_surface_manager.cc",
"toast/arc_toast_surface_manager.h",
]
......
......@@ -4,101 +4,9 @@
#include "ash/public/cpp/external_arc/overlay/arc_overlay_controller.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "ui/aura/window_targeter.h"
#include "ui/views/widget/widget.h"
namespace ash {
ArcOverlayController::ArcOverlayController(aura::Window* host_window)
: host_window_(host_window) {
DCHECK(host_window_);
VLOG(1) << "Host is " << host_window_->GetName();
host_window_observer_.Observe(host_window_);
overlay_container_ = new views::NativeViewHost();
overlay_container_observer_.Observe(overlay_container_);
auto* const widget = views::Widget::GetWidgetForNativeWindow(
host_window_->GetToplevelWindow());
DCHECK(widget);
DCHECK(widget->GetContentsView());
widget->GetContentsView()->AddChildView(overlay_container_);
}
ArcOverlayController::ArcOverlayController() = default;
ArcOverlayController::~ArcOverlayController() = default;
void ArcOverlayController::AttachOverlay(aura::Window* overlay_window) {
if (!overlay_container_ || !host_window_)
return;
DCHECK(overlay_window);
DCHECK(!overlay_container_->native_view())
<< "An overlay is already attached";
VLOG(1) << "Attaching overlay " << overlay_window->GetName() << " to host "
<< host_window_->GetName();
overlay_window_ = overlay_window;
overlay_window_observer_.Observe(overlay_window);
overlay_container_->Attach(overlay_window_);
overlay_container_->GetNativeViewContainer()->SetEventTargeter(
std::make_unique<aura::WindowTargeter>());
UpdateHostBounds();
}
void ArcOverlayController::OnWindowDestroying(aura::Window* window) {
if (host_window_observer_.IsObservingSource(window)) {
host_window_ = nullptr;
host_window_observer_.RemoveObservation();
}
if (overlay_window_observer_.IsObservingSource(window)) {
overlay_window_ = nullptr;
overlay_window_observer_.RemoveObservation();
}
}
void ArcOverlayController::OnViewIsDeleting(views::View* observed_view) {
if (overlay_container_observer_.IsObservingSource(observed_view)) {
overlay_container_ = nullptr;
overlay_container_observer_.RemoveObservation();
}
}
void ArcOverlayController::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) {
if (host_window_observer_.IsObservingSource(window) &&
old_bounds.size() != new_bounds.size()) {
UpdateHostBounds();
}
}
void ArcOverlayController::UpdateHostBounds() {
if (!overlay_container_observer_.IsObserving()) {
LOG(ERROR) << "No container to resize";
return;
}
gfx::Point origin;
gfx::Size size = host_window_->bounds().size();
ConvertPointFromWindow(host_window_, &origin);
overlay_container_->SetBounds(origin.x(), origin.y(), size.width(),
size.height());
}
void ArcOverlayController::ConvertPointFromWindow(aura::Window* window,
gfx::Point* point) {
views::Widget* const widget = overlay_container_->GetWidget();
aura::Window::ConvertPointToTarget(window, widget->GetNativeWindow(), point);
views::View::ConvertPointFromWidget(widget->GetContentsView(), point);
}
} // namespace ash
......@@ -6,63 +6,21 @@
#define ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_CONTROLLER_H_
#include "ash/public/cpp/ash_public_export.h"
#include "base/scoped_observation.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/view_observer.h"
namespace aura {
class Window;
}
namespace ash {
// Maintains an exo::ShellSurface as an overlay on top of another Aura window.
//
// An instance of this class is first constructed for the host window, which the
// overlay window will appear on top of. The overlay window is then attached via
// a call to |AttachOverlay| as it is expected to be created after the host.
class ASH_PUBLIC_EXPORT ArcOverlayController : public aura::WindowObserver,
public views::ViewObserver {
class ASH_PUBLIC_EXPORT ArcOverlayController {
public:
explicit ArcOverlayController(aura::Window* host_window);
~ArcOverlayController() override;
// Disallow copying and moving
// Note: Moving an observer would require some work to deregister/re-register
// it. If the instance is owned by a unique_ptr, the pointer can be moved much
// more cheaply.
ArcOverlayController(const ArcOverlayController&) = delete;
ArcOverlayController(ArcOverlayController&&) = delete;
ArcOverlayController& operator=(const ArcOverlayController&) = delete;
ArcOverlayController& operator=(ArcOverlayController&&) = delete;
ArcOverlayController();
virtual ~ArcOverlayController();
// Attaches the window that is intended to be used as the overlay.
// This is expected to be a toplevel window, and it will be reparented.
void AttachOverlay(aura::Window* overlay_window);
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override;
// views::ViewObserver:
void OnViewIsDeleting(views::View* observed_view) override;
private:
void UpdateHostBounds();
void ConvertPointFromWindow(aura::Window* window, gfx::Point* point);
aura::Window* host_window_ = nullptr;
base::ScopedObservation<aura::Window, aura::WindowObserver>
host_window_observer_{this};
aura::Window* overlay_window_ = nullptr;
base::ScopedObservation<aura::Window, aura::WindowObserver>
overlay_window_observer_{this};
views::NativeViewHost* overlay_container_ = nullptr;
base::ScopedObservation<views::View, views::ViewObserver>
overlay_container_observer_{this};
virtual void AttachOverlay(aura::Window* overlay_window) = 0;
};
} // namespace ash
......
// Copyright 2020 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 "ash/public/cpp/external_arc/overlay/arc_overlay_controller_impl.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "ui/aura/window_targeter.h"
#include "ui/views/widget/widget.h"
namespace ash {
ArcOverlayControllerImpl::ArcOverlayControllerImpl(aura::Window* host_window)
: host_window_(host_window) {
DCHECK(host_window_);
VLOG(1) << "Host is " << host_window_->GetName();
host_window_observer_.Observe(host_window_);
overlay_container_ = new views::NativeViewHost();
overlay_container_observer_.Observe(overlay_container_);
auto* const widget = views::Widget::GetWidgetForNativeWindow(
host_window_->GetToplevelWindow());
DCHECK(widget);
DCHECK(widget->GetContentsView());
widget->GetContentsView()->AddChildView(overlay_container_);
}
ArcOverlayControllerImpl::~ArcOverlayControllerImpl() = default;
void ArcOverlayControllerImpl::AttachOverlay(aura::Window* overlay_window) {
if (!overlay_container_ || !host_window_)
return;
DCHECK(overlay_window);
DCHECK(!overlay_container_->native_view())
<< "An overlay is already attached";
VLOG(1) << "Attaching overlay " << overlay_window->GetName() << " to host "
<< host_window_->GetName();
overlay_window_ = overlay_window;
overlay_window_observer_.Observe(overlay_window);
overlay_container_->Attach(overlay_window_);
overlay_container_->GetNativeViewContainer()->SetEventTargeter(
std::make_unique<aura::WindowTargeter>());
UpdateHostBounds();
}
void ArcOverlayControllerImpl::OnWindowDestroying(aura::Window* window) {
if (host_window_observer_.IsObservingSource(window)) {
host_window_ = nullptr;
host_window_observer_.RemoveObservation();
}
if (overlay_window_observer_.IsObservingSource(window)) {
overlay_window_ = nullptr;
overlay_window_observer_.RemoveObservation();
}
}
void ArcOverlayControllerImpl::OnViewIsDeleting(views::View* observed_view) {
if (overlay_container_observer_.IsObservingSource(observed_view)) {
overlay_container_ = nullptr;
overlay_container_observer_.RemoveObservation();
}
}
void ArcOverlayControllerImpl::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) {
if (host_window_observer_.IsObservingSource(window) &&
old_bounds.size() != new_bounds.size()) {
UpdateHostBounds();
}
}
void ArcOverlayControllerImpl::UpdateHostBounds() {
if (!overlay_container_observer_.IsObserving()) {
LOG(ERROR) << "No container to resize";
return;
}
gfx::Point origin;
gfx::Size size = host_window_->bounds().size();
ConvertPointFromWindow(host_window_, &origin);
overlay_container_->SetBounds(origin.x(), origin.y(), size.width(),
size.height());
}
void ArcOverlayControllerImpl::ConvertPointFromWindow(aura::Window* window,
gfx::Point* point) {
views::Widget* const widget = overlay_container_->GetWidget();
aura::Window::ConvertPointToTarget(window, widget->GetNativeWindow(), point);
views::View::ConvertPointFromWidget(widget->GetContentsView(), point);
}
} // namespace ash
// Copyright 2020 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 ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_CONTROLLER_IMPL_H_
#define ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_CONTROLLER_IMPL_H_
#include "ash/public/cpp/external_arc/overlay/arc_overlay_controller.h"
#include "base/scoped_observation.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/view_observer.h"
namespace ash {
// Maintains an exo::ShellSurface as an overlay on top of another Aura window.
//
// An instance of this class is first constructed for the host window, which the
// overlay window will appear on top of. The overlay window is then attached via
// a call to |AttachOverlay| as it is expected to be created after the host.
class ASH_PUBLIC_EXPORT ArcOverlayControllerImpl : public ArcOverlayController,
public aura::WindowObserver,
public views::ViewObserver {
public:
explicit ArcOverlayControllerImpl(aura::Window* host_window);
~ArcOverlayControllerImpl() override;
// Disallow copying and moving
// Note: Moving an observer would require some work to deregister/re-register
// it. If the instance is owned by a unique_ptr, the pointer can be moved much
// more cheaply.
ArcOverlayControllerImpl(const ArcOverlayControllerImpl&) = delete;
ArcOverlayControllerImpl(ArcOverlayControllerImpl&&) = delete;
ArcOverlayControllerImpl& operator=(const ArcOverlayControllerImpl&) = delete;
ArcOverlayControllerImpl& operator=(ArcOverlayControllerImpl&&) = delete;
// ArcOverlayController:
void AttachOverlay(aura::Window* overlay_window) override;
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override;
// views::ViewObserver:
void OnViewIsDeleting(views::View* observed_view) override;
private:
void UpdateHostBounds();
void ConvertPointFromWindow(aura::Window* window, gfx::Point* point);
aura::Window* host_window_ = nullptr;
base::ScopedObservation<aura::Window, aura::WindowObserver>
host_window_observer_{this};
aura::Window* overlay_window_ = nullptr;
base::ScopedObservation<aura::Window, aura::WindowObserver>
overlay_window_observer_{this};
views::NativeViewHost* overlay_container_ = nullptr;
base::ScopedObservation<views::View, views::ViewObserver>
overlay_container_observer_{this};
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_CONTROLLER_IMPL_H_
......@@ -4,7 +4,7 @@
#include "ash/public/cpp/external_arc/overlay/arc_overlay_manager.h"
#include "ash/public/cpp/external_arc/overlay/arc_overlay_controller.h"
#include "ash/public/cpp/external_arc/overlay/arc_overlay_controller_impl.h"
#include "base/logging.h"
#include "components/exo/shell_surface_base.h"
#include "components/exo/shell_surface_util.h"
......@@ -37,14 +37,19 @@ ArcOverlayManager* ArcOverlayManager::instance() {
return singleton;
}
std::unique_ptr<ArcOverlayController> ArcOverlayManager::CreateController(
aura::Window* host_window) {
return std::make_unique<ArcOverlayControllerImpl>(host_window);
}
base::ScopedClosureRunner ArcOverlayManager::RegisterHostWindow(
std::string overlay_token,
aura::Window* host_window) {
DCHECK_EQ(0u, token_to_controller_map_.count(overlay_token));
DCHECK(host_window);
token_to_controller_map_.emplace(
overlay_token, std::make_unique<ArcOverlayController>(host_window));
token_to_controller_map_.emplace(overlay_token,
CreateController(host_window));
return base::ScopedClosureRunner(
base::BindOnce(&ArcOverlayManager::DeregisterHostWindow,
......
......@@ -49,6 +49,9 @@ class ASH_PUBLIC_EXPORT ArcOverlayManager : public aura::EnvObserver,
ArcOverlayManager& operator=(const ArcOverlayManager&) = delete;
ArcOverlayManager& operator=(ArcOverlayManager&&) = delete;
virtual std::unique_ptr<ArcOverlayController> CreateController(
aura::Window* host_window);
// The host window must be registered before the overlay window.
// The returned closure should be destroyed when the overlay window is
// destroyed.
......
// Copyright 2020 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 "ash/public/cpp/external_arc/overlay/test/fake_arc_overlay_controller_impl.h"
namespace ash {
FakeArcOverlayControllerImpl::FakeArcOverlayControllerImpl(
aura::Window* host_window) {}
FakeArcOverlayControllerImpl::~FakeArcOverlayControllerImpl() = default;
void FakeArcOverlayControllerImpl::AttachOverlay(aura::Window* overlay_window) {
}
} // namespace ash
// Copyright 2020 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 ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_TEST_FAKE_ARC_OVERLAY_CONTROLLER_IMPL_H_
#define ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_TEST_FAKE_ARC_OVERLAY_CONTROLLER_IMPL_H_
#include "ash/public/cpp/external_arc/overlay/arc_overlay_controller.h"
namespace ash {
class ASH_PUBLIC_EXPORT FakeArcOverlayControllerImpl
: public ArcOverlayController {
public:
explicit FakeArcOverlayControllerImpl(aura::Window* host_window);
~FakeArcOverlayControllerImpl() override;
// ArcOverlayController:
void AttachOverlay(aura::Window* overlay_window) override;
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_TEST_FAKE_ARC_OVERLAY_CONTROLLER_IMPL_H_
// Copyright 2020 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 "ash/public/cpp/external_arc/overlay/test/test_arc_overlay_manager.h"
#include "ash/public/cpp/external_arc/overlay/test/fake_arc_overlay_controller_impl.h"
namespace ash {
TestArcOverlayManager::TestArcOverlayManager() = default;
TestArcOverlayManager::~TestArcOverlayManager() = default;
std::unique_ptr<ArcOverlayController> TestArcOverlayManager::CreateController(
aura::Window* host_window) {
return std::make_unique<FakeArcOverlayControllerImpl>(host_window);
}
} // namespace ash
// Copyright 2020 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 ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_TEST_TEST_ARC_OVERLAY_MANAGER_H_
#define ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_TEST_TEST_ARC_OVERLAY_MANAGER_H_
#include "ash/public/cpp/external_arc/overlay/arc_overlay_manager.h"
namespace ash {
class ASH_PUBLIC_EXPORT TestArcOverlayManager : public ArcOverlayManager {
public:
TestArcOverlayManager();
~TestArcOverlayManager() override;
// ArcOverlayManager:
std::unique_ptr<ArcOverlayController> CreateController(
aura::Window* host_window) override;
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_TEST_TEST_ARC_OVERLAY_MANAGER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment