Commit bad8a05f authored by Nicholas Hollingum's avatar Nicholas Hollingum Committed by Commit Bot

Allow Crostini to register its app windows for self-activation.

Based on go/crostini-self-activate, we implement the wiring to allow
crostini windows to activate themselves. This involves:
 - Hooking the surface request up to the shell_surface
 - Building the exo::Permission framework suggested by oshima@
 - Building utilities to grant and revoke permissions
 - Hooking the shelf app controller up so it can grant and remove
   permissions.

This is a remake of crrev.com/c/1850690

Bug: 899587
Change-Id: Ib9c5af8a876fe190fc72be86b873170186c62c0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1935771
Commit-Queue: Nic Hollingum <hollingum@google.com>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarYury Khmel <khmel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#721883}
parent 0c197630
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h" #include "ash/public/cpp/window_properties.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/containers/flat_tree.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/crostini/crostini_force_close_watcher.h" #include "chrome/browser/chromeos/crostini/crostini_force_close_watcher.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
...@@ -32,6 +34,7 @@ ...@@ -32,6 +34,7 @@
#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "components/arc/arc_util.h" #include "components/arc/arc_util.h"
#include "components/exo/permission.h"
#include "components/exo/shell_surface_util.h" #include "components/exo/shell_surface_util.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window.h"
...@@ -46,6 +49,11 @@ ...@@ -46,6 +49,11 @@
namespace { namespace {
// Time allowed for apps to self-activate after launch, see
// go/crostini-self-activate for details.
constexpr base::TimeDelta kSelfActivationTimeout =
base::TimeDelta::FromSeconds(5);
void MoveWindowFromOldDisplayToNewDisplay(aura::Window* window, void MoveWindowFromOldDisplayToNewDisplay(aura::Window* window,
display::Display& old_display, display::Display& old_display,
display::Display& new_display) { display::Display& new_display) {
...@@ -306,6 +314,10 @@ void CrostiniAppWindowShelfController::OnWindowDestroying( ...@@ -306,6 +314,10 @@ void CrostiniAppWindowShelfController::OnWindowDestroying(
} }
aura_window_to_app_window_.erase(app_window_it); aura_window_to_app_window_.erase(app_window_it);
base::EraseIf(activation_permissions_, [&window](const auto& element) {
return element.first == window;
});
} }
AppWindowLauncherItemController* AppWindowLauncherItemController*
...@@ -367,6 +379,24 @@ void CrostiniAppWindowShelfController::OnAppLaunchRequested( ...@@ -367,6 +379,24 @@ void CrostiniAppWindowShelfController::OnAppLaunchRequested(
const std::string& app_id, const std::string& app_id,
int64_t display_id) { int64_t display_id) {
crostini_app_display_.Register(app_id, display_id); crostini_app_display_.Register(app_id, display_id);
// Remove the old permissions and add a permission for every window the app
// currently has open.
activation_permissions_.clear();
ash::ShelfModel* model = owner()->shelf_model();
AppWindowLauncherItemController* launcher_item_controller =
model->GetAppWindowLauncherItemController(
model->items()[model->ItemIndexByAppID(app_id)].id);
// Apps run for the first time won't have a launcher controller yet, return
// early because they won't have windows either so permissions aren't
// necessary.
if (!launcher_item_controller)
return;
for (ui::BaseWindow* app_window : launcher_item_controller->windows()) {
activation_permissions_.emplace(
app_window->GetNativeWindow(),
exo::GrantPermissionToActivate(app_window->GetNativeWindow(),
kSelfActivationTimeout));
}
} }
void CrostiniAppWindowShelfController::Restart(const ash::ShelfID& shelf_id, void CrostiniAppWindowShelfController::Restart(const ash::ShelfID& shelf_id,
......
...@@ -5,11 +5,10 @@ ...@@ -5,11 +5,10 @@
#ifndef CHROME_BROWSER_UI_ASH_LAUNCHER_CROSTINI_APP_WINDOW_SHELF_CONTROLLER_H_ #ifndef CHROME_BROWSER_UI_ASH_LAUNCHER_CROSTINI_APP_WINDOW_SHELF_CONTROLLER_H_
#define CHROME_BROWSER_UI_ASH_LAUNCHER_CROSTINI_APP_WINDOW_SHELF_CONTROLLER_H_ #define CHROME_BROWSER_UI_ASH_LAUNCHER_CROSTINI_APP_WINDOW_SHELF_CONTROLLER_H_
#include <map>
#include <memory> #include <memory>
#include <set>
#include <vector> #include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -24,6 +23,10 @@ namespace aura { ...@@ -24,6 +23,10 @@ namespace aura {
class Window; class Window;
} }
namespace exo {
class Permission;
}
class AppWindowBase; class AppWindowBase;
class ChromeLauncherController; class ChromeLauncherController;
...@@ -56,7 +59,7 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController, ...@@ -56,7 +59,7 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController,
private: private:
using AuraWindowToAppWindow = using AuraWindowToAppWindow =
std::map<aura::Window*, std::unique_ptr<AppWindowBase>>; base::flat_map<aura::Window*, std::unique_ptr<AppWindowBase>>;
void RegisterAppWindow(aura::Window* window, const std::string& shelf_app_id); void RegisterAppWindow(aura::Window* window, const std::string& shelf_app_id);
void UnregisterAppWindow(AppWindowBase* app_window); void UnregisterAppWindow(AppWindowBase* app_window);
...@@ -76,6 +79,11 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController, ...@@ -76,6 +79,11 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController,
std::set<aura::Window*> observed_windows_; std::set<aura::Window*> observed_windows_;
CrostiniAppDisplay crostini_app_display_; CrostiniAppDisplay crostini_app_display_;
// Permission objects that allow this controller to manage which application
// windows can activate themselves.
base::flat_map<aura::Window*, std::unique_ptr<exo::Permission>>
activation_permissions_;
// These two member variables track an app restart request. When // These two member variables track an app restart request. When
// app_id_to_restart_ is not empty the controller observes that app and // app_id_to_restart_ is not empty the controller observes that app and
// relaunches it when all of its windows are closed. // relaunches it when all of its windows are closed.
......
...@@ -35,6 +35,8 @@ source_set("exo") { ...@@ -35,6 +35,8 @@ source_set("exo") {
"layer_tree_frame_sink_holder.h", "layer_tree_frame_sink_holder.h",
"mime_utils.cc", "mime_utils.cc",
"mime_utils.h", "mime_utils.h",
"permission.cc",
"permission.h",
"pointer.cc", "pointer.cc",
"pointer.h", "pointer.h",
"pointer_constraint_delegate.h", "pointer_constraint_delegate.h",
...@@ -235,6 +237,7 @@ source_set("unit_tests") { ...@@ -235,6 +237,7 @@ source_set("unit_tests") {
"gaming_seat_unittest.cc", "gaming_seat_unittest.cc",
"keyboard_unittest.cc", "keyboard_unittest.cc",
"notification_unittest.cc", "notification_unittest.cc",
"permission_unittest.cc",
"pointer_unittest.cc", "pointer_unittest.cc",
"seat_unittest.cc", "seat_unittest.cc",
"shared_memory_unittest.cc", "shared_memory_unittest.cc",
......
// Copyright 2019 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 "components/exo/permission.h"
#include "base/time/time.h"
namespace exo {
Permission::Permission(Permission::Capability capability,
base::TimeDelta timeout)
: capability_(capability), expiry_(base::Time::Now() + timeout) {}
void Permission::Revoke() {
// Revoke the permission by setting its expiry to be in the past.
expiry_ = {};
}
bool Permission::Check(Permission::Capability capability) const {
return capability_ == capability && base::Time::Now() < expiry_;
}
} // namespace exo
// Copyright 2019 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 COMPONENTS_EXO_PERMISSION_H_
#define COMPONENTS_EXO_PERMISSION_H_
#include "base/time/time.h"
namespace exo {
class Permission {
public:
enum class Capability {
kActivate,
};
// Create a permission with the given |capability| until |timeout| elapses.
Permission(Capability capability, base::TimeDelta timeout);
// Delete copy and move.
Permission(const Permission& other) = delete;
Permission(Permission&& other) = delete;
Permission& operator=(const Permission& other) = delete;
Permission& operator=(Permission&& other) = delete;
virtual ~Permission() = default;
// Prevent this permission from returning true on subsequent Check()s.
void Revoke();
// Returns true iff this permission was created with the given |capability|
// and is not expired.
bool Check(Capability capability) const;
private:
Capability capability_;
base::Time expiry_;
};
} // namespace exo
#endif // COMPONENTS_EXO_PERMISSION_H_
// Copyright 2019 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 "components/exo/permission.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace exo {
namespace {
TEST(PermissionsTest, ActiveCapability) {
Permission p{Permission::Capability::kActivate, base::TimeDelta::FromDays(1)};
ASSERT_TRUE(p.Check(Permission::Capability::kActivate));
ASSERT_FALSE(p.Check(static_cast<Permission::Capability>(
(int)(Permission::Capability::kActivate) + 1)));
}
TEST(PermissionsTest, Revoke) {
Permission p{Permission::Capability::kActivate, base::TimeDelta::FromDays(1)};
ASSERT_TRUE(p.Check(Permission::Capability::kActivate));
p.Revoke();
ASSERT_FALSE(p.Check(Permission::Capability::kActivate));
}
TEST(PermissionsTest, Expire) {
Permission p{Permission::Capability::kActivate,
base::TimeDelta::FromMilliseconds(0)};
ASSERT_FALSE(p.Check(Permission::Capability::kActivate));
}
} // namespace
} // namespace exo
...@@ -608,6 +608,11 @@ void ShellSurfaceBase::OnSetApplicationId(const char* application_id) { ...@@ -608,6 +608,11 @@ void ShellSurfaceBase::OnSetApplicationId(const char* application_id) {
SetApplicationId(application_id); SetApplicationId(application_id);
} }
void ShellSurfaceBase::OnActivationRequested() {
if (widget_ && HasPermissionToActivate(widget_->GetNativeWindow()))
this->Activate();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// SurfaceObserver overrides: // SurfaceObserver overrides:
......
...@@ -144,6 +144,7 @@ class ShellSurfaceBase : public SurfaceTreeHost, ...@@ -144,6 +144,7 @@ class ShellSurfaceBase : public SurfaceTreeHost,
void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override; void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override;
void OnSetStartupId(const char* startup_id) override; void OnSetStartupId(const char* startup_id) override;
void OnSetApplicationId(const char* application_id) override; void OnSetApplicationId(const char* application_id) override;
void OnActivationRequested() override;
// Overridden from SurfaceObserver: // Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override; void OnSurfaceDestroying(Surface* surface) override;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/exo/buffer.h" #include "components/exo/buffer.h"
#include "components/exo/client_controlled_shell_surface.h" #include "components/exo/client_controlled_shell_surface.h"
#include "components/exo/display.h" #include "components/exo/display.h"
#include "components/exo/permission.h"
#include "components/exo/shell_surface_util.h" #include "components/exo/shell_surface_util.h"
#include "components/exo/sub_surface.h" #include "components/exo/sub_surface.h"
#include "components/exo/surface.h" #include "components/exo/surface.h"
...@@ -313,6 +314,41 @@ TEST_F(ShellSurfaceTest, SetApplicationId) { ...@@ -313,6 +314,41 @@ TEST_F(ShellSurfaceTest, SetApplicationId) {
EXPECT_EQ(nullptr, GetShellApplicationId(window)); EXPECT_EQ(nullptr, GetShellApplicationId(window));
} }
TEST_F(ShellSurfaceTest, ActivationPermission) {
gfx::Size buffer_size(64, 64);
std::unique_ptr<Buffer> buffer(
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
std::unique_ptr<Surface> surface(new Surface);
std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
surface->Attach(buffer.get());
surface->Commit();
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
ASSERT_TRUE(window);
// No permission granted so can't activate.
EXPECT_FALSE(HasPermissionToActivate(window));
// Can grant permission.
std::unique_ptr<exo::Permission> permission =
GrantPermissionToActivate(window, base::TimeDelta::FromDays(1));
EXPECT_TRUE(permission->Check(Permission::Capability::kActivate));
EXPECT_TRUE(HasPermissionToActivate(window));
// Overriding the permission revokes the previous one.
std::unique_ptr<exo::Permission> permission2 =
GrantPermissionToActivate(window, base::TimeDelta::FromDays(2));
EXPECT_FALSE(permission->Check(Permission::Capability::kActivate));
EXPECT_TRUE(permission2->Check(Permission::Capability::kActivate));
// The old permission no longer affects the window
permission.reset();
EXPECT_TRUE(HasPermissionToActivate(window));
// Deleting the permission revokes.
permission2.reset();
EXPECT_FALSE(HasPermissionToActivate(window));
}
TEST_F(ShellSurfaceTest, EmulateOverrideRedirect) { TEST_F(ShellSurfaceTest, EmulateOverrideRedirect) {
gfx::Size buffer_size(64, 64); gfx::Size buffer_size(64, 64);
std::unique_ptr<Buffer> buffer( std::unique_ptr<Buffer> buffer(
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
#include "components/exo/shell_surface_util.h" #include "components/exo/shell_surface_util.h"
#include <memory>
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "components/exo/permission.h"
#include "components/exo/shell_surface_base.h" #include "components/exo/shell_surface_base.h"
#include "components/exo/surface.h" #include "components/exo/surface.h"
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
...@@ -14,6 +17,8 @@ ...@@ -14,6 +17,8 @@
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h" #include "ui/wm/core/window_util.h"
DEFINE_UI_CLASS_PROPERTY_TYPE(exo::Permission*)
namespace exo { namespace exo {
namespace { namespace {
...@@ -23,9 +28,12 @@ DEFINE_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) ...@@ -23,9 +28,12 @@ DEFINE_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
// Application Id set by the client. // Application Id set by the client.
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kApplicationIdKey, nullptr) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kApplicationIdKey, nullptr)
// Application Id set by the client. // Startup Id set by the client.
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kStartupIdKey, nullptr) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kStartupIdKey, nullptr)
// Permission object allowing this window to activate itself.
DEFINE_UI_CLASS_PROPERTY_KEY(exo::Permission*, kPermissionKey, nullptr)
} // namespace } // namespace
void SetShellApplicationId(aura::Window* window, void SetShellApplicationId(aura::Window* window,
...@@ -114,4 +122,41 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) { ...@@ -114,4 +122,41 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) {
} }
} }
namespace {
// An activation-permission object whose lifetime is tied to a window property.
class ScopedWindowActivationPermission : public Permission {
public:
ScopedWindowActivationPermission(aura::Window* window,
base::TimeDelta timeout)
: Permission(Permission::Capability::kActivate, timeout),
window_(window) {
Permission* other = window_->GetProperty(kPermissionKey);
if (other) {
other->Revoke();
}
window_->SetProperty(kPermissionKey, reinterpret_cast<Permission*>(this));
}
~ScopedWindowActivationPermission() override {
if (window_->GetProperty(kPermissionKey) == this)
window_->ClearProperty(kPermissionKey);
}
private:
aura::Window* window_;
};
} // namespace
std::unique_ptr<Permission> GrantPermissionToActivate(aura::Window* window,
base::TimeDelta timeout) {
return std::make_unique<ScopedWindowActivationPermission>(window, timeout);
}
bool HasPermissionToActivate(aura::Window* window) {
Permission* permission = window->GetProperty(kPermissionKey);
return permission && permission->Check(Permission::Capability::kActivate);
}
} // namespace exo } // namespace exo
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef COMPONENTS_EXO_SHELL_SURFACE_UTIL_H_ #ifndef COMPONENTS_EXO_SHELL_SURFACE_UTIL_H_
#define COMPONENTS_EXO_SHELL_SURFACE_UTIL_H_ #define COMPONENTS_EXO_SHELL_SURFACE_UTIL_H_
#include <memory>
#include <string> #include <string>
#include "base/optional.h" #include "base/optional.h"
...@@ -13,12 +14,17 @@ namespace aura { ...@@ -13,12 +14,17 @@ namespace aura {
class Window; class Window;
} }
namespace base {
class TimeDelta;
}
namespace ui { namespace ui {
class LocatedEvent; class LocatedEvent;
} }
namespace exo { namespace exo {
class Permission;
class Surface; class Surface;
class ShellSurfaceBase; class ShellSurfaceBase;
...@@ -51,6 +57,16 @@ ShellSurfaceBase* GetShellSurfaceBaseForWindow(aura::Window* window); ...@@ -51,6 +57,16 @@ ShellSurfaceBase* GetShellSurfaceBaseForWindow(aura::Window* window);
// requested grab. // requested grab.
Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event); Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event);
// Allow the |window| to activate itself for the diration of |timeout|. Returns
// the permission object, where deleting the object ammounts to Revoke()ing the
// permission.
std::unique_ptr<exo::Permission> GrantPermissionToActivate(
aura::Window* window,
base::TimeDelta timeout);
// Returns true if the |window| has permission to activate itself.
bool HasPermissionToActivate(aura::Window* window);
} // namespace exo } // namespace exo
#endif // COMPONENTS_EXO_SHELL_SURFACE_UTIL_H_ #endif // COMPONENTS_EXO_SHELL_SURFACE_UTIL_H_
...@@ -16,7 +16,7 @@ namespace base { ...@@ -16,7 +16,7 @@ namespace base {
namespace trace_event { namespace trace_event {
class TracedValue; class TracedValue;
} }
} } // namespace base
namespace exo { namespace exo {
class Surface; class Surface;
...@@ -58,6 +58,7 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver { ...@@ -58,6 +58,7 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver {
void OnSetParent(Surface* parent, const gfx::Point& position) override {} void OnSetParent(Surface* parent, const gfx::Point& position) override {}
void OnSetStartupId(const char* startup_id) override {} void OnSetStartupId(const char* startup_id) override {}
void OnSetApplicationId(const char* application_id) override {} void OnSetApplicationId(const char* application_id) override {}
void OnActivationRequested() override {}
// Overridden from SurfaceObserver: // Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override; void OnSurfaceDestroying(Surface* surface) override;
......
...@@ -530,6 +530,13 @@ void Surface::SetParent(Surface* parent, const gfx::Point& position) { ...@@ -530,6 +530,13 @@ void Surface::SetParent(Surface* parent, const gfx::Point& position) {
delegate_->OnSetParent(parent, position); delegate_->OnSetParent(parent, position);
} }
void Surface::RequestActivation() {
TRACE_EVENT0("exo", "Surface::RequestActivation");
if (delegate_)
delegate_->OnActivationRequested();
}
void Surface::SetClientSurfaceId(int32_t client_surface_id) { void Surface::SetClientSurfaceId(int32_t client_surface_id) {
if (client_surface_id) if (client_surface_id)
window_->SetProperty(kClientSurfaceIdKey, client_surface_id); window_->SetProperty(kClientSurfaceIdKey, client_surface_id);
......
...@@ -35,7 +35,7 @@ namespace base { ...@@ -35,7 +35,7 @@ namespace base {
namespace trace_event { namespace trace_event {
class TracedValue; class TracedValue;
} }
} } // namespace base
namespace gfx { namespace gfx {
class GpuFence; class GpuFence;
...@@ -278,6 +278,9 @@ class Surface final : public ui::PropertyHandler { ...@@ -278,6 +278,9 @@ class Surface final : public ui::PropertyHandler {
// Sets the |surface_hierarchy_content_bounds_|. // Sets the |surface_hierarchy_content_bounds_|.
void SetSurfaceHierarchyContentBoundsForTest(const gfx::Rect& content_bounds); void SetSurfaceHierarchyContentBoundsForTest(const gfx::Rect& content_bounds);
// Requests that this surface should be made active (i.e. foregrounded).
void RequestActivation();
private: private:
struct State { struct State {
State(); State();
......
...@@ -44,6 +44,9 @@ class SurfaceDelegate { ...@@ -44,6 +44,9 @@ class SurfaceDelegate {
// Called when surface was requested to set a specific application ID label. // Called when surface was requested to set a specific application ID label.
virtual void OnSetApplicationId(const char* application_id) = 0; virtual void OnSetApplicationId(const char* application_id) = 0;
// Called when the surface's application wants it to be activated.
virtual void OnActivationRequested() = 0;
protected: protected:
virtual ~SurfaceDelegate() {} virtual ~SurfaceDelegate() {}
}; };
......
...@@ -82,6 +82,7 @@ class SurfaceTreeHost : public SurfaceDelegate, ...@@ -82,6 +82,7 @@ class SurfaceTreeHost : public SurfaceDelegate,
void OnSetParent(Surface* parent, const gfx::Point& position) override {} void OnSetParent(Surface* parent, const gfx::Point& position) override {}
void OnSetStartupId(const char* startup_id) override {} void OnSetStartupId(const char* startup_id) override {}
void OnSetApplicationId(const char* application_id) override {} void OnSetApplicationId(const char* application_id) override {}
void OnActivationRequested() override {}
// Overridden from ui::ContextFactoryObserver: // Overridden from ui::ContextFactoryObserver:
void OnLostSharedContext() override; void OnLostSharedContext() override;
......
...@@ -206,10 +206,8 @@ void AuraSurface::SetOcclusionTracking(bool tracking) { ...@@ -206,10 +206,8 @@ void AuraSurface::SetOcclusionTracking(bool tracking) {
} }
void AuraSurface::Activate() { void AuraSurface::Activate() {
if (!surface_) if (surface_)
return; surface_->RequestActivation();
// TODO(hollingum): implement me.
LOG(WARNING) << "Surface requested focus, but that is not implemented";
} }
void AuraSurface::DrawAttention() { void AuraSurface::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