Skip to content

Commit

Permalink
[input] Add setting to allow/deny input device grabbing. JB#33644
Browse files Browse the repository at this point in the history
Grabbing touch input events is problematic - especially with devices
that use stateful protocol B for reporting. In general it would be better
to allow lipstick to see all the touch events but ignore them while
display is not in fully powered up state.

Add a setting that can be used to instruct mce not to grab touch input
device nodes. By default the grabbing is allowed.

Normally platform specific configuration files are expected to be used
when needed, but users can also tweak the setting via mcetool option
--set-input-grab-allowed.
  • Loading branch information
spiiroin committed Jan 7, 2016
1 parent 1837d95 commit 0fa2554
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .depend
Expand Up @@ -2,6 +2,7 @@ builtin-gconf.o:\
builtin-gconf.c\
builtin-gconf.h\
datapipe.h\
event-input.h\
mce-dbus.h\
mce-io.h\
mce-log.h\
Expand All @@ -17,6 +18,7 @@ builtin-gconf.pic.o:\
builtin-gconf.c\
builtin-gconf.h\
datapipe.h\
event-input.h\
mce-dbus.h\
mce-io.h\
mce-log.h\
Expand Down
6 changes: 6 additions & 0 deletions builtin-gconf.c
Expand Up @@ -24,6 +24,7 @@

#include "powerkey.h"
#include "tklock.h"
#include "event-input.h"

#include "modules/memnotify.h"
#include "modules/filter-brightness-als.h"
Expand Down Expand Up @@ -1441,6 +1442,11 @@ static const setting_t gconf_defaults[] =
.type = "i",
.def = "100",
},
{
.key = MCE_GCONF_INPUT_GRAB_ALLOWED,
.type = "i",
.def = G_STRINGIFY(DEFAULT_INPUT_GRAB_ALLOWED),
},
{
// MCE_LED_PATTERN_BATTERY_CHARGING @ mce.h
.key = "/system/osso/dsm/leds/PatternBatteryCharging",
Expand Down
122 changes: 120 additions & 2 deletions event-input.c
Expand Up @@ -342,6 +342,9 @@ struct evin_input_grab_t
/** Input grab is wanted */
bool ig_want_grab;

/** Input grab is allowed */
bool ig_allow_grab;

/** Input grab is active */
bool ig_have_grab;

Expand All @@ -365,6 +368,7 @@ static void evin_input_grab_cancel_release_timer (evin_input_grab
static void evin_input_grab_rethink (evin_input_grab_t *self);
static void evin_input_grab_set_touching (evin_input_grab_t *self, bool touching);
static void evin_input_grab_request_grab (evin_input_grab_t *self, bool want_grab);
static void evin_input_grab_allow_grab (evin_input_grab_t *self, bool allow_grab);
static void evin_input_grab_iomon_cb (gpointer data, gpointer user_data);

/* ------------------------------------------------------------------------- *
Expand Down Expand Up @@ -398,6 +402,15 @@ static void evin_kp_grab_changed (evin_input_grab
static void evin_kp_grab_event_filter_cb (struct input_event *ev);
static void evin_kp_grab_wanted_cb (gconstpointer data);

/* ------------------------------------------------------------------------- *
* GCONF_SETTINGS
* ------------------------------------------------------------------------- */

static void evin_gconf_input_grab_rethink (void);
static void evin_gconf_cb (GConfClient *const gcc, const guint id, GConfEntry *const entry, gpointer const data);
static void evin_gconf_init (void);
static void evin_gconf_quit (void);

/* ------------------------------------------------------------------------- *
* MODULE_INIT
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -2709,11 +2722,13 @@ evin_input_grab_rethink(evin_input_grab_t *self)
}

// do we want to change state?
if( self->ig_have_grab == self->ig_want_grab )
bool need = self->ig_want_grab && self->ig_allow_grab;

if( self->ig_have_grab == need )
goto EXIT;

// make the transition
self->ig_have_grab = self->ig_want_grab;
self->ig_have_grab = need;

// and report it
if( self->ig_grab_changed_cb )
Expand Down Expand Up @@ -2758,6 +2773,22 @@ evin_input_grab_request_grab(evin_input_grab_t *self, bool want_grab)
return;
}

/** Feed allow/deny grab control to input grab state machine
*/
static void
evin_input_grab_allow_grab(evin_input_grab_t *self, bool allow_grab)
{
if( self->ig_allow_grab == allow_grab )
goto EXIT;

self->ig_allow_grab = allow_grab;

evin_input_grab_rethink(self);

EXIT:
return;
}

/** Callback for changing iomonitor input grab state
*/
static void
Expand Down Expand Up @@ -2958,6 +2989,7 @@ static evin_input_grab_t evin_ts_grab_state =

.ig_want_grab = false,
.ig_have_grab = false,
.ig_allow_grab = false,

.ig_release_id = 0,
.ig_release_ms = TS_RELEASE_DELAY_DEFAULT,
Expand Down Expand Up @@ -3188,6 +3220,7 @@ static evin_input_grab_t evin_kp_grab_state =

.ig_want_grab = false,
.ig_have_grab = false,
.ig_allow_grab = false,

.ig_release_id = 0,
.ig_release_ms = 200,
Expand Down Expand Up @@ -3239,6 +3272,87 @@ evin_kp_grab_wanted_cb(gconstpointer data)
evin_input_grab_request_grab(&evin_kp_grab_state, required);
}

/* ========================================================================= *
* GCONF_SETTINGS
* ========================================================================= */

/** Flag: Input device types that can be grabbed */
static gint evin_gconf_input_grab_allowed = DEFAULT_INPUT_GRAB_ALLOWED;
/** GConf notifier id for tracking evin_gconf_input_grab_allowed changes */
static guint evin_gconf_input_grab_allowed_id = 0;

/** Handle changes to the list of grabbable input devices
*/
static void evin_gconf_input_grab_rethink(void)
{
bool ts = (evin_gconf_input_grab_allowed & MCE_INPUT_GRAB_ALLOW_TS) != 0;
bool kp = (evin_gconf_input_grab_allowed & MCE_INPUT_GRAB_ALLOW_KP) != 0;

evin_input_grab_allow_grab(&evin_ts_grab_state, ts);
evin_input_grab_allow_grab(&evin_kp_grab_state, kp);
}

/** GConf callback for event input related settings
*
* @param gcc Unused
* @param id Connection ID from gconf_client_notify_add()
* @param entry The modified GConf entry
* @param data Unused
*/
static void evin_gconf_cb(GConfClient *const gcc, const guint id,
GConfEntry *const entry, gpointer const data)
{
(void)gcc;
(void)data;
(void)id;

const GConfValue *gcv = gconf_entry_get_value(entry);

if( !gcv ) {
mce_log(LL_DEBUG, "GConf Key `%s' has been unset",
gconf_entry_get_key(entry));
goto EXIT;
}

if( id == evin_gconf_input_grab_allowed_id ) {
gint old = evin_gconf_input_grab_allowed;

evin_gconf_input_grab_allowed = gconf_value_get_int(gcv);

mce_log(LL_NOTICE, "evin_gconf_input_grab_allowed: %d -> %d",
old, evin_gconf_input_grab_allowed);
evin_gconf_input_grab_rethink();
}
else {
mce_log(LL_WARN, "Spurious GConf value received; confused!");
}

EXIT:
return;
}

/** Get intial gconf based settings and add change notifiers
*/
static void evin_gconf_init(void)
{
/* Bitmask of input devices that can be grabbed */
mce_gconf_track_int(MCE_GCONF_INPUT_GRAB_ALLOWED,
&evin_gconf_input_grab_allowed,
DEFAULT_INPUT_GRAB_ALLOWED,
evin_gconf_cb,
&evin_gconf_input_grab_allowed_id);

evin_gconf_input_grab_rethink();
}

/** Remove gconf change notifiers
*/
static void evin_gconf_quit(void)
{
mce_gconf_notifier_remove(evin_gconf_input_grab_allowed_id),
evin_gconf_input_grab_allowed_id = 0;
}

/* ========================================================================= *
* MODULE_INIT
* ========================================================================= */
Expand All @@ -3258,6 +3372,8 @@ mce_input_init(void)

evin_ts_grab_init();

evin_gconf_init();

#ifdef ENABLE_DOUBLETAP_EMULATION
/* Get fake doubletap policy configuration & track changes */
mce_gconf_notifier_add(MCE_GCONF_EVENT_INPUT_PATH,
Expand Down Expand Up @@ -3323,6 +3439,8 @@ mce_input_exit(void)
/* Remove input device directory monitor */
evin_devdir_monitor_quit();

evin_gconf_quit();

evin_iomon_quit();

/* Reset input grab state machines */
Expand Down
7 changes: 7 additions & 0 deletions event-input.h
Expand Up @@ -43,6 +43,13 @@
/** Path to the touch unblock delay setting */
#define MCE_GCONF_TOUCH_UNBLOCK_DELAY_PATH MCE_GCONF_EVENT_INPUT_PATH "/touch_unblock_delay"

/** Input device grabbing allowed setting */
#define MCE_GCONF_INPUT_GRAB_ALLOWED MCE_GCONF_EVENT_INPUT_PATH "/input_grab_allowed"
#define MCE_INPUT_GRAB_ALLOW_NONE (0)
#define MCE_INPUT_GRAB_ALLOW_TS (1<<0)
#define MCE_INPUT_GRAB_ALLOW_KP (1<<1)
#define DEFAULT_INPUT_GRAB_ALLOWED 3 // = MCE_INPUT_GRAB_ALLOW_TS | KP

/* When MCE is made modular, this will be handled differently */
gboolean mce_input_init(void);
void mce_input_exit(void);
Expand Down
49 changes: 49 additions & 0 deletions tools/mcetool.c
Expand Up @@ -2343,6 +2343,42 @@ static void xmce_get_lpmui_triggering(void)

printf("%-"PAD1"s %s\n", "LPM UI triggering:", work);
}
/* ------------------------------------------------------------------------- *
* input_grab triggering
* ------------------------------------------------------------------------- */

/** Lookuptable for mce radio state bits */
static const symbol_t input_grab_allowed_lut[] =
{
{ "ts", MCE_INPUT_GRAB_ALLOW_TS },
{ "kp", MCE_INPUT_GRAB_ALLOW_KP },
{ "none", MCE_INPUT_GRAB_ALLOW_NONE },
{ 0, 0 }
};

/** Set automatic lpm ui triggering mode
*
* @param args string of comma separated lpm ui triggering names
*/
static bool xmce_set_input_grab_allowed(const char *args)
{
int mask = mcetool_parse_bitmask(input_grab_allowed_lut, args);
mcetool_gconf_set_int(MCE_GCONF_INPUT_GRAB_ALLOWED, mask);
return true;
}

/** Get current lpm ui triggering mode from mce and print it out
*/
static void xmce_get_input_grab_allowed(void)
{
gint mask = 0;
char work[64] = "unknown";
if( mcetool_gconf_get_int(MCE_GCONF_INPUT_GRAB_ALLOWED, &mask) )
mcetool_format_bitmask(input_grab_allowed_lut, mask,
work, sizeof work);

printf("%-"PAD1"s %s\n", "Input grab allowed:", work);
}

/* ------------------------------------------------------------------------- *
* call state
Expand Down Expand Up @@ -5455,6 +5491,7 @@ static bool xmce_get_status(const char *args)
xmce_get_tklock_blank();
xmce_get_lipstick_core_delay();
xmce_get_input_policy_mode();
xmce_get_input_grab_allowed();
xmce_get_touch_unblock_delay();
xmce_get_exception_lengths();

Expand Down Expand Up @@ -6539,6 +6576,18 @@ static const mce_opt_t options[] =
"mce policy logic. If the problem persists, the problem is more\n"
"likely to exist at the ui side input handling logic.\n"
},
{
.name = "set-input-grab-allowed",
.with_arg = xmce_set_input_grab_allowed,
.values = "bit1[,bit2][...]",
.usage =
"set the input devices that mce is allowed to grab based on policy\n"
"\n"
"Valid input device types to use are:\n"
" none - no input files will be grabbed by mce\n"
" ts - allow mce to grab touch screen devices\n"
" kp - allow mce to grab keypad devices (with volkeys)\n"
},
{
.name = "set-touch-unblock-delay",
.with_arg = xmce_set_touch_unblock_delay,
Expand Down

0 comments on commit 0fa2554

Please sign in to comment.