aboutsummaryrefslogtreecommitdiffstats
path: root/community/mce/0002-tilt-to-wake-Wake-screen-when-wrist-gesture-arrives.patch
diff options
context:
space:
mode:
Diffstat (limited to 'community/mce/0002-tilt-to-wake-Wake-screen-when-wrist-gesture-arrives.patch')
-rw-r--r--community/mce/0002-tilt-to-wake-Wake-screen-when-wrist-gesture-arrives.patch592
1 files changed, 592 insertions, 0 deletions
diff --git a/community/mce/0002-tilt-to-wake-Wake-screen-when-wrist-gesture-arrives.patch b/community/mce/0002-tilt-to-wake-Wake-screen-when-wrist-gesture-arrives.patch
new file mode 100644
index 00000000000..09eee154a4e
--- /dev/null
+++ b/community/mce/0002-tilt-to-wake-Wake-screen-when-wrist-gesture-arrives.patch
@@ -0,0 +1,592 @@
+From f37925316e80f8b9765e51909bce21eba1843c0d Mon Sep 17 00:00:00 2001
+From: MagneFire <IDaNLContact@gmail.com>
+Date: Sun, 7 Mar 2021 21:44:09 +0100
+Subject: [PATCH] tilt-to-wake: Wake screen when wrist gesture arrives.
+
+---
+ builtin-gconf.c | 10 ++
+ datapipe.c | 4 +
+ datapipe.h | 1 +
+ evdev.h | 1 +
+ mce-sensorfw.c | 206 ++++++++++++++++++++++++++++++++++++++
+ mce-sensorfw.h | 4 +
+ modules/display.h | 8 ++
+ modules/sensor-gestures.c | 25 +++++
+ tests/ut/ut_display.c | 5 +
+ tools/mcetool.c | 32 ++++++
+ 10 files changed, 296 insertions(+)
+
+diff --git a/builtin-gconf.c b/builtin-gconf.c
+index 5517292..b04689c 100644
+--- a/builtin-gconf.c
++++ b/builtin-gconf.c
+@@ -1265,6 +1265,16 @@ static const setting_t gconf_defaults[] =
+ .type = "b",
+ .def = G_STRINGIFY(MCE_DEFAULT_FLIPOVER_GESTURE_ENABLED),
+ },
++ {
++ .key = MCE_SETTING_WRIST_GESTURE_ENABLED,
++ .type = "b",
++ .def = G_STRINGIFY(MCE_DEFAULT_WRIST_GESTURE_ENABLED),
++ },
++ {
++ .key = MCE_SETTING_WRIST_GESTURE_AVAILABLE,
++ .type = "i",
++ .def = G_STRINGIFY(MCE_DEFAULT_WRIST_GESTURE_AVAILABLE),
++ },
+ {
+ .key = MCE_SETTING_ORIENTATION_CHANGE_IS_ACTIVITY,
+ .type = "b",
+diff --git a/datapipe.c b/datapipe.c
+index 8daee62..89c550d 100644
+--- a/datapipe.c
++++ b/datapipe.c
+@@ -700,6 +700,9 @@ datapipe_t proximity_sensor_required_pipe = DATAPIPE_INIT(proximity_sensor
+ /** proximity blanking; read only */
+ datapipe_t proximity_blanked_pipe = DATAPIPE_INIT(proximity_blanked, boolean, false, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);
+
++/** wrist gesture; read only */
++datapipe_t wristgesture_sensor_pipe = DATAPIPE_INIT(wristgesture_sensor, boolean, false, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);
++
+ /** Ambient light sensor; read only */
+ datapipe_t light_sensor_actual_pipe = DATAPIPE_INIT(light_sensor_actual, int, 400, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);
+
+@@ -1346,6 +1349,7 @@ void mce_datapipe_quit(void)
+ datapipe_free(&proximity_sensor_effective_pipe);
+ datapipe_free(&proximity_sensor_required_pipe);
+ datapipe_free(&proximity_blanked_pipe);
++ datapipe_free(&wristgesture_sensor_pipe);
+ datapipe_free(&light_sensor_actual_pipe);
+ datapipe_free(&light_sensor_filtered_pipe);
+ datapipe_free(&light_sensor_poll_request_pipe);
+diff --git a/datapipe.h b/datapipe.h
+index 780881f..f5827a3 100644
+--- a/datapipe.h
++++ b/datapipe.h
+@@ -243,6 +243,7 @@ extern datapipe_t proximity_sensor_actual_pipe;
+ extern datapipe_t proximity_sensor_effective_pipe;
+ extern datapipe_t proximity_sensor_required_pipe;
+ extern datapipe_t proximity_blanked_pipe;
++extern datapipe_t wristgesture_sensor_pipe;
+ extern datapipe_t light_sensor_actual_pipe;
+ extern datapipe_t light_sensor_filtered_pipe;
+ extern datapipe_t light_sensor_poll_request_pipe;
+diff --git a/evdev.h b/evdev.h
+index be89a42..e7faf7a 100644
+--- a/evdev.h
++++ b/evdev.h
+@@ -55,6 +55,7 @@ typedef enum {
+ GESTURE_SWIPE_FROM_BOTTOM = 3,
+ GESTURE_DOUBLETAP = 4, /* To conform with value used in
+ * Nokia N9 kernel driver */
++ GESTURE_TILT_TO_WAKE = 5,
+ GESTURE_FPWAKEUP = 16,
+
+ /* Modifiers */
+diff --git a/mce-sensorfw.c b/mce-sensorfw.c
+index c71e5f7..7c49104 100644
+--- a/mce-sensorfw.c
++++ b/mce-sensorfw.c
+@@ -30,6 +30,8 @@
+ #include "mce-log.h"
+ #include "mce-dbus.h"
+ #include "libwakelock.h"
++#include "evdev.h"
++#include "mce-setting.h"
+
+ #include <linux/input.h>
+
+@@ -195,6 +197,7 @@ typedef enum
+ SFW_SENSOR_ID_PS,
+ SFW_SENSOR_ID_ALS,
+ SFW_SENSOR_ID_ORIENT,
++ SFW_SENSOR_ID_WRIST,
+ SFW_SENSOR_ID_ACCELEROMETER,
+ SFW_SENSOR_ID_COMPASS,
+ SFW_SENSOR_ID_GYROSCOPE,
+@@ -218,6 +221,7 @@ sensor_id_available(sensor_id_t id)
+ case SFW_SENSOR_ID_PS:
+ case SFW_SENSOR_ID_ALS:
+ case SFW_SENSOR_ID_ORIENT:
++ case SFW_SENSOR_ID_WRIST:
+ break;
+ default:
+ available = mce_in_sensortest_mode();
+@@ -268,6 +272,7 @@ sensor_id_available(sensor_id_t id)
+ #define SFW_SENSOR_INTERFACE_PS "local.ProximitySensor"
+ #define SFW_SENSOR_INTERFACE_ALS "local.ALSSensor"
+ #define SFW_SENSOR_INTERFACE_ORIENT "local.OrientationSensor"
++#define SFW_SENSOR_INTERFACE_WRIST "local.WristGestureSensor"
+ #define SFW_SENSOR_INTERFACE_ACCELEROMETER "local.AccelerometerSensor"
+ #define SFW_SENSOR_INTERFACE_COMPASS "local.CompassSensor"
+ #define SFW_SENSOR_INTERFACE_GYROSCOPE "local.GyroscopeSensor"
+@@ -311,6 +316,7 @@ sensor_id_available(sensor_id_t id)
+ #define SFW_SENSOR_METHOD_READ_PS "proximity"
+ #define SFW_SENSOR_METHOD_READ_ALS "lux"
+ #define SFW_SENSOR_METHOD_READ_ORIENT "orientation"
++#define SFW_SENSOR_METHOD_READ_WRIST "wristgesture"
+ #define SFW_SENSOR_METHOD_READ_ACCELEROMETER "xyz"
+ #define SFW_SENSOR_METHOD_READ_COMPASS "value" // or "declinationvalue"?
+ #define SFW_SENSOR_METHOD_READ_GYROSCOPE "value"
+@@ -335,6 +341,7 @@ sensor_id_available(sensor_id_t id)
+ #define SFW_SENSOR_NAME_PS "proximitysensor"
+ #define SFW_SENSOR_NAME_ALS "alssensor"
+ #define SFW_SENSOR_NAME_ORIENT "orientationsensor"
++#define SFW_SENSOR_NAME_WRIST "wristgesturesensor"
+ #define SFW_SENSOR_NAME_ACCELEROMETER "accelerometersensor"
+ #define SFW_SENSOR_NAME_COMPASS "compasssensor"
+ #define SFW_SENSOR_NAME_GYROSCOPE "gyroscopesensor"
+@@ -348,6 +355,13 @@ sensor_id_available(sensor_id_t id)
+ #define SFW_SENSOR_NAME_TEMPERATURE "temperaturesensor"
+
+ // ----------------------------------------------------------------
++#ifndef MCE_SETTING_DISPLAY_PATH
++#define MCE_SETTING_DISPLAY_PATH "/system/osso/dsm/display"
++#endif
++
++#ifndef MCE_SETTING_WRIST_GESTURE_AVAILABLE
++#define MCE_SETTING_WRIST_GESTURE_AVAILABLE MCE_SETTING_DISPLAY_PATH "/wrist_sensor_available"
++#endif
+
+ /* ========================================================================= *
+ * FORWARD_DECLARATIONS
+@@ -365,6 +379,7 @@ typedef struct sfw_backend_t sfw_backend_t;
+ typedef struct sfw_sample_als_t sfw_sample_als_t;
+ typedef struct sfw_sample_ps_t sfw_sample_ps_t;
+ typedef struct sfw_sample_orient_t sfw_sample_orient_t;
++typedef struct sfw_sample_wrist_t sfw_sample_wrist_t;
+ typedef struct sfw_sample_accelerometer_t sfw_sample_accelerometer_t;
+ typedef struct sfw_sample_compass_t sfw_sample_compass_t;
+ typedef struct sfw_sample_gyroscope_t sfw_sample_gyroscope_t;
+@@ -400,6 +415,9 @@ typedef struct sfw_sample_temperature_t sfw_sample_temperature_t;
+ /** Ambient light level [lux] to use when sensor can't be enabled */
+ #define SFW_NOTIFY_DEFAULT_ALS 400
+
++#define SFW_NOTIFY_DEFAULT_WRIST false
++#define SFW_NOTIFY_EXCEPTION_WRIST false
++
+ /** Orientation state to use when sensor can't be enabled */
+ #define SFW_NOTIFY_DEFAULT_ORIENT MCE_ORIENTATION_UNDEFINED
+
+@@ -479,6 +497,16 @@ struct sfw_sample_orient_t
+
+ static const char *sfw_sample_orient_repr(const sfw_sample_orient_t *self);
+
++/** Wrist gesture data block as sensord sends them */
++struct sfw_sample_wrist_t
++{
++ /* microseconds, monotonic */
++ uint64_t wrist_timestamp;
++
++ /* wrist tilted [bool] */
++ uint8_t wrist_tilted;
++};
++
+ typedef enum sfw_lid_type_t
+ {
+ SFW_LID_TYPE_UNKNOWN = -1, // UnknownLid
+@@ -724,6 +752,7 @@ static bool sfw_backend_parse_data (DBusMessageIter *data, int arg_
+ static bool sfw_backend_als_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
+ static bool sfw_backend_ps_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
+ static bool sfw_backend_orient_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
++static bool sfw_backend_wrist_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
+ static bool sfw_backend_accelerometer_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
+ static bool sfw_backend_compass_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
+ static bool sfw_backend_gyroscope_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
+@@ -739,6 +768,7 @@ static bool sfw_backend_temperature_value_cb (sfw_plugin_t *plugin, DBusMessa
+ static void sfw_backend_als_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
+ static void sfw_backend_ps_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
+ static void sfw_backend_orient_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
++static void sfw_backend_wrist_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
+ static void sfw_backend_accelerometer_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
+ static void sfw_backend_compass_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
+ static void sfw_backend_gyroscope_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
+@@ -1209,6 +1239,8 @@ static void sfw_service_do_query (sfw_service_t *self);
+ static sfw_plugin_t *sfw_service_plugin (const sfw_service_t *self, sensor_id_t id);
+ static void sfw_service_set_sensor (const sfw_service_t *self, sensor_id_t id, bool enable);
+
++static void sfw_set_wrist_available (sfw_plugin_t * plugin);
++
+ /* ========================================================================= *
+ * SENSORFW_EXCEPTION
+ * ========================================================================= */
+@@ -1246,6 +1278,9 @@ static void (*sfw_notify_als_cb)(int lux) = 0;
+ /** Orientation change callback used for notifying upper level logic */
+ static void (*sfw_notify_orient_cb)(int state) = 0;
+
++/** Wrist gesture change callback used for notifying upper level logic */
++static void (*sfw_notify_wrist_cb)(int state) = 0;
++
+ // (exported API defined in "mce-sensorfw.h")
+
+ static gboolean mce_sensorfw_evdev_cb (GIOChannel *chn, GIOCondition cnd, gpointer aptr);
+@@ -1582,6 +1617,31 @@ EXIT:
+ return ack;
+ }
+
++static bool
++sfw_backend_wrist_value_cb(sfw_plugin_t *plugin, DBusMessageIter *data)
++{
++ bool ack = false;
++ dbus_uint64_t tck = 0;
++ dbus_uint32_t val = 0;
++
++ if( !sfw_backend_parse_data(data,
++ DBUS_TYPE_UINT64, &tck,
++ DBUS_TYPE_UINT32, &val,
++ DBUS_TYPE_INVALID) )
++ goto EXIT;
++
++ const sfw_sample_wrist_t sample = {
++ .wrist_timestamp = tck,
++ .wrist_tilted = (val < 1) ? true : false,
++ };
++
++ sfw_plugin_handle_sample(plugin, &sample);
++
++ ack = true;
++EXIT:
++ return ack;
++}
++
+ static bool
+ sfw_backend_accelerometer_value_cb(sfw_plugin_t *plugin, DBusMessageIter *data)
+ {
+@@ -2116,6 +2176,114 @@ sfw_backend_orient_sample_cb(sfw_plugin_t *plugin, sfw_notify_t type, const void
+ return;
+ }
+
++extern void evin_iomon_generate_activity (struct input_event *ev, bool cooked, bool raw);
++
++/** Callback for handling wrist events from sensord */
++static void
++sfw_backend_wrist_sample_cb(sfw_plugin_t *plugin, sfw_notify_t type, const void *sampledata)
++{
++ static const sfw_sample_wrist_t default_value = {
++ .wrist_tilted = SFW_NOTIFY_DEFAULT_WRIST,
++ };
++
++ static sfw_sample_wrist_t cached_value = {
++ .wrist_tilted = SFW_NOTIFY_DEFAULT_WRIST,
++ };
++
++ static bool tracking_active = false;
++
++ struct input_event *ev;
++
++ (void)plugin;
++ const sfw_sample_wrist_t *sample = sampledata;
++
++ if( sample ) {
++ mce_log(LL_DEBUG, "WRIST: UPDATE %s %s",
++ sfw_notify_name(type),
++ sample ? "tiled" : "untiled");
++ }
++
++ switch( type ) {
++ default:
++ case NOTIFY_REPEAT:
++ break;
++
++ case NOTIFY_FORGET:
++ case NOTIFY_RESET:
++ sfw_set_wrist_available(plugin);
++ tracking_active = false;
++ cached_value = default_value;
++ break;
++
++ case NOTIFY_RESTORE:
++ sfw_set_wrist_available(plugin);
++ tracking_active = true;
++ break;
++
++ case NOTIFY_EVDEV:
++ case NOTIFY_SENSORD:
++ sfw_set_wrist_available(plugin);
++ cached_value = *sample;
++ break;
++ }
++
++ /* Default value is used unless we are in fully working state */
++ sample = tracking_active ? &cached_value : &default_value ;
++
++ if( sfw_notify_wrist_cb ) {
++ mce_log(LL_DEBUG, "WRIST: NOTIFY %s %s",
++ sfw_notify_name(type),
++ sample ? "tiled" : "untiled");
++ sfw_notify_wrist_cb(sample->wrist_tilted);
++ }
++
++ ev = malloc(sizeof(struct input_event));
++
++ mce_log(LL_DEVEL, "tilt-to-wake gesture from wrist gesture");
++
++ ev->type = EV_MSC;
++ ev->code = MSC_GESTURE;
++ ev->value = GESTURE_TILT_TO_WAKE;
++
++ evin_iomon_generate_activity(ev, true, true);
++
++ submode_t submode = mce_get_submode_int32();
++
++ /* If the event eater is active, don't send anything */
++ if( submode & MCE_SUBMODE_EVEATER )
++ goto EXIT;
++
++ /* Gesture events count as actual non-synthetized
++ * user activity. */
++ evin_iomon_generate_activity(ev, false, true);
++
++ /* But otherwise are handled in powerkey.c. */
++ datapipe_exec_full(&keypress_event_pipe, &ev);
++EXIT:
++ return;
++}
++
++/** Set availability of wrist tilt sensor based on connection state.
++ */
++static void
++sfw_set_wrist_available(sfw_plugin_t *plugin)
++{
++ mce_log(LL_DEBUG, "WRIST: sfw_set_wrist_available: %d", plugin->plg_session->ses_state);
++ switch(plugin->plg_session->ses_state) {
++ case SESSION_INITIAL:
++ case SESSION_IDLE:
++ case SESSION_REQUESTING:
++ case SESSION_INVALID:
++ mce_setting_set_int(MCE_SETTING_WRIST_GESTURE_AVAILABLE, 0);
++ break;
++ case SESSION_ACTIVE:
++ /* Only when a session is active we know that the sensor can be enabled. */
++ mce_setting_set_int(MCE_SETTING_WRIST_GESTURE_AVAILABLE, 1);
++ case SESSION_ERROR:
++ break;
++ }
++}
++
+ /** Callback for handling accelerometer events from sensord */
+ static void
+ sfw_backend_accelerometer_sample_cb(sfw_plugin_t *plugin, sfw_notify_t type, const void *sampledata)
+@@ -2608,6 +2776,15 @@ static const sfw_backend_t sfw_backend_lut[SFW_SENSOR_ID_COUNT] =
+ .be_sample_cb = sfw_backend_orient_sample_cb,
+ .be_value_method = SFW_SENSOR_METHOD_READ_ORIENT,
+ },
++ [SFW_SENSOR_ID_WRIST] = {
++ .be_sensor_name = SFW_SENSOR_NAME_WRIST,
++ .be_sensor_object = 0,
++ .be_sensor_interface = SFW_SENSOR_INTERFACE_WRIST,
++ .be_sample_size = sizeof(sfw_sample_wrist_t),
++ .be_value_cb = sfw_backend_wrist_value_cb,
++ .be_sample_cb = sfw_backend_wrist_sample_cb,
++ .be_value_method = SFW_SENSOR_METHOD_READ_WRIST,
++ },
+ [SFW_SENSOR_ID_ACCELEROMETER] = {
+ .be_sensor_name = SFW_SENSOR_NAME_ACCELEROMETER,
+ .be_sensor_object = 0,
+@@ -5183,6 +5360,35 @@ mce_sensorfw_orient_disable(void)
+
+ // ----------------------------------------------------------------
+
++/** Set Wrist notification callback
++ *
++ * @param cb function to call when Orientation events are received
++ */
++void
++mce_sensorfw_wrist_set_notify(void (*cb)(int state))
++{
++ sfw_plugin_t *plugin = sfw_service_plugin(sfw_service, SFW_SENSOR_ID_WRIST);
++ sfw_plugin_repeat_value(plugin);
++}
++
++/** Try to enable Wrist input
++ */
++void
++mce_sensorfw_wrist_enable(void)
++{
++ sfw_service_set_sensor(sfw_service, SFW_SENSOR_ID_WRIST, true);
++}
++
++/** Try to disable Wrist input
++ */
++void
++mce_sensorfw_wrist_disable(void)
++{
++ sfw_service_set_sensor(sfw_service, SFW_SENSOR_ID_WRIST, false);
++}
++
++// ----------------------------------------------------------------
++
+ /** Callback function for processing evdev events
+ *
+ * @param chn io channel
+diff --git a/mce-sensorfw.h b/mce-sensorfw.h
+index cfd8d66..1daf3c0 100644
+--- a/mce-sensorfw.h
++++ b/mce-sensorfw.h
+@@ -50,6 +50,10 @@ void mce_sensorfw_orient_set_notify(void (*cb)(int state));
+ void mce_sensorfw_orient_enable(void);
+ void mce_sensorfw_orient_disable(void);
+
++void mce_sensorfw_wrist_set_notify(void (*cb)(int state));
++void mce_sensorfw_wrist_enable(void);
++void mce_sensorfw_wrist_disable(void);
++
+ # ifdef __cplusplus
+ };
+ # endif
+diff --git a/modules/display.h b/modules/display.h
+index bfb9d4d..8075401 100644
+--- a/modules/display.h
++++ b/modules/display.h
+@@ -186,6 +186,14 @@
+ # define MCE_SETTING_ORIENTATION_CHANGE_IS_ACTIVITY MCE_SETTING_DISPLAY_PATH "/orientation_change_is_activity"
+ # define MCE_DEFAULT_ORIENTATION_CHANGE_IS_ACTIVITY true
+
++/** Whether MCE is allowed to use wrist gesture sensor */
++# define MCE_SETTING_WRIST_GESTURE_ENABLED MCE_SETTING_DISPLAY_PATH "/wrist_sensor_enabled"
++# define MCE_DEFAULT_WRIST_GESTURE_ENABLED true
++
++/** Whether the wrist gesture sensor is available on the hardware */
++# define MCE_SETTING_WRIST_GESTURE_AVAILABLE MCE_SETTING_DISPLAY_PATH "/wrist_sensor_available"
++# define MCE_DEFAULT_WRIST_GESTURE_AVAILABLE 1
++
+ /* ------------------------------------------------------------------------- *
+ * Color profile related settings
+ * ------------------------------------------------------------------------- */
+diff --git a/modules/sensor-gestures.c b/modules/sensor-gestures.c
+index f648009..5d606eb 100644
+--- a/modules/sensor-gestures.c
++++ b/modules/sensor-gestures.c
+@@ -57,6 +57,9 @@ static gint orientation_sensor_effective_id = 0;
+ static gboolean sg_flipover_gesture_enabled = MCE_DEFAULT_FLIPOVER_GESTURE_ENABLED;
+ static guint sg_flipover_gesture_enabled_setting_id = 0;
+
++/** Use of wrist gesture enabled */
++static gboolean sg_wrist_gesture_enabled = MCE_DEFAULT_WRIST_GESTURE_ENABLED;
++static guint sg_wrist_gesture_enabled_setting_id = 0;
+ /* ========================================================================= *
+ * FUNCTIONS
+ * ========================================================================= */
+@@ -465,6 +468,15 @@ static void sg_setting_cb(GConfClient *const gcc, const guint id,
+ if( id == sg_flipover_gesture_enabled_setting_id ) {
+ sg_flipover_gesture_enabled = gconf_value_get_bool(gcv);
+ }
++ else if( id == sg_wrist_gesture_enabled_setting_id ) {
++ sg_wrist_gesture_enabled = gconf_value_get_bool(gcv);
++ mce_log(LL_CRIT, "sg_wrist_gesture_enabled: %d", sg_wrist_gesture_enabled);
++ if (sg_wrist_gesture_enabled) {
++ mce_sensorfw_wrist_enable();
++ } else {
++ mce_sensorfw_wrist_disable();
++ }
++ }
+ else {
+ mce_log(LL_WARN, "Spurious GConf value received; confused!");
+ }
+@@ -482,6 +494,11 @@ static void sg_setting_init(void)
+ MCE_DEFAULT_FLIPOVER_GESTURE_ENABLED,
+ sg_setting_cb,
+ &sg_flipover_gesture_enabled_setting_id);
++ mce_setting_track_bool(MCE_SETTING_WRIST_GESTURE_ENABLED,
++ &sg_wrist_gesture_enabled,
++ MCE_DEFAULT_WRIST_GESTURE_ENABLED,
++ sg_setting_cb,
++ &sg_wrist_gesture_enabled_setting_id);
+ }
+
+ /** Stop tracking setting changes */
+@@ -489,6 +506,8 @@ static void sg_setting_quit(void)
+ {
+ mce_setting_notifier_remove(sg_flipover_gesture_enabled_setting_id),
+ sg_flipover_gesture_enabled_setting_id = 0;
++ mce_setting_notifier_remove(sg_wrist_gesture_enabled_setting_id),
++ sg_wrist_gesture_enabled_setting_id = 0;
+ }
+
+ /* ========================================================================= *
+@@ -508,6 +527,12 @@ const gchar *g_module_check_init(GModule *module)
+ sg_setting_init();
+ sg_datapipe_init();
+
++ if (sg_wrist_gesture_enabled) {
++ mce_sensorfw_wrist_enable();
++ } else {
++ mce_sensorfw_wrist_disable();
++ }
++
+ return NULL;
+ }
+
+diff --git a/tests/ut/ut_display.c b/tests/ut/ut_display.c
+index 216b3d8..673d01c 100644
+--- a/tests/ut/ut_display.c
++++ b/tests/ut/ut_display.c
+@@ -821,6 +821,11 @@ void, mce_sensorfw_orient_set_notify, (void (*cb)(int state)))
+ (void)cb;
+ }
+
++EXTERN_STUB (
++void, mce_sensorfw_wrist_enable, (void))
++{
++}
++
+ /*
+ * tklock.c stubs {{{1
+ */
+diff --git a/tools/mcetool.c b/tools/mcetool.c
+index e067c43..f5d519d 100644
+--- a/tools/mcetool.c
++++ b/tools/mcetool.c
+@@ -4159,6 +4159,29 @@ static void xmce_get_orientation_change_is_activity(void)
+ printf("%-"PAD1"s %s\n", "Orientation change is activity:", txt);
+ }
+
++/** Set wrist gesture detection toggle
++ *
++ * @param args string suitable for interpreting as enabled/disabled
++ */
++static bool xmce_set_wrist_gesture_detection(const char *args)
++{
++ gboolean val = xmce_parse_enabled(args);
++ xmce_setting_set_bool(MCE_SETTING_WRIST_GESTURE_ENABLED, val);
++ return true;
++}
++
++/** Show wrist gesture detection toggle
++ */
++static void xmce_get_wrist_gesture_detection(void)
++{
++ gboolean val = 0;
++ char txt[32] = "unknown";
++
++ if( xmce_setting_get_bool(MCE_SETTING_WRIST_GESTURE_ENABLED, &val) )
++ snprintf(txt, sizeof txt, "%s", val ? "enabled" : "disabled");
++ printf("%-"PAD1"s %s\n", "Wrist tilt gesture detection:", txt);
++}
++
+ /** Set flipover gesture detection toggle
+ *
+ * @param args string suitable for interpreting as enabled/disabled
+@@ -6532,6 +6555,7 @@ static bool xmce_get_status(const char *args)
+ xmce_get_orientation_sensor_mode();
+ xmce_get_orientation_change_is_activity();
+ xmce_get_flipover_gesture_detection();
++ xmce_get_wrist_gesture_detection();
+ xmce_get_ps_mode();
+ xmce_get_ps_on_demand();
+ xmce_get_ps_uncover_delay();
+@@ -7542,6 +7566,14 @@ static const mce_opt_t options[] =
+ " 'enabled' flipover gestures can be used to silence calls/alarms\n"
+ " 'disabled' turning device over does not affect calls/alarms\n"
+ },
++ {
++ .name = "set-wrist-gesture-detection",
++ .with_arg = xmce_set_wrist_gesture_detection,
++ .values = "enabled|disabled",
++ "set the wrist gesture detection toggle; valid modes are:\n"
++ " 'enabled' flipover gestures can be used to silence calls/alarms\n"
++ " 'disabled' turning device over does not affect calls/alarms\n"
++ },
+ {
+ .name = "get-color-profile-ids",
+ .flag = 'a',