Skip to content

Commit

Permalink
[battery-udev] Expose battery charging state. JB#44852
Browse files Browse the repository at this point in the history
For example CSD tests need more detailed information about battery
charging state.

Track udev battery status, expose it as mce battery state on D-Bus.

Required D-Bus constants are included in mce-dev >= 1.28.0.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Oct 7, 2019
1 parent b32e355 commit 513dbb5
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 26 deletions.
74 changes: 74 additions & 0 deletions datapipe.c
Expand Up @@ -116,6 +116,7 @@ static const char *datapipe_hook_tklock_request_value (gconstpointer data);
static const char *datapipe_hook_charger_state_value (gconstpointer data);
static const char *datapipe_hook_charger_type_value (gconstpointer data);
static const char *datapipe_hook_battery_status_value (gconstpointer data);
static const char *datapipe_hook_battery_state_value (gconstpointer data);
static const char *datapipe_hook_camera_button_state_value(gconstpointer data);
static const char *datapipe_hook_audio_route_value (gconstpointer data);
static const char *datapipe_hook_usb_cable_state_value (gconstpointer data);
Expand Down Expand Up @@ -249,6 +250,13 @@ const char *tklock_status_repr(int status);
const char *battery_status_repr (battery_status_t state);
const char *battery_status_to_dbus(battery_status_t state);

/* ------------------------------------------------------------------------- *
* BATTERY_STATE
* ------------------------------------------------------------------------- */

const char *battery_state_repr (battery_state_t state);
const char *battery_state_to_dbus(battery_state_t state);

/* ------------------------------------------------------------------------- *
* ALARM_STATE
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -506,6 +514,14 @@ datapipe_hook_battery_status_value(gconstpointer data)
}
#define datapipe_hook_battery_status_change 0

static const char *
datapipe_hook_battery_state_value(gconstpointer data)
{
battery_state_t value = GPOINTER_TO_INT(data);
return battery_state_repr(value);
}
#define datapipe_hook_battery_state_change 0

static const char *
datapipe_hook_camera_button_state_value(gconstpointer data)
{
Expand Down Expand Up @@ -724,6 +740,9 @@ datapipe_t charger_state_pipe = DATAPIPE_INIT(charger_state, c
/** Battery status; read only */
datapipe_t battery_status_pipe = DATAPIPE_INIT(battery_status, battery_status, BATTERY_STATUS_UNDEF, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);

/** Battery state; read only */
datapipe_t battery_state_pipe = DATAPIPE_INIT(battery_state, battery_state, BATTERY_STATE_UNKNOWN, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);

/** Battery charge level; read only */
datapipe_t battery_level_pipe = DATAPIPE_INIT(battery_level, int, BATTERY_LEVEL_INITIAL, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);

Expand Down Expand Up @@ -1303,6 +1322,7 @@ void mce_datapipe_quit(void)
datapipe_free(&topmost_window_pid_pipe);
datapipe_free(&camera_button_state_pipe);
datapipe_free(&battery_status_pipe);
datapipe_free(&battery_state_pipe);
datapipe_free(&charger_type_pipe);
datapipe_free(&charger_state_pipe);
datapipe_free(&interaction_expected_pipe);
Expand Down Expand Up @@ -1810,6 +1830,60 @@ const char *tklock_status_repr(int status)
return repr;
}

/** Convert battery_state_t enum to human readable string
*
* @param state battery_state_t enumeration value
*
* @return human readable representation of state
*/
const char *
battery_state_repr(battery_state_t state)
{
const char *repr = "invalid";

switch( state ) {
case BATTERY_STATE_UNKNOWN: repr = "unknown"; break;
case BATTERY_STATE_CHARGING: repr = "charging"; break;
case BATTERY_STATE_DISCHARGING: repr = "discharging"; break;
case BATTERY_STATE_NOT_CHARGING: repr = "not_charging"; break;
case BATTERY_STATE_FULL: repr = "full"; break;
default: break;
}

return repr;
}

/** Convert battery_state_t enum to dbus argument string
*
* @param state battery_state_t enumeration value
*
* @return representation of state for use over dbus
*/
const char *
battery_state_to_dbus(battery_state_t state)
{
const char *res = MCE_BATTERY_STATE_UNKNOWN;

switch( state ) {
case BATTERY_STATE_CHARGING:
res = MCE_BATTERY_STATE_CHARGING;
break;
case BATTERY_STATE_DISCHARGING:
res = MCE_BATTERY_STATE_DISCHARGING;
break;
case BATTERY_STATE_NOT_CHARGING:
res = MCE_BATTERY_STATE_NOT_CHARGING;
break;
case BATTERY_STATE_FULL:
res = MCE_BATTERY_STATE_FULL;
break;
default:
break;
}

return res;
}

/** Convert battery_status_t enum to human readable string
*
* @param state battery_status_t enumeration value
Expand Down
1 change: 1 addition & 0 deletions datapipe.h
Expand Up @@ -257,6 +257,7 @@ extern datapipe_t interaction_expected_pipe;
extern datapipe_t charger_type_pipe;
extern datapipe_t charger_state_pipe;
extern datapipe_t battery_status_pipe;
extern datapipe_t battery_state_pipe;
extern datapipe_t battery_level_pipe;
extern datapipe_t topmost_window_pid_pipe;
extern datapipe_t camera_button_state_pipe;
Expand Down
115 changes: 115 additions & 0 deletions mce-common.c
Expand Up @@ -85,6 +85,8 @@ static void common_dbus_send_charger_state (DBusMessage *const req);
static gboolean common_dbus_get_charger_state_cb (DBusMessage *const req);
static void common_dbus_send_battery_status (DBusMessage *const req);
static gboolean common_dbus_get_battery_status_cb (DBusMessage *const req);
static void common_dbus_send_battery_state (DBusMessage *const req);
static gboolean common_dbus_get_battery_state_cb (DBusMessage *const req);
static void common_dbus_send_battery_level (DBusMessage *const req);
static gboolean common_dbus_get_battery_level_cb (DBusMessage *const req);
static gboolean common_dbus_initial_cb (gpointer aptr);
Expand All @@ -99,6 +101,7 @@ static void common_datapipe_usb_cable_state_cb (gconstpointer data);
static void common_datapipe_charger_type_cb (gconstpointer data);
static void common_datapipe_charger_state_cb (gconstpointer data);
static void common_datapipe_battery_status_cb (gconstpointer data);
static void common_datapipe_battery_state_cb (gconstpointer data);
static void common_datapipe_battery_level_cb (gconstpointer data);
static void common_datapipe_proximity_sensor_actual_cb(gconstpointer data);
static void common_datapipe_init (void);
Expand Down Expand Up @@ -127,6 +130,9 @@ static charger_state_t charger_state = CHARGER_STATE_UNDEF;
/** Battery status; assume undefined */
static battery_status_t battery_status = BATTERY_STATUS_UNDEF;

/** Battery state; assume unknown */
static battery_state_t battery_state = BATTERY_STATE_UNKNOWN;

/** Battery charge level: assume 100% */
static gint battery_level = BATTERY_LEVEL_INITIAL;

Expand Down Expand Up @@ -589,6 +595,69 @@ common_dbus_get_battery_status_cb(DBusMessage *const req)
return TRUE;
}

/* ------------------------------------------------------------------------- *
* battery_state
* ------------------------------------------------------------------------- */

/** Send battery_state D-Bus signal / method call reply
*
* @param req method call message to reply, or NULL to send signal
*/
static void
common_dbus_send_battery_state(DBusMessage *const req)
{
static const char *last = 0;

DBusMessage *msg = NULL;

const char *value = battery_state_to_dbus(battery_state);

if( req ) {
msg = dbus_new_method_reply(req);
}
else if( last == value ) {
goto EXIT;
}
else {
last = value;
msg = dbus_new_signal(MCE_SIGNAL_PATH,
MCE_SIGNAL_IF,
MCE_BATTERY_STATE_SIG);
}

if( !dbus_message_append_args(msg,
DBUS_TYPE_STRING, &value,
DBUS_TYPE_INVALID) )
goto EXIT;

mce_log(LL_DEBUG, "%s: %s = %s",
req ? "reply" : "broadcast",
"battery_state", value);

dbus_send_message(msg), msg = 0;

EXIT:

if( msg )
dbus_message_unref(msg);
}

/** Callback for handling battery_state D-Bus queries
*
* @param req method call message to reply
*/
static gboolean
common_dbus_get_battery_state_cb(DBusMessage *const req)
{
mce_log(LL_DEBUG, "battery_state query from: %s",
mce_dbus_get_message_sender_ident(req));

if( !dbus_message_get_no_reply(req) )
common_dbus_send_battery_state(req);

return TRUE;
}

/* ------------------------------------------------------------------------- *
* battery_level
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -694,6 +763,13 @@ static mce_dbus_handler_t common_dbus_handlers[] =
.args =
" <arg name=\"battery_status\" type=\"s\"/>\n"
},
{
.interface = MCE_SIGNAL_IF,
.name = MCE_BATTERY_STATE_SIG,
.type = DBUS_MESSAGE_TYPE_SIGNAL,
.args =
" <arg name=\"battery_state\" type=\"s\"/>\n"
},
{
.interface = MCE_SIGNAL_IF,
.name = MCE_BATTERY_LEVEL_SIG,
Expand Down Expand Up @@ -734,6 +810,14 @@ static mce_dbus_handler_t common_dbus_handlers[] =
.args =
" <arg direction=\"out\" name=\"battery_status\" type=\"s\"/>\n"
},
{
.interface = MCE_REQUEST_IF,
.name = MCE_BATTERY_STATE_GET,
.type = DBUS_MESSAGE_TYPE_METHOD_CALL,
.callback = common_dbus_get_battery_state_cb,
.args =
" <arg direction=\"out\" name=\"battery_state\" type=\"s\"/>\n"
},
{
.interface = MCE_REQUEST_IF,
.name = MCE_BATTERY_LEVEL_GET,
Expand Down Expand Up @@ -771,6 +855,7 @@ static gboolean common_dbus_initial_cb(gpointer aptr)
common_dbus_send_charger_type(0);
common_dbus_send_charger_state(0);
common_dbus_send_battery_status(0);
common_dbus_send_battery_state(0);
common_dbus_send_battery_level(0);

common_dbus_initial_id = 0;
Expand Down Expand Up @@ -918,6 +1003,32 @@ static void common_datapipe_battery_status_cb(gconstpointer data)
return;
}

/* ------------------------------------------------------------------------- *
* battery_state
* ------------------------------------------------------------------------- */

/** Callback for handling battery_state_pipe state changes
*
* @param data battery_state (as void pointer)
*/
static void common_datapipe_battery_state_cb(gconstpointer data)
{
battery_state_t prev = battery_state;
battery_state = GPOINTER_TO_INT(data);

if( battery_state == prev )
goto EXIT;

mce_log(LL_DEBUG, "battery_state = %s -> %s",
battery_state_repr(prev),
battery_state_repr(battery_state));

common_dbus_send_battery_state(0);

EXIT:
return;
}

/* ------------------------------------------------------------------------- *
* battery_level
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -992,6 +1103,10 @@ static datapipe_handler_t common_datapipe_handlers[] =
.datapipe = &battery_status_pipe,
.output_cb = common_datapipe_battery_status_cb,
},
{
.datapipe = &battery_state_pipe,
.output_cb = common_datapipe_battery_state_cb,
},
{
.datapipe = &battery_level_pipe,
.output_cb = common_datapipe_battery_level_cb,
Expand Down
3 changes: 3 additions & 0 deletions mce.conf
Expand Up @@ -219,6 +219,9 @@
<allow send_destination="com.nokia.mce"
send_interface="com.nokia.mce.request"
send_member="get_battery_status"/>
<allow send_destination="com.nokia.mce"
send_interface="com.nokia.mce.request"
send_member="get_battery_state"/>
<allow send_destination="com.nokia.mce"
send_interface="com.nokia.mce.request"
send_member="get_battery_level"/>
Expand Down
13 changes: 13 additions & 0 deletions mce.h
Expand Up @@ -313,6 +313,19 @@ const char *tklock_status_repr(int status);
/** Assumed initial battery level */
#define BATTERY_LEVEL_INITIAL 100

/** Raw udev battery status */
typedef enum
{
BATTERY_STATE_UNKNOWN,
BATTERY_STATE_CHARGING,
BATTERY_STATE_DISCHARGING,
BATTERY_STATE_NOT_CHARGING,
BATTERY_STATE_FULL,
} battery_state_t;

const char *battery_state_repr(battery_state_t state);
const char *battery_state_to_dbus(battery_state_t state);

/** Battery status */
typedef enum {
BATTERY_STATUS_UNDEF = -1, /**< Battery status not known */
Expand Down

0 comments on commit 513dbb5

Please sign in to comment.