aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2014-12-18 11:57:07 +0000
committerAlex Bennée <alex.bennee@linaro.org>2015-01-07 11:36:04 +0000
commit1aeb96f196116eae9d6ebe0f6ff71c31bda4b471 (patch)
tree4cf20f70ccfa7e31c9fd79b264278f6b757f1593
parentad32d88b0479c84ad4a66e23d481740471df351b (diff)
downloadqemu-android-1aeb96f196116eae9d6ebe0f6ff71c31bda4b471.tar.gz
ranchu: trigger rotation in goldfish_sensors on command
The original hw-sensors code miscalculated radians from degrees, which probably happened to work on the legacy emulator, but was giving some pretty strange values on the Android side. When fixing this, Android calculates almost clean 9/90/180/270 orientation value based on the below (slightly adjusted for time drift and low-pass filtering on the Android side). Also add support for all 4 rotation modes, which will be useful when emulating tablets in addition to phone UI models, where full rotation including 180 degress is supported. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> [CD: radians fix, 4 rotation modes] Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--hw/arm/ranchu.c2
-rw-r--r--hw/input/goldfish_sensors.c53
-rw-r--r--include/hw/input/goldfish_sensors.h23
3 files changed, 78 insertions, 0 deletions
diff --git a/hw/arm/ranchu.c b/hw/arm/ranchu.c
index 2901b3f8ad..4391a40b48 100644
--- a/hw/arm/ranchu.c
+++ b/hw/arm/ranchu.c
@@ -40,6 +40,7 @@
#include "monitor/monitor.h"
#include "hw/misc/android_pipe.h"
#include "hw/display/goldfish_fb.h"
+#include "hw/input/goldfish_sensors.h"
/* Maximum number of emulators that can run at once (affects how
* far through the TCP port space from 5554 we will scan to find
@@ -471,6 +472,7 @@ static int ranchu_rotation_state = 0; /* 0-3 */
static void android_console_rotate_screen(Monitor *mon, const QDict *qdict)
{
ranchu_rotation_state = ((ranchu_rotation_state + 1) % 4);
+ goldfish_sensors_set_rotation(ranchu_rotation_state);
/* The mapping between QEMU and Android's idea of rotation are
reversed */
switch (ranchu_rotation_state) {
diff --git a/hw/input/goldfish_sensors.c b/hw/input/goldfish_sensors.c
index f15e69cef2..ba09a9ff03 100644
--- a/hw/input/goldfish_sensors.c
+++ b/hw/input/goldfish_sensors.c
@@ -21,10 +21,12 @@
* GNU General Public License for more details.
*/
+#include <math.h>
#include "sysemu/char.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "trace.h"
+#include "hw/input/goldfish_sensors.h"
#include "hw/misc/android_pipe.h"
#include "hw/misc/android_qemud.h"
@@ -82,6 +84,57 @@ typedef struct SensorsPipe {
GString *recv_outstanding;
} SensorsPipe;
+#define RADIANS_PER_DEGREE (M_PI / 180.0)
+
+void goldfish_sensors_set_rotation(int rotation)
+{
+ /* The Android framework computes the orientation by looking at
+ * the accelerometer sensor (*not* the orientation sensor !)
+ *
+ * That's because the gravity is a constant 9.81 vector that
+ * can be determined quite easily.
+ *
+ * Also, for some reason, the framework code considers that the phone should
+ * be inclined by 30 degrees along the phone's X axis to be considered
+ * in its ideal "vertical" position.
+ *
+ * If the phone is completely vertical, rotating it will not do anything !
+ */
+ const double g = 9.81;
+ const double angle = 20.0;
+ const double cos_angle = cos(angle * RADIANS_PER_DEGREE);
+ const double sin_angle = sin(angle * RADIANS_PER_DEGREE);
+
+ switch (rotation) {
+ case 0:
+ /* Natural layout */
+ sensor_config.sensors.acceleration.x = 0.0;
+ sensor_config.sensors.acceleration.y = g*cos_angle;
+ sensor_config.sensors.acceleration.z = g*sin_angle;
+ break;
+ case 1:
+ /* Rotate 90 degrees clockwise */
+ sensor_config.sensors.acceleration.x = g*cos_angle;
+ sensor_config.sensors.acceleration.y = 0.0;
+ sensor_config.sensors.acceleration.z = g*sin_angle;
+ break;
+ case 2:
+ /* Rotate 180 degrees clockwise */
+ sensor_config.sensors.acceleration.x = 0.0;
+ sensor_config.sensors.acceleration.y = -1.0 * g*cos_angle;
+ sensor_config.sensors.acceleration.z = g*sin_angle;
+ break;
+ case 3:
+ /* Rotate 270 degrees clockwise */
+ sensor_config.sensors.acceleration.x = -1.0 * g*cos_angle;
+ sensor_config.sensors.acceleration.y = 0.0;
+ sensor_config.sensors.acceleration.z = g*sin_angle;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
/* I'll just append to a GString holding our data here, which we
* truncate as we page back out....
diff --git a/include/hw/input/goldfish_sensors.h b/include/hw/input/goldfish_sensors.h
new file mode 100644
index 0000000000..e5f0257242
--- /dev/null
+++ b/include/hw/input/goldfish_sensors.h
@@ -0,0 +1,23 @@
+/*
+ * Goldfish Sensors public declarations.
+ *
+ * Copyright (C) 2014 Alex Bennée <alex.bennee@linaor.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef HW_INPUT_GOLDFISH_SENSORS_FB_H
+#define HW_INPUT_GOLDFISH_SENSORS_FB_H
+
+void goldfish_sensors_set_rotation(int rotation);
+
+#endif /* HW_INPUT_GOLDFISH_SENSORS_FB_H */