Commit b283b57e authored by Ryan Daum's avatar Ryan Daum Committed by Commit Bot

[chromecast] Add rounded corners to webviews

  * Centralizes rounded corner decoration, putting them on the window
    manager and adding a method to enable/disable as needed.

  * Add roundy corners to webviews, enabled on first webview and
    remove on destruction of final.

  * Add notification of color inversion to the window manager -- for
    accessibility to call into -- to invert the color of the rounded
    corners.

Bug: internal b/141369549
Test: manual
Change-Id: Ic0d6de3c718300add6f99b84b47a243bd5c74da3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1874059Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Reviewed-by: default avatarRandy Rossi <rmrossi@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709142}
parent 1693af2c
...@@ -15,10 +15,12 @@ namespace chromecast { ...@@ -15,10 +15,12 @@ namespace chromecast {
WebviewAsyncService::WebviewAsyncService( WebviewAsyncService::WebviewAsyncService(
std::unique_ptr<webview::WebviewService::AsyncService> service, std::unique_ptr<webview::WebviewService::AsyncService> service,
std::unique_ptr<grpc::ServerCompletionQueue> cq, std::unique_ptr<grpc::ServerCompletionQueue> cq,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
CastWindowManager* cast_window_manager)
: ui_task_runner_(std::move(ui_task_runner)), : ui_task_runner_(std::move(ui_task_runner)),
cq_(std::move(cq)), cq_(std::move(cq)),
service_(std::move(service)) { service_(std::move(service)),
window_manager_(cast_window_manager) {
base::PlatformThread::Create(0, this, &rpc_thread_); base::PlatformThread::Create(0, this, &rpc_thread_);
} }
......
...@@ -16,14 +16,20 @@ ...@@ -16,14 +16,20 @@
namespace chromecast { namespace chromecast {
class CastWindowManager;
// This is a service that provides a GRPC interface to create and control // This is a service that provides a GRPC interface to create and control
// webviews. See the proto file for commands. // webviews. See the proto file for commands.
class WebviewAsyncService : public base::PlatformThread::Delegate { class WebviewAsyncService : public base::PlatformThread::Delegate {
public: public:
// If |cast_window_manager| is nullptr, rounded corner decorations will not be
// added to webviews.
// TODO(rdaum): Remove default nullptr once internal uses are updated.
WebviewAsyncService( WebviewAsyncService(
std::unique_ptr<webview::WebviewService::AsyncService> service, std::unique_ptr<webview::WebviewService::AsyncService> service,
std::unique_ptr<grpc::ServerCompletionQueue> cq, std::unique_ptr<grpc::ServerCompletionQueue> cq,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
CastWindowManager* cast_window_manager = nullptr);
~WebviewAsyncService() override; ~WebviewAsyncService() override;
private: private:
......
...@@ -4,14 +4,61 @@ ...@@ -4,14 +4,61 @@
#include "chromecast/browser/webview/webview_window_manager.h" #include "chromecast/browser/webview/webview_window_manager.h"
#include "chromecast/graphics/cast_window_manager.h"
#include "components/exo/shell_surface_util.h" #include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h" #include "components/exo/surface.h"
#include "ui/aura/env.h" #include "ui/aura/env.h"
namespace chromecast { namespace chromecast {
WebviewWindowManager::WebviewWindowManager() { // Keeps track of the creation and destruction of webview container windows, and
// adds and removes the root window rounded corner decoration accordingly.
// Rounded corners only need to be present when webviews are being displayed.
class RoundedCornersObserver : public WebviewWindowManager::Observer,
public aura::WindowObserver {
public:
explicit RoundedCornersObserver(CastWindowManager* cast_window_manager)
: cast_window_manager_(cast_window_manager) {}
~RoundedCornersObserver() override {}
// WebviewWindowManager::Observer implementation
void OnNewWebviewContainerWindow(aura::Window* window, int app_id) override {
// Observe the lifecycle of this window so we can remove rounded corners
// when it goes away.
window->AddObserver(this);
// Add rounded corners on the first created window.
if (cast_window_manager_ && !num_container_windows_) {
cast_window_manager_->SetEnableRoundedCorners(true);
}
num_container_windows_++;
}
// aura::WindowObserver implementation
void OnWindowDestroyed(aura::Window* window) override {
// Remove the rounded corners when we're out of container windows.
num_container_windows_--;
DCHECK_GE(num_container_windows_, 0);
if (cast_window_manager_ && !num_container_windows_) {
cast_window_manager_->SetEnableRoundedCorners(false);
}
}
private:
CastWindowManager* cast_window_manager_;
int num_container_windows_ = 0;
DISALLOW_COPY_AND_ASSIGN(RoundedCornersObserver);
};
WebviewWindowManager::WebviewWindowManager(
CastWindowManager* cast_window_manager)
: rounded_corners_observer_(
std::make_unique<RoundedCornersObserver>(cast_window_manager)) {
aura::Env::GetInstance()->AddObserver(this); aura::Env::GetInstance()->AddObserver(this);
AddObserver(rounded_corners_observer_.get());
} }
WebviewWindowManager::~WebviewWindowManager() { WebviewWindowManager::~WebviewWindowManager() {
......
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
namespace chromecast { namespace chromecast {
class CastWindowManager;
class RoundedCornersObserver;
// Keeps track of new aura::Windows and listen for window property events to // Keeps track of new aura::Windows and listen for window property events to
// find Exo windows with the |exo::kClientSurfaceIdKey| property set. // find Exo windows with the |exo::kClientSurfaceIdKey| property set.
class WebviewWindowManager : public aura::EnvObserver, class WebviewWindowManager : public aura::EnvObserver,
...@@ -26,7 +29,7 @@ class WebviewWindowManager : public aura::EnvObserver, ...@@ -26,7 +29,7 @@ class WebviewWindowManager : public aura::EnvObserver,
int app_id) = 0; int app_id) = 0;
}; };
WebviewWindowManager(); explicit WebviewWindowManager(CastWindowManager* cast_window_manager);
~WebviewWindowManager() override; ~WebviewWindowManager() override;
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
...@@ -43,6 +46,7 @@ class WebviewWindowManager : public aura::EnvObserver, ...@@ -43,6 +46,7 @@ class WebviewWindowManager : public aura::EnvObserver,
std::vector<aura::Window*> observed_windows_; std::vector<aura::Window*> observed_windows_;
base::ObserverList<Observer>::Unchecked observers_; base::ObserverList<Observer>::Unchecked observers_;
std::unique_ptr<RoundedCornersObserver> rounded_corners_observer_;
DISALLOW_COPY_AND_ASSIGN(WebviewWindowManager); DISALLOW_COPY_AND_ASSIGN(WebviewWindowManager);
}; };
......
...@@ -103,6 +103,12 @@ class CastWindowManager { ...@@ -103,6 +103,12 @@ class CastWindowManager {
// disabled. // disabled.
virtual void RemoveTouchActivityObserver( virtual void RemoveTouchActivityObserver(
CastTouchActivityObserver* observer) = 0; CastTouchActivityObserver* observer) = 0;
// Turns on and off the root window rounded window corners decoration.
virtual void SetEnableRoundedCorners(bool enable) = 0;
// Called when color inversion is turned on or off.
virtual void NotifyColorInversionEnabled(bool enabled) = 0;
}; };
} // namespace chromecast } // namespace chromecast
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chromecast/graphics/cast_window_tree_host_aura.h" #include "chromecast/graphics/cast_window_tree_host_aura.h"
#include "chromecast/graphics/gestures/cast_system_gesture_event_handler.h" #include "chromecast/graphics/gestures/cast_system_gesture_event_handler.h"
#include "chromecast/graphics/gestures/side_swipe_detector.h" #include "chromecast/graphics/gestures/side_swipe_detector.h"
#include "chromecast/graphics/rounded_window_corners.h"
#include "ui/aura/client/default_capture_client.h" #include "ui/aura/client/default_capture_client.h"
#include "ui/aura/client/focus_change_observer.h" #include "ui/aura/client/focus_change_observer.h"
#include "ui/aura/client/screen_position_client.h" #include "ui/aura/client/screen_position_client.h"
...@@ -257,6 +258,10 @@ void CastWindowManagerAura::Setup() { ...@@ -257,6 +258,10 @@ void CastWindowManagerAura::Setup() {
system_gesture_dispatcher_.get(), root_window); system_gesture_dispatcher_.get(), root_window);
} }
// Add rounded corners, but defaulted to hidden until explicitly asked for by
// a component.
rounded_window_corners_ = RoundedWindowCorners::Create(this);
#if BUILDFLAG(IS_CAST_AUDIO_ONLY) #if BUILDFLAG(IS_CAST_AUDIO_ONLY)
if (base::FeatureList::IsEnabled(kReduceHeadlessFrameRate)) { if (base::FeatureList::IsEnabled(kReduceHeadlessFrameRate)) {
ui::Compositor* compositor = window_tree_host_->compositor(); ui::Compositor* compositor = window_tree_host_->compositor();
...@@ -373,4 +378,12 @@ void CastWindowManagerAura::RemoveTouchActivityObserver( ...@@ -373,4 +378,12 @@ void CastWindowManagerAura::RemoveTouchActivityObserver(
event_gate_->RemoveObserver(observer); event_gate_->RemoveObserver(observer);
} }
void CastWindowManagerAura::SetEnableRoundedCorners(bool enable) {
rounded_window_corners_->SetEnabled(enable);
}
void CastWindowManagerAura::NotifyColorInversionEnabled(bool enabled) {
rounded_window_corners_->SetColorInversion(enabled);
}
} // namespace chromecast } // namespace chromecast
...@@ -29,6 +29,7 @@ class CastSystemGestureEventHandler; ...@@ -29,6 +29,7 @@ class CastSystemGestureEventHandler;
class CastSystemGestureDispatcher; class CastSystemGestureDispatcher;
class SideSwipeDetector; class SideSwipeDetector;
class CastWindowTreeHostAura; class CastWindowTreeHostAura;
class RoundedWindowCorners;
class CastWindowManagerAura : public CastWindowManager, class CastWindowManagerAura : public CastWindowManager,
public aura::client::WindowParentingClient { public aura::client::WindowParentingClient {
...@@ -54,6 +55,8 @@ class CastWindowManagerAura : public CastWindowManager, ...@@ -54,6 +55,8 @@ class CastWindowManagerAura : public CastWindowManager,
void AddTouchActivityObserver(CastTouchActivityObserver* observer) override; void AddTouchActivityObserver(CastTouchActivityObserver* observer) override;
void RemoveTouchActivityObserver( void RemoveTouchActivityObserver(
CastTouchActivityObserver* observer) override; CastTouchActivityObserver* observer) override;
void SetEnableRoundedCorners(bool enable) override;
void NotifyColorInversionEnabled(bool enabled) override;
// aura::client::WindowParentingClient implementation: // aura::client::WindowParentingClient implementation:
aura::Window* GetDefaultParent(aura::Window* window, aura::Window* GetDefaultParent(aura::Window* window,
...@@ -75,6 +78,7 @@ class CastWindowManagerAura : public CastWindowManager, ...@@ -75,6 +78,7 @@ class CastWindowManagerAura : public CastWindowManager,
std::unique_ptr<CastSystemGestureDispatcher> system_gesture_dispatcher_; std::unique_ptr<CastSystemGestureDispatcher> system_gesture_dispatcher_;
std::unique_ptr<CastSystemGestureEventHandler> system_gesture_event_handler_; std::unique_ptr<CastSystemGestureEventHandler> system_gesture_event_handler_;
std::unique_ptr<SideSwipeDetector> side_swipe_detector_; std::unique_ptr<SideSwipeDetector> side_swipe_detector_;
std::unique_ptr<RoundedWindowCorners> rounded_window_corners_;
std::vector<WindowId> window_order_; std::vector<WindowId> window_order_;
base::ObserverList<Observer>::Unchecked observer_list_; base::ObserverList<Observer>::Unchecked observer_list_;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/events/test/event_generator.h" #include "ui/events/test/event_generator.h"
#include "ui/views/test/views_test_base.h"
namespace chromecast { namespace chromecast {
namespace test { namespace test {
...@@ -53,7 +54,9 @@ class TestWindow { ...@@ -53,7 +54,9 @@ class TestWindow {
} // namespace } // namespace
using CastWindowManagerAuraTest = aura::test::AuraTestBase; // ViewsTestBase needed so that views/widget initialization is setup correctly
// for test runs.
using CastWindowManagerAuraTest = views::ViewsTestBase;
TEST_F(CastWindowManagerAuraTest, InitialWindowId) { TEST_F(CastWindowManagerAuraTest, InitialWindowId) {
CastTestWindowDelegate window_delegate; CastTestWindowDelegate window_delegate;
......
...@@ -43,4 +43,7 @@ void CastWindowManagerDefault::AddTouchActivityObserver( ...@@ -43,4 +43,7 @@ void CastWindowManagerDefault::AddTouchActivityObserver(
void CastWindowManagerDefault::RemoveTouchActivityObserver( void CastWindowManagerDefault::RemoveTouchActivityObserver(
CastTouchActivityObserver* observer) {} CastTouchActivityObserver* observer) {}
void CastWindowManagerDefault::SetEnableRoundedCorners(bool enable) {}
void CastWindowManagerDefault::NotifyColorInversionEnabled(bool enabled) {}
} // namespace chromecast } // namespace chromecast
...@@ -35,6 +35,8 @@ class CastWindowManagerDefault : public CastWindowManager { ...@@ -35,6 +35,8 @@ class CastWindowManagerDefault : public CastWindowManager {
void AddTouchActivityObserver(CastTouchActivityObserver* observer) override; void AddTouchActivityObserver(CastTouchActivityObserver* observer) override;
void RemoveTouchActivityObserver( void RemoveTouchActivityObserver(
CastTouchActivityObserver* observer) override; CastTouchActivityObserver* observer) override;
void SetEnableRoundedCorners(bool enable) override;
void NotifyColorInversionEnabled(bool enabled) override;
private: private:
DISALLOW_COPY_AND_ASSIGN(CastWindowManagerDefault); DISALLOW_COPY_AND_ASSIGN(CastWindowManagerDefault);
......
...@@ -20,6 +20,8 @@ class RoundedWindowCorners { ...@@ -20,6 +20,8 @@ class RoundedWindowCorners {
RoundedWindowCorners(); RoundedWindowCorners();
virtual ~RoundedWindowCorners(); virtual ~RoundedWindowCorners();
virtual void SetEnabled(bool enable) = 0;
virtual void SetColorInversion(bool enable) = 0; virtual void SetColorInversion(bool enable) = 0;
}; };
......
...@@ -68,6 +68,7 @@ class RoundedWindowCornersAura : public RoundedWindowCorners { ...@@ -68,6 +68,7 @@ class RoundedWindowCornersAura : public RoundedWindowCorners {
explicit RoundedWindowCornersAura(CastWindowManager* window_manager); explicit RoundedWindowCornersAura(CastWindowManager* window_manager);
~RoundedWindowCornersAura() override; ~RoundedWindowCornersAura() override;
void SetEnabled(bool enable) override;
void SetColorInversion(bool enable) override; void SetColorInversion(bool enable) override;
private: private:
...@@ -108,13 +109,23 @@ RoundedWindowCornersAura::RoundedWindowCornersAura( ...@@ -108,13 +109,23 @@ RoundedWindowCornersAura::RoundedWindowCornersAura(
window_manager->SetZOrder(widget_->GetNativeView(), window_manager->SetZOrder(widget_->GetNativeView(),
mojom::ZOrder::CORNERS_OVERLAY); mojom::ZOrder::CORNERS_OVERLAY);
widget_->Show(); // Remain hidden until explicitly shown. Rounded corners are only needed for
// specific circumstances such as webviews.
widget_->Hide();
} }
RoundedWindowCornersAura::~RoundedWindowCornersAura() { RoundedWindowCornersAura::~RoundedWindowCornersAura() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
} }
void RoundedWindowCornersAura::SetEnabled(bool enable) {
if (enable) {
widget_->Show();
} else {
widget_->Hide();
}
}
void RoundedWindowCornersAura::SetColorInversion(bool enable) { void RoundedWindowCornersAura::SetColorInversion(bool enable) {
for (auto* view : corners_) for (auto* view : corners_)
view->SetColorInversion(enable); view->SetColorInversion(enable);
......
...@@ -16,6 +16,7 @@ class RoundedWindowCornersDefault : public RoundedWindowCorners { ...@@ -16,6 +16,7 @@ class RoundedWindowCornersDefault : public RoundedWindowCorners {
RoundedWindowCornersDefault() {} RoundedWindowCornersDefault() {}
~RoundedWindowCornersDefault() override {} ~RoundedWindowCornersDefault() override {}
void SetEnabled(bool enable) override {}
void SetColorInversion(bool enable) override {} void SetColorInversion(bool enable) override {}
private: private:
......
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