1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "ash/ash_switches.h"
8 #include "ash/content/display/screen_orientation_controller_chromeos.h"
9 #include "ash/display/display_info.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/shell.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/test/ash_test_helper.h"
14 #include "ash/test/display_manager_test_api.h"
15 #include "ash/test/test_shell_delegate.h"
16 #include "ash/test/test_system_tray_delegate.h"
17 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
18 #include "base/command_line.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "chromeos/accelerometer/accelerometer_reader.h"
21 #include "chromeos/accelerometer/accelerometer_types.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h"
26 #include "ui/aura/window.h"
27 #include "ui/gfx/display.h"
28 #include "ui/message_center/message_center.h"
29 #include "ui/views/test/webview_test_helper.h"
30 #include "ui/views/view.h"
31 #include "ui/views/views_delegate.h"
32 #include "ui/wm/public/activation_client.h"
38 const float kDegreesToRadians
= 3.1415926f
/ 180.0f
;
39 const float kMeanGravity
= 9.8066f
;
41 DisplayInfo
CreateDisplayInfo(int64 id
, const gfx::Rect
& bounds
) {
42 DisplayInfo
info(id
, "dummy", false);
43 info
.SetBounds(bounds
);
47 void EnableMaximizeMode(bool enable
) {
49 ->maximize_mode_controller()
50 ->EnableMaximizeModeWindowManager(enable
);
53 bool RotationLocked() {
54 return Shell::GetInstance()
55 ->screen_orientation_controller()
59 void SetInternalDisplayRotation(gfx::Display::Rotation rotation
) {
60 Shell::GetInstance()->display_manager()->SetDisplayRotation(
61 gfx::Display::InternalDisplayId(), rotation
,
62 gfx::Display::ROTATION_SOURCE_USER
);
65 void SetRotationLocked(bool rotation_locked
) {
66 Shell::GetInstance()->screen_orientation_controller()->SetRotationLocked(
70 void TriggerLidUpdate(const gfx::Vector3dF
& lid
) {
71 scoped_refptr
<chromeos::AccelerometerUpdate
> update(
72 new chromeos::AccelerometerUpdate());
73 update
->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN
, lid
.x(), lid
.y(), lid
.z());
74 Shell::GetInstance()->screen_orientation_controller()->OnAccelerometerUpdated(
78 // Attaches the NativeView of |web_contents| to |parent| without changing the
79 // currently active window.
80 void AttachWebContents(content::WebContents
* web_contents
,
81 aura::Window
* parent
) {
82 aura::Window
* window
= web_contents
->GetNativeView();
84 parent
->AddChild(window
);
87 // Attaches the NativeView of |web_contents| to |parent|, ensures that it is
88 // visible, and activates the parent window.
89 void AttachAndActivateWebContents(content::WebContents
* web_contents
,
90 aura::Window
* parent
) {
91 AttachWebContents(web_contents
, parent
);
92 Shell::GetInstance()->activation_client()->ActivateWindow(parent
);
97 class ScreenOrientationControllerTest
: public test::AshTestBase
{
99 ScreenOrientationControllerTest();
100 ~ScreenOrientationControllerTest() override
;
102 ScreenOrientationController
* delegate() {
103 return screen_orientation_controller_
;
106 // Creates and initializes and empty content::WebContents that is backed by a
107 // content::BrowserContext and that has an aura::Window.
108 content::WebContents
* CreateWebContents();
110 // Creates a secondary content::WebContents, with a separate
111 // content::BrowserContext.
112 content::WebContents
* CreateSecondaryWebContents();
114 // test::AshTestBase:
115 void SetUp() override
;
118 ScreenOrientationController
* screen_orientation_controller_
;
120 // Optional content::BrowserContext used for two window tests.
121 scoped_ptr
<content::BrowserContext
> secondary_browser_context_
;
123 // Setups underlying content layer so that content::WebContents can be
125 scoped_ptr
<views::WebViewTestHelper
> webview_test_helper_
;
127 DISALLOW_COPY_AND_ASSIGN(ScreenOrientationControllerTest
);
130 ScreenOrientationControllerTest::ScreenOrientationControllerTest() {
131 webview_test_helper_
.reset(new views::WebViewTestHelper());
134 ScreenOrientationControllerTest::~ScreenOrientationControllerTest() {
137 content::WebContents
* ScreenOrientationControllerTest::CreateWebContents() {
138 return views::ViewsDelegate::GetInstance()->CreateWebContents(
139 ash_test_helper()->test_shell_delegate()->GetActiveBrowserContext(),
143 content::WebContents
*
144 ScreenOrientationControllerTest::CreateSecondaryWebContents() {
145 secondary_browser_context_
.reset(new content::TestBrowserContext());
146 return views::ViewsDelegate::GetInstance()->CreateWebContents(
147 secondary_browser_context_
.get(), nullptr);
150 void ScreenOrientationControllerTest::SetUp() {
151 base::CommandLine::ForCurrentProcess()->AppendSwitch(
152 switches::kAshUseFirstDisplayAsInternal
);
153 base::CommandLine::ForCurrentProcess()->AppendSwitch(
154 switches::kAshEnableTouchViewTesting
);
155 test::AshTestBase::SetUp();
156 screen_orientation_controller_
=
157 Shell::GetInstance()->screen_orientation_controller();
160 // Tests that a content::WebContents can lock rotation.
161 TEST_F(ScreenOrientationControllerTest
, LockOrientation
) {
162 scoped_ptr
<content::WebContents
> content(CreateWebContents());
163 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
164 ASSERT_NE(nullptr, content
->GetNativeView());
165 ASSERT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
166 ASSERT_FALSE(RotationLocked());
168 AttachAndActivateWebContents(content
.get(), focus_window
.get());
169 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
170 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
171 EXPECT_TRUE(RotationLocked());
174 // Tests that a content::WebContents can unlock rotation.
175 TEST_F(ScreenOrientationControllerTest
, Unlock
) {
176 scoped_ptr
<content::WebContents
> content(CreateWebContents());
177 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
178 ASSERT_NE(nullptr, content
->GetNativeView());
179 ASSERT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
180 ASSERT_FALSE(RotationLocked());
182 AttachAndActivateWebContents(content
.get(), focus_window
.get());
183 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
184 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
185 EXPECT_TRUE(RotationLocked());
187 delegate()->Unlock(content
.get());
188 EXPECT_FALSE(RotationLocked());
191 // Tests that a content::WebContents is able to change the orientation of the
192 // display after having locked rotation.
193 TEST_F(ScreenOrientationControllerTest
, OrientationChanges
) {
194 scoped_ptr
<content::WebContents
> content(CreateWebContents());
195 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
196 ASSERT_NE(nullptr, content
->GetNativeView());
197 ASSERT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
198 ASSERT_FALSE(RotationLocked());
200 AttachAndActivateWebContents(content
.get(), focus_window
.get());
201 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockPortrait
);
202 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
203 EXPECT_TRUE(RotationLocked());
205 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
206 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
209 // Tests that orientation can only be set by the first content::WebContents that
210 // has set a rotation lock.
211 TEST_F(ScreenOrientationControllerTest
, SecondContentCannotChangeOrientation
) {
212 scoped_ptr
<content::WebContents
> content1(CreateWebContents());
213 scoped_ptr
<content::WebContents
> content2(CreateSecondaryWebContents());
214 scoped_ptr
<aura::Window
> focus_window1(CreateTestWindowInShellWithId(0));
215 scoped_ptr
<aura::Window
> focus_window2(CreateTestWindowInShellWithId(1));
216 ASSERT_NE(content1
->GetNativeView(), content2
->GetNativeView());
218 AttachAndActivateWebContents(content1
.get(), focus_window1
.get());
219 AttachWebContents(content2
.get(), focus_window2
.get());
220 delegate()->Lock(content1
.get(), blink::WebScreenOrientationLockLandscape
);
221 delegate()->Lock(content2
.get(), blink::WebScreenOrientationLockPortrait
);
222 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
225 // Tests that only the content::WebContents that set a rotation lock can perform
227 TEST_F(ScreenOrientationControllerTest
, SecondContentCannotUnlock
) {
228 scoped_ptr
<content::WebContents
> content1(CreateWebContents());
229 scoped_ptr
<content::WebContents
> content2(CreateSecondaryWebContents());
230 scoped_ptr
<aura::Window
> focus_window1(CreateTestWindowInShellWithId(0));
231 scoped_ptr
<aura::Window
> focus_window2(CreateTestWindowInShellWithId(1));
232 ASSERT_NE(content1
->GetNativeView(), content2
->GetNativeView());
234 AttachAndActivateWebContents(content1
.get(), focus_window1
.get());
235 AttachWebContents(content2
.get(), focus_window2
.get());
236 delegate()->Lock(content1
.get(), blink::WebScreenOrientationLockLandscape
);
237 delegate()->Unlock(content2
.get());
238 EXPECT_TRUE(RotationLocked());
241 // Tests that a rotation lock is applied only while the content::WebContents are
242 // a part of the active window.
243 TEST_F(ScreenOrientationControllerTest
, ActiveWindowChangesUpdateLock
) {
244 scoped_ptr
<content::WebContents
> content(CreateWebContents());
245 scoped_ptr
<aura::Window
> focus_window1(CreateTestWindowInShellWithId(0));
246 scoped_ptr
<aura::Window
> focus_window2(CreateTestWindowInShellWithId(1));
248 AttachAndActivateWebContents(content
.get(), focus_window1
.get());
249 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
250 ASSERT_TRUE(RotationLocked());
252 aura::client::ActivationClient
* activation_client
=
253 Shell::GetInstance()->activation_client();
254 activation_client
->ActivateWindow(focus_window2
.get());
255 EXPECT_FALSE(RotationLocked());
257 activation_client
->ActivateWindow(focus_window1
.get());
258 EXPECT_TRUE(RotationLocked());
261 // Tests that switching between windows with different orientation locks change
263 TEST_F(ScreenOrientationControllerTest
, ActiveWindowChangesUpdateOrientation
) {
264 scoped_ptr
<content::WebContents
> content1(CreateWebContents());
265 scoped_ptr
<content::WebContents
> content2(CreateSecondaryWebContents());
266 scoped_ptr
<aura::Window
> focus_window1(CreateTestWindowInShellWithId(0));
267 scoped_ptr
<aura::Window
> focus_window2(CreateTestWindowInShellWithId(1));
268 AttachAndActivateWebContents(content1
.get(), focus_window1
.get());
269 AttachWebContents(content2
.get(), focus_window2
.get());
271 delegate()->Lock(content1
.get(), blink::WebScreenOrientationLockLandscape
);
272 delegate()->Lock(content2
.get(), blink::WebScreenOrientationLockPortrait
);
273 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
275 aura::client::ActivationClient
* activation_client
=
276 Shell::GetInstance()->activation_client();
277 activation_client
->ActivateWindow(focus_window2
.get());
278 EXPECT_TRUE(RotationLocked());
279 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
281 activation_client
->ActivateWindow(focus_window1
.get());
282 EXPECT_TRUE(RotationLocked());
283 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
286 // Tests that a rotation lock is removed when the setting window is hidden, and
287 // that it is reapplied when the window becomes visible.
288 TEST_F(ScreenOrientationControllerTest
, VisibilityChangesLock
) {
289 scoped_ptr
<content::WebContents
> content(CreateWebContents());
290 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
291 AttachAndActivateWebContents(content
.get(), focus_window
.get());
292 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
293 EXPECT_TRUE(RotationLocked());
295 aura::Window
* window
= content
->GetNativeView();
297 EXPECT_FALSE(RotationLocked());
300 EXPECT_TRUE(RotationLocked());
303 // Tests that when a window is destroyed that its rotation lock is removed, and
304 // window activations no longer change the lock
305 TEST_F(ScreenOrientationControllerTest
, WindowDestructionRemovesLock
) {
306 scoped_ptr
<content::WebContents
> content(CreateWebContents());
307 scoped_ptr
<aura::Window
> focus_window1(CreateTestWindowInShellWithId(0));
308 scoped_ptr
<aura::Window
> focus_window2(CreateTestWindowInShellWithId(1));
310 AttachAndActivateWebContents(content
.get(), focus_window1
.get());
311 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
312 ASSERT_TRUE(RotationLocked());
314 focus_window1
->RemoveChild(content
->GetNativeView());
316 EXPECT_FALSE(RotationLocked());
318 aura::client::ActivationClient
* activation_client
=
319 Shell::GetInstance()->activation_client();
320 activation_client
->ActivateWindow(focus_window2
.get());
321 EXPECT_FALSE(RotationLocked());
323 activation_client
->ActivateWindow(focus_window1
.get());
324 EXPECT_FALSE(RotationLocked());
327 // Tests that accelerometer readings in each of the screen angles will trigger a
328 // rotation of the internal display.
329 TEST_F(ScreenOrientationControllerTest
, DisplayRotation
) {
330 EnableMaximizeMode(true);
331 // Now test rotating in all directions.
332 TriggerLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
333 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
334 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
335 EXPECT_EQ(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
336 TriggerLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
337 EXPECT_EQ(gfx::Display::ROTATE_270
, GetCurrentInternalDisplayRotation());
338 TriggerLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
339 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
342 // Tests that low angles are ignored by the accelerometer (i.e. when the device
343 // is almost laying flat).
344 TEST_F(ScreenOrientationControllerTest
, RotationIgnoresLowAngles
) {
345 EnableMaximizeMode(true);
346 TriggerLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, -kMeanGravity
));
347 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
348 TriggerLidUpdate(gfx::Vector3dF(-2.0f
, 0.0f
, -kMeanGravity
));
349 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
350 TriggerLidUpdate(gfx::Vector3dF(0.0f
, 2.0f
, -kMeanGravity
));
351 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
352 TriggerLidUpdate(gfx::Vector3dF(2.0f
, 0.0f
, -kMeanGravity
));
353 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
354 TriggerLidUpdate(gfx::Vector3dF(0.0f
, -2.0f
, -kMeanGravity
));
355 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
358 // Tests that the display will stick to the current orientation beyond the
359 // halfway point, preventing frequent updates back and forth.
360 TEST_F(ScreenOrientationControllerTest
, RotationSticky
) {
361 EnableMaximizeMode(true);
362 gfx::Vector3dF
gravity(0.0f
, -kMeanGravity
, 0.0f
);
363 TriggerLidUpdate(gravity
);
364 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
366 // Turn past half-way point to next direction and rotation should remain
368 float degrees
= 50.0;
369 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
370 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
371 TriggerLidUpdate(gravity
);
372 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
374 // Turn more and the screen should rotate.
376 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
377 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
378 TriggerLidUpdate(gravity
);
379 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
381 // Turn back just beyond the half-way point and the new rotation should
382 // still be in effect.
384 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
385 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
386 TriggerLidUpdate(gravity
);
387 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
390 // Tests that the display will stick to its current orientation when the
391 // rotation lock has been set.
392 TEST_F(ScreenOrientationControllerTest
, RotationLockPreventsRotation
) {
393 EnableMaximizeMode(true);
394 SetRotationLocked(true);
396 // Turn past the threshold for rotation.
397 float degrees
= 90.0;
398 gfx::Vector3dF
gravity(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
,
399 -cos(degrees
* kDegreesToRadians
) * kMeanGravity
,
401 TriggerLidUpdate(gravity
);
402 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
404 SetRotationLocked(false);
405 TriggerLidUpdate(gravity
);
406 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
409 // The TrayDisplay class that is responsible for adding/updating MessageCenter
410 // notifications is only added to the SystemTray on ChromeOS.
411 // Tests that the screen rotation notifications are suppressed when
412 // triggered by the accelerometer.
413 TEST_F(ScreenOrientationControllerTest
, BlockRotationNotifications
) {
414 EnableMaximizeMode(true);
415 test::TestSystemTrayDelegate
* tray_delegate
=
416 static_cast<test::TestSystemTrayDelegate
*>(
417 Shell::GetInstance()->system_tray_delegate());
418 tray_delegate
->set_should_show_display_notification(true);
420 message_center::MessageCenter
* message_center
=
421 message_center::MessageCenter::Get();
423 EXPECT_EQ(0u, message_center
->NotificationCount());
424 EXPECT_FALSE(message_center
->HasPopupNotifications());
426 // Make sure notifications are still displayed when
427 // adjusting the screen rotation directly when in maximize mode
428 ASSERT_NE(gfx::Display::ROTATE_270
, GetCurrentInternalDisplayRotation());
429 SetInternalDisplayRotation(gfx::Display::ROTATE_270
);
430 SetRotationLocked(false);
431 EXPECT_EQ(gfx::Display::ROTATE_270
, GetCurrentInternalDisplayRotation());
432 EXPECT_EQ(1u, message_center
->NotificationCount());
433 EXPECT_TRUE(message_center
->HasPopupNotifications());
435 // Clear all notifications
436 message_center
->RemoveAllNotifications(false);
437 EXPECT_EQ(0u, message_center
->NotificationCount());
438 EXPECT_FALSE(message_center
->HasPopupNotifications());
440 // Make sure notifications are blocked when adjusting the screen rotation
441 // via the accelerometer while in maximize mode
442 // Rotate the screen 90 degrees
443 ASSERT_NE(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
444 TriggerLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
445 ASSERT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
446 EXPECT_EQ(0u, message_center
->NotificationCount());
447 EXPECT_FALSE(message_center
->HasPopupNotifications());
449 // Make sure notifications are still displayed when
450 // adjusting the screen rotation directly when not in maximize mode
451 EnableMaximizeMode(false);
452 // Reset the screen rotation.
453 SetInternalDisplayRotation(gfx::Display::ROTATE_0
);
454 // Clear all notifications
455 message_center
->RemoveAllNotifications(false);
456 ASSERT_NE(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
457 ASSERT_EQ(0u, message_center
->NotificationCount());
458 ASSERT_FALSE(message_center
->HasPopupNotifications());
459 SetInternalDisplayRotation(gfx::Display::ROTATE_180
);
460 EXPECT_EQ(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
461 EXPECT_EQ(1u, message_center
->NotificationCount());
462 EXPECT_TRUE(message_center
->HasPopupNotifications());
465 // Tests that if a user has set a display rotation that it is restored upon
466 // exiting maximize mode.
467 TEST_F(ScreenOrientationControllerTest
, ResetUserRotationUponExit
) {
468 SetInternalDisplayRotation(gfx::Display::ROTATE_90
);
469 EnableMaximizeMode(true);
471 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
472 EXPECT_EQ(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
474 EnableMaximizeMode(false);
475 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
478 // Tests that if a user sets a display rotation that accelerometer rotation
480 TEST_F(ScreenOrientationControllerTest
,
481 NonAccelerometerRotationChangesLockRotation
) {
482 EnableMaximizeMode(true);
483 ASSERT_FALSE(RotationLocked());
484 SetInternalDisplayRotation(gfx::Display::ROTATE_270
);
485 EXPECT_TRUE(RotationLocked());
488 // Tests that if a user changes the display rotation, while rotation is locked,
489 // that the updates are recorded. Upon exiting maximize mode the latest user
490 // rotation should be applied.
491 TEST_F(ScreenOrientationControllerTest
, UpdateUserRotationWhileRotationLocked
) {
492 EnableMaximizeMode(true);
493 SetInternalDisplayRotation(gfx::Display::ROTATE_270
);
494 // User sets rotation to the same rotation that the display was at when
495 // maximize mode was activated.
496 SetInternalDisplayRotation(gfx::Display::ROTATE_0
);
497 EnableMaximizeMode(false);
498 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
501 // Tests that when the orientation lock is set to Landscape, that rotation can
502 // be done between the two angles of the orientation.
503 TEST_F(ScreenOrientationControllerTest
, LandscapeOrientationAllowsRotation
) {
504 scoped_ptr
<content::WebContents
> content(CreateWebContents());
505 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
506 EnableMaximizeMode(true);
508 AttachAndActivateWebContents(content
.get(), focus_window
.get());
509 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
510 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
511 EXPECT_TRUE(RotationLocked());
513 // Inverse of orientation is allowed
514 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
515 EXPECT_EQ(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
517 // Display rotations between are not allowed
518 TriggerLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
519 EXPECT_EQ(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
520 TriggerLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
521 EXPECT_EQ(gfx::Display::ROTATE_180
, GetCurrentInternalDisplayRotation());
524 // Tests that when the orientation lock is set to Portrait, that rotaiton can be
525 // done between the two angles of the orientation.
526 TEST_F(ScreenOrientationControllerTest
, PortraitOrientationAllowsRotation
) {
527 scoped_ptr
<content::WebContents
> content(CreateWebContents());
528 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
529 EnableMaximizeMode(true);
531 AttachAndActivateWebContents(content
.get(), focus_window
.get());
532 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockPortrait
);
533 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
534 EXPECT_TRUE(RotationLocked());
536 // Inverse of orientation is allowed
537 TriggerLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
538 EXPECT_EQ(gfx::Display::ROTATE_270
, GetCurrentInternalDisplayRotation());
540 // Display rotations between are not allowed
541 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
542 EXPECT_EQ(gfx::Display::ROTATE_270
, GetCurrentInternalDisplayRotation());
543 TriggerLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
544 EXPECT_EQ(gfx::Display::ROTATE_270
, GetCurrentInternalDisplayRotation());
547 // Tests that for an orientation lock which does not allow rotation, that the
548 // display rotation remains constant.
549 TEST_F(ScreenOrientationControllerTest
, OrientationLockDisallowsRotation
) {
550 scoped_ptr
<content::WebContents
> content(CreateWebContents());
551 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
552 EnableMaximizeMode(true);
554 AttachAndActivateWebContents(content
.get(), focus_window
.get());
555 delegate()->Lock(content
.get(),
556 blink::WebScreenOrientationLockPortraitPrimary
);
557 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
558 EXPECT_TRUE(RotationLocked());
560 // Rotation does not change.
561 TriggerLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
562 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
563 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
564 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
565 TriggerLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
566 EXPECT_EQ(gfx::Display::ROTATE_90
, GetCurrentInternalDisplayRotation());
569 // Tests that after a content::WebContents has applied an orientation lock which
570 // supports rotation, that a user rotation lock does not allow rotation.
571 TEST_F(ScreenOrientationControllerTest
, UserRotationLockDisallowsRotation
) {
572 scoped_ptr
<content::WebContents
> content(CreateWebContents());
573 scoped_ptr
<aura::Window
> focus_window(CreateTestWindowInShellWithId(0));
574 EnableMaximizeMode(true);
576 AttachAndActivateWebContents(content
.get(), focus_window
.get());
577 delegate()->Lock(content
.get(), blink::WebScreenOrientationLockLandscape
);
578 delegate()->Unlock(content
.get());
580 SetRotationLocked(true);
581 EXPECT_TRUE(RotationLocked());
582 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
584 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
585 EXPECT_EQ(gfx::Display::ROTATE_0
, GetCurrentInternalDisplayRotation());
588 // Tests that when MaximizeMode is triggered before the internal display is
589 // ready, that ScreenOrientationController still begins listening to events,
590 // which require an internal display to be acted upon.
591 TEST_F(ScreenOrientationControllerTest
, InternalDisplayNotAvailableAtStartup
) {
592 int64 internal_display_id
= gfx::Display::InternalDisplayId();
593 gfx::Display::SetInternalDisplayId(gfx::Display::kInvalidDisplayID
);
595 EnableMaximizeMode(true);
597 // Should not crash, even thought there is no internal display.
598 SetInternalDisplayRotation(gfx::Display::ROTATE_180
);
599 EXPECT_FALSE(RotationLocked());
601 // With an internal display now available, functionality should resume.
602 gfx::Display::SetInternalDisplayId(internal_display_id
);
603 SetInternalDisplayRotation(gfx::Display::ROTATE_90
);
604 EXPECT_TRUE(RotationLocked());
607 // Verifies rotating an inactive Display is sucessful.
608 TEST_F(ScreenOrientationControllerTest
, RotateInactiveDisplay
) {
609 const int64 kInternalDisplayId
= 9;
610 const int64 kExternalDisplayId
= 10;
611 const gfx::Display::Rotation kNewRotation
= gfx::Display::ROTATE_180
;
613 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
615 const DisplayInfo internal_display_info
=
616 CreateDisplayInfo(kInternalDisplayId
, gfx::Rect(0, 0, 500, 500));
617 const DisplayInfo external_display_info
=
618 CreateDisplayInfo(kExternalDisplayId
, gfx::Rect(1, 1, 500, 500));
620 std::vector
<DisplayInfo
> display_info_list_two_active
;
621 display_info_list_two_active
.push_back(internal_display_info
);
622 display_info_list_two_active
.push_back(external_display_info
);
624 std::vector
<DisplayInfo
> display_info_list_one_active
;
625 display_info_list_one_active
.push_back(external_display_info
);
627 // The DisplayInfo list with two active displays needs to be added first so
628 // that the DisplayManager can track the |internal_display_info| as inactive
629 // instead of non-existent.
630 ash::Shell::GetInstance()->display_manager()->UpdateDisplays(
631 display_info_list_two_active
);
632 ash::Shell::GetInstance()->display_manager()->UpdateDisplays(
633 display_info_list_one_active
);
635 test::DisplayManagerTestApi(display_manager
)
636 .SetInternalDisplayId(kInternalDisplayId
);
638 ASSERT_NE(kNewRotation
, display_manager
->GetDisplayInfo(kInternalDisplayId
)
639 .GetActiveRotation());
641 delegate()->SetDisplayRotation(kNewRotation
,
642 gfx::Display::ROTATION_SOURCE_ACTIVE
);
644 // TODO(bruthig): Uncomment when www.crbug.com/480703 is fixed. This test
645 // still adds value by ensuring a crash does not occur. See
646 // www.crbug.com/479503.
647 // ASSERT_EQ(kNewRotation, display_manager->GetDisplayInfo(kInternalDisplayId)
648 // .GetActiveRotation());