Skip to content

Commit

Permalink
Add option for disabling power key when proximity is covered
Browse files Browse the repository at this point in the history
Similarly to double tap, also power key actions can now be
* always allowed
* never allowed
* allowed if proximity sensor is not covered

Default is "always", i.e. power key works the same way as before.

The setting can be changed via mcetool option
  -Z, --set-powerkey-action=<never|always|proximity>

The setting persists over mce / device restarts.

[mce] Add option for disabling power key when proximity is covered
  • Loading branch information
spiiroin committed Mar 24, 2014
1 parent 9f5fb76 commit 1fa79ec
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 7 deletions.
6 changes: 6 additions & 0 deletions builtin-gconf.c
Expand Up @@ -1500,6 +1500,12 @@ static const setting_t gconf_defaults[] =
.type = "i",
.def = "2",
},
{
// MCE_GCONF_POWERKEY_MODE @ powerkey.h
.key = "/system/osso/dsm/powerkey/mode",
.type = "i",
.def = "1",
},
{
.key = NULL,
}
Expand Down
125 changes: 120 additions & 5 deletions powerkey.c
Expand Up @@ -37,6 +37,7 @@
#include "powerkey.h"

#include "mce-log.h" /* mce_log(), LL_* */
#include "mce-gconf.h"
#include "mce-conf.h" /* mce_conf_get_int(),
* mce_conf_get_string()
*/
Expand Down Expand Up @@ -154,6 +155,118 @@ static void powerkey_wakelock_rethink(void)
#endif
}

/** Power key press actions mode */
static gint powerkey_action_mode = PWRKEY_ENABLE_DEFAULT;

/** GConf callback ID for powerkey_action_mode */
static guint powerkey_action_mode_cb_id = 0;

/** GConf callback for powerkey related settings
*
* @param gcc (not used)
* @param id Connection ID from gconf_client_notify_add()
* @param entry The modified GConf entry
* @param data (not used)
*/
static void powerkey_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 == powerkey_action_mode_cb_id ) {
gint old = powerkey_action_mode;
powerkey_action_mode = gconf_value_get_int(gcv);
mce_log(LL_NOTICE, "powerkey_action_mode: %d -> %d",
old, powerkey_action_mode);
}
else {
mce_log(LL_WARN, "Spurious GConf value received; confused!");
}

EXIT:
return;
}

/** Get gconf values and add change notifiers
*/
static void powerkey_gconf_init(void)
{
/* Power key press handling mode */
mce_gconf_notifier_add(MCE_GCONF_POWERKEY_PATH,
MCE_GCONF_POWERKEY_MODE,
powerkey_gconf_cb,
&powerkey_action_mode_cb_id);
mce_gconf_get_int(MCE_GCONF_POWERKEY_MODE, &powerkey_action_mode);
}

/** Remove gconf change notifiers
*/
static void powerkey_gconf_quit(void)
{
/* Power key press handling mode */
if( powerkey_action_mode_cb_id ) {
mce_gconf_notifier_remove(GINT_TO_POINTER(powerkey_action_mode_cb_id), 0);
powerkey_action_mode_cb_id = 0;
}
}

/** Should power key action be ignored predicate
*/
static bool powerkey_ignore_action(void)
{
/* Assume that power key action should be ignored */
bool ignore_powerkey = true;

alarm_ui_state_t alarm_ui_state =
datapipe_get_gint(alarm_ui_state_pipe);
cover_state_t proximity_sensor_state =
datapipe_get_gint(proximity_sensor_pipe);


/* Ignore keypress if the alarm UI is visible */
if ((alarm_ui_state == MCE_ALARM_UI_VISIBLE_INT32) ||
(alarm_ui_state == MCE_ALARM_UI_RINGING_INT32)) {
mce_log(LL_DEVEL, "[powerkey] ignored due to alarm state");
goto EXIT;
}


/* Proximity sensor state vs power key press handling mode */
switch( powerkey_action_mode ) {
case PWRKEY_ENABLE_NEVER:
mce_log(LL_DEVEL, "[powerkey] ignored due to setting=never");
goto EXIT;

case PWRKEY_ENABLE_ALWAYS:
break;

default:
case PWRKEY_ENABLE_NO_PROXIMITY:
if( proximity_sensor_state != COVER_CLOSED )
break;

mce_log(LL_DEVEL, "[powerkey] ignored due to proximity");
goto EXIT;
}

/* There was no reason to ignore the powere key action */
ignore_powerkey = false;

EXIT:

return ignore_powerkey;
}

/**
* Generic logic for key presses
*
Expand All @@ -166,13 +279,9 @@ static void generic_powerkey_handler(poweraction_t action,
mce_log(LL_DEVEL, "action=%d, signal=%s", (int)action,
dbus_signal ?: "n/a");

alarm_ui_state_t alarm_ui_state =
datapipe_get_gint(alarm_ui_state_pipe);
submode_t submode = mce_get_submode_int32();

/* Ignore keypress if the alarm UI is visible */
if ((alarm_ui_state == MCE_ALARM_UI_VISIBLE_INT32) ||
(alarm_ui_state == MCE_ALARM_UI_RINGING_INT32))
if( powerkey_ignore_action() )
goto EXIT;

switch (action) {
Expand Down Expand Up @@ -768,6 +877,9 @@ gboolean mce_powerkey_init(void)
(void)parse_action(tmp, &doublepresssignal, &doublepressaction);
g_free(tmp);

/* Setup gconf tracking */
powerkey_gconf_init();

status = TRUE;

EXIT:
Expand All @@ -781,6 +893,9 @@ gboolean mce_powerkey_init(void)
*/
void mce_powerkey_exit(void)
{
/* Remove gconf tracking */
powerkey_gconf_quit();

/* Remove triggers/filters from datapipes */
remove_input_trigger_from_datapipe(&keypress_pipe,
powerkey_trigger);
Expand Down
21 changes: 21 additions & 0 deletions powerkey.h
Expand Up @@ -23,6 +23,27 @@

#include <glib.h>

/** Path to the GConf settings for the powerkey module */
# define MCE_GCONF_POWERKEY_PATH "/system/osso/dsm/powerkey"

/** Path to the powerkey mode GConf setting */
# define MCE_GCONF_POWERKEY_MODE MCE_GCONF_POWERKEY_PATH "/mode"

/** Power key action enable modes */
typedef enum
{
/** Power key actions disabled */
PWRKEY_ENABLE_NEVER,

/** Power key actions always enabled */
PWRKEY_ENABLE_ALWAYS,

/** Power key actions enabled when PS is not covered */
PWRKEY_ENABLE_NO_PROXIMITY,

PWRKEY_ENABLE_DEFAULT = PWRKEY_ENABLE_ALWAYS,
} pwrkey_mode_t;

/** Configuration value used for the disabled policy */
#define POWER_DISABLED_STR "disabled"
/** Configuration value used for the device menu policy */
Expand Down
51 changes: 49 additions & 2 deletions tools/mcetool.c
Expand Up @@ -38,6 +38,7 @@
#include <mce/mode-names.h>

#include "../tklock.h"
#include "../powerkey.h"
#include "../event-input.h"
#include "../modules/display.h"
#include "../modules/doubletap.h"
Expand Down Expand Up @@ -2068,6 +2069,45 @@ static void xmce_get_blank_timeout(void)
printf("%-"PAD1"s %s (seconds)\n", "Blank timeout:", txt);
}

/* ------------------------------------------------------------------------- *
* powerkey
* ------------------------------------------------------------------------- */

/** Lookup table for powerkey wakeup policies
*/
static const symbol_t powerkey_action[] = {
{ "never", PWRKEY_ENABLE_NEVER },
{ "always", PWRKEY_ENABLE_ALWAYS },
{ "proximity", PWRKEY_ENABLE_NO_PROXIMITY },
{ NULL, -1 }
};

/** Set powerkey wakeup mode
*
* @param args string that can be parsed to powerkey wakeup mode
*/
static void xmce_set_powerkey_action(const char *args)
{
debugf("%s(%s)\n", __FUNCTION__, args);
int val = lookup(powerkey_action, args);
if( val < 0 ) {
errorf("%s: invalid powerkey policy value\n", args);
exit(EXIT_FAILURE);
}
mcetool_gconf_set_int(MCE_GCONF_POWERKEY_MODE, val);
}

/** Get current powerkey wakeup mode from mce and print it out
*/
static void xmce_get_powerkey_action(void)
{
gint val = 0;
const char *txt = 0;
if( mcetool_gconf_get_int(MCE_GCONF_POWERKEY_MODE, &val) )
txt = rlookup(powerkey_action, val);
printf("%-"PAD1"s %s \n", "Powerkey wakeup policy:", txt ?: "unknown");
}

/* ------------------------------------------------------------------------- *
* doubletab
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -2640,6 +2680,7 @@ static void xmce_get_status(void)
xmce_get_autolock_mode();
xmce_get_doubletap_mode();
xmce_get_doubletap_wakeup();
xmce_get_powerkey_action();
xmce_get_low_power_mode();
xmce_get_als_mode();
xmce_get_ps_mode();
Expand Down Expand Up @@ -2769,6 +2810,9 @@ EXTRA" 'disabled', 'show-unlock-screen', 'unlock'\n"
PARAM"-z, --set-doubletap-wakeup=<never|always|proximity>\n"
EXTRA"set the doubletap wakeup mode; valid modes are:\n"
EXTRA" 'never', 'always', 'proximity'\n"
PARAM"-Z, --set-powerkey-action=<never|always|proximity>\n"
EXTRA"set the doubletap wakeup mode; valid modes are:\n"
EXTRA" 'never', 'always', 'proximity'\n"
PARAM"-r, --enable-radio=<master|cellular|wlan|bluetooth>\n"
EXTRA"enable the specified radio; valid radios are:\n"
EXTRA" 'master', 'cellular',\n"
Expand Down Expand Up @@ -2926,7 +2970,7 @@ PROG_NAME" v"G_STRINGIFY(PRG_VERSION)"\n"

// Unused short options left ....
// - - - - - - - - - - - - - - - - - - - - - - w x - -
// - - - - - - - - - - - - - - - - - - - - - - W X - Z
// - - - - - - - - - - - - - - - - - - - - - - W X - -

const char OPT_S[] =
"B::" // --block,
Expand Down Expand Up @@ -2967,6 +3011,7 @@ const char OPT_S[] =
"K:" // --set-autolock-mode
"M:" // --set-doubletap-mode
"z:" // --set-doubletap-wakeup
"Z:" // --set-powerkey-action
"O:" // --set-dim-timeouts
"s:" // --set-suspend-policy
"S:" // --set-cpu-scaling-governor
Expand Down Expand Up @@ -3025,6 +3070,7 @@ struct option const OPT_L[] =
{ "set-autolock-mode", 1, 0, 'K' }, // xmce_set_autolock_mode()
{ "set-doubletap-mode", 1, 0, 'M' }, // xmce_set_doubletap_mode()
{ "set-doubletap-wakeup", 1, 0, 'z' }, // xmce_set_doubletap_wakeup()
{ "set-powerkey-action", 1, 0, 'Z' }, // xmce_set_powerkey_action()
{ "set-dim-timeouts", 1, 0, 'O' }, // xmce_set_dim_timeouts()
{ "set-suspend-policy", 1, 0, 's' }, // xmce_set_suspend_policy()
{ "set-cpu-scaling-governor", 1, 0, 's' }, // xmce_set_cpu_scaling_governor()
Expand Down Expand Up @@ -3081,7 +3127,8 @@ int main(int argc, char **argv)
case 'q': xmce_tklock_open(optarg); break;
case 'Q': xmce_tklock_close(); break;
case 'M': xmce_set_doubletap_mode(optarg); break;
case 'z': xmce_set_doubletap_wakeup(optarg); break;
case 'z': xmce_set_doubletap_wakeup(optarg); break;
case 'Z': xmce_set_powerkey_action(optarg); break;

case 'r': xmce_enable_radio(optarg); break;
case 'R': xmce_disable_radio(optarg); break;
Expand Down

0 comments on commit 1fa79ec

Please sign in to comment.