Skip to content

Commit

Permalink
[proximity] Optionally make proximity sensor behave like lid sensor. …
Browse files Browse the repository at this point in the history
…Fixes MER#1201

On devices that have a lid cover sensor, mce uses it for turning the
display on/off when the cover is opened/closed. On devices that do not
have a dedicated lid sensor, users might prefer using proximity sensor
for that purpose even if it has some side effects.

Add a setting for making mce treat proximity sensor act as if were
a lid sensor.

The setting is disabled by default and can be changed with:

  mcetool --set-ps-acts-as-lid=<enabled|disabled>

The value of the setting persists over mce / device restarts.
  • Loading branch information
spiiroin committed Aug 4, 2015
1 parent c7c12b9 commit 05e2ff1
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 40 deletions.
2 changes: 2 additions & 0 deletions .depend
Expand Up @@ -7,6 +7,7 @@ builtin-gconf.o:\
modules/display.h\
modules/filter-brightness-als.h\
modules/memnotify.h\
modules/proximity.h\
powerkey.h\
tklock.h\

Expand All @@ -19,6 +20,7 @@ builtin-gconf.pic.o:\
modules/display.h\
modules/filter-brightness-als.h\
modules/memnotify.h\
modules/proximity.h\
powerkey.h\
tklock.h\

Expand Down
11 changes: 8 additions & 3 deletions builtin-gconf.c
Expand Up @@ -28,6 +28,7 @@
#include "modules/memnotify.h"
#include "modules/filter-brightness-als.h"
#include "modules/display.h"
#include "modules/proximity.h"

#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -1506,10 +1507,14 @@ static const setting_t gconf_defaults[] =
.def = "101", // use > 100 for "only when charger is connected"
},
{
// MCE_GCONF_PROXIMITY_PS_ENABLED_PATH @ proximity.h
.key = "/system/osso/dsm/proximity/ps_enabled",
.key = MCE_GCONF_PROXIMITY_PS_ENABLED_PATH,
.type = "b",
.def = "true",
.def = G_STRINGIFY(DEFAULT_PROXIMITY_PS_ENABLED),
},
{
.key = MCE_GCONF_PROXIMITY_PS_ACTS_AS_LID,
.type = "b",
.def = G_STRINGIFY(DEFAULT_PROXIMITY_PS_ACTS_AS_LID),
},
{
// MCE_GCONF_DOUBLETAP_MODE @ doubletap.h
Expand Down
126 changes: 91 additions & 35 deletions modules/proximity.c
Expand Up @@ -48,9 +48,6 @@ G_MODULE_EXPORT module_info_struct module_info = {
/** State of proximity sensor monitoring */
static gboolean proximity_monitor_active = FALSE;

/** Last proximity sensor state */
static cover_state_t old_proximity_sensor_state = COVER_UNDEF;

/** Cached call state */
static call_state_t call_state = CALL_STATE_INVALID;

Expand All @@ -63,6 +60,18 @@ static display_state_t display_state = MCE_DISPLAY_UNDEF;
/** Cached submode state */
static submode_t submode = MCE_NORMAL_SUBMODE;

/** Configuration value for use proximity sensor */
static gboolean use_ps_conf_value = DEFAULT_PROXIMITY_PS_ENABLED;

/** Configuration change id for use_ps_conf_value */
static guint use_ps_conf_id = 0;

/** Configuration value for ps acts as lid sensor */
static gboolean ps_acts_as_lid = DEFAULT_PROXIMITY_PS_ACTS_AS_LID;

/** Configuration change id for ps_acts_as_lid */
static guint ps_acts_as_lid_conf_id = 0;

/** Broadcast proximity state within MCE
*
* @param state COVER_CLOSED or COVER_OPEN
Expand All @@ -74,20 +83,35 @@ static void report_proximity(cover_state_t state)

/* Execute datapipe if state has changed */

/* FIXME: figure out where things break down if we do not
* omit the non-change datapipe execute ... */
//if( old_state != state )
if( old_state != state )
{
mce_log(LL_NOTICE, "state: %s -> %s",
cover_state_repr(old_state),
cover_state_repr(state));

execute_datapipe(&proximity_sensor_pipe,
GINT_TO_POINTER(state),
USE_INDATA, CACHE_INDATA);
}
}

/* Update last-seen proximity state */
old_proximity_sensor_state = state;
/** Broadcast faked lid input state within mce
*
* @param state COVER_CLOSED, COVER_OPEN or COVER_UNDEF
*/
static void report_lid_input(cover_state_t state)
{
cover_state_t old_state = datapipe_get_gint(lid_cover_sensor_pipe);

if( state != old_state ) {
mce_log(LL_NOTICE, "state: %s -> %s",
cover_state_repr(old_state),
cover_state_repr(state));

execute_datapipe(&lid_cover_sensor_pipe,
GINT_TO_POINTER(state),
USE_INDATA, CACHE_INDATA);
}
}

/**
Expand All @@ -104,7 +128,10 @@ static void ps_sensorfw_iomon_cb(bool covered)
else
proximity_sensor_state = COVER_OPEN;

report_proximity(proximity_sensor_state);
if( ps_acts_as_lid )
report_lid_input(proximity_sensor_state);
else
report_proximity(proximity_sensor_state);

return;
}
Expand Down Expand Up @@ -150,28 +177,23 @@ static void disable_proximity_monitor(void)
return;
}

/** Configuration value for use proximity sensor */
static gboolean use_ps_conf_value = TRUE;

/** Configuration change id for use proximity sensor */
static guint use_ps_conf_id = 0;

/**
* Update the proximity monitoring
*/
static void update_proximity_monitor(void)
{
static gboolean old_enable = FALSE;

gboolean enable = FALSE;
gboolean fake_open = FALSE;

/* Default to keeping the proximity sensor always enabled. */
enable = TRUE;
gboolean enable = TRUE;

if( !use_ps_conf_value ) {
fake_open = TRUE;
enable = FALSE;

if( ps_acts_as_lid )
report_lid_input(COVER_UNDEF);
else
report_proximity(COVER_OPEN);
}

if( old_enable == enable )
Expand All @@ -184,8 +206,7 @@ static void update_proximity_monitor(void)
}

EXIT:
if( !enable && fake_open )
report_proximity(COVER_OPEN);
return;
}

/** GConf callback for use proximity sensor setting
Expand All @@ -202,17 +223,38 @@ static void use_ps_conf_cb(GConfClient *const gcc, const guint id,

const GConfValue *gcv;

if( id != use_ps_conf_id ) {
mce_log(LL_WARN, "Spurious GConf value received; confused!");
if( !(gcv = gconf_entry_get_value(entry)) ) {
mce_log(LL_WARN, "GConf value removed; confused!");
goto EXIT;
}

if( !(gcv = gconf_entry_get_value(entry)) ) {
// config removed -> use proximity sensor
use_ps_conf_value = TRUE;
if( id == use_ps_conf_id ) {
gboolean old = use_ps_conf_value;
use_ps_conf_value = gconf_value_get_bool(gcv);

if( use_ps_conf_value == old )
goto EXIT;

}
else if( id == ps_acts_as_lid_conf_id ) {
gboolean old = ps_acts_as_lid;
ps_acts_as_lid = gconf_value_get_bool(gcv);

if( ps_acts_as_lid == old )
goto EXIT;

if( ps_acts_as_lid ) {
// ps is lid now -> set ps to open state
report_proximity(COVER_OPEN);
}
else {
// ps is ps again -> invalidate lid state
report_lid_input(COVER_UNDEF);
}
}
else {
use_ps_conf_value = gconf_value_get_bool(gcv);
mce_log(LL_WARN, "Spurious GConf value received; confused!");
goto EXIT;
}

update_proximity_monitor();
Expand Down Expand Up @@ -297,13 +339,24 @@ const gchar *g_module_check_init(GModule *module)
submode_trigger);

/* PS enabled setting */
mce_gconf_notifier_add(MCE_GCONF_PROXIMITY_PATH,
MCE_GCONF_PROXIMITY_PS_ENABLED_PATH,
use_ps_conf_cb,
&use_ps_conf_id);

mce_gconf_get_bool(MCE_GCONF_PROXIMITY_PS_ENABLED_PATH,
&use_ps_conf_value);
mce_gconf_track_bool(MCE_GCONF_PROXIMITY_PS_ENABLED_PATH,
&use_ps_conf_value,
DEFAULT_PROXIMITY_PS_ENABLED,
use_ps_conf_cb,
&use_ps_conf_id);

/* PS acts as LID sensor */
mce_gconf_track_bool(MCE_GCONF_PROXIMITY_PS_ACTS_AS_LID,
&ps_acts_as_lid,
DEFAULT_PROXIMITY_PS_ACTS_AS_LID,
use_ps_conf_cb,
&ps_acts_as_lid_conf_id);

/* If the proximity sensor input is used for toggling
* lid state, we must take care not to leave proximity
* tracking to covered state. */
if( ps_acts_as_lid )
report_proximity(COVER_OPEN);

/* enable/disable sensor based on initial conditions */
update_proximity_monitor();
Expand All @@ -325,6 +378,9 @@ void g_module_unload(GModule *module)
mce_gconf_notifier_remove(use_ps_conf_id),
use_ps_conf_id = 0;

mce_gconf_notifier_remove(ps_acts_as_lid_conf_id),
ps_acts_as_lid_conf_id = 0;

/* Remove triggers/filters from datapipes */
remove_output_trigger_from_datapipe(&display_state_pipe,
display_state_trigger);
Expand Down
9 changes: 7 additions & 2 deletions modules/proximity.h
Expand Up @@ -25,7 +25,12 @@
/** Path to the GConf settings for the proximity */
#define MCE_GCONF_PROXIMITY_PATH "/system/osso/dsm/proximity"

/** Path to the ALS enabled GConf setting */
#define MCE_GCONF_PROXIMITY_PS_ENABLED_PATH MCE_GCONF_PROXIMITY_PATH "/ps_enabled"
/** Proximity sensor enabled GConf setting */
#define MCE_GCONF_PROXIMITY_PS_ENABLED_PATH MCE_GCONF_PROXIMITY_PATH "/ps_enabled"
#define DEFAULT_PROXIMITY_PS_ENABLED true

/** Proximity sensor acts as lid sensor setting */
#define MCE_GCONF_PROXIMITY_PS_ACTS_AS_LID MCE_GCONF_PROXIMITY_PATH "/ps_acts_as_lid"
#define DEFAULT_PROXIMITY_PS_ACTS_AS_LID false

#endif /* _PROXIMITY_H_ */
31 changes: 31 additions & 0 deletions tools/mcetool.c
Expand Up @@ -2833,6 +2833,29 @@ static void xmce_get_ps_blocks_touch(void)
printf("%-"PAD1"s %s\n", "Touch can be blocked by ps:", txt);
}

/** Set ps acts as lid sensor mode
*
* @param args string suitable for interpreting as enabled/disabled
*/
static bool xmce_set_ps_acts_as_lid(const char *args)
{
gboolean val = xmce_parse_enabled(args);
mcetool_gconf_set_bool(MCE_GCONF_PROXIMITY_PS_ACTS_AS_LID, val);
return true;
}

/** Get current ps acts as lid mode and print it out
*/
static void xmce_get_ps_acts_as_lid(void)
{
gboolean val = 0;
char txt[32] = "unknown";

if( mcetool_gconf_get_bool(MCE_GCONF_PROXIMITY_PS_ACTS_AS_LID, &val) )
snprintf(txt, sizeof txt, "%s", val ? "enabled" : "disabled");
printf("%-"PAD1"s %s\n", "PS acts as LID sensor:", txt);
}

/* ------------------------------------------------------------------------- *
* als
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -4555,6 +4578,7 @@ static bool xmce_get_status(const char *args)
xmce_get_orientation_sensor_mode();
xmce_get_ps_mode();
xmce_get_ps_blocks_touch();
xmce_get_ps_acts_as_lid();
xmce_get_lid_sensor_mode();
xmce_get_filter_lid_with_als();
xmce_get_dim_timeouts();
Expand Down Expand Up @@ -5242,6 +5266,13 @@ static const mce_opt_t options[] =
"allow ps to block touch input; valid modes are:\n"
"'enabled' and 'disabled'\n"
},
{
.name = "set-ps-acts-as-lid",
.with_arg = xmce_set_ps_acts_as_lid,
.values = "enabled|disabled",
"make ps act as lid sensor; valid modes are:\n"
"'enabled' and 'disabled'\n"
},
{
.name = "set-lid-sensor-mode",
.with_arg = xmce_set_lid_sensor_mode,
Expand Down

0 comments on commit 05e2ff1

Please sign in to comment.