Skip to content

Commit

Permalink
chromeos: add SingleProcessMash mode
Browse files Browse the repository at this point in the history
This makes Ash create an Env if passed SingleProcessMash. In addition this
makes all window creation go through a factory that ensures the right env is
supplied.

See https://docs.google.com/document/d/11ha_KioDdXe4iZS2AML1foKnCJlNKm7Q1hFr6VW8dV4/edit
for more details.

This also adds the feature to ui/base.

BUG=847992
TEST=covered by tests

Change-Id: Ica3c433627222f0e076dddaf19b1ab09168cebeb
Reviewed-on: https://chromium-review.googlesource.com/1168282
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582411}
  • Loading branch information
Scott Violet authored and Commit Bot committed Aug 11, 2018
1 parent 6c0f9aa commit b092ae6
Show file tree
Hide file tree
Showing 89 changed files with 551 additions and 248 deletions.
6 changes: 6 additions & 0 deletions ash/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ assert(enable_hidpi)
assert(use_ozone)

component("ash") {
friend = [
":ash_unittests",
":test_support_common",
]
public = [
"accelerators/accelerator_commands.h",
"accelerators/accelerator_confirmation_dialog.h",
Expand Down Expand Up @@ -1180,6 +1184,8 @@ component("ash") {
"wallpaper/wallpaper_view.cc",
"wallpaper/wallpaper_widget_controller.cc",
"wallpaper/wallpaper_window_state_manager.cc",
"window_factory.cc",
"window_factory.h",
"wm/always_on_top_controller.cc",
"wm/ash_focus_rules.cc",
"wm/base_state.cc",
Expand Down
22 changes: 22 additions & 0 deletions ash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,28 @@ Ash used to support a "mus" mode that ran the mojo window service from
//services/ui on a background thread in the browser process. This configuration
was deprecated in April 2018.

SingleProcessMash
-----------------

Before launching Mash we plan to launch SingleProcessMash. SingleProcessMash is
similar to "classic ash" in that ash and the browser still live in the same
process and on the same thread, but all non-ash UI code (such as browser
windows) will use the WindowService over mojo. This results in exercising much
of the same code as in mash, but everything is still in the process.

In SingleProcessMash mode there are two aura::Envs. Ash (Shell) creates one and
the browser creates one. In order to ensure the right one is used do the
following:

. When creating a Widget set the parent and/or context. If you don't need a
specific parent (container), more often than not using a context of
Shell::GetRootWindowForNewWindows() is what you want.
. If you are creating aura::Windows directly, use the ash::window_factory.
. If you need access to aura::Env, get it from Shell. Shell always returns the
right one, regardless of mode.

See https://docs.google.com/document/d/11ha_KioDdXe4iZS2AML1foKnCJlNKm7Q1hFr6VW8dV4/edit for more details.

Mash Tests
-----
ash_unittests has some tests specific to Mash, but in general Ash code should
Expand Down
6 changes: 6 additions & 0 deletions ash/app_launch_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "services/service_manager/public/cpp/service_test.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/window_server_test.mojom.h"
#include "ui/base/ui_base_features.h"
#include "ui/views/layout/layout_provider.h"

namespace ash {
Expand All @@ -36,6 +37,11 @@ class AppLaunchTest : public service_manager::test::ServiceTest {
};

TEST_F(AppLaunchTest, TestQuickLaunch) {
// This test launches ash in a separate service. That doesn't make sense with
// SingleProcessMash.
if (features::IsSingleProcessMash())
return;

connector()->StartService(mojom::kServiceName);
connector()->StartService(quick_launch::mojom::kServiceName);

Expand Down
6 changes: 6 additions & 0 deletions ash/ash_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ui/aura/mus/window_tree_host_mus_init_params.h"
#include "ui/aura/test/env_test_helper.h"
#include "ui/aura/window.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display.h"
#include "ui/display/display_list.h"
#include "ui/display/screen_base.h"
Expand Down Expand Up @@ -93,6 +94,11 @@ void OnEmbed(bool success) {
}

TEST_F(AshServiceTest, OpenWindow) {
// This test launches ash in a separate service. That doesn't make sense with
// SingleProcessMash.
if (features::IsSingleProcessMash())
return;

display::ScreenBase screen;
screen.display_list().AddDisplay(
display::Display(1, gfx::Rect(0, 0, 200, 200)),
Expand Down
6 changes: 4 additions & 2 deletions ash/components/fast_ink/fast_ink_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ FastInkView::FastInkView(aura::Window* container,
// but with potential tearing. Note that we have to draw into a temporary
// surface and copy it into GPU memory buffer to avoid flicker.
gpu_memory_buffer_ =
aura::Env::GetInstance()
widget_->GetNativeWindow()
->env()
->context_factory()
->GetGpuMemoryBufferManager()
->CreateGpuMemoryBuffer(buffer_size_,
Expand Down Expand Up @@ -395,7 +396,8 @@ void FastInkView::SubmitCompositorFrame() {
// new instance to be created in lost context situations is acceptable and
// keeps the code simple.
if (!resource->context_provider) {
resource->context_provider = aura::Env::GetInstance()
resource->context_provider = widget_->GetNativeWindow()
->env()
->context_factory()
->SharedMainThreadContextProvider();
if (!resource->context_provider) {
Expand Down
7 changes: 4 additions & 3 deletions ash/display/cursor_window_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "ash/root_window_controller.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/window_factory.h"
#include "base/command_line.h"
#include "base/metrics/histogram_macros.h"
#include "components/prefs/pref_service.h"
Expand Down Expand Up @@ -219,7 +220,7 @@ void CursorWindowController::SetDisplay(const display::Display& display) {
void CursorWindowController::UpdateLocation() {
if (!cursor_window_)
return;
gfx::Point point = aura::Env::GetInstance()->last_mouse_location();
gfx::Point point = Shell::Get()->aura_env()->last_mouse_location();
point.Offset(-bounds_in_screen_.x(), -bounds_in_screen_.y());
point.Offset(-hot_point_.x(), -hot_point_.y());
gfx::Rect bounds = cursor_window_->bounds();
Expand Down Expand Up @@ -263,7 +264,7 @@ void CursorWindowController::SetContainer(aura::Window* container) {
} else {
// Reusing the window does not work when the display is disconnected.
// Just creates a new one instead. crbug.com/384218.
cursor_window_.reset(new aura::Window(delegate_.get()));
cursor_window_ = window_factory::NewWindow(delegate_.get());
cursor_window_->SetTransparent(true);
cursor_window_->Init(ui::LAYER_TEXTURED);
cursor_window_->SetEventTargetingPolicy(
Expand Down Expand Up @@ -371,7 +372,7 @@ void CursorWindowController::UpdateCursorVisibility() {

void CursorWindowController::UpdateCursorView() {
cursor_view_.reset(new cursor::CursorView(
container_, aura::Env::GetInstance()->last_mouse_location(),
container_, Shell::Get()->aura_env()->last_mouse_location(),
is_cursor_motion_blur_enabled_));
UpdateCursorImage();
}
Expand Down
4 changes: 2 additions & 2 deletions ash/display/display_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ TEST_F(DisplayManagerTest, UpdateMouseCursorAfterRotateZoom) {
// Make sure just rotating will not change native location.
UpdateDisplay("300x200,200x150");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
aura::Env* env = aura::Env::GetInstance();
aura::Env* env = Shell::Get()->aura_env();

ui::test::EventGenerator generator1(root_windows[0]);
ui::test::EventGenerator generator2(root_windows[1]);
Expand Down Expand Up @@ -3589,7 +3589,7 @@ TEST_F(DisplayManagerUiScaleTest, UpdateMouseCursorAfterRotateZoom) {
// Make sure just zooming will not change native location.
UpdateDisplay("600x400*2,400x300");
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
aura::Env* env = aura::Env::GetInstance();
aura::Env* env = Shell::Get()->aura_env();

ui::test::EventGenerator generator1(root_windows[0]);
ui::test::EventGenerator generator2(root_windows[1]);
Expand Down
2 changes: 1 addition & 1 deletion ash/display/display_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void MoveCursorTo(AshWindowTreeHost* ash_host,
Shell::GetPrimaryRootWindow()->GetHost()->ConvertScreenInPixelsToDIP(
&new_point_in_screen);
}
aura::Env::GetInstance()->SetLastMouseLocation(new_point_in_screen);
Shell::Get()->aura_env()->SetLastMouseLocation(new_point_in_screen);
}
}

Expand Down
28 changes: 14 additions & 14 deletions ash/display/mirror_window_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "ash/public/cpp/config.h"
#include "ash/root_window_settings.h"
#include "ash/shell.h"
#include "ash/window_factory.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/aura/client/capture_client.h"
Expand Down Expand Up @@ -122,6 +123,10 @@ int64_t GetCurrentReflectingSourceId() {
return display::kInvalidDisplayId;
}

ui::ContextFactoryPrivate* GetContextFactoryPrivate() {
return Shell::Get()->aura_env()->context_factory_private();
}

} // namespace

struct MirrorWindowController::MirroringHostInfo {
Expand Down Expand Up @@ -213,7 +218,7 @@ void MirrorWindowController::UpdateWindow(
host->Show();

aura::Window* mirror_window = host_info->mirror_window =
new aura::Window(nullptr);
window_factory::NewWindow().release();
mirror_window->Init(ui::LAYER_SOLID_COLOR);
host->window()->AddChild(mirror_window);
host_info->ash_host->SetRootWindowTransformer(std::move(transformer));
Expand All @@ -223,15 +228,12 @@ void MirrorWindowController::UpdateWindow(
DCHECK_NE(gfx::kNullAcceleratedWidget, host->GetAcceleratedWidget());
if (reflector_) {
reflector_->AddMirroringLayer(mirror_window->layer());
} else if (aura::Env::GetInstance()->context_factory_private()) {
reflector_ =
aura::Env::GetInstance()
->context_factory_private()
->CreateReflector(
Shell::GetRootWindowForDisplayId(reflecting_source_id_)
->GetHost()
->compositor(),
mirror_window->layer());
} else if (GetContextFactoryPrivate()) {
reflector_ = GetContextFactoryPrivate()->CreateReflector(
Shell::GetRootWindowForDisplayId(reflecting_source_id_)
->GetHost()
->compositor(),
mirror_window->layer());
}
} else {
AshWindowTreeHost* ash_host =
Expand Down Expand Up @@ -261,8 +263,7 @@ void MirrorWindowController::UpdateWindow(

if (mirroring_host_info_map_.empty() && reflector_) {
// Close the mirror window if all displays are disconnected.
aura::Env::GetInstance()->context_factory_private()->RemoveReflector(
reflector_.get());
GetContextFactoryPrivate()->RemoveReflector(reflector_.get());
reflector_.reset();
}
}
Expand Down Expand Up @@ -301,8 +302,7 @@ void MirrorWindowController::CloseIfNotNecessary() {

void MirrorWindowController::Close(bool delay_host_deletion) {
if (reflector_) {
aura::Env::GetInstance()->context_factory_private()->RemoveReflector(
reflector_.get());
GetContextFactoryPrivate()->RemoveReflector(reflector_.get());
reflector_.reset();
}

Expand Down
18 changes: 9 additions & 9 deletions ash/display/mouse_cursor_event_filter_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ TEST_F(MouseCursorEventFilterTest, WarpMouse) {
// Touch the right edge of the primary root window. Pointer should warp.
EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
EXPECT_EQ("501,11", // by 2px.
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());

// Touch the left edge of the secondary root window. Pointer should warp.
EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 11)));
EXPECT_EQ("498,11", // by 2px.
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());

// Touch the left edge of the primary root window.
EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(0, 11)));
Expand Down Expand Up @@ -86,13 +86,13 @@ TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) {
// because 1px left of (0, 500) is outside the primary root window.
EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(501, 500)));
EXPECT_EQ("501,500",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());

// Touch the left edge of the secondary root window. Pointer should warp
// because 1px left of (0, 480) is inside the primary root window.
EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 480)));
EXPECT_EQ("498,480", // by 2px.
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
}

// Verifies if the mouse pointer correctly moves between displays with
Expand All @@ -107,18 +107,18 @@ TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplaysInNative) {
.placement_list[0]
.position);

aura::Env::GetInstance()->SetLastMouseLocation(gfx::Point(900, 123));
Shell::Get()->aura_env()->SetLastMouseLocation(gfx::Point(900, 123));

EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 123)));
EXPECT_EQ("500,123",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
// Touch the edge of 2nd display again and make sure it warps to
// 1st dislay.
EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(500, 123)));
// TODO(oshima): Due to a bug in EventGenerator, the screen coordinates
// is shrunk by dsf once. Fix this.
EXPECT_EQ("498,61",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
}

// Verifies if MouseCursorEventFilter::set_mouse_warp_enabled() works as
Expand All @@ -129,12 +129,12 @@ TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) {
event_filter()->set_mouse_warp_enabled(false);
EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
EXPECT_EQ("499,11",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());

event_filter()->set_mouse_warp_enabled(true);
EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
EXPECT_EQ("501,11",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
}

// Verifies cursor's device scale factor is updated when a cursor has moved
Expand Down
6 changes: 3 additions & 3 deletions ash/display/root_window_transformers_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ TEST_F(RootWindowTransformersTest, RotateAndMagnify) {
generator1.MoveMouseToInHost(40, 80);
EXPECT_EQ("50,90", event_handler.GetLocationAndReset());
EXPECT_EQ("50,90",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
EXPECT_EQ(display::Display::ROTATE_0,
GetActiveDisplayRotation(display1.id()));
EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
Expand All @@ -209,7 +209,7 @@ TEST_F(RootWindowTransformersTest, RotateAndMagnify) {
generator1.MoveMouseToInHost(39, 120);
EXPECT_EQ("110,70", event_handler.GetLocationAndReset());
EXPECT_EQ("110,70",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
EXPECT_EQ(display::Display::ROTATE_90,
GetActiveDisplayRotation(display1.id()));
EXPECT_EQ(display::Display::ROTATE_0, GetActiveDisplayRotation(display2_id));
Expand All @@ -235,7 +235,7 @@ TEST_F(RootWindowTransformersTest, RotateAndMagnify) {
generator2.MoveMouseToInHost(172, 219);
EXPECT_EQ("95,80", event_handler.GetLocationAndReset());
EXPECT_EQ("145,200",
aura::Env::GetInstance()->last_mouse_location().ToString());
Shell::Get()->aura_env()->last_mouse_location().ToString());
EXPECT_EQ(display::Display::ROTATE_90,
GetActiveDisplayRotation(display1.id()));
EXPECT_EQ(display::Display::ROTATE_270,
Expand Down
15 changes: 14 additions & 1 deletion ash/display/screen_ash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
#include "base/logging.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display.h"
#include "ui/display/display_finder.h"
#include "ui/display/manager/display_manager.h"
Expand Down Expand Up @@ -89,7 +91,7 @@ ScreenAsh::ScreenAsh() = default;
ScreenAsh::~ScreenAsh() = default;

gfx::Point ScreenAsh::GetCursorScreenPoint() {
return aura::Env::GetInstance()->last_mouse_location();
return Shell::Get()->aura_env()->last_mouse_location();
}

bool ScreenAsh::IsWindowUnderCursor(gfx::NativeWindow window) {
Expand Down Expand Up @@ -121,6 +123,17 @@ display::Display ScreenAsh::GetDisplayNearestWindow(
gfx::NativeView window) const {
if (!window)
return GetPrimaryDisplay();

if (::features::IsSingleProcessMash()) {
// In IsSingleProcessMash() ScreenAsh is also called from non-ash code.
// Non-ash code creates aura Windows that are not parented to Ash's root
// Windows. Check for this first.
aura::WindowTreeHostMus* window_tree_host_mus =
aura::WindowTreeHostMus::ForWindow(window);
if (window_tree_host_mus)
return window_tree_host_mus->GetDisplay();
}

const aura::Window* root_window = window->GetRootWindow();
if (!root_window)
return GetPrimaryDisplay();
Expand Down
Loading

0 comments on commit b092ae6

Please sign in to comment.