sensord: transpose acc/gyro axis w.r.t the display rotation 87/71087/1
authorkibak.yoon <kibak.yoon@samsung.com>
Tue, 24 May 2016 05:00:39 +0000 (14:00 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Tue, 24 May 2016 05:00:39 +0000 (14:00 +0900)
Change-Id: I23f81740000c13d377038b15b1904da642b4060e
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/client/client.cpp
src/client/dbus_listener.cpp [new file with mode: 0755]
src/client/dbus_listener.h [new file with mode: 0644]
src/client/sensor_event_listener.cpp
src/client/sensor_event_listener.h

index ae79346..b9b99c1 100644 (file)
@@ -30,6 +30,7 @@
 #include <sensor_info_manager.h>
 #include <vector>
 #include <algorithm>
+#include "dbus_listener.h"
 
 using std::vector;
 
@@ -636,6 +637,7 @@ API int sensord_connect(sensor_t sensor)
        }
 
        set_power_save_state_cb();
+       dbus_listener::init();
        return handle;
 }
 
diff --git a/src/client/dbus_listener.cpp b/src/client/dbus_listener.cpp
new file mode 100755 (executable)
index 0000000..7f96ef1
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <sensor_log.h>
+#include "sensor_event_listener.h"
+#include "dbus_listener.h"
+
+#define HANDLE_GERROR(Err) \
+       do { \
+               if ((Err)) { \
+                       _E("GError: %s", Err->message); \
+                       g_error_free(Err); \
+                       Err = NULL; \
+               } \
+       } while (0)
+
+#define ROTATION_DBUS_DEST             "org.tizen.system.coord"
+#define ROTATION_DBUS_OBJ_PATH "/Org/Tizen/System/Coord/Rotation"
+#define ROTATION_DBUS_IFACE            "org.tizen.system.coord.rotation"
+#define ROTATION_DBUS_SIGNAL   "Changed"
+#define ROTATION_DBUS_METHOD   "Degree"
+
+static void rotation_signal_cb(GDBusConnection *conn, const gchar *sender,
+               const gchar *obj_path, const gchar *iface, const gchar *signal_name,
+               GVariant *param, gpointer user_data)
+{
+       gint state;
+       g_variant_get(param, "(i)", &state);
+       sensor_event_listener::get_instance().set_display_rotation(state);
+}
+
+static void rotation_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+       GError *error = NULL;
+       GDBusConnection *conn = G_DBUS_CONNECTION(source_object);
+       GVariant *result = g_dbus_connection_call_finish(conn, res, &error);
+       HANDLE_GERROR(error);
+       ret_if(result == NULL);
+
+       gint state;
+       g_variant_get(result, "(i)", &state);
+       g_variant_unref(result);
+       sensor_event_listener::get_instance().set_display_rotation(state);
+}
+
+dbus_listener::dbus_listener()
+: m_connection(NULL)
+{
+#ifndef GLIB_VERSION_2_36
+       g_type_init();
+#endif
+}
+
+dbus_listener::~dbus_listener()
+{
+       disconnect();
+}
+
+void dbus_listener::init(void)
+{
+       static dbus_listener listener;
+       static bool done = false;
+       ret_if(done);
+       listener.connect();
+       done = true;
+}
+
+void dbus_listener::connect(void)
+{
+       GError *gerr = NULL;
+
+       gchar *addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr);
+       HANDLE_GERROR(gerr);
+       retm_if(addr == NULL, "Getting address failed");
+
+       g_dbus_connection_new_for_address(addr,
+                       (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
+                       NULL, NULL, on_connection_ready, this);
+       g_free(addr);
+}
+
+void dbus_listener::on_connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+       GError *gerr = NULL;
+       dbus_listener *listener = static_cast<dbus_listener*>(user_data);
+
+       GDBusConnection *conn = g_dbus_connection_new_finish(res, &gerr);
+       HANDLE_GERROR(gerr);
+
+       retm_if(conn == NULL, "Connection failed");
+       _D("Dbus connection established: %s", g_dbus_connection_get_unique_name(conn));
+
+       listener->m_connection = conn;
+       listener->get_current_state();
+       listener->subscribe();
+}
+
+void dbus_listener::disconnect(void)
+{
+       ret_if(!m_connection);
+       g_dbus_connection_close_sync(m_connection, NULL, NULL);
+       g_object_unref(m_connection);
+}
+
+void dbus_listener::subscribe(void)
+{
+       /* Diplay rotation */
+       g_dbus_connection_signal_subscribe(m_connection,
+                       ROTATION_DBUS_DEST, ROTATION_DBUS_IFACE, ROTATION_DBUS_SIGNAL, ROTATION_DBUS_OBJ_PATH,
+                       NULL, G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)rotation_signal_cb, NULL, NULL);
+}
+
+void dbus_listener::get_current_state(void)
+{
+       /* Display rotation */
+       g_dbus_connection_call(m_connection,
+                       ROTATION_DBUS_DEST, ROTATION_DBUS_OBJ_PATH, ROTATION_DBUS_IFACE, ROTATION_DBUS_METHOD,
+                       NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, (GAsyncReadyCallback)rotation_read_cb, NULL);
+}
diff --git a/src/client/dbus_listener.h b/src/client/dbus_listener.h
new file mode 100644 (file)
index 0000000..3d4a804
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _DBUS_LISTENER_H_
+#define _DBUS_LISTENER_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <cmutex.h>
+
+class dbus_listener {
+public:
+       static void init(void);
+
+private:
+       GDBusConnection *m_connection;
+
+       dbus_listener();
+       ~dbus_listener();
+
+       void connect(void);
+       void disconnect(void);
+
+       void subscribe(void);
+       void get_current_state(void);
+
+       static void on_connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data);
+};
+
+#endif /* _DBUS_LISTENER_H_ */
index 2dc8cd4..0215b29 100644 (file)
@@ -45,6 +45,7 @@ sensor_event_listener::sensor_event_listener()
 , m_thread_state(THREAD_STATE_TERMINATE)
 , m_hup_observer(NULL)
 , m_client_info(sensor_client_info::get_instance())
+, m_display_rotation(AUTO_ROTATION_DEGREE_UNKNOWN)
 {
 }
 
@@ -237,6 +238,36 @@ bool sensor_event_listener::is_valid_callback(client_callback_info *cb_info)
        return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
 }
 
+void sensor_event_listener::align_sensor_axis(sensor_t sensor, sensor_data_t *data)
+{
+       sensor_type_t type = sensor_to_sensor_info(sensor)->get_type();
+
+       if (type != ACCELEROMETER_SENSOR && type != GYROSCOPE_SENSOR && type != GRAVITY_SENSOR)
+               return;
+
+       float x, y;
+
+       switch (m_display_rotation) {
+       case AUTO_ROTATION_DEGREE_90:   /* Landscape Left */
+               x = -data->values[1];
+               y = data->values[0];
+               break;
+       case AUTO_ROTATION_DEGREE_180:  /* Portrait Bottom */
+               x = -data->values[0];
+               y = -data->values[1];
+               break;
+       case AUTO_ROTATION_DEGREE_270:  /* Landscape Right */
+               x = data->values[1];
+               y = -data->values[0];
+               break;
+       default:
+               return;
+       }
+
+       data->values[0] = x;
+       data->values[1] = y;
+}
+
 gboolean sensor_event_listener::callback_dispatcher(gpointer data)
 {
        client_callback_info *cb_info = (client_callback_info*) data;
@@ -452,3 +483,13 @@ bool sensor_event_listener::start_event_listener(void)
 
        return true;
 }
+
+void sensor_event_listener::set_display_rotation(int rt)
+{
+       _D("New display rotation: %d", rt);
+
+       if (rt < AUTO_ROTATION_DEGREE_0 || rt > AUTO_ROTATION_DEGREE_270)
+               return;
+
+       m_display_rotation = rt;
+}
index 1c94475..5bb92ab 100644 (file)
@@ -77,6 +77,8 @@ public:
        void clear(void);
 
        void set_hup_observer(hup_observer_t observer);
+       void set_display_rotation(int rt);
+
 private:
        enum thread_state {
                THREAD_STATE_START,
@@ -97,6 +99,9 @@ private:
 
        sensor_client_info &m_client_info;
 
+       /* WC1's rotation control */
+       int m_display_rotation;
+
        sensor_event_listener();
        ~sensor_event_listener();
 
@@ -121,6 +126,9 @@ private:
        static gboolean callback_dispatcher(gpointer data);
 
        void set_thread_state(thread_state state);
+
+       /* WC1's sensor axis alignment */
+       void align_sensor_axis(sensor_t sensor, sensor_data_t *data);
 };
 
 #endif /* _SENSOR_EVENT_LISTENER_H_ */