Commit ec1de388 authored by James Cook's avatar James Cook Committed by Commit Bot

cros: Add ws2::DisplayManagerMus

This provides ScreenMus with information about display configuration.
It is used by the browser when running out-of-process ash ("mash") and
by mini-mojo-apps under ash_shell_with_content for development purposes.

Next step: Hook up FrameDecorationValues

TBR=tsepez@chromium.org
BUG=839592
TEST=services_unittests

Change-Id: I281e141e92d7a1a8e82780063f20a4d75fd79d23
Reviewed-on: https://chromium-review.googlesource.com/1050949
Commit-Queue: James Cook <jamescook@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557350}
parent 8ddcbeda
......@@ -21,7 +21,8 @@ int main(int argc, const char** argv) {
settings.log_file = log_filename.value().c_str();
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
logging::InitLogging(settings);
logging::SetLogItems(true /* process_id */, true /* thread_id */,
true /* timestamp */, false /* tick_count */);
ash::shell::ShellMainDelegate delegate;
content::ContentMainParams params(&delegate);
params.argc = argc;
......
......@@ -18,6 +18,8 @@ interface DisplayManagerObserver {
int64 internal_display_id);
};
// TODO(jamescook): Rename to ScreenProvider.
interface DisplayManager {
// Adding an observer triggers a notification with the initial values.
AddObserver(DisplayManagerObserver observer);
};
......@@ -10,6 +10,7 @@ import("//services/service_manager/public/service_manifest.gni")
import("//services/service_manager/public/tools/test/service_test.gni")
component("lib") {
friend = [ ":tests" ]
public = [
"gpu_support.h",
"ids.h",
......@@ -28,6 +29,8 @@ component("lib") {
"client_root.h",
"client_window.cc",
"client_window.h",
"display_manager_mus.cc",
"display_manager_mus.h",
"window_host_frame_sink_client.cc",
"window_host_frame_sink_client.h",
"window_service.cc",
......@@ -103,6 +106,7 @@ source_set("tests") {
testonly = true
sources = [
"display_manager_mus_unittest.cc",
"window_service_client_unittest.cc",
"window_tree_client_unittest.cc",
]
......@@ -116,6 +120,7 @@ source_set("tests") {
"//mojo/public/cpp/bindings",
"//services/service_manager/public/cpp:service_test_support",
"//services/service_manager/public/mojom",
"//services/ui/common:task_runner_test_base",
"//services/ui/public/cpp",
"//services/ui/public/interfaces",
"//testing/gtest",
......
// Copyright 2018 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 "services/ui/ws2/display_manager_mus.h"
#include "ui/display/screen.h"
using display::Display;
using display::Screen;
namespace ui {
namespace ws2 {
namespace {
int64_t GetPrimaryDisplayId() {
return Screen::GetScreen()->GetPrimaryDisplay().id();
}
int64_t GetInternalDisplayId() {
return Display::HasInternalDisplay() ? Display::InternalDisplayId()
: display::kInvalidDisplayId;
}
} // namespace
DisplayManagerMus::DisplayManagerMus() {
Screen::GetScreen()->AddObserver(this);
}
DisplayManagerMus::~DisplayManagerMus() {
Screen::GetScreen()->RemoveObserver(this);
}
void DisplayManagerMus::AddBinding(mojom::DisplayManagerRequest request) {
bindings_.AddBinding(this, std::move(request));
}
void DisplayManagerMus::AddObserver(mojom::DisplayManagerObserverPtr observer) {
mojom::DisplayManagerObserver* observer_impl = observer.get();
observers_.AddPtr(std::move(observer));
NotifyObserver(observer_impl);
}
void DisplayManagerMus::OnDidProcessDisplayChanges() {
// Display changes happen in batches, so notify observers after the batch is
// complete, rather than on every add/remove/metrics change.
NotifyAllObservers();
}
void DisplayManagerMus::NotifyAllObservers() {
observers_.ForAllPtrs([this](mojom::DisplayManagerObserver* observer) {
NotifyObserver(observer);
});
}
void DisplayManagerMus::NotifyObserver(
mojom::DisplayManagerObserver* observer) {
observer->OnDisplaysChanged(GetAllDisplays(), GetPrimaryDisplayId(),
GetInternalDisplayId());
}
std::vector<mojom::WsDisplayPtr> DisplayManagerMus::GetAllDisplays() {
std::vector<Display> displays = Screen::GetScreen()->GetAllDisplays();
std::vector<mojom::WsDisplayPtr> ws_displays;
ws_displays.reserve(displays.size());
for (const Display& display : displays) {
mojom::WsDisplayPtr ws_display = mojom::WsDisplay::New();
ws_display->display = display;
// TODO(jamescook): Add a delegate to get frame decoration values from ash.
ws_display->frame_decoration_values = mojom::FrameDecorationValues::New();
ws_displays.push_back(std::move(ws_display));
}
return ws_displays;
}
} // namespace ws2
} // namespace ui
// Copyright 2018 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 SERVICES_UI_WS2_DISPLAY_MANAGER_MUS_H_
#define SERVICES_UI_WS2_DISPLAY_MANAGER_MUS_H_
#include "base/component_export.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/ui/public/interfaces/display_manager.mojom.h"
#include "ui/display/display_observer.h"
namespace ui {
namespace ws2 {
// Provides information about displays to window service clients.
// display::Screen must outlive this object. Exported for test.
// TODO(jamescook): Rename to DisplayManagerWs or whatever we end up calling the
// window server library. It is named Mus to match ScreenMus.
class COMPONENT_EXPORT(WINDOW_SERVICE) DisplayManagerMus
: public mojom::DisplayManager,
public display::DisplayObserver {
public:
DisplayManagerMus();
~DisplayManagerMus() override;
void AddBinding(mojom::DisplayManagerRequest request);
// mojom::DisplayManager:
void AddObserver(mojom::DisplayManagerObserverPtr observer) override;
// display::DisplayObserver:
void OnDidProcessDisplayChanges() override;
private:
std::vector<mojom::WsDisplayPtr> GetAllDisplays();
void NotifyAllObservers();
void NotifyObserver(mojom::DisplayManagerObserver* observer);
mojo::BindingSet<mojom::DisplayManager> bindings_;
mojo::InterfacePtrSet<mojom::DisplayManagerObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(DisplayManagerMus);
};
} // namespace ws2
} // namespace ui
#endif // SERVICES_UI_WS2_DISPLAY_MANAGER_MUS_H_
// Copyright 2018 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 "services/ui/ws2/display_manager_mus.h"
#include <stdint.h>
#include "base/strings/string_number_conversions.h"
#include "services/ui/common/task_runner_test_base.h"
#include "services/ui/public/interfaces/display_manager.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
#include "ui/display/screen_base.h"
using display::Display;
using display::DisplayList;
using display::DisplayObserver;
namespace ui {
namespace ws2 {
namespace {
std::string DisplayIdsToString(
const std::vector<mojom::WsDisplayPtr>& wm_displays) {
std::string display_ids;
for (const auto& wm_display : wm_displays) {
if (!display_ids.empty())
display_ids += " ";
display_ids += base::NumberToString(wm_display->display.id());
}
return display_ids;
}
// A testing screen that generates the OnDidProcessDisplayChanges() notification
// similar to production code.
class TestScreen : public display::ScreenBase {
public:
TestScreen() { display::Screen::SetScreenInstance(this); }
~TestScreen() override { display::Screen::SetScreenInstance(nullptr); }
void AddDisplay(const Display& display, DisplayList::Type type) {
display_list().AddDisplay(display, type);
for (DisplayObserver& observer : *display_list().observers())
observer.OnDidProcessDisplayChanges();
}
void UpdateDisplay(const Display& display, DisplayList::Type type) {
display_list().UpdateDisplay(display, type);
for (DisplayObserver& observer : *display_list().observers())
observer.OnDidProcessDisplayChanges();
}
void RemoveDisplay(int64_t display_id) {
display_list().RemoveDisplay(display_id);
for (DisplayObserver& observer : *display_list().observers())
observer.OnDidProcessDisplayChanges();
}
private:
DISALLOW_COPY_AND_ASSIGN(TestScreen);
};
class TestDisplayManagerObserver : public mojom::DisplayManagerObserver {
public:
TestDisplayManagerObserver() = default;
~TestDisplayManagerObserver() override = default;
mojom::DisplayManagerObserverPtr GetPtr() {
mojom::DisplayManagerObserverPtr ptr;
binding_.Bind(mojo::MakeRequest(&ptr));
return ptr;
}
// mojom::DisplayManagerObserver:
void OnDisplaysChanged(std::vector<mojom::WsDisplayPtr> displays,
int64_t primary_display_id,
int64_t internal_display_id) override {
display_ids_ = DisplayIdsToString(displays);
primary_display_id_ = primary_display_id;
internal_display_id_ = internal_display_id;
}
mojo::Binding<mojom::DisplayManagerObserver> binding_{this};
std::string display_ids_;
int64_t primary_display_id_ = 0;
int64_t internal_display_id_ = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TestDisplayManagerObserver);
};
// Mojo needs a task runner.
using DisplayManagerMusTest = TaskRunnerTestBase;
TEST_F(DisplayManagerMusTest, AddRemoveDisplay) {
TestScreen screen;
screen.AddDisplay(Display(111, gfx::Rect(0, 0, 640, 480)),
DisplayList::Type::PRIMARY);
Display::SetInternalDisplayId(111);
DisplayManagerMus manager;
TestDisplayManagerObserver observer;
// Adding an observer triggers an update.
manager.AddObserver(observer.GetPtr());
// Wait for mojo message to observer.
RunUntilIdle();
EXPECT_EQ("111", observer.display_ids_);
EXPECT_EQ(111, observer.primary_display_id_);
EXPECT_EQ(111, observer.internal_display_id_);
observer.display_ids_.clear();
// Adding a display triggers an update.
screen.AddDisplay(Display(222, gfx::Rect(640, 0, 640, 480)),
DisplayList::Type::NOT_PRIMARY);
// Wait for mojo message to observer.
RunUntilIdle();
EXPECT_EQ("111 222", observer.display_ids_);
EXPECT_EQ(111, observer.primary_display_id_);
observer.display_ids_.clear();
// Updating which display is primary triggers an update.
screen.UpdateDisplay(Display(222, gfx::Rect(640, 0, 800, 600)),
DisplayList::Type::PRIMARY);
// Wait for mojo message to observer.
RunUntilIdle();
EXPECT_EQ("111 222", observer.display_ids_);
EXPECT_EQ(222, observer.primary_display_id_);
observer.display_ids_.clear();
// Removing a display triggers an update.
screen.RemoveDisplay(111);
// Wait for mojo message to observer.
RunUntilIdle();
EXPECT_EQ("222", observer.display_ids_);
EXPECT_EQ(222, observer.primary_display_id_);
}
} // namespace
} // namespace ws2
} // namespace ui
......@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "services/ui/ws2/client_window.h"
#include "services/ui/ws2/display_manager_mus.h"
#include "services/ui/ws2/gpu_support.h"
#include "services/ui/ws2/window_service_client.h"
#include "services/ui/ws2/window_service_delegate.h"
......@@ -18,7 +19,9 @@ namespace ws2 {
WindowService::WindowService(WindowServiceDelegate* delegate,
std::unique_ptr<GpuSupport> gpu_support)
: delegate_(delegate), gpu_support_(std::move(gpu_support)) {
: delegate_(delegate),
gpu_support_(std::move(gpu_support)),
display_manager_mus_(std::make_unique<DisplayManagerMus>()) {
// MouseLocationManager is necessary for providing the shared memory with the
// location of the mouse to clients.
aura::Env::GetInstance()->CreateMouseLocationManager();
......@@ -87,8 +90,7 @@ void WindowService::BindClipboardRequest(mojom::ClipboardRequest request) {
void WindowService::BindDisplayManagerRequest(
mojom::DisplayManagerRequest request) {
// TODO: https://crbug.com/839592.
NOTIMPLEMENTED();
display_manager_mus_->AddBinding(std::move(request));
}
void WindowService::BindImeDriverRequest(mojom::IMEDriverRequest request) {
......
......@@ -31,6 +31,7 @@ class WindowTreeClient;
namespace ws2 {
class ClientWindow;
class DisplayManagerMus;
class GpuSupport;
class WindowServiceClient;
class WindowServiceDelegate;
......@@ -79,6 +80,8 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowService
// GpuSupport may be null in tests.
std::unique_ptr<GpuSupport> gpu_support_;
std::unique_ptr<DisplayManagerMus> display_manager_mus_;
service_manager::BinderRegistry registry_;
std::unique_ptr<WindowTreeFactory> window_tree_factory_;
......
......@@ -54,6 +54,7 @@ class WindowServiceTestHelper {
}
~WindowServiceTestHelper() {
service_.reset();
aura_test_helper_.TearDown();
ui::TerminateContextFactoryForTests();
}
......
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