Commit da089db0 authored by flackr's avatar flackr Committed by Commit bot

Disable screen rotation when splitview is engaged and only allow splitview in landscape.

BUG=408962
TEST=SplitSplitViewControllerTest.LandscapeOnly

Review URL: https://codereview.chromium.org/535973002

Cr-Commit-Position: refs/heads/master@{#293180}
parent cce52da2
...@@ -67,6 +67,7 @@ class ATHENA_EXPORT ScreenManager { ...@@ -67,6 +67,7 @@ class ATHENA_EXPORT ScreenManager {
// TODO(flackr): Extract and use ash DisplayManager to set rotation // TODO(flackr): Extract and use ash DisplayManager to set rotation
// instead: http://crbug.com/401044. // instead: http://crbug.com/401044.
virtual void SetRotation(gfx::Display::Rotation rotation) = 0; virtual void SetRotation(gfx::Display::Rotation rotation) = 0;
virtual void SetRotationLocked(bool rotation_locked) = 0;
// Returns the LayerAnimator to use to animate the entire screen (e.g. fade // Returns the LayerAnimator to use to animate the entire screen (e.g. fade
// screen to white). // screen to white).
......
...@@ -203,6 +203,7 @@ class ScreenManagerImpl : public ScreenManager { ...@@ -203,6 +203,7 @@ class ScreenManagerImpl : public ScreenManager {
virtual aura::Window* CreateContainer(const ContainerParams& params) OVERRIDE; virtual aura::Window* CreateContainer(const ContainerParams& params) OVERRIDE;
virtual aura::Window* GetContext() OVERRIDE { return root_window_; } virtual aura::Window* GetContext() OVERRIDE { return root_window_; }
virtual void SetRotation(gfx::Display::Rotation rotation) OVERRIDE; virtual void SetRotation(gfx::Display::Rotation rotation) OVERRIDE;
virtual void SetRotationLocked(bool rotation_locked) OVERRIDE;
virtual ui::LayerAnimator* GetScreenAnimator() OVERRIDE; virtual ui::LayerAnimator* GetScreenAnimator() OVERRIDE;
// Not owned. // Not owned.
...@@ -214,11 +215,16 @@ class ScreenManagerImpl : public ScreenManager { ...@@ -214,11 +215,16 @@ class ScreenManagerImpl : public ScreenManager {
scoped_ptr< ::wm::ScopedCaptureClient> capture_client_; scoped_ptr< ::wm::ScopedCaptureClient> capture_client_;
scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_; scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_;
gfx::Display::Rotation last_requested_rotation_;
bool rotation_locked_;
DISALLOW_COPY_AND_ASSIGN(ScreenManagerImpl); DISALLOW_COPY_AND_ASSIGN(ScreenManagerImpl);
}; };
ScreenManagerImpl::ScreenManagerImpl(aura::Window* root_window) ScreenManagerImpl::ScreenManagerImpl(aura::Window* root_window)
: root_window_(root_window) { : root_window_(root_window),
last_requested_rotation_(gfx::Display::ROTATE_0),
rotation_locked_(false) {
DCHECK(root_window_); DCHECK(root_window_);
DCHECK(!instance); DCHECK(!instance);
instance = this; instance = this;
...@@ -329,7 +335,8 @@ aura::Window* ScreenManagerImpl::CreateContainer( ...@@ -329,7 +335,8 @@ aura::Window* ScreenManagerImpl::CreateContainer(
} }
void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) { void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) {
if (rotation == last_requested_rotation_ = rotation;
if (rotation_locked_ || rotation ==
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation()) { gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation()) {
return; return;
} }
...@@ -340,6 +347,12 @@ void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) { ...@@ -340,6 +347,12 @@ void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) {
SetDisplayRotation(rotation); SetDisplayRotation(rotation);
} }
void ScreenManagerImpl::SetRotationLocked(bool rotation_locked) {
rotation_locked_ = rotation_locked;
if (!rotation_locked_)
SetRotation(last_requested_rotation_);
}
ui::LayerAnimator* ScreenManagerImpl::GetScreenAnimator() { ui::LayerAnimator* ScreenManagerImpl::GetScreenAnimator() {
return root_window_->layer()->GetAnimator(); return root_window_->layer()->GetAnimator();
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <cmath> #include <cmath>
#include "athena/screen/public/screen_manager.h"
#include "athena/wm/public/window_list_provider.h" #include "athena/wm/public/window_list_provider.h"
#include "athena/wm/public/window_manager.h" #include "athena/wm/public/window_manager.h"
#include "base/bind.h" #include "base/bind.h"
...@@ -33,6 +34,11 @@ gfx::Transform GetTargetTransformForBoundsAnimation(const gfx::Rect& from, ...@@ -33,6 +34,11 @@ gfx::Transform GetTargetTransformForBoundsAnimation(const gfx::Rect& from,
return transform; return transform;
} }
bool IsLandscapeOrientation(gfx::Display::Rotation rotation) {
return rotation == gfx::Display::ROTATE_0 ||
rotation == gfx::Display::ROTATE_180;
}
} // namespace } // namespace
SplitViewController::SplitViewController( SplitViewController::SplitViewController(
...@@ -88,7 +94,7 @@ void SplitViewController::ActivateSplitMode(aura::Window* left, ...@@ -88,7 +94,7 @@ void SplitViewController::ActivateSplitMode(aura::Window* left,
} }
} }
state_ = ACTIVE; SetState(ACTIVE);
if (right_window_ != right) { if (right_window_ != right) {
right_window_ = right; right_window_ = right;
container_->StackChildAtTop(right_window_); container_->StackChildAtTop(right_window_);
...@@ -124,7 +130,7 @@ void SplitViewController::ReplaceWindow(aura::Window* window, ...@@ -124,7 +130,7 @@ void SplitViewController::ReplaceWindow(aura::Window* window,
void SplitViewController::DeactivateSplitMode() { void SplitViewController::DeactivateSplitMode() {
CHECK_EQ(ACTIVE, state_); CHECK_EQ(ACTIVE, state_);
state_ = INACTIVE; SetState(INACTIVE);
UpdateLayout(false); UpdateLayout(false);
left_window_ = right_window_ = NULL; left_window_ = right_window_ = NULL;
} }
...@@ -143,10 +149,21 @@ gfx::Rect SplitViewController::GetRightTargetBounds() { ...@@ -143,10 +149,21 @@ gfx::Rect SplitViewController::GetRightTargetBounds() {
container_width / 2, 0, container_width / 2, work_area.height()); container_width / 2, 0, container_width / 2, work_area.height());
} }
void SplitViewController::SetState(SplitViewController::State state) {
if (state_ == state)
return;
state_ = state;
ScreenManager::Get()->SetRotationLocked(state_ != INACTIVE);
}
void SplitViewController::UpdateLayout(bool animate) { void SplitViewController::UpdateLayout(bool animate) {
CHECK(left_window_); CHECK(left_window_);
CHECK(right_window_); CHECK(right_window_);
// Splitview can be activated from SplitViewController::ActivateSplitMode or
// SplitViewController::ScrollEnd. Additionally we don't want to rotate the
// screen while engaging splitview (i.e. state_ == SCROLLING).
if (state_ == INACTIVE && !animate) { if (state_ == INACTIVE && !animate) {
if (!wm::IsActiveWindow(left_window_)) if (!wm::IsActiveWindow(left_window_))
left_window_->Hide(); left_window_->Hide();
...@@ -238,7 +255,7 @@ void SplitViewController::ScrollBegin(BezelController::Bezel bezel, ...@@ -238,7 +255,7 @@ void SplitViewController::ScrollBegin(BezelController::Bezel bezel,
float delta) { float delta) {
if (!CanScroll()) if (!CanScroll())
return; return;
state_ = SCROLLING; SetState(SCROLLING);
aura::Window::Windows windows = window_list_provider_->GetWindowList(); aura::Window::Windows windows = window_list_provider_->GetWindowList();
CHECK(windows.size() >= 2); CHECK(windows.size() >= 2);
...@@ -271,15 +288,15 @@ void SplitViewController::ScrollEnd() { ...@@ -271,15 +288,15 @@ void SplitViewController::ScrollEnd() {
int container_width = container_->GetBoundsInScreen().width(); int container_width = container_->GetBoundsInScreen().width();
if (std::abs(container_width / 2 - separator_position_) <= if (std::abs(container_width / 2 - separator_position_) <=
kMaxDistanceFromMiddle) { kMaxDistanceFromMiddle) {
state_ = ACTIVE; SetState(ACTIVE);
separator_position_ = container_width / 2; separator_position_ = container_width / 2;
} else if (separator_position_ < container_width / 2) { } else if (separator_position_ < container_width / 2) {
separator_position_ = 0; separator_position_ = 0;
state_ = INACTIVE; SetState(INACTIVE);
wm::ActivateWindow(right_window_); wm::ActivateWindow(right_window_);
} else { } else {
separator_position_ = container_width; separator_position_ = container_width;
state_ = INACTIVE; SetState(INACTIVE);
wm::ActivateWindow(left_window_); wm::ActivateWindow(left_window_);
} }
UpdateLayout(true); UpdateLayout(true);
...@@ -293,9 +310,11 @@ void SplitViewController::ScrollUpdate(float delta) { ...@@ -293,9 +310,11 @@ void SplitViewController::ScrollUpdate(float delta) {
} }
bool SplitViewController::CanScroll() { bool SplitViewController::CanScroll() {
// TODO(mfomitchev): return false in vertical orientation, in full screen. // TODO(mfomitchev): return false in full screen.
bool result = (!IsSplitViewModeActive() && bool result = (!IsSplitViewModeActive() &&
window_list_provider_->GetWindowList().size() >= 2); window_list_provider_->GetWindowList().size() >= 2 &&
IsLandscapeOrientation(gfx::Screen::GetNativeScreen()->
GetDisplayNearestWindow(container_).rotation()));
return result; return result;
} }
......
...@@ -17,6 +17,7 @@ class Transform; ...@@ -17,6 +17,7 @@ class Transform;
namespace athena { namespace athena {
class WindowListProvider; class WindowListProvider;
class SplitViewControllerTest;
// Responsible for entering split view mode, exiting from split view mode, and // Responsible for entering split view mode, exiting from split view mode, and
// laying out the windows in split view mode. // laying out the windows in split view mode.
...@@ -55,6 +56,8 @@ class ATHENA_EXPORT SplitViewController ...@@ -55,6 +56,8 @@ class ATHENA_EXPORT SplitViewController
aura::Window* right_window() { return right_window_; } aura::Window* right_window() { return right_window_; }
private: private:
friend class SplitViewControllerTest;
enum State { enum State {
// Split View mode is not active. |left_window_| and |right_window| are // Split View mode is not active. |left_window_| and |right_window| are
// NULL. // NULL.
...@@ -68,6 +71,7 @@ class ATHENA_EXPORT SplitViewController ...@@ -68,6 +71,7 @@ class ATHENA_EXPORT SplitViewController
ACTIVE ACTIVE
}; };
void SetState(State state);
void UpdateLayout(bool animate); void UpdateLayout(bool animate);
void SetWindowTransforms(const gfx::Transform& left_transform, void SetWindowTransforms(const gfx::Transform& left_transform,
......
...@@ -4,16 +4,47 @@ ...@@ -4,16 +4,47 @@
#include "athena/wm/split_view_controller.h" #include "athena/wm/split_view_controller.h"
#include "athena/screen/public/screen_manager.h"
#include "athena/test/athena_test_base.h" #include "athena/test/athena_test_base.h"
#include "athena/wm/public/window_list_provider.h" #include "athena/wm/public/window_list_provider.h"
#include "athena/wm/test/window_manager_impl_test_api.h" #include "athena/wm/test/window_manager_impl_test_api.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
namespace athena { namespace athena {
typedef test::AthenaTestBase SplitViewControllerTest; class SplitViewControllerTest : public test::AthenaTestBase {
public:
SplitViewControllerTest() {}
virtual ~SplitViewControllerTest() {}
// test::AthenaTestBase:
virtual void SetUp() OVERRIDE {
test::AthenaTestBase::SetUp();
api_.reset(new test::WindowManagerImplTestApi);
}
virtual void TearDown() OVERRIDE {
api_.reset();
test::AthenaTestBase::TearDown();
}
bool IsSplitViewAllowed() const {
return api_->GetSplitViewController()->CanScroll();
}
test::WindowManagerImplTestApi* api() {
return api_.get();
}
private:
scoped_ptr<test::WindowManagerImplTestApi> api_;
DISALLOW_COPY_AND_ASSIGN(SplitViewControllerTest);
};
// Tests that when split mode is activated, the windows on the left and right // Tests that when split mode is activated, the windows on the left and right
// are selected correctly. // are selected correctly.
...@@ -26,9 +57,8 @@ TEST_F(SplitViewControllerTest, SplitModeActivation) { ...@@ -26,9 +57,8 @@ TEST_F(SplitViewControllerTest, SplitModeActivation) {
windows.push_back(window.release()); windows.push_back(window.release());
} }
test::WindowManagerImplTestApi api; SplitViewController* controller = api()->GetSplitViewController();
SplitViewController* controller = api.GetSplitViewController(); WindowListProvider* list_provider = api()->GetWindowListProvider();
WindowListProvider* list_provider = api.GetWindowListProvider();
ASSERT_FALSE(controller->IsSplitViewModeActive()); ASSERT_FALSE(controller->IsSplitViewModeActive());
controller->ActivateSplitMode(NULL, NULL); controller->ActivateSplitMode(NULL, NULL);
...@@ -66,4 +96,41 @@ TEST_F(SplitViewControllerTest, SplitModeActivation) { ...@@ -66,4 +96,41 @@ TEST_F(SplitViewControllerTest, SplitModeActivation) {
EXPECT_EQ(windows[5], *(list_provider->GetWindowList().rbegin() + 1)); EXPECT_EQ(windows[5], *(list_provider->GetWindowList().rbegin() + 1));
} }
TEST_F(SplitViewControllerTest, LandscapeOnly) {
aura::test::TestWindowDelegate delegate;
ScopedVector<aura::Window> windows;
const int kNumWindows = 2;
for (size_t i = 0; i < kNumWindows; ++i) {
scoped_ptr<aura::Window> window = CreateTestWindow(NULL, gfx::Rect());
windows.push_back(window.release());
}
ASSERT_EQ(gfx::Display::ROTATE_0,
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation());
SplitViewController* controller = api()->GetSplitViewController();
ASSERT_TRUE(IsSplitViewAllowed());
ASSERT_FALSE(controller->IsSplitViewModeActive());
controller->ActivateSplitMode(NULL, NULL);
ASSERT_TRUE(controller->IsSplitViewModeActive());
// Screen rotation should be locked while in splitview.
ScreenManager::Get()->SetRotation(gfx::Display::ROTATE_90);
EXPECT_EQ(gfx::Display::ROTATE_0,
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation());
// Screen is rotated on exiting splitview.
controller->DeactivateSplitMode();
ASSERT_EQ(gfx::Display::ROTATE_90,
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation());
// Entering splitview should now be disabled now that the screen is in a
// portrait orientation.
EXPECT_FALSE(IsSplitViewAllowed());
// Rotating back to 0 allows splitview again.
ScreenManager::Get()->SetRotation(gfx::Display::ROTATE_0);
EXPECT_TRUE(IsSplitViewAllowed());
}
} // namespace athena } // namespace athena
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