Skip to content

Commit

Permalink
Make lid sensor policy work similarly to proximity sensor
Browse files Browse the repository at this point in the history
The lid sensor policy is implemented as a display state filter that
does not allow turning on the display for any reason while the
sensor is in closed position. This can be problematic in case there
are false positives from the lid sensor for any reason.

Instead of global display state filtering apply similar case by
case rules when the lid sensor is in closed position as what are
used for the proximity sensor:
* Display power up requests via D-Bus are ignored
* Calls/alarms/notifications will not turn on display
* By default power key can be used to turn display on
* Sliding keyboard out does not turn display on
* Touch input can be optionally blocked
* LPM display state is not allowed

The configurable behavior follows the settings for the proximity sensor.

[mce] Make lid sensor policy work similarly to proximity sensor. Fixes JB#29011
  • Loading branch information
spiiroin committed Jun 11, 2015
1 parent c5de9a6 commit 9c86840
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 76 deletions.
9 changes: 7 additions & 2 deletions event-input.c
Expand Up @@ -1917,8 +1917,13 @@ evin_iomon_touchscreen_cb(gpointer data, gsize bytes_read)
cover_state_t proximity_sensor_state =
datapipe_get_gint(proximity_sensor_pipe);

mce_log(LL_DEVEL, "[doubletap] as power key event; proximity=%s",
proximity_state_repr(proximity_sensor_state));
cover_state_t lid_cover_policy_state =
datapipe_get_gint(lid_cover_policy_pipe);

mce_log(LL_DEVEL, "[doubletap] as power key event; "
"proximity=%s, lid=%s",
proximity_state_repr(proximity_sensor_state),
proximity_state_repr(lid_cover_policy_state));

/* Mimic N9 style gesture event for which we
* already have logic in place. Possible filtering
Expand Down
15 changes: 8 additions & 7 deletions modules/display.c
Expand Up @@ -1182,12 +1182,6 @@ static gpointer mdy_datapipe_display_state_filter_cb(gpointer data)
goto UPDATE;
}

/* Display stays off while lid_cover is on */
if( lid_cover_policy_state == COVER_CLOSED ) {
next_state = MCE_DISPLAY_OFF;
goto UPDATE;
}

/* Handle update-mode override */
if( mdy_update_mode ) {
next_state = MCE_DISPLAY_ON;
Expand Down Expand Up @@ -4026,7 +4020,8 @@ static void mdy_blanking_rethink_proximity(void)
break;

case MCE_DISPLAY_LPM_OFF:
if( proximity_state == COVER_OPEN )
if( proximity_state == COVER_OPEN &&
lid_cover_policy_state == COVER_OPEN )
execute_datapipe(&display_state_req_pipe,
GINT_TO_POINTER(MCE_DISPLAY_LPM_ON),
USE_INDATA, CACHE_INDATA);
Expand Down Expand Up @@ -7231,6 +7226,12 @@ static const char *mdy_dbus_get_reason_to_block_display_on(void)
break;
}

/* lid closed? */
if( lid_cover_policy_state == COVER_CLOSED ) {
reason = "lid closed";
goto EXIT;
}

/* proximity covered? */
if( proximity_state == COVER_CLOSED ) {
reason = "proximity covered";
Expand Down
19 changes: 14 additions & 5 deletions powerkey.c
Expand Up @@ -1461,6 +1461,9 @@ pwrkey_stm_ignore_action(void)
cover_state_t proximity_sensor_state =
datapipe_get_gint(proximity_sensor_pipe);

cover_state_t lid_cover_policy_state =
datapipe_get_gint(lid_cover_policy_pipe);

call_state_t call_state =
datapipe_get_gint(call_state_pipe);

Expand Down Expand Up @@ -1521,12 +1524,18 @@ pwrkey_stm_ignore_action(void)
/* fall through */
default:
case PWRKEY_ENABLE_NO_PROXIMITY:
if( proximity_sensor_state != COVER_CLOSED )
break;
if( lid_cover_policy_state == COVER_CLOSED ) {
mce_log(LL_DEVEL, "[powerkey] ignored due to lid");
ignore_powerkey = true;
goto EXIT;
}

mce_log(LL_DEVEL, "[powerkey] ignored due to proximity");
ignore_powerkey = true;
goto EXIT;
if( proximity_sensor_state == COVER_CLOSED ) {
mce_log(LL_DEVEL, "[powerkey] ignored due to proximity");
ignore_powerkey = true;
goto EXIT;
}
break;
}

EXIT:
Expand Down
151 changes: 89 additions & 62 deletions tklock.c
Expand Up @@ -186,6 +186,10 @@ static void tklock_datapipe_quit(void);

static void tklock_lid_sensor_rethink(void);

// keyboard slide state machine

static void tklock_keyboard_slide_rethink(void);

// autolock state machine

static gboolean tklock_autolock_cb(gpointer aptr);
Expand Down Expand Up @@ -814,6 +818,9 @@ static cover_state_t proximity_state_actual = COVER_OPEN;
/** Effective proximity state; assume not covered */
static cover_state_t proximity_state_effective = COVER_OPEN;

/** Lid cover policy state; assume open */
static cover_state_t lid_cover_policy_state = COVER_OPEN;

/** Timer id for delayed proximity uncovering */
static guint tklock_datapipe_proximity_uncover_id = 0;

Expand Down Expand Up @@ -1426,6 +1433,10 @@ static void tklock_datapipe_touchscreen_cb(gconstpointer const data)

default:
case DBLTAP_ENABLE_NO_PROXIMITY:
if( lid_cover_policy_state == COVER_CLOSED ) {
mce_log(LL_DEVEL, "[doubletap] ignored due to lid=closed");
goto EXIT;
}
if( proximity_state_actual != COVER_OPEN ) {
mce_log(LL_DEVEL, "[doubletap] ignored due to proximity");
goto EXIT;
Expand Down Expand Up @@ -1572,63 +1583,11 @@ static void tklock_datapipe_keyboard_slide_input_cb(gconstpointer const data)
if( kbd_slide_input_state == prev )
goto EXIT;

mce_log(LL_DEBUG, "kbd_slide_input_state = %s -> %s",
mce_log(LL_DEVEL, "kbd_slide_input_state = %s -> %s",
cover_state_repr(prev),
cover_state_repr(kbd_slide_input_state));

bool display_on = (display_state_next == MCE_DISPLAY_ON ||
display_state_next == MCE_DISPLAY_DIM);

switch( kbd_slide_input_state ) {
case COVER_OPEN:
/* In any case opening the kbd slide will cancel
* other autorelock triggers */
if( autorelock_trigger != AUTORELOCK_NO_TRIGGERS ) {
mce_log(LL_DEBUG, "autorelock canceled: kbd slide opened");
autorelock_trigger = AUTORELOCK_NO_TRIGGERS;
}

if( !display_on && proximity_state_actual == COVER_OPEN ) {
mce_log(LL_DEBUG, "autorelock primed: on kbd slide close");
autorelock_trigger = AUTORELOCK_KBD_SLIDE;

mce_log(LL_DEBUG, "display -> on");
execute_datapipe(&display_state_req_pipe,
GINT_TO_POINTER(MCE_DISPLAY_ON),
USE_INDATA, CACHE_INDATA);
execute_datapipe(&tk_lock_pipe,
GINT_TO_POINTER(LOCK_OFF),
USE_INDATA, CACHE_INDATA);
}
break;

case COVER_CLOSED:
if( autorelock_trigger == AUTORELOCK_KBD_SLIDE ) {
mce_log(LL_DEBUG, "autorelock triggered: kbd slide closed");
autorelock_trigger = AUTORELOCK_NO_TRIGGERS;

mce_log(LL_DEBUG, "display -> off");

execute_datapipe(&tk_lock_pipe,
GINT_TO_POINTER(LOCK_ON),
USE_INDATA, CACHE_INDATA);

execute_datapipe(&display_state_req_pipe,
GINT_TO_POINTER(MCE_DISPLAY_OFF),
USE_INDATA, CACHE_INDATA);
}

/* In any case closing the kbd slide will cancel
* other autorelock triggers */
if( autorelock_trigger != AUTORELOCK_NO_TRIGGERS ) {
mce_log(LL_DEBUG, "autorelock canceled: kbd slide closed");
autorelock_trigger = AUTORELOCK_NO_TRIGGERS;
}
break;

default:
break;
}
tklock_keyboard_slide_rethink();

EXIT:
return;
Expand All @@ -1646,7 +1605,7 @@ tklock_datapipe_keyboard_slide_output_cb(gconstpointer const data)
if( kbd_slide_output_state == prev )
goto EXIT;

mce_log(LL_DEBUG, "kbd_slide_output_state = %s -> %s",
mce_log(LL_DEVEL, "kbd_slide_output_state = %s -> %s",
cover_state_repr(prev),
cover_state_repr(kbd_slide_output_state));

Expand Down Expand Up @@ -1753,10 +1712,6 @@ static void tklock_datapipe_lid_cover_sensor_cb(gconstpointer data)
return;
}

/** Lid cover policy state; assume open
*/
static cover_state_t lid_cover_policy_state = COVER_OPEN;

/** Change notifications from lid_cover_policy_pipe
*/
static void tklock_datapipe_lid_cover_policy_cb(gconstpointer data)
Expand Down Expand Up @@ -2334,6 +2289,69 @@ static void tklock_lid_sensor_rethink(void)
return;
}

/* ========================================================================= *
* KEYBOARD SLIDE STATE MACHINE
* ========================================================================= */

static void tklock_keyboard_slide_rethink(void)
{
bool display_on = (display_state_next == MCE_DISPLAY_ON ||
display_state_next == MCE_DISPLAY_DIM);

switch( kbd_slide_input_state ) {
case COVER_OPEN:
/* In any case opening the kbd slide will cancel
* other autorelock triggers */
if( autorelock_trigger != AUTORELOCK_NO_TRIGGERS ) {
mce_log(LL_DEBUG, "autorelock canceled: kbd slide opened");
autorelock_trigger = AUTORELOCK_NO_TRIGGERS;
}

if( !display_on &&
proximity_state_actual == COVER_OPEN &&
lid_cover_policy_state == COVER_OPEN ) {
mce_log(LL_DEBUG, "autorelock primed: on kbd slide close");
autorelock_trigger = AUTORELOCK_KBD_SLIDE;

mce_log(LL_DEBUG, "display -> on");
execute_datapipe(&display_state_req_pipe,
GINT_TO_POINTER(MCE_DISPLAY_ON),
USE_INDATA, CACHE_INDATA);
execute_datapipe(&tk_lock_pipe,
GINT_TO_POINTER(LOCK_OFF),
USE_INDATA, CACHE_INDATA);
}
break;

case COVER_CLOSED:
if( autorelock_trigger == AUTORELOCK_KBD_SLIDE ) {
mce_log(LL_DEBUG, "autorelock triggered: kbd slide closed");
autorelock_trigger = AUTORELOCK_NO_TRIGGERS;

mce_log(LL_DEBUG, "display -> off");

execute_datapipe(&tk_lock_pipe,
GINT_TO_POINTER(LOCK_ON),
USE_INDATA, CACHE_INDATA);

execute_datapipe(&display_state_req_pipe,
GINT_TO_POINTER(MCE_DISPLAY_OFF),
USE_INDATA, CACHE_INDATA);
}

/* In any case closing the kbd slide will cancel
* other autorelock triggers */
if( autorelock_trigger != AUTORELOCK_NO_TRIGGERS ) {
mce_log(LL_DEBUG, "autorelock canceled: kbd slide closed");
autorelock_trigger = AUTORELOCK_NO_TRIGGERS;
}
break;

default:
break;
}
}

/* ========================================================================= *
* AUTOLOCK STATE MACHINE
*
Expand Down Expand Up @@ -2860,6 +2878,9 @@ static void tklock_uiexcept_rethink(void)
else if( !exdata.insync ) {
mce_log(LL_NOTICE, "NOT UNBLANKING; still out of sync");
}
else if( lid_cover_policy_state == COVER_CLOSED ) {
mce_log(LL_NOTICE, "NOT UNBLANKING; lid covered");
}
else if( proximity_state_effective == COVER_CLOSED ) {
mce_log(LL_NOTICE, "NOT UNBLANKING; proximity covered");
}
Expand Down Expand Up @@ -2951,7 +2972,8 @@ static void tklock_uiexcept_finish(void)
* we use raw sensor data here instead of the filtered
* proximity_state_effective that is normally used
* with unblanking policies. */
if( proximity_state_actual != COVER_OPEN )
if( proximity_state_actual != COVER_OPEN ||
lid_cover_policy_state != COVER_OPEN )
break;

execute_datapipe(&display_state_req_pipe,
Expand Down Expand Up @@ -3278,6 +3300,10 @@ static void tklock_lpmui_rethink(void)
if( exception_state != UIEXC_NONE )
goto EXIT;

/* when lid is closed */
if( lid_cover_policy_state != COVER_OPEN )
goto EXIT;

/* or when proximity is covered */
if( proximity_state_effective != COVER_OPEN )
goto EXIT;
Expand Down Expand Up @@ -3661,8 +3687,9 @@ static void tklock_evctrl_rethink(void)
* only when proximity sensor is not covered / proximity
* blocks input feature is disabled */
if( grab_ts ||
!proximity_blocks_touch ||
proximity_state_effective == COVER_OPEN ) {
( (proximity_state_effective == COVER_OPEN ||
!proximity_blocks_touch) &&
(lid_cover_policy_state == COVER_OPEN) ) ) {
execute_datapipe(&touch_grab_wanted_pipe,
GINT_TO_POINTER(grab_ts),
USE_INDATA, CACHE_INDATA);
Expand Down
4 changes: 4 additions & 0 deletions tools/mcetool.c
Expand Up @@ -4805,6 +4805,8 @@ static const mce_opt_t options[] =
.usage =
"set the doubletap wakeup mode; valid modes are:\n"
"'never', 'always', 'proximity'\n"
"\n"
"Note: proximity setting applies for lid sensor too."
},
{
.name = "set-powerkey-action",
Expand All @@ -4817,6 +4819,8 @@ static const mce_opt_t options[] =
" always - always act\n"
" proximity - act if proximity sensor is not covered\n"
" proximity2 - act if display is on or PS not covered\n"
"\n"
"Note: proximity settings apply for lid sensor too."
},
{
.name = "set-powerkey-blanking",
Expand Down

0 comments on commit 9c86840

Please sign in to comment.