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

exo: Allow a shell surface to act as an overlay

Set up an overlay manager that allows an exo::ShellSurface to become an
overlay on top of a different window.

The initial use case is for a Android Play Billing popup to overlay a
Trusted Web App, when the app invokes a Payments API.

The shell surface must use the revised
aura_shell_surface::set_client_surface_str_id request to set a valid
overlay token.

The code to have the payment component hook into the overlay manager is
in a followup CL.

Bug: b:172592701
Test: Test Payment app shows the Play Store overlay

Change-Id: I7929b0a28ac4f4dd6e069632ada3419062f1b794
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2519929
Commit-Queue: Daniel Nicoara <dnicoara@chromium.org>
Auto-Submit: Lloyd Pique <lpique@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826508}
parent 2bbc1aeb
......@@ -24,6 +24,10 @@ static_library("external_arc") {
"message_center/arc_notification_surface_manager_impl.h",
"message_center/arc_notification_view.cc",
"message_center/arc_notification_view.h",
"overlay/arc_overlay_controller.cc",
"overlay/arc_overlay_controller.h",
"overlay/arc_overlay_manager.cc",
"overlay/arc_overlay_manager.h",
"toast/arc_toast_surface_manager.cc",
"toast/arc_toast_surface_manager.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/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;
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
// 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_H_
#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 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 {
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;
// 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};
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_CONTROLLER_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/arc_overlay_manager.h"
#include "ash/public/cpp/external_arc/overlay/arc_overlay_controller.h"
#include "base/logging.h"
#include "components/exo/shell_surface_base.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "ui/aura/env.h"
namespace {
ash::ArcOverlayManager* singleton = nullptr;
const char* kBillingIdPrefix = "billing_id:";
} // namespace
namespace ash {
ArcOverlayManager::ArcOverlayManager() {
DCHECK(!singleton);
singleton = this;
env_observer_.Observe(aura::Env::GetInstance());
}
ArcOverlayManager::~ArcOverlayManager() {
DCHECK(singleton);
singleton = nullptr;
}
ArcOverlayManager* ArcOverlayManager::instance() {
return singleton;
}
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));
return base::ScopedClosureRunner(
base::BindOnce(&ArcOverlayManager::DeregisterHostWindow,
base::Unretained(this), std::move(overlay_token)));
}
void ArcOverlayManager::DeregisterHostWindow(const std::string& overlay_token) {
auto it = token_to_controller_map_.find(overlay_token);
DCHECK(it != token_to_controller_map_.end());
if (it == token_to_controller_map_.end())
return;
token_to_controller_map_.erase(it);
}
void ArcOverlayManager::OnWindowInitialized(aura::Window* window) {
// We only ever observe the most recent window being created
if (observed_window_observer_.IsObserving())
observed_window_observer_.RemoveObservation();
observed_window_ = window;
observed_window_observer_.Observe(observed_window_);
}
void ArcOverlayManager::OnWindowDestroying(aura::Window* window) {
if (observed_window_observer_.IsObservingSource(window)) {
observed_window_observer_.RemoveObservation();
observed_window_ = nullptr;
}
}
void ArcOverlayManager::OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) {
// shell_surface_base sets this key soon after creating the widget
if (!exo::IsShellMainSurfaceKey(key))
return;
// We don't need to observe the window after this.
observed_window_observer_.RemoveObservation();
observed_window_ = nullptr;
// If this isn't a variant of a ShellSurfaceBase, ignore it
auto* shell_surface_base = exo::GetShellSurfaceBaseForWindow(window);
if (!shell_surface_base)
return;
auto* shell_root_surface = shell_surface_base->root_surface();
DCHECK(shell_root_surface);
// If client surface id doesn't have a particular prefix, ignore it entirely.
std::string client_surface_id = shell_root_surface->GetClientSurfaceId();
if (!base::StartsWith(client_surface_id, kBillingIdPrefix))
return;
std::string overlay_token =
client_surface_id.substr(strlen(kBillingIdPrefix));
RegisterOverlayWindow(std::move(overlay_token), shell_surface_base);
}
void ArcOverlayManager::RegisterOverlayWindow(
std::string overlay_token,
exo::ShellSurfaceBase* shell_surface_base) {
auto it = token_to_controller_map_.find(overlay_token);
if (it == token_to_controller_map_.end()) {
LOG(WARNING) << "No host window registered for token " << overlay_token;
return;
}
// Set a few properties of the shell root surface for its use as an overlay
shell_surface_base->root_surface()->SetFrame(exo::SurfaceFrameType::OVERLAY);
// Use the shell surface widget window as the overlay
DCHECK(shell_surface_base->GetWidget());
DCHECK(shell_surface_base->GetWidget()->GetNativeWindow());
it->second->AttachOverlay(shell_surface_base->GetWidget()->GetNativeWindow());
}
} // 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_MANAGER_H_
#define ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_MANAGER_H_
#include <unordered_map>
#include "ash/public/cpp/ash_public_export.h"
#include "base/callback_helpers.h"
#include "base/containers/flat_map.h"
#include "base/scoped_observation.h"
#include "ui/aura/env.h"
#include "ui/aura/env_observer.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
namespace aura {
class Window;
class Env;
} // namespace aura
namespace exo {
class ShellSurfaceBase;
}
namespace ash {
class ArcOverlayController;
// Allows an exo::ShellSurface window to become an overlay on top of a different
// Aura window.
class ASH_PUBLIC_EXPORT ArcOverlayManager : public aura::EnvObserver,
public aura::WindowObserver {
public:
// Returns the single ArcOverlayManager instance.
static ArcOverlayManager* instance();
ArcOverlayManager();
~ArcOverlayManager() 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.
ArcOverlayManager(const ArcOverlayManager&) = delete;
ArcOverlayManager(ArcOverlayManager&&) = delete;
ArcOverlayManager& operator=(const ArcOverlayManager&) = delete;
ArcOverlayManager& operator=(ArcOverlayManager&&) = delete;
// The host window must be registered before the overlay window.
// The returned closure should be destroyed when the overlay window is
// destroyed.
base::ScopedClosureRunner RegisterHostWindow(std::string overlay_token,
aura::Window* host_window);
// aura::EnvObserver:
void OnWindowInitialized(aura::Window* window) override;
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
void OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) override;
private:
void DeregisterHostWindow(const std::string& overlay_token);
void RegisterOverlayWindow(std::string overlay_token,
exo::ShellSurfaceBase* shell_surface_base);
base::flat_map<std::string, std::unique_ptr<ArcOverlayController>>
token_to_controller_map_;
base::ScopedObservation<aura::Env, aura::EnvObserver> env_observer_{this};
aura::Window* observed_window_ = nullptr;
base::ScopedObservation<aura::Window, aura::WindowObserver>
observed_window_observer_{this};
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_EXTERNAL_ARC_OVERLAY_ARC_OVERLAY_MANAGER_H_
......@@ -9,6 +9,7 @@
#include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/external_arc/keyboard/arc_input_method_surface_manager.h"
#include "ash/public/cpp/external_arc/message_center/arc_notification_surface_manager_impl.h"
#include "ash/public/cpp/external_arc/overlay/arc_overlay_manager.h"
#include "ash/public/cpp/external_arc/toast/arc_toast_surface_manager.h"
#include "ash/shell.h"
#include "base/command_line.h"
......@@ -122,7 +123,8 @@ ExoParts::~ExoParts() {
wayland_server_.reset();
}
ExoParts::ExoParts() {
ExoParts::ExoParts()
: arc_overlay_manager_(std::make_unique<ash::ArcOverlayManager>()) {
wayland_server_ = exo::WaylandServerController::CreateIfNecessary(
std::make_unique<ChromeFileHelper>(),
std::make_unique<ash::ArcNotificationSurfaceManagerImpl>(),
......
......@@ -9,6 +9,10 @@
#include "base/macros.h"
namespace ash {
class ArcOverlayManager;
}
namespace exo {
class WaylandServerController;
}
......@@ -23,6 +27,7 @@ class ExoParts {
private:
ExoParts();
std::unique_ptr<ash::ArcOverlayManager> arc_overlay_manager_;
std::unique_ptr<exo::WaylandServerController> wayland_server_;
DISALLOW_COPY_AND_ASSIGN(ExoParts);
......
......@@ -6,6 +6,7 @@
#include "base/optional.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "ui/aura/env.h"
......@@ -47,7 +48,17 @@ void WebviewWindowManager::OnWindowPropertyChanged(aura::Window* window,
if (key != exo::kClientSurfaceIdKey)
return;
int app_id = window->GetProperty(exo::kClientSurfaceIdKey);
// Note: The property was originally an integer, and was switched to be a
// string. For compatibility integer values are converted to a string via
// base::NumberToString before being set as the property value.
std::string* app_id_str = window->GetProperty(exo::kClientSurfaceIdKey);
if (!app_id_str)
return;
int app_id = 0;
if (!base::StringToInt(*app_id_str, &app_id))
return;
LOG(INFO) << "Found window for webview " << app_id;
for (auto& observer : observers_)
observer.OnNewWebviewContainerWindow(window, app_id);
......
......@@ -4,6 +4,7 @@
#include "chromecast/graphics/rounded_window_corners_manager.h"
#include "base/strings/string_number_conversions.h"
#include "chromecast/graphics/cast_window_manager.h"
#include "components/exo/surface.h"
#include "ui/aura/env.h"
......@@ -156,7 +157,17 @@ void RoundedWindowCornersManager::OnWindowPropertyChanged(aura::Window* window,
if (key != exo::kClientSurfaceIdKey)
return;
int app_id = window->GetProperty(exo::kClientSurfaceIdKey);
// Note: The property was originally an integer, and was switched to be a
// string. For compatibility integer values are converted to a string via
// base::NumberToString before being set as the property value.
std::string* app_id_str = window->GetProperty(exo::kClientSurfaceIdKey);
if (!app_id_str)
return;
int app_id = 0;
if (!base::StringToInt(*app_id_str, &app_id))
return;
LOG(INFO) << "Found window for webview " << app_id;
rounded_corners_observer_->OnNewWebviewContainerWindow(window, app_id);
}
......
......@@ -68,7 +68,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> window =
std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_TEXTURED);
window->SetProperty(exo::kClientSurfaceIdKey, 1);
window->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
root_window->AddChild(window.get());
EXPECT_CALL(*mock_cast_window_manager_, SetEnableRoundedCorners(true));
window->Show();
......@@ -87,7 +87,7 @@ TEST_F(RoundedWindowCornersManagerTest,
window->Show();
root_window->AddChild(window.get());
EXPECT_CALL(*mock_cast_window_manager_, SetEnableRoundedCorners(true));
window->SetProperty(exo::kClientSurfaceIdKey, 1);
window->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
EXPECT_CALL(*mock_cast_window_manager_, SetEnableRoundedCorners(false));
window = nullptr;
......@@ -99,7 +99,7 @@ TEST_F(RoundedWindowCornersManagerTest, RemoveRoundedCornersAfterHidingWindow) {
std::unique_ptr<aura::Window> window =
std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_TEXTURED);
window->SetProperty(exo::kClientSurfaceIdKey, 1);
window->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
root_window->AddChild(window.get());
EXPECT_CALL(*mock_cast_window_manager_, SetEnableRoundedCorners(true));
window->Show();
......@@ -118,8 +118,8 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> window2 =
std::make_unique<aura::Window>(nullptr);
window2->Init(ui::LAYER_TEXTURED);
window1->SetProperty(exo::kClientSurfaceIdKey, 1);
window2->SetProperty(exo::kClientSurfaceIdKey, 2);
window1->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
window2->SetProperty(exo::kClientSurfaceIdKey, new std::string("2"));
root_window->AddChild(window1.get());
root_window->AddChild(window2.get());
EXPECT_CALL(*mock_cast_window_manager_, SetEnableRoundedCorners(true));
......@@ -141,8 +141,8 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> window2 =
std::make_unique<aura::Window>(nullptr);
window2->Init(ui::LAYER_TEXTURED);
window1->SetProperty(exo::kClientSurfaceIdKey, 1);
window2->SetProperty(exo::kClientSurfaceIdKey, 2);
window1->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
window2->SetProperty(exo::kClientSurfaceIdKey, new std::string("2"));
root_window->AddChild(window1.get());
root_window->AddChild(window2.get());
EXPECT_CALL(*mock_cast_window_manager_, SetEnableRoundedCorners(true));
......@@ -161,7 +161,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......@@ -184,7 +184,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......@@ -210,7 +210,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......@@ -231,7 +231,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......@@ -257,7 +257,7 @@ TEST_F(RoundedWindowCornersManagerTest, AddRoundedCornersWhenSiblingIsHidden) {
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......@@ -285,7 +285,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......@@ -313,7 +313,7 @@ TEST_F(RoundedWindowCornersManagerTest,
std::unique_ptr<aura::Window> webview =
std::make_unique<aura::Window>(nullptr);
webview->Init(ui::LAYER_TEXTURED);
webview->SetProperty(exo::kClientSurfaceIdKey, 1);
webview->SetProperty(exo::kClientSurfaceIdKey, new std::string("1"));
std::unique_ptr<aura::Window> sibling =
std::make_unique<aura::Window>(nullptr);
sibling->Init(ui::LAYER_TEXTURED);
......
......@@ -146,6 +146,10 @@ const base::Optional<int32_t> GetShellClientAccessibilityId(
return id;
}
bool IsShellMainSurfaceKey(const void* key) {
return kMainSurfaceKey == key;
}
void SetShellMainSurface(aura::Window* window, Surface* surface) {
window->SetProperty(kMainSurfaceKey, surface);
}
......
......@@ -58,6 +58,9 @@ void SetShellClientAccessibilityId(aura::Window* window,
const base::Optional<int32_t> GetShellClientAccessibilityId(
aura::Window* window);
// Returns true if the given key is the shell main surface key
bool IsShellMainSurfaceKey(const void* key);
// Sets the main surface for the window.
void SetShellMainSurface(aura::Window* window, Surface* surface);
......
......@@ -228,7 +228,7 @@ int surface_id = 0;
} // namespace
DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kClientSurfaceIdKey, 0)
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kClientSurfaceIdKey, nullptr)
ScopedSurface::ScopedSurface(Surface* surface, SurfaceObserver* observer)
: surface_(surface), observer_(observer) {
......@@ -575,15 +575,17 @@ void Surface::RequestActivation() {
delegate_->OnActivationRequested();
}
void Surface::SetClientSurfaceId(int32_t client_surface_id) {
if (client_surface_id)
window_->SetProperty(kClientSurfaceIdKey, client_surface_id);
void Surface::SetClientSurfaceId(const char* client_surface_id) {
if (client_surface_id && strlen(client_surface_id) > 0)
window_->SetProperty(kClientSurfaceIdKey,
new std::string(client_surface_id));
else
window_->ClearProperty(kClientSurfaceIdKey);
}
int32_t Surface::GetClientSurfaceId() const {
return window_->GetProperty(kClientSurfaceIdKey);
std::string Surface::GetClientSurfaceId() const {
std::string* value = window_->GetProperty(kClientSurfaceIdKey);
return value ? *value : std::string();
}
void Surface::SetEmbeddedSurfaceId(
......
......@@ -59,7 +59,7 @@ class PropertyHelper;
enum class Transform { NORMAL, ROTATE_90, ROTATE_180, ROTATE_270 };
// A property key to store the surface Id set by the client.
extern const ui::ClassProperty<int32_t>* const kClientSurfaceIdKey;
extern const ui::ClassProperty<std::string*>* const kClientSurfaceIdKey;
// This class represents a rectangular area that is displayed on the screen.
// It has a location, size and pixel contents.
......@@ -188,8 +188,8 @@ class Surface final : public ui::PropertyHandler {
void SetParent(Surface* parent, const gfx::Point& position);
// Request that surface should have a specific ID assigned by client.
void SetClientSurfaceId(int32_t client_surface_id);
int32_t GetClientSurfaceId() const;
void SetClientSurfaceId(const char* client_surface_id);
std::string GetClientSurfaceId() const;
// Enable embedding of an arbitrary viz surface in this exo surface.
// If the callback is valid, a SurfaceDrawQuad will be emitted targeting
......
......@@ -1231,9 +1231,9 @@ TEST_P(SurfaceTest, DestroyAttachedBuffer) {
TEST_P(SurfaceTest, SetClientSurfaceId) {
auto surface = std::make_unique<Surface>();
constexpr int kTestId = 42;
const std::string kTestId = "42";
surface->SetClientSurfaceId(kTestId);
surface->SetClientSurfaceId(kTestId.c_str());
EXPECT_EQ(kTestId, surface->GetClientSurfaceId());
}
......
......@@ -24,7 +24,7 @@
DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="zaura_shell" version="11">
<interface name="zaura_shell" version="12">
<description summary="aura_shell">
The global interface exposing aura shell capabilities is used to
instantiate an interface extension for a wl_surface object.
......@@ -85,7 +85,7 @@
</event>
</interface>
<interface name="zaura_surface" version="10">
<interface name="zaura_surface" version="12">
<description summary="aura shell interface to a wl_surface">
An additional interface to a wl_surface object, which allows the
client to access aura shell specific functionality for surface.
......@@ -151,6 +151,7 @@
<request name="set_client_surface_id" since="7">
<description summary="set the client surface ID of this surface">
Deprecated. Please use set_client_surface_str_id instead.
Set the identifier of the surface assigned by the client.
</description>
<arg name="client_surface_id" type="int" />
......@@ -241,6 +242,16 @@
</description>
<arg name="mode" type="uint" enum="fullscreen_mode"/>
</request>
<!-- Version 12 additions -->
<request name="set_client_surface_str_id" since="12">
<description summary="set the client surface ID of this surface">
Set the identifier of the surface assigned by the client.
</description>
<arg name="client_surface_id" type="string" />
</request>
</interface>
<interface name="zaura_output" version="6">
......
......@@ -16,6 +16,7 @@
#include "ash/public/cpp/window_properties.h"
#include "ash/wm/window_state.h"
#include "base/strings/string_number_conversions.h"
#include "components/exo/wayland/server_util.h"
#include "components/exo/wayland/wayland_display_observer.h"
#include "components/exo/wayland/wl_output.h"
......@@ -119,10 +120,13 @@ void aura_surface_set_application_id(wl_client* client,
GetUserDataAs<AuraSurface>(resource)->SetApplicationId(application_id);
}
void aura_surface_set_client_surface_id(wl_client* client,
wl_resource* resource,
int client_surface_id) {
GetUserDataAs<AuraSurface>(resource)->SetClientSurfaceId(client_surface_id);
void aura_surface_set_client_surface_id_DEPRECATED(wl_client* client,
wl_resource* resource,
int client_surface_id) {
// DEPRECATED. Use aura_surface_set_client_surface_str_id
std::string client_surface_str_id = base::NumberToString(client_surface_id);
GetUserDataAs<AuraSurface>(resource)->SetClientSurfaceId(
client_surface_str_id.c_str());
}
void aura_surface_set_occlusion_tracking(wl_client* client,
......@@ -149,18 +153,25 @@ void aura_surface_set_fullscreen_mode(wl_client* client,
GetUserDataAs<AuraSurface>(resource)->SetFullscreenMode(mode);
}
void aura_surface_set_client_surface_str_id(wl_client* client,
wl_resource* resource,
const char* client_surface_id) {
GetUserDataAs<AuraSurface>(resource)->SetClientSurfaceId(client_surface_id);
}
const struct zaura_surface_interface aura_surface_implementation = {
aura_surface_set_frame,
aura_surface_set_parent,
aura_surface_set_frame_colors,
aura_surface_set_startup_id,
aura_surface_set_application_id,
aura_surface_set_client_surface_id,
aura_surface_set_client_surface_id_DEPRECATED,
aura_surface_set_occlusion_tracking,
aura_surface_unset_occlusion_tracking,
aura_surface_activate,
aura_surface_draw_attention,
aura_surface_set_fullscreen_mode};
aura_surface_set_fullscreen_mode,
aura_surface_set_client_surface_str_id};
} // namespace
......@@ -208,7 +219,7 @@ void AuraSurface::SetApplicationId(const char* application_id) {
surface_->SetApplicationId(application_id);
}
void AuraSurface::SetClientSurfaceId(int client_surface_id) {
void AuraSurface::SetClientSurfaceId(const char* client_surface_id) {
if (surface_)
surface_->SetClientSurfaceId(client_surface_id);
}
......
......@@ -17,7 +17,7 @@ struct wl_resource;
namespace exo {
namespace wayland {
constexpr uint32_t kZAuraShellVersion = 11;
constexpr uint32_t kZAuraShellVersion = 12;
// Adds bindings to the Aura Shell. Normally this implies Ash on ChromeOS
// builds. On non-ChromeOS builds the protocol provides access to Aura windowing
......@@ -38,7 +38,7 @@ class AuraSurface : public SurfaceObserver,
void SetParent(AuraSurface* parent, const gfx::Point& position);
void SetStartupId(const char* startup_id);
void SetApplicationId(const char* application_id);
void SetClientSurfaceId(int client_surface_id);
void SetClientSurfaceId(const char* client_surface_id);
void SetOcclusionTracking(bool tracking);
void Activate();
void DrawAttention();
......
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