Commit f96e813b authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

Mash: Implement ScreenOrientationDelegateChromeos

Test: put in tablet mode, go to [1], press Lock in Current Orientation

[1] https://whatwebcando.today/screen-orientation.html

Bug: 889981
Change-Id: I2a4381b511c260a3845fbfd42a597cafe581fb43
Reviewed-on: https://chromium-review.googlesource.com/c/1250097
Commit-Queue: Evan Stade <estade@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600845}
parent aa5c01d9
......@@ -10,6 +10,7 @@
#include "ash/ash_export.h"
#include "ash/display/display_configuration_controller.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/public/interfaces/ash_window_manager.mojom.h"
#include "ash/wm/tablet_mode/tablet_mode_observer.h"
#include "base/macros.h"
#include "base/observer_list.h"
......@@ -25,17 +26,7 @@ class Window;
namespace ash {
enum class OrientationLockType {
kAny = 0,
kNatural,
kCurrent,
kPortrait,
kLandscape,
kPortraitPrimary,
kPortraitSecondary,
kLandscapePrimary,
kLandscapeSecondary
};
using OrientationLockType = mojom::OrientationLockType;
// Test if the orientation lock type is primary/landscape/portrait.
bool IsPrimaryOrientation(OrientationLockType type);
......
......@@ -11,7 +11,10 @@
namespace ash {
class ScreenOrientationController;
namespace mojom {
enum class OrientationLockType;
}
class ScreenOrientationControllerTestApi {
public:
......@@ -26,9 +29,9 @@ class ScreenOrientationControllerTestApi {
void SetRotationLocked(bool rotation_locked);
OrientationLockType UserLockedOrientation() const;
mojom::OrientationLockType UserLockedOrientation() const;
OrientationLockType GetCurrentOrientation() const;
mojom::OrientationLockType GetCurrentOrientation() const;
void UpdateNaturalOrientation();
......
......@@ -14,6 +14,18 @@ enum SnapDirection {
kRight, // The phantom window controller is previewing a snap to the left.
};
enum OrientationLockType {
kAny,
kNatural,
kCurrent,
kPortrait,
kLandscape,
kPortraitPrimary,
kPortraitSecondary,
kLandscapePrimary,
kLandscapeSecondary,
};
// Interface exposed via WindowTree::BindWindowManagerInterface(). This
// interface is used for functionality specific to Ash that is associated with
// windows created by the window service.
......@@ -24,6 +36,12 @@ interface AshWindowManager {
CommitSnap(uint64 window_id, SnapDirection snap);
// Locks or unlocks the screen orientation. The provided window is the source
// of the orientation request and need not be a top level window, but the
// client connection type must not be an embedding (i.e. renderer).
LockOrientation(uint64 window_id, OrientationLockType type);
UnlockOrientation(uint64 window_id);
// Maximizes the window in response to a double click or tap on the HTCAPTION
// area.
MaximizeWindowByCaptionClick(uint64 window_id, ui.mojom.PointerKind pointer);
......
......@@ -29,8 +29,11 @@ class ScopedWindowTargeter;
namespace ash {
class SplitViewController;
namespace mojom {
enum class OrientationLockType;
}
class SplitViewController;
// Split view divider. It passes the mouse/gesture events to SplitViewController
// to resize the left and right windows accordingly. The divider widget should
......@@ -45,13 +48,13 @@ class ASH_EXPORT SplitViewDivider : public aura::WindowObserver,
// Gets the size of the divider widget. The divider widget is enlarged during
// dragging. For now, it's a vertical rectangle.
static gfx::Size GetDividerSize(const gfx::Rect& work_area_bounds,
OrientationLockType screen_orientation,
mojom::OrientationLockType screen_orientation,
bool is_dragging);
// static version of GetDividerBoundsInScreen(bool is_dragging) function.
static gfx::Rect GetDividerBoundsInScreen(
const gfx::Rect& work_area_bounds_in_screen,
OrientationLockType screen_orientation,
mojom::OrientationLockType screen_orientation,
int divider_position,
bool is_dragging);
......
......@@ -4,6 +4,7 @@
#include "ash/ws/ash_window_manager.h"
#include "ash/display/screen_orientation_controller.h"
#include "ash/shell.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h"
......@@ -53,6 +54,40 @@ void AshWindowManager::CommitSnap(ws::Id window_id, mojom::SnapDirection snap) {
}
}
void AshWindowManager::LockOrientation(
ws::Id window_id,
mojom::OrientationLockType lock_orientation) {
if (window_tree_->connection_type() ==
ws::WindowTree::ConnectionType::kEmbedding) {
DVLOG(1) << "LockOrientation not allowed from embed connection";
return;
}
aura::Window* window = window_tree_->GetWindowByTransportId(window_id);
if (window) {
Shell::Get()->screen_orientation_controller()->LockOrientationForWindow(
window, lock_orientation);
} else {
DVLOG(1) << "LockOrientation passed invalid window, id=" << window_id;
}
}
void AshWindowManager::UnlockOrientation(ws::Id window_id) {
if (window_tree_->connection_type() ==
ws::WindowTree::ConnectionType::kEmbedding) {
DVLOG(1) << "UnlockOrientation not allowed from embed connection";
return;
}
aura::Window* window = window_tree_->GetWindowByTransportId(window_id);
if (window) {
Shell::Get()->screen_orientation_controller()->UnlockOrientationForWindow(
window);
} else {
DVLOG(1) << "UnlockOrientation passed invalid window, id=" << window_id;
}
}
void AshWindowManager::MaximizeWindowByCaptionClick(
ws::Id window_id,
ui::mojom::PointerKind pointer) {
......
......@@ -33,6 +33,9 @@ class AshWindowManager : public mojom::AshWindowManager,
void AddWindowToTabletMode(ws::Id window_id) override;
void ShowSnapPreview(ws::Id window_id, mojom::SnapDirection snap) override;
void CommitSnap(ws::Id window_id, mojom::SnapDirection snap) override;
void LockOrientation(ws::Id window_id,
mojom::OrientationLockType lock_orientation) override;
void UnlockOrientation(ws::Id window_id) override;
void MaximizeWindowByCaptionClick(ws::Id window_id,
ui::mojom::PointerKind pointer) override;
void BounceWindow(ws::Id window_id) override;
......
......@@ -49,6 +49,7 @@ specific_include_rules = {
# https://crbug.com/665064
"+ash/shell_delegate.h",
],
# Only used in !mash
"screen_orientation_delegate_chromeos.cc": [
"+ash/display/screen_orientation_controller.h",
"+ash/shell.h",
......
......@@ -206,12 +206,8 @@ void ChromeBrowserMainExtraPartsAsh::PreProfileInit() {
if (features::IsUsingWindowService())
immersive_context_ = std::make_unique<ImmersiveContextMus>();
// TODO(estade): implement ScreenOrientationDelegateChromeos for Mash and
// remove this condition.
if (!features::IsUsingWindowService()) {
screen_orientation_delegate_ =
std::make_unique<ScreenOrientationDelegateChromeos>();
}
app_list_client_ = std::make_unique<AppListClientImpl>();
......
......@@ -4,40 +4,55 @@
#include "chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h"
#include "ash/display/screen_orientation_controller.h" // mash-ok
#include "ash/shell.h" // mash-ok
#include "ash/display/screen_orientation_controller.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "ash/shell.h"
#include "chrome/browser/ui/ash/tablet_mode_client.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/service_manager_connection.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/aura/mus/window_mus.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/base/ui_base_features.h"
#include "ui/views/mus/desktop_window_tree_host_mus.h"
#include "ui/views/mus/mus_client.h"
namespace {
ash::OrientationLockType ToAshOrientationLockType(
ash::mojom::OrientationLockType ToAshOrientationLockType(
blink::WebScreenOrientationLockType blink_orientation_lock) {
switch (blink_orientation_lock) {
case blink::kWebScreenOrientationLockDefault:
case blink::kWebScreenOrientationLockAny:
return ash::OrientationLockType::kAny;
return ash::mojom::OrientationLockType::kAny;
case blink::kWebScreenOrientationLockPortrait:
return ash::OrientationLockType::kPortrait;
return ash::mojom::OrientationLockType::kPortrait;
case blink::kWebScreenOrientationLockPortraitPrimary:
return ash::OrientationLockType::kPortraitPrimary;
return ash::mojom::OrientationLockType::kPortraitPrimary;
case blink::kWebScreenOrientationLockPortraitSecondary:
return ash::OrientationLockType::kPortraitSecondary;
return ash::mojom::OrientationLockType::kPortraitSecondary;
case blink::kWebScreenOrientationLockLandscape:
return ash::OrientationLockType::kLandscape;
return ash::mojom::OrientationLockType::kLandscape;
case blink::kWebScreenOrientationLockLandscapePrimary:
return ash::OrientationLockType::kLandscapePrimary;
return ash::mojom::OrientationLockType::kLandscapePrimary;
case blink::kWebScreenOrientationLockLandscapeSecondary:
return ash::OrientationLockType::kLandscapeSecondary;
return ash::mojom::OrientationLockType::kLandscapeSecondary;
case blink::kWebScreenOrientationLockNatural:
return ash::OrientationLockType::kNatural;
return ash::mojom::OrientationLockType::kNatural;
}
return ash::OrientationLockType::kAny;
return ash::mojom::OrientationLockType::kAny;
}
} // namespace
ScreenOrientationDelegateChromeos::ScreenOrientationDelegateChromeos() {
if (features::IsUsingWindowService()) {
ash_window_manager_ =
views::MusClient::Get()
->window_tree_client()
->BindWindowManagerInterface<ash::mojom::AshWindowManager>();
}
content::WebContents::SetScreenOrientationDelegate(this);
}
......@@ -53,9 +68,16 @@ bool ScreenOrientationDelegateChromeos::FullScreenRequired(
void ScreenOrientationDelegateChromeos::Lock(
content::WebContents* web_contents,
blink::WebScreenOrientationLockType orientation_lock) {
ash::Shell::Get()->screen_orientation_controller()->LockOrientationForWindow(
web_contents->GetNativeView(),
if (features::IsUsingWindowService()) {
ash_window_manager_->LockOrientation(
aura::WindowMus::Get(web_contents->GetNativeView())->server_id(),
ToAshOrientationLockType(orientation_lock));
} else {
ash::Shell::Get()
->screen_orientation_controller()
->LockOrientationForWindow(web_contents->GetNativeView(),
ToAshOrientationLockType(orientation_lock));
}
}
bool ScreenOrientationDelegateChromeos::ScreenOrientationProviderSupported() {
......@@ -65,7 +87,12 @@ bool ScreenOrientationDelegateChromeos::ScreenOrientationProviderSupported() {
void ScreenOrientationDelegateChromeos::Unlock(
content::WebContents* web_contents) {
if (features::IsUsingWindowService()) {
ash_window_manager_->UnlockOrientation(
aura::WindowMus::Get(web_contents->GetNativeView())->server_id());
} else {
ash::Shell::Get()
->screen_orientation_controller()
->UnlockOrientationForWindow(web_contents->GetNativeView());
}
}
......@@ -5,10 +5,10 @@
#ifndef CHROME_BROWSER_UI_ASH_SCREEN_ORIENTATION_DELEGATE_CHROMEOS_H_
#define CHROME_BROWSER_UI_ASH_SCREEN_ORIENTATION_DELEGATE_CHROMEOS_H_
#include "ash/public/interfaces/ash_window_manager.mojom.h"
#include "content/public/browser/screen_orientation_delegate.h"
// Chrome OS implementation for screen orientation JS api. TODO(estade):
// implement for Mash.
// Chrome OS implementation for screen orientation JS api.
class ScreenOrientationDelegateChromeos
: public content::ScreenOrientationDelegate {
public:
......@@ -23,6 +23,8 @@ class ScreenOrientationDelegateChromeos
bool ScreenOrientationProviderSupported() override;
void Unlock(content::WebContents* web_contents) override;
ash::mojom::AshWindowManagerAssociatedPtr ash_window_manager_;
DISALLOW_COPY_AND_ASSIGN(ScreenOrientationDelegateChromeos);
};
......
// 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 "chrome/test/base/in_process_browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/base/ui_base_features.h"
using ScreenOrientationDelegateChromeosTest = InProcessBrowserTest;
// Tests that an orientation delegate is created and set. Regression test for
// https://crbug.com/889981
IN_PROC_BROWSER_TEST_F(ScreenOrientationDelegateChromeosTest, Basic) {
EXPECT_NE(nullptr, content::GetScreenOrientationDelegate());
}
......@@ -1792,6 +1792,7 @@ test("browser_tests") {
"../browser/ui/ash/multi_user/test_multi_user_window_manager.cc",
"../browser/ui/ash/multi_user/test_multi_user_window_manager.h",
"../browser/ui/ash/network/networking_config_chromeos_browsertest.cc",
"../browser/ui/ash/screen_orientation_delegate_chromeos_browsertest.cc",
"../browser/ui/ash/shelf_browsertest.cc",
"../browser/ui/ash/system_tray_client_browsertest.cc",
"../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc",
......
......@@ -120,6 +120,10 @@ void ScreenOrientationProvider::SetDelegate(
delegate_ = delegate;
}
ScreenOrientationDelegate* ScreenOrientationProvider::GetDelegateForTesting() {
return delegate_;
}
void ScreenOrientationProvider::DidToggleFullscreenModeForTab(
bool entered_fullscreen,
bool will_cause_resize) {
......
......@@ -42,7 +42,8 @@ class CONTENT_EXPORT ScreenOrientationProvider
// Provide a delegate which creates delegates for platform implementations.
// The delegate is not owned by ScreenOrientationProvider.
static void SetDelegate(ScreenOrientationDelegate* delegate_);
static void SetDelegate(ScreenOrientationDelegate* delegate);
static ScreenOrientationDelegate* GetDelegateForTesting();
// WebContentsObserver
void DidToggleFullscreenModeForTab(bool entered_fullscreen,
......
......@@ -48,6 +48,7 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/screen_orientation/screen_orientation_provider.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
......@@ -1989,6 +1990,10 @@ bool IsInnerInterstitialPageConnected(InterstitialPage* interstitial_page) {
frame_connector->GetParentRenderWidgetHostView();
}
ScreenOrientationDelegate* GetScreenOrientationDelegate() {
return ScreenOrientationProvider::GetDelegateForTesting();
}
std::vector<RenderWidgetHostView*> GetInputEventRouterRenderWidgetHostViews(
WebContents* web_contents) {
return static_cast<WebContentsImpl*>(web_contents)
......
......@@ -879,6 +879,10 @@ void CancelKeyboardLock(WebContents* web_contents);
// WebContents.
bool IsInnerInterstitialPageConnected(InterstitialPage* interstitial_page);
// Returns the screen orientation provider that's been set via
// WebContents::SetScreenOrientationDelegate(). May return null.
ScreenOrientationDelegate* GetScreenOrientationDelegate();
// Returns all the RenderWidgetHostViews inside the |web_contents| that are
// registered in the RenderWidgetHostInputEventRouter.
std::vector<RenderWidgetHostView*> GetInputEventRouterRenderWidgetHostViews(
......
......@@ -67,6 +67,17 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowTree
public aura::WindowObserver,
public aura::client::CaptureClientObserver {
public:
enum class ConnectionType {
// This client is the result of an embedding, InitForEmbed() was called.
kEmbedding,
// This client is not the result of an embedding. More specifically
// InitFromFactory() was called. Generally this means the client first
// connected to mojom::WindowTreeFactory and then called
// mojom::WindowTreeFactory::CreateWindowTree().
kOther,
};
WindowTree(WindowService* window_service,
ClientSpecificId client_id,
mojom::WindowTreeClient* client,
......@@ -123,6 +134,8 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowTree
const std::string& client_name() const { return client_name_; }
ConnectionType connection_type() const { return connection_type_; }
// Returns true if at a compositor frame sink has been created for at least
// one of the roots.
bool HasAtLeastOneRootWithCompositorFrameSink();
......@@ -149,17 +162,6 @@ class COMPONENT_EXPORT(WINDOW_SERVICE) WindowTree
using ClientRoots = std::vector<std::unique_ptr<ClientRoot>>;
enum class ConnectionType {
// This client is the result of an embedding, InitForEmbed() was called.
kEmbedding,
// This client is not the result of an embedding. More specifically
// InitFromFactory() was called. Generally this means the client first
// connected to mojom::WindowTreeFactory and then called
// mojom::WindowTreeFactory::CreateWindowTree().
kOther,
};
enum class DeleteClientRootReason {
// The window is being destroyed.
kDeleted,
......
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