Skip to content

Commit

Permalink
[callstate] Make it possible to ignore incoming calls. Fixes JB#37565
Browse files Browse the repository at this point in the history
The existing workaround for allowing powerkey to be used for blanking the
display after ignoring an incoming calls leaves the callstate to ringing
state. When ignoring incoming call while already having an active call,
this effectively leaves in-call proximity blanking disabled.

Add ignored call state enum value for use within mce callstate plugin.

Separate call state enum <-> string translations functions dealing with
D-Bus interface from the ones dealing with internal diagnostic logging.

Add ignore_incoming_calls datapipe and bind it to ignoring all calls that
are currently in the ringing state and re-evaluating overall call state.

Execute the ignore_incoming_calls datapipe when D-Bus message indicating
that call ui has ignored incoming calls is received.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Feb 21, 2017
1 parent ba8186a commit 42ccef8
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 9 deletions.
46 changes: 42 additions & 4 deletions datapipe.c
Expand Up @@ -132,6 +132,13 @@ datapipe_struct submode_pipe;
/** The call state */
datapipe_struct call_state_pipe;

/** The ignore incoming call "state".
*
* Note: Related actions happen when true is executed on the
* datapipe, but the cached value always remains at false.
*/
datapipe_struct ignore_incoming_call_pipe;

/** The call type */
datapipe_struct call_type_pipe;

Expand Down Expand Up @@ -720,6 +727,8 @@ void mce_datapipe_init(void)
0, GINT_TO_POINTER(0));
setup_datapipe(&call_state_pipe, READ_ONLY, DONT_FREE_CACHE,
0, GINT_TO_POINTER(CALL_STATE_NONE));
setup_datapipe(&ignore_incoming_call_pipe, READ_ONLY, DONT_FREE_CACHE,
0, GINT_TO_POINTER(false));
setup_datapipe(&call_type_pipe, READ_ONLY, DONT_FREE_CACHE,
0, GINT_TO_POINTER(NORMAL_CALL));
setup_datapipe(&alarm_ui_state_pipe, READ_ONLY, DONT_FREE_CACHE,
Expand Down Expand Up @@ -889,6 +898,7 @@ void mce_datapipe_quit(void)
free_datapipe(&alarm_ui_state_pipe);
free_datapipe(&call_type_pipe);
free_datapipe(&call_state_pipe);
free_datapipe(&ignore_incoming_call_pipe);
free_datapipe(&master_radio_pipe);
free_datapipe(&system_state_pipe);
free_datapipe(&heartbeat_pipe);
Expand Down Expand Up @@ -1250,19 +1260,47 @@ static const mce_translation_t call_state_translation[] =
}
};

/** MCE call state number to string
/** MCE call state number to string on D-Bus
*/
const char *call_state_repr(call_state_t state)
const char *call_state_to_dbus(call_state_t state)
{
return mce_translate_int_to_string(call_state_translation, state);
}

/** String to MCE call state number */
call_state_t call_state_parse(const char *name)
/** String from D-Bus to MCE call state number */
call_state_t call_state_from_dbus(const char *name)
{
return mce_translate_string_to_int(call_state_translation, name);
}

/** MCE call state number to string (for diagnostic logging)
*/
const char *call_state_repr(call_state_t state)
{
const char *repr = "invalid";

switch( state ) {
case CALL_STATE_NONE:
repr = MCE_CALL_STATE_NONE;
break;
case CALL_STATE_RINGING:
repr = MCE_CALL_STATE_RINGING;
break;
case CALL_STATE_ACTIVE:
repr = MCE_CALL_STATE_ACTIVE;
break;
case CALL_STATE_SERVICE:
repr = MCE_CALL_STATE_SERVICE;
break;
case CALL_STATE_IGNORED:
repr = "ignored";
break;
default:
break;
}
return repr;
}

/** Mapping of call type integer <-> call type string */
static const mce_translation_t call_type_translation[] =
{
Expand Down
1 change: 1 addition & 0 deletions datapipe.h
Expand Up @@ -120,6 +120,7 @@ extern datapipe_struct system_state_pipe;
extern datapipe_struct master_radio_pipe;
extern datapipe_struct submode_pipe;
extern datapipe_struct call_state_pipe;
extern datapipe_struct ignore_incoming_call_pipe;
extern datapipe_struct call_type_pipe;
extern datapipe_struct tk_lock_pipe;
extern datapipe_struct charger_state_pipe;
Expand Down
7 changes: 5 additions & 2 deletions mce.h
Expand Up @@ -226,11 +226,14 @@ typedef enum {
/** There's an active call */
CALL_STATE_ACTIVE = 2,
/** The device is in service state */
CALL_STATE_SERVICE = 3
CALL_STATE_SERVICE = 3,
/** Ringing call that is ignored by call ui and mce */
CALL_STATE_IGNORED = 4,
} call_state_t;

const char *call_state_repr(call_state_t state);
call_state_t call_state_parse(const char *name);
const char *call_state_to_dbus(call_state_t state);
call_state_t call_state_from_dbus(const char *name);

/** Call type */
typedef enum {
Expand Down
151 changes: 148 additions & 3 deletions modules/callstate.c
Expand Up @@ -220,6 +220,20 @@ static void clients_get_state (const char *dbus_name, ofono_vcall_t *vcall);
static void clients_init (void);
static void clients_quit (void);

/** Mark incoming vcall as ignored
*
* @param self oFono voice call object
*/
static void
ofono_vcall_ignore_incoming_call(ofono_vcall_t *self)
{
if( self->state == CALL_STATE_RINGING ) {
mce_log(LL_DEBUG, "ignoring incoming vcall: %s",
self->name ?: "unnamed");
self->state = CALL_STATE_IGNORED;
}
}

/** Merge emergency data to oFono voice call object
*
* @param self oFono voice call object
Expand Down Expand Up @@ -1208,6 +1222,39 @@ static const ofono_vcall_t clients_vcall_def =
.type = NORMAL_CALL,
};

/** Enumeration callback for ignoring incoming calls
*
* @param key D-Bus name of the client (as void pointer)
* @param val ofono_vcall_t data of the client (as void pointer)
* @param aptr NULL (unused)
*/
static void
clients_ignore_incoming_calls_cb(gpointer key, gpointer val, gpointer aptr)
{
(void)key;
(void)aptr;

ofono_vcall_t *simulated = val;

ofono_vcall_ignore_incoming_call(simulated);
}

/** Mark all incoming calls as ignored
*
* @param combined ofono_vcall_t data to update
*/
static void
clients_ignore_incoming_calls(void)
{
if( !clients_state_lut )
goto EXIT;

g_hash_table_foreach(clients_state_lut, clients_ignore_incoming_calls_cb, 0);

EXIT:
return;
}

/** Enumeration callback for evaluating combined dbus client state
*
* @param key D-Bus name of the client (as void pointer)
Expand Down Expand Up @@ -1336,7 +1383,7 @@ send_call_state(DBusMessage *const method_call,
if (call_state != NULL)
sstate = call_state;
else
sstate = call_state_repr(datapipe_get_gint(call_state_pipe));
sstate = call_state_to_dbus(datapipe_get_gint(call_state_pipe));

if (call_type != NULL)
stype = call_type;
Expand Down Expand Up @@ -1455,7 +1502,7 @@ change_call_state_dbus_cb(DBusMessage *const msg)
}

/* Convert call state to enum */
curr.state = call_state_parse(state);
curr.state = call_state_from_dbus(state);
if( curr.state == CALL_STATE_INVALID ) {
mce_log(LL_WARN, "Invalid call state received; request ignored");
goto EXIT;
Expand Down Expand Up @@ -1539,6 +1586,31 @@ get_call_state_dbus_cb(DBusMessage *const msg)
* MANAGE CALL STATE TRANSITIONS
* ========================================================================= */

/** Callback for ignoring incoming voice call states
*/
static void
call_state_ignore_incoming_calls_cb(gpointer key, gpointer value, gpointer aptr)
{
(void)key; //const char *name = key;
(void)aptr;
ofono_vcall_t *vcall = value;

ofono_vcall_ignore_incoming_call(vcall);
}

/** Internally ignore incoming calls
*/
static void
call_state_ignore_incoming_calls(void)
{
/* Consider simulated call states */
clients_ignore_incoming_calls();

/* consider ofono voice call properties */
if( vcalls_lut )
g_hash_table_foreach(vcalls_lut, call_state_ignore_incoming_calls_cb, 0);
}

/** Callback for merging voice call stats
*/
static void
Expand Down Expand Up @@ -1673,7 +1745,7 @@ call_state_rethink_forced(void)
}

/* ========================================================================= *
* MODULE LOAD / UNLOAD
* D-BUS CALLBACKS
* ========================================================================= */

/** Array of dbus message handlers */
Expand Down Expand Up @@ -1772,6 +1844,73 @@ static void mce_callstate_quit_dbus(void)
mce_dbus_handler_unregister_array(callstate_dbus_handlers);
}

/* ========================================================================= *
* DATAPIPE CALLBACKS
* ========================================================================= */

/** Handle call state change notifications
*
* @param data call state (as void pointer)
*/
static void
callstate_datapipe_ignore_incoming_call_cb(gconstpointer data)
{
bool ignore_incoming_call = GPOINTER_TO_INT(data);

mce_log(LL_DEBUG, "ignore_incoming_call = %s",
ignore_incoming_call ? "YES" : "NO");

// Note: Edge triggered
if( !ignore_incoming_call )
goto EXIT;

call_state_ignore_incoming_calls();
call_state_rethink_now();

EXIT:
return;
}

/** Array of datapipe handlers */
static datapipe_handler_t callstate_datapipe_handlers[] =
{
// output triggers
{
.datapipe = &ignore_incoming_call_pipe,
.output_cb = callstate_datapipe_ignore_incoming_call_cb,
},
// sentinel
{
.datapipe = 0,
}
};

static datapipe_bindings_t callstate_datapipe_bindings =
{
.module = "callstate",
.handlers = callstate_datapipe_handlers,
};

/** Append triggers/filters to datapipes
*/
static void
callstate_datapipes_init(void)
{
datapipe_bindings_init(&callstate_datapipe_bindings);
}

/** Remove triggers/filters from datapipes
*/
static void
callstate_datapipes_quit(void)
{
datapipe_bindings_quit(&callstate_datapipe_bindings);
}

/* ========================================================================= *
* MODULE LOAD / UNLOAD
* ========================================================================= */

/**
* Init function for the call state module
*
Expand All @@ -1793,6 +1932,9 @@ const gchar *g_module_check_init(GModule *module)
vcalls_init();
modems_init();

/* install datapipe hooks */
callstate_datapipes_init();

/* install dbus message handlers */
mce_callstate_init_dbus();

Expand All @@ -1817,6 +1959,9 @@ void g_module_unload(GModule *module)
/* remove dbus message handlers */
mce_callstate_quit_dbus();

/* remove datapipe hooks */
callstate_datapipes_quit();

/* remove all timers & callbacks */
mce_wltimer_delete(call_state_rethink_tmr),
call_state_rethink_tmr = 0;
Expand Down
8 changes: 8 additions & 0 deletions powerkey.c
Expand Up @@ -2126,7 +2126,15 @@ static gboolean pwrkey_dbus_ignore_incoming_call_cb(DBusMessage *const req)

if( call_state == CALL_STATE_RINGING ) {
mce_log(LL_DEBUG, "start ignoring incoming calls");

/* Update powerkey module specific toggle */
pwrkey_ignore_incoming_call = true;

/* Make also callstate plugin ignore incoming calls. This
* should lead to call_state changing from RINGING to ACTIVE
* or NONE depending on whether there are other calls or not. */
execute_datapipe(&ignore_incoming_call_pipe, GINT_TO_POINTER(true),
USE_INDATA, DONT_CACHE_INDATA);
}

if( !dbus_message_get_no_reply(req) ) {
Expand Down

0 comments on commit 42ccef8

Please sign in to comment.