From 1b2ef3c89cd32df2515c27a8cf03709ae97262ed Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Tue, 24 May 2016 14:00:39 +0900 Subject: [PATCH] sensord: transpose acc/gyro axis w.r.t the display rotation Change-Id: I23f81740000c13d377038b15b1904da642b4060e Signed-off-by: kibak.yoon --- src/client/client.cpp | 2 + src/client/dbus_listener.cpp | 135 +++++++++++++++++++++++++++++++++++ src/client/dbus_listener.h | 46 ++++++++++++ src/client/sensor_event_listener.cpp | 41 +++++++++++ src/client/sensor_event_listener.h | 8 +++ 5 files changed, 232 insertions(+) create mode 100755 src/client/dbus_listener.cpp create mode 100644 src/client/dbus_listener.h diff --git a/src/client/client.cpp b/src/client/client.cpp index ae79346..b9b99c1 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -30,6 +30,7 @@ #include #include #include +#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 index 0000000..7f96ef1 --- /dev/null +++ b/src/client/dbus_listener.cpp @@ -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 +#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(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 index 0000000..3d4a804 --- /dev/null +++ b/src/client/dbus_listener.h @@ -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 +#include +#include + +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_ */ diff --git a/src/client/sensor_event_listener.cpp b/src/client/sensor_event_listener.cpp index 2dc8cd4..0215b29 100644 --- a/src/client/sensor_event_listener.cpp +++ b/src/client/sensor_event_listener.cpp @@ -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; +} diff --git a/src/client/sensor_event_listener.h b/src/client/sensor_event_listener.h index 1c94475..5bb92ab 100644 --- a/src/client/sensor_event_listener.h +++ b/src/client/sensor_event_listener.h @@ -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_ */ -- 2.7.4