orientation: Correct handling of orientation on threshold

The old code gave a priority to portrait orientation, so that if
rotation reached the portrait threshold, it switched straight away.

This is problematic if the device you're dealing with isn't a mostly
portrait phone, but a tablet that can be used in both orientations
equally.

Landscape thresholds and portrait thresholds can (and they do) overlap.
In the overlapping area we should try to keep the previous orientation
until that threshold has passed.

[Bastien Nocera: Added test change]
This commit is contained in:
Nikita Malyavin
2019-08-10 03:51:21 +10:00
committed by hadess
parent 1400548215
commit bb5fbcc2f9
2 changed files with 17 additions and 13 deletions

View File

@@ -65,38 +65,42 @@ orientation_calc (OrientationUp prev,
int in_x, int in_y, int in_z, int in_x, int in_y, int in_z,
gdouble scale) gdouble scale)
{ {
int rotation;
OrientationUp ret = prev; OrientationUp ret = prev;
int x, y, z; int x, y, z;
int portrait_rotation;
int landscape_rotation;
/* this code expects 1G ~= 256 */ /* this code expects 1G ~= 256 */
x = SCALE(in_x); x = SCALE(in_x);
y = SCALE(in_y); y = SCALE(in_y);
z = SCALE(in_z); z = SCALE(in_z);
/* Portrait check */ portrait_rotation = round(atan2(x, sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES); landscape_rotation = round(atan2(y, sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
if (abs(rotation) > THRESHOLD_PORTRAIT) { /* Don't change orientation if we are on the common border of two thresholds */
ret = (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP; if (abs(portrait_rotation) > THRESHOLD_PORTRAIT && abs(landscape_rotation) > THRESHOLD_LANDSCAPE)
return prev;
/* Portrait check */
if (abs(portrait_rotation) > THRESHOLD_PORTRAIT) {
ret = (portrait_rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
/* Some threshold to switching between portrait modes */ /* Some threshold to switching between portrait modes */
if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) { if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
if (abs(rotation) < SAME_AXIS_LIMIT) { if (abs(portrait_rotation) < SAME_AXIS_LIMIT) {
ret = prev; ret = prev;
} }
} }
} else { } else {
/* Landscape check */ /* Landscape check */
rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES); if (abs(landscape_rotation) > THRESHOLD_LANDSCAPE) {
ret = (landscape_rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
if (abs(rotation) > THRESHOLD_LANDSCAPE) {
ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
/* Some threshold to switching between landscape modes */ /* Some threshold to switching between landscape modes */
if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) { if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
if (abs(rotation) < SAME_AXIS_LIMIT) { if (abs(landscape_rotation) < SAME_AXIS_LIMIT) {
ret = prev; ret = prev;
} }
} }

View File

@@ -68,9 +68,9 @@ test_orientation_threshold (void)
OrientationUp expected; OrientationUp expected;
} orientations[] = { } orientations[] = {
{ 0, -ONEG, 0, ORIENTATION_NORMAL }, { 0, -ONEG, 0, ORIENTATION_NORMAL },
{ 183, -ONEG, 0, ORIENTATION_LEFT_UP }, { 183, -ONEG, 0, ORIENTATION_NORMAL },
{ 176, -ONEG, 0, ORIENTATION_NORMAL }, { 176, -ONEG, 0, ORIENTATION_NORMAL },
{ 183, -ONEG, 0, ORIENTATION_LEFT_UP }, { 183, -ONEG, 0, ORIENTATION_NORMAL },
}; };
guint i, num_failures; guint i, num_failures;
OrientationUp prev; OrientationUp prev;