Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2175)

Unified Diff: ash/display/display_manager.cc

Issue 196413017: Auto rotate on lid rotation changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Stick to current rotation and add tests. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/display/display_manager.cc
diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc
index fb4bd6eeb46e7be72f7b24226e2582cddc5da607..6fd818a5eb0f7c4878251c742ac3af3c47645b4b 100644
--- a/ash/display/display_manager.cc
+++ b/ash/display/display_manager.cc
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "ash/accelerometer/accelerometer_controller.h"
#include "ash/ash_switches.h"
#include "ash/display/display_layout_store.h"
#include "ash/display/screen_ash.h"
@@ -28,6 +29,7 @@
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/vector3d_f.h"
#if defined(USE_X11)
#include "ui/base/x/x11_util.h"
@@ -66,6 +68,10 @@ const float kUIScalesFor2x[] =
const float kUIScalesFor1280[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f };
const float kUIScalesFor1366[] = {0.5f, 0.6f, 0.75f, 1.0f, 1.125f };
+// The angle which the screen has to be rotated past before the display will
+// rotate to match it (i.e. 45.0f is no stickiness).
+const float kDisplayRotationStickyAngleDegrees = 60.0f;
+
struct DisplaySortFunctor {
bool operator()(const gfx::Display& a, const gfx::Display& b) {
return a.id() < b.id();
@@ -969,6 +975,62 @@ void DisplayManager::CreateScreenForShutdown() const {
}
}
+void DisplayManager::OnAccelerometerUpdated(const gfx::Vector3dF& base,
+ const gfx::Vector3dF& lid) {
+ gfx::Vector3dF lid_flattened(lid.x(), lid.y(), 0.0f);
+ float lid_flattened_length = lid_flattened.Length();
+ // When the lid is close to being flat, don't change rotation as it is too
+ // sensitive to slight movements.
+ if (lid_flattened_length < 0.3)
+ return;
+
+ // The reference vector is the angle of gravity when the device is rotated
+ // clockwise by 45 degrees. Computing the angle between this vector and
+ // gravity we can easily determine the expected display rotation.
+ gfx::Vector3dF reference(-1.0f, 1.0f, 0.0f);
+
+ // Set the down vector to match the expected direction of gravity given the
+ // last configured rotation. This is used to enforce a stickiness that the
+ // user must overcome to rotate the display and prevents frequent rotations
+ // when holding the device near 45 degrees.
+ gfx::Display::Rotation current_rotation =
+ GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
+ gfx::Vector3dF down(0.0f, 0.0f, 0.0f);
+ if (current_rotation == gfx::Display::ROTATE_0)
+ down.set_x(-1.0f);
+ else if (current_rotation == gfx::Display::ROTATE_90)
+ down.set_y(1.0f);
+ else if (current_rotation == gfx::Display::ROTATE_180)
+ down.set_x(1.0f);
+ else
+ down.set_y(-1.0f);
+
+ // Don't rotate if the screen has not passed the threshold.
+ float sticky_angle = acos(gfx::DotProduct(down, lid_flattened) /
+ down.Length() / lid_flattened_length) * 180.0 / 3.1415965;
+ if (sticky_angle < kDisplayRotationStickyAngleDegrees)
+ return;
+
+ float angle = acos(gfx::DotProduct(reference, lid_flattened) /
+ reference.Length() / lid_flattened_length) * 180.0 / 3.1415965;
+
+ gfx::Vector3dF cross(reference);
+ cross.Cross(lid);
+ float sign = gfx::DotProduct(cross, gfx::Vector3dF(0.0f, 0.0f, 1.0f));
+ if (sign < 0.0f)
+ angle = 360.0f - angle;
+
+ gfx::Display::Rotation new_rotation = gfx::Display::ROTATE_90;
+ if (angle < 90.0f)
+ new_rotation = gfx::Display::ROTATE_0;
+ else if (angle < 180.0f)
+ new_rotation = gfx::Display::ROTATE_270;
+ else if (angle < 270.0f)
+ new_rotation = gfx::Display::ROTATE_180;
+
+ SetDisplayRotation(gfx::Display::InternalDisplayId(), new_rotation);
+}
+
gfx::Display* DisplayManager::FindDisplayForId(int64 id) {
for (DisplayList::iterator iter = displays_.begin();
iter != displays_.end(); ++iter) {

Powered by Google App Engine
This is Rietveld 408576698