diff --git a/.depend b/.depend
index dadcbab1..f42a3969 100644
--- a/.depend
+++ b/.depend
@@ -1344,6 +1344,16 @@ tklock.pic.o:\
systemui/tklock-dbus-names.h\
tklock.h\
+tools/dummy_compositor.o:\
+ tools/dummy_compositor.c\
+ builtin-gconf.h\
+ mce-dbus.h\
+
+tools/dummy_compositor.pic.o:\
+ tools/dummy_compositor.c\
+ builtin-gconf.h\
+ mce-dbus.h\
+
tools/evdev_trace.o:\
tools/evdev_trace.c\
evdev.h\
@@ -1356,16 +1366,6 @@ tools/evdev_trace.pic.o:\
mce-log.h\
tools/fileusers.h\
-tools/dummy_compositor.o:\
- tools/dummy_compositor.c\
- builtin-gconf.h\
- mce-dbus.h\
-
-tools/dummy_compositor.pic.o:\
- tools/dummy_compositor.c\
- builtin-gconf.h\
- mce-dbus.h\
-
tools/fileusers.o:\
tools/fileusers.c\
mce-log.h\
diff --git a/datapipe.c b/datapipe.c
index 9154a320..97f59695 100644
--- a/datapipe.c
+++ b/datapipe.c
@@ -5,6 +5,7 @@
*
* Copyright © 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2014-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author David Weinehall
* @author Simo Piiroinen
@@ -113,6 +114,7 @@ static const char *datapipe_hook_call_state_value (gconstpointer data);
static const char *datapipe_hook_call_type_value (gconstpointer data);
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_camera_button_state_value(gconstpointer data);
static const char *datapipe_hook_audio_route_value (gconstpointer data);
@@ -202,6 +204,13 @@ const char *service_state_repr(service_state_t state);
const char *usb_cable_state_repr (usb_cable_state_t state);
const char *usb_cable_state_to_dbus(usb_cable_state_t state);
+/* ------------------------------------------------------------------------- *
+ * CHARGER_TYPE
+ * ------------------------------------------------------------------------- */
+
+const char *charger_type_repr (charger_type_t type);
+const char *charger_type_to_dbus(charger_type_t type);
+
/* ------------------------------------------------------------------------- *
* CHARGER_STATE
* ------------------------------------------------------------------------- */
@@ -473,6 +482,14 @@ datapipe_hook_tklock_request_value(gconstpointer data)
}
#define datapipe_hook_tklock_request_change 0
+static const char *
+datapipe_hook_charger_type_value(gconstpointer data)
+{
+ charger_type_t value = GPOINTER_TO_INT(data);
+ return charger_type_repr(value);
+}
+#define datapipe_hook_charger_type_change 0
+
static const char *
datapipe_hook_charger_state_value(gconstpointer data)
{
@@ -698,6 +715,9 @@ datapipe_t tklock_request_pipe = DATAPIPE_INIT(tklock_request,
/** UI side is in a state where user interaction is expected */
datapipe_t interaction_expected_pipe = DATAPIPE_INIT(interaction_expected, boolean, false, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);
+/** Charger type; read only */
+datapipe_t charger_type_pipe = DATAPIPE_INIT(charger_type, charger_type, CHARGER_TYPE_NONE, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);
+
/** Charger state; read only */
datapipe_t charger_state_pipe = DATAPIPE_INIT(charger_state, charger_state, CHARGER_STATE_UNDEF, 0, DATAPIPE_FILTERING_DENIED, DATAPIPE_CACHE_DEFAULT);
@@ -1283,6 +1303,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(&charger_type_pipe);
datapipe_free(&charger_state_pipe);
datapipe_free(&interaction_expected_pipe);
datapipe_free(&tklock_request_pipe);
@@ -1614,6 +1635,51 @@ const char *usb_cable_state_to_dbus(usb_cable_state_t state)
return res;
}
+/** Convert charger_type_t enum to human readable string
+ *
+ * @param type charger_type_t enumeration value
+ *
+ * @return human readable representation of type
+ */
+const char *
+charger_type_repr(charger_type_t type)
+{
+ const char *repr = "unknown";
+ switch( type ) {
+ case CHARGER_TYPE_NONE: repr = "none"; break;
+ case CHARGER_TYPE_USB: repr = "usb"; break;
+ case CHARGER_TYPE_DCP: repr = "dcp"; break;
+ case CHARGER_TYPE_HVDCP: repr = "hwdcp"; break;
+ case CHARGER_TYPE_CDP: repr = "cdp"; break;
+ case CHARGER_TYPE_WIRELESS: repr = "wireless"; break;
+ case CHARGER_TYPE_OTHER: repr = "other"; break;
+ default: break;
+ }
+ return repr;
+}
+
+/** Convert charger_type_t enum to dbus argument string
+ *
+ * @param type charger_type_t enumeration value
+ *
+ * @return representation of type for use over dbus
+ */
+const char *
+charger_type_to_dbus(charger_type_t type)
+{
+ const char *repr = MCE_CHARGER_TYPE_OTHER;
+ switch( type ) {
+ case CHARGER_TYPE_NONE: repr = MCE_CHARGER_TYPE_NONE; break;
+ case CHARGER_TYPE_USB: repr = MCE_CHARGER_TYPE_USB; break;
+ case CHARGER_TYPE_DCP: repr = MCE_CHARGER_TYPE_DCP; break;
+ case CHARGER_TYPE_HVDCP: repr = MCE_CHARGER_TYPE_HVDCP; break;
+ case CHARGER_TYPE_CDP: repr = MCE_CHARGER_TYPE_CDP; break;
+ case CHARGER_TYPE_WIRELESS: repr = MCE_CHARGER_TYPE_WIRELESS; break;
+ default: break;
+ }
+ return repr;
+}
+
/** Convert charger_state_t enum to human readable string
*
* @param state charger_state_t enumeration value
diff --git a/datapipe.h b/datapipe.h
index 5d8a48fb..a06b2581 100644
--- a/datapipe.h
+++ b/datapipe.h
@@ -4,6 +4,7 @@
*
* Copyright © 2007 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2014-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author David Weinehall
* @author: Simo Piiroinen
@@ -253,6 +254,7 @@ extern datapipe_t ignore_incoming_call_event_pipe;
extern datapipe_t call_type_pipe;
extern datapipe_t tklock_request_pipe;
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_level_pipe;
diff --git a/mce-common.c b/mce-common.c
index e4032a83..e65f60f0 100644
--- a/mce-common.c
+++ b/mce-common.c
@@ -3,6 +3,7 @@
* Common state logic for Mode Control Entity
*
* Copyright (C) 2017-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author Simo Piiroinen
*
@@ -78,6 +79,8 @@ static void common_on_proximity_quit (void);
static void common_dbus_send_usb_cable_state (DBusMessage *const req);
static gboolean common_dbus_get_usb_cable_state_cb(DBusMessage *const req);
+static void common_dbus_send_charger_type (DBusMessage *const req);
+static gboolean common_dbus_get_charger_type_cb (DBusMessage *const req);
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);
@@ -93,6 +96,7 @@ static void common_dbus_quit (void);
* ------------------------------------------------------------------------- */
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_level_cb (gconstpointer data);
@@ -114,6 +118,9 @@ void mce_common_quit(void);
/** USB cable status; assume undefined */
static usb_cable_state_t usb_cable_state = USB_CABLE_UNDEF;
+/** Charger type; assume none */
+static charger_type_t charger_type = CHARGER_TYPE_NONE;
+
/** Charger state; assume undefined */
static charger_state_t charger_state = CHARGER_STATE_UNDEF;
@@ -393,6 +400,69 @@ common_dbus_get_usb_cable_state_cb(DBusMessage *const req)
return TRUE;
}
+/* ------------------------------------------------------------------------- *
+ * charger_type
+ * ------------------------------------------------------------------------- */
+
+/** Send charger_type D-Bus signal / method call reply
+ *
+ * @param req method call message to reply, or NULL to send signal
+ */
+static void
+common_dbus_send_charger_type(DBusMessage *const req)
+{
+ static const char *last = 0;
+
+ DBusMessage *msg = NULL;
+
+ const char *value = charger_type_to_dbus(charger_type);
+
+ 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_CHARGER_TYPE_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",
+ "charger_type", value);
+
+ dbus_send_message(msg), msg = 0;
+
+EXIT:
+
+ if( msg )
+ dbus_message_unref(msg);
+}
+
+/** Callback for handling charger_type D-Bus queries
+ *
+ * @param req method call message to reply
+ */
+static gboolean
+common_dbus_get_charger_type_cb(DBusMessage *const req)
+{
+ mce_log(LL_DEBUG, "charger_type query from: %s",
+ mce_dbus_get_message_sender_ident(req));
+
+ if( !dbus_message_get_no_reply(req) )
+ common_dbus_send_charger_type(req);
+
+ return TRUE;
+}
+
/* ------------------------------------------------------------------------- *
* charger_state
* ------------------------------------------------------------------------- */
@@ -562,7 +632,7 @@ common_dbus_send_battery_level(DBusMessage *const req)
mce_log(LL_DEBUG, "%s: %s = %d",
req ? "reply" : "broadcast",
- "charger_state", value);
+ "battery_level", value);
dbus_send_message(msg), msg = 0;
@@ -603,6 +673,13 @@ static mce_dbus_handler_t common_dbus_handlers[] =
.args =
" \n"
},
+ {
+ .interface = MCE_SIGNAL_IF,
+ .name = MCE_CHARGER_TYPE_SIG,
+ .type = DBUS_MESSAGE_TYPE_SIGNAL,
+ .args =
+ " \n"
+ },
{
.interface = MCE_SIGNAL_IF,
.name = MCE_CHARGER_STATE_SIG,
@@ -633,6 +710,14 @@ static mce_dbus_handler_t common_dbus_handlers[] =
.args =
" \n"
},
+ {
+ .interface = MCE_REQUEST_IF,
+ .name = MCE_CHARGER_TYPE_GET,
+ .type = DBUS_MESSAGE_TYPE_METHOD_CALL,
+ .callback = common_dbus_get_charger_type_cb,
+ .args =
+ " \n"
+ },
{
.interface = MCE_REQUEST_IF,
.name = MCE_CHARGER_STATE_GET,
@@ -683,6 +768,7 @@ static gboolean common_dbus_initial_cb(gpointer aptr)
* some values to undefined state.
*/
common_dbus_send_usb_cable_state(0);
+ common_dbus_send_charger_type(0);
common_dbus_send_charger_state(0);
common_dbus_send_battery_status(0);
common_dbus_send_battery_level(0);
@@ -754,6 +840,32 @@ static void common_datapipe_usb_cable_state_cb(gconstpointer data)
return;
}
+/* ------------------------------------------------------------------------- *
+ * charger_type
+ * ------------------------------------------------------------------------- */
+
+/** Callback for handling charger_type_pipe state changes
+ *
+ * @param data charger_type (as void pointer)
+ */
+static void common_datapipe_charger_type_cb(gconstpointer data)
+{
+ charger_type_t prev = charger_type;
+ charger_type = GPOINTER_TO_INT(data);
+
+ if( charger_type == prev )
+ goto EXIT;
+
+ mce_log(LL_DEBUG, "charger_type = %s -> %s",
+ charger_type_repr(prev),
+ charger_type_repr(charger_type));
+
+ common_dbus_send_charger_type(0);
+
+EXIT:
+ return;
+}
+
/* ------------------------------------------------------------------------- *
* charger_state
* ------------------------------------------------------------------------- */
@@ -868,6 +980,10 @@ static datapipe_handler_t common_datapipe_handlers[] =
.datapipe = &usb_cable_state_pipe,
.output_cb = common_datapipe_usb_cable_state_cb,
},
+ {
+ .datapipe = &charger_type_pipe,
+ .output_cb = common_datapipe_charger_type_cb,
+ },
{
.datapipe = &charger_state_pipe,
.output_cb = common_datapipe_charger_state_cb,
diff --git a/mce-dbus.h b/mce-dbus.h
index d180e7ad..18fd3d4a 100644
--- a/mce-dbus.h
+++ b/mce-dbus.h
@@ -4,6 +4,7 @@
*
* Copyright © 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2013-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author David Weinehall
* @author Simo Piiroinen
@@ -49,6 +50,25 @@
*/
# define MCE_CHARGER_STATE_REQ "req_charger_state"
+/** Override current charger type
+ *
+ * Available in devel flavor mce only, and only to privileged applications.
+ *
+ * @since mce 1.102.0
+ *
+ * @param string: current charger type, one of:
+ * - #MCE_CHARGER_TYPE_NONE
+ * - #MCE_CHARGER_TYPE_USB
+ * - #MCE_CHARGER_TYPE_DCP
+ * - #MCE_CHARGER_TYPE_HVDCP
+ * - #MCE_CHARGER_TYPE_CDP
+ * - #MCE_CHARGER_TYPE_WIRELESS
+ * - #MCE_CHARGER_TYPE_OTHER
+ *
+ * @return boolean true if accepted, false / error reply otherwise
+ */
+# define MCE_CHARGER_TYPE_REQ "req_charger_type"
+
/** Override current battery level
*
* Available in devel flavor mce only, and only to privileged applications.
diff --git a/mce.conf b/mce.conf
index 2ccd69fe..f403ec59 100644
--- a/mce.conf
+++ b/mce.conf
@@ -225,6 +225,9 @@
+
* Copyright © 2004-2011 Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2012-2017 Jolla Ltd.
+ * Copyright (C) 2012-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author David Weinehall
* @author Irina Bezruk
@@ -334,6 +335,41 @@ typedef enum {
const char *charger_state_repr(charger_state_t state);
const char *charger_state_to_dbus(charger_state_t state);
+/** Known charger types
+ *
+ * Note that the ordering is:
+ *
+ * a) significant in the sense that in case there are several chargers
+ * connected and active at the same time, maximum numerical value is
+ * exposed as effective charger type on D-Bus
+ *
+ * b) internal to mce, so that values can and should be rearranged if
+ * there should be changes in what makes sense to ui side.
+ */
+typedef enum
+{
+ CHARGER_TYPE_NONE,
+
+ /* Charger types that do not carry special meaning from
+ * sfos UI point of view.
+ */
+ CHARGER_TYPE_OTHER,
+ CHARGER_TYPE_WIRELESS,
+ CHARGER_TYPE_CDP, // Charging Downstream Port
+
+ /* Wall chargers imply notification on disconnect
+ */
+ CHARGER_TYPE_DCP, // Dedicated Charging Port
+ CHARGER_TYPE_HVDCP, // High Voltage DCP
+
+ /* PC connection implies usb mode management
+ */
+ CHARGER_TYPE_USB, // Standard Downstream Port
+} charger_type_t;
+
+const char *charger_type_repr(charger_type_t type);
+const char *charger_type_to_dbus(charger_type_t type);
+
/** Camera button state */
typedef enum {
CAMERA_BUTTON_UNDEF = -1, /**< Camera button state not set */
diff --git a/modules/battery-udev.c b/modules/battery-udev.c
index efd76edd..e08f481e 100644
--- a/modules/battery-udev.c
+++ b/modules/battery-udev.c
@@ -2,7 +2,8 @@
* @file battery-udev.c
* Battery module -- this implements battery and charger logic for MCE
*
- * Copyright (C) 2018 Jolla Ltd.
+ * Copyright (C) 2018-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author Simo Piiroinen
*
@@ -58,10 +59,12 @@
#define BATTERY_CAPACITY_FULL 90 // statefs uses 96
/* Power supply device properties we are interested in */
-#define PROP_PRESENT "POWER_SUPPLY_PRESENT"
-#define PROP_ONLINE "POWER_SUPPLY_ONLINE"
-#define PROP_CAPACITY "POWER_SUPPLY_CAPACITY"
-#define PROP_STATUS "POWER_SUPPLY_STATUS"
+#define PROP_PRESENT "POWER_SUPPLY_PRESENT"
+#define PROP_ONLINE "POWER_SUPPLY_ONLINE"
+#define PROP_CAPACITY "POWER_SUPPLY_CAPACITY"
+#define PROP_STATUS "POWER_SUPPLY_STATUS"
+#define PROP_REAL_TYPE "POWER_SUPPLY_REAL_TYPE"
+#define PROP_TYPE "POWER_SUPPLY_TYPE"
/** INI-file group for blacklisting device properties */
#define MCE_CONF_BATTERY_UDEV_PROPERTY_BLACKLIST_GROUP "BatteryUDevPropertyBlacklist"
@@ -115,6 +118,9 @@ typedef struct
/** Charger connected; for use with charger_state_pipe */
charger_state_t charger_state;
+
+ /** Charger type; for tweaking UI behavior */
+ charger_type_t charger_type;
} mcebat_t;
typedef struct udevtracker_t udevtracker_t;
@@ -191,6 +197,7 @@ static gboolean mcebat_dbus_client_removed_cb (DBusMessage *const msg);
static bool mcebat_dbus_add_client (const char *dbus_name);
static void mcebat_dbus_evaluate_battery_status(void);
static gboolean mcebat_dbus_charger_state_req_cb (DBusMessage *const msg);
+static gboolean mcebat_dbus_charger_type_req_cb (DBusMessage *const msg);
static gboolean mcebat_dbus_battery_level_req_cb (DBusMessage *const msg);
#endif // ENABLE_BATTERY_SIMULATION
@@ -217,6 +224,7 @@ static bool udevproperty_set (udevproperty_t *self, const ch
* UDEVDEVICE
* ------------------------------------------------------------------------- */
+static charger_type_t udevdevice_lookup_charger_type(const char *name);
static void udevdevice_init_blacklist (void);
static void udevdevice_quit_blacklist (void);
static bool udevdevice_is_blacklisted (const char *name);
@@ -287,6 +295,7 @@ static mcebat_t mcebat_datapipe = {
.battery_level = BATTERY_LEVEL_INITIAL,
.battery_status = BATTERY_STATUS_UNDEF,
.charger_state = CHARGER_STATE_UNDEF,
+ .charger_type = CHARGER_TYPE_NONE,
};
/** Cached battery state as derived from udev
@@ -295,6 +304,7 @@ static mcebat_t mcebat_actual = {
.battery_level = BATTERY_LEVEL_INITIAL,
.battery_status = BATTERY_STATUS_UNDEF,
.charger_state = CHARGER_STATE_UNDEF,
+ .charger_type = CHARGER_TYPE_NONE,
};
#ifdef ENABLE_BATTERY_SIMULATION
@@ -342,6 +352,8 @@ static const char * const udevproperty_used_keys[] = {
PROP_PRESENT,
// charger
PROP_ONLINE,
+ PROP_REAL_TYPE,
+ PROP_TYPE,
// battery
PROP_CAPACITY,
PROP_STATUS,
@@ -485,6 +497,77 @@ mcebat_dbus_evaluate_battery_status(void)
return;
}
+/** D-Bus callback: Simulated charger type requested
+ *
+ * @param msg The D-Bus message
+ *
+ * @return TRUE
+ */
+static gboolean
+mcebat_dbus_charger_type_req_cb(DBusMessage *const msg)
+{
+ dbus_bool_t accepted = false;
+ const char *sender = dbus_message_get_sender(msg);
+ DBusError error = DBUS_ERROR_INIT;
+ const char *type = 0;
+ DBusMessage *reply = 0;
+
+ mce_log(LL_DEVEL, "charger type request from %s",
+ mce_dbus_get_name_owner_ident(sender));
+
+ if( !mcebat_dbus_add_client(sender) )
+ goto EXIT;
+
+ if( !dbus_message_get_args(msg, &error,
+ DBUS_TYPE_STRING, &type,
+ DBUS_TYPE_INVALID) ) {
+ goto EXIT;
+ }
+
+ if( !strcmp(type, MCE_CHARGER_TYPE_NONE) )
+ mcebat_simulated.charger_type = CHARGER_TYPE_NONE;
+ else if( !strcmp(type, MCE_CHARGER_TYPE_USB) )
+ mcebat_simulated.charger_type = CHARGER_TYPE_USB;
+ else if( !strcmp(type, MCE_CHARGER_TYPE_DCP) )
+ mcebat_simulated.charger_type = CHARGER_TYPE_DCP;
+ else if( !strcmp(type, MCE_CHARGER_TYPE_HVDCP) )
+ mcebat_simulated.charger_type = CHARGER_TYPE_HVDCP;
+ else if( !strcmp(type, MCE_CHARGER_TYPE_CDP) )
+ mcebat_simulated.charger_type = CHARGER_TYPE_CDP;
+ else if( !strcmp(type, MCE_CHARGER_TYPE_WIRELESS) )
+ mcebat_simulated.charger_type = CHARGER_TYPE_WIRELESS;
+ else
+ mcebat_simulated.charger_type = CHARGER_TYPE_OTHER;
+
+ mcebat_dbus_evaluate_battery_status();
+ mcebat_update();
+
+ accepted = true;
+
+EXIT:
+ /* Setup the reply */
+ reply = dbus_new_method_reply(msg);
+
+ /* Append the result */
+ if( !dbus_message_append_args(reply,
+ DBUS_TYPE_BOOLEAN, &accepted,
+ DBUS_TYPE_INVALID)) {
+ mce_log(LL_ERR,"Failed to append reply arguments to D-Bus "
+ "message for %s.%s",
+ MCE_REQUEST_IF, dbus_message_get_member(msg));
+ }
+ else if( !dbus_message_get_no_reply(msg) ) {
+ dbus_send_message(reply), reply = 0;
+ }
+
+ if( reply )
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return TRUE;
+}
+
/** D-Bus callback: Simulated charger state requested
*
* @param msg The D-Bus message
@@ -612,6 +695,16 @@ static mce_dbus_handler_t callstate_dbus_handlers[] =
{
/* method calls */
#ifdef ENABLE_BATTERY_SIMULATION
+ {
+ .interface = MCE_REQUEST_IF,
+ .name = MCE_CHARGER_TYPE_REQ,
+ .type = DBUS_MESSAGE_TYPE_METHOD_CALL,
+ .callback = mcebat_dbus_charger_type_req_cb,
+ .privileged = true,
+ .args =
+ " \n"
+ " \n"
+ },
{
.interface = MCE_REQUEST_IF,
.name = MCE_CHARGER_STATE_REQ,
@@ -679,6 +772,15 @@ mcebat_update(void)
mcebat_t prev = mcebat_datapipe;
mcebat_datapipe = *curr;
+ if( prev.charger_type != curr->charger_type ) {
+ mce_log(LL_CRUCIAL, "charger_type: %s -> %s",
+ charger_type_repr(prev.charger_type),
+ charger_type_repr(curr->charger_type));
+
+ datapipe_exec_full(&charger_type_pipe,
+ GINT_TO_POINTER(curr->charger_type));
+ }
+
if( prev.charger_state != curr->charger_state ) {
mce_log(LL_CRUCIAL, "charger_state: %s -> %s",
charger_state_repr(prev.charger_state),
@@ -943,6 +1045,60 @@ udevproperty_set(udevproperty_t *self, const char *val)
* UDEVDEVICE
* ========================================================================= */
+/** Lookup charger type based on device name / value of type property
+ *
+ * @param name string to match
+ *
+ * @return charger_type_t enumeration value
+ */
+static charger_type_t
+udevdevice_lookup_charger_type(const char *name)
+{
+ static const struct {
+ const char *name;
+ int value;
+ } lut[] = {
+ /* Type map - adapted from statefs sources
+ */
+ { "CDP", CHARGER_TYPE_CDP },
+ { "USB_CDP", CHARGER_TYPE_CDP },
+ { "USB_DCP", CHARGER_TYPE_DCP },
+ { "USB_HVDCP", CHARGER_TYPE_HVDCP },
+ { "USB_HVDCP_3", CHARGER_TYPE_HVDCP },
+ { "Mains", CHARGER_TYPE_DCP },
+ { "USB", CHARGER_TYPE_USB },
+ { "USB_ACA", CHARGER_TYPE_USB },
+
+ /* Additions since leaving statefs behind
+ */
+ { "WIRELESS", CHARGER_TYPE_WIRELESS },
+ { "AC", CHARGER_TYPE_DCP },
+
+ /* To make connect/disconnect transitions
+ * cleaner, ignore "Unknown" reporting
+ */
+ { "Unknown", CHARGER_TYPE_NONE },
+
+ /* Sentinel */
+ { 0, 0 }
+ };
+
+ charger_type_t value = CHARGER_TYPE_OTHER;
+ if( name ) {
+ for( size_t i = 0; ; ++i ) {
+ if( lut[i].name == 0 ) {
+ mce_log(LL_WARN, "unknown charger type: %s", name);
+ break;
+ }
+ if( !g_ascii_strcasecmp(lut[i].name, name) ) {
+ value = lut[i].value;
+ break;
+ }
+ }
+ }
+ return value;
+}
+
/** Initialize device blacklist lookup table
*/
static void
@@ -1248,9 +1404,36 @@ udevdevice_evaluate_charger(udevdevice_t *self, mcebat_t *mcebat)
bool active = (present == 1 || online == 1);
- if( active )
+ if( active ) {
mcebat->charger_state = CHARGER_STATE_ON;
+ /* Charger is online, evaluate charger type
+ *
+ * Legacy QC devices have TYPE property that has
+ * content sfos sw stack knows how to interpret.
+ *
+ * More recent QC devices might expose "USB_PD" in
+ * TYPE prop and have additional REAL_TYPE property
+ * containing old style data.
+ *
+ * MTK devices have multiple power supply device
+ * nodes visible in udev and charger type must be
+ * determined from device node name.
+ */
+ const char *name;
+ if( !(name = udevdevice_get_str_prop(self, PROP_REAL_TYPE, 0)) ) {
+ if( !(name = udevdevice_get_str_prop(self, PROP_TYPE, 0)) )
+ name = udevdevice_name(self);
+ }
+
+ charger_type_t type = udevdevice_lookup_charger_type(name);
+
+ /* Update effective charger type exposed on D-Bus
+ */
+ if( mcebat->charger_type < type )
+ mcebat->charger_type = type;
+ }
+
mce_log(LL_DEBUG, "%s: charger @ "
"present=%d online=%d -> active=%d",
udevdevice_name(self),
@@ -1449,6 +1632,10 @@ udevtracker_rethink(udevtracker_t *self)
* indicate charging activity. */
mcebat_actual.charger_state = CHARGER_STATE_OFF;
+ /* Reset charger type, iterator chooses maximum of
+ * none < other < wall chargers < pc connection. */
+ mcebat_actual.charger_type = CHARGER_TYPE_NONE;
+
g_hash_table_foreach(self->udt_devices, udevdevice_evaluate_charger_cb, &mcebat_actual);
g_hash_table_foreach(self->udt_devices, udevdevice_evaluate_battery_cb, &mcebat_actual);
diff --git a/rpm/mce.spec b/rpm/mce.spec
index 990fbcd6..9d7ffc16 100644
--- a/rpm/mce.spec
+++ b/rpm/mce.spec
@@ -20,7 +20,7 @@ BuildRequires: pkgconfig(dsme) >= 0.65.0
BuildRequires: pkgconfig(thermalmanager_dbus_if)
BuildRequires: pkgconfig(libiphb)
BuildRequires: pkgconfig(glib-2.0) >= 2.36.0
-BuildRequires: pkgconfig(mce) >= 1.26.0
+BuildRequires: pkgconfig(mce) >= 1.27.0
BuildRequires: pkgconfig(libngf0) >= 0.24
BuildRequires: pkgconfig(libsystemd-daemon)
BuildRequires: kernel-headers >= 2.6.32
diff --git a/tools/mcetool.c b/tools/mcetool.c
index 76b90ad2..1e3941cc 100644
--- a/tools/mcetool.c
+++ b/tools/mcetool.c
@@ -3,6 +3,7 @@
*
* Copyright © 2005-2011 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2012-2019 Jolla Ltd.
+ * Copyright (c) 2019 Open Mobile Platform LLC.
*
* @author David Weinehall
* @author Santtu Lakkala
@@ -139,6 +140,7 @@ static bool xmce_get_color_profile_ids (const ch
static bool xmce_set_color_profile (const char *args);
static void xmce_get_color_profile (void);
#ifdef ENABLE_BATTERY_SIMULATION
+static bool xmce_set_charger_type (const char *type);
static bool xmce_set_charger_state (const char *state);
static bool xmce_set_battery_level (int level);
#endif
@@ -438,6 +440,7 @@ static bool mcetool_do_disable_led_pattern(const char *args);
static bool mcetool_do_activate_pattern (const char *args);
static bool mcetool_do_deactivate_pattern (const char *args);
#ifdef ENABLE_BATTERY_SIMULATION
+static bool mcetool_do_set_charger_type(const char *arg);
static bool mcetool_do_set_charger_state (const char *arg);
static bool mcetool_do_set_battery_level (const char *arg);
#endif
@@ -2583,6 +2586,33 @@ static void xmce_get_color_profile(void)
* ------------------------------------------------------------------------- */
#ifdef ENABLE_BATTERY_SIMULATION
+static bool xmce_set_charger_type(const char *type)
+{
+ dbus_bool_t ret = false;
+ DBusError err = DBUS_ERROR_INIT;
+ DBusMessage *rsp = 0;
+ gboolean ack = xmce_ipc(MCE_CHARGER_TYPE_REQ, &rsp,
+ DBUS_TYPE_STRING, &type,
+ DBUS_TYPE_INVALID);
+ if( !ack || !rsp )
+ goto EXIT;
+
+ if( !dbus_message_get_args(rsp, &err,
+ DBUS_TYPE_BOOLEAN, &ret,
+ DBUS_TYPE_INVALID) )
+ goto EXIT;
+
+EXIT:
+ if( dbus_error_is_set(&err) ) {
+ errorf("set %s: %s: %s\n", type, err.name, err.message);
+ dbus_error_free(&err);
+ }
+
+ if( rsp ) dbus_message_unref(rsp);
+
+ return ack && ret;
+}
+
static bool xmce_set_charger_state(const char *state)
{
dbus_bool_t ret = false;
@@ -2638,6 +2668,31 @@ static bool xmce_set_battery_level(int level)
return ack && ret;
}
+static bool mcetool_do_set_charger_type(const char *arg)
+{
+ const char * const lut[] = {
+ MCE_CHARGER_TYPE_NONE,
+ MCE_CHARGER_TYPE_USB,
+ MCE_CHARGER_TYPE_DCP,
+ MCE_CHARGER_TYPE_HVDCP,
+ MCE_CHARGER_TYPE_CDP,
+ MCE_CHARGER_TYPE_WIRELESS,
+ MCE_CHARGER_TYPE_OTHER,
+ 0
+ };
+
+ for( size_t i = 0; ; ++i ) {
+ if( !lut[i] ) {
+ errorf("%s: invalid charger type\n", arg);
+ return false;
+ }
+ if( !strcmp(lut[i], arg) )
+ break;
+ }
+
+ return xmce_set_charger_type(arg);
+}
+
static bool mcetool_do_set_charger_state(const char *arg)
{
const char * const lut[] = {
@@ -7863,6 +7918,20 @@ static const mce_opt_t options[] =
" disables the feature.\n"
},
#ifdef ENABLE_BATTERY_SIMULATION
+ {
+ .name = "set-charger-type",
+ .with_arg = mcetool_do_set_charger_type,
+ .values =
+ MCE_CHARGER_TYPE_NONE "|"
+ MCE_CHARGER_TYPE_USB "|"
+ MCE_CHARGER_TYPE_DCP "|"
+ MCE_CHARGER_TYPE_HVDCP "|"
+ MCE_CHARGER_TYPE_CDP "|"
+ MCE_CHARGER_TYPE_WIRELESS "|"
+ MCE_CHARGER_TYPE_OTHER,
+ .usage =
+ "Override charger type for debugging purposes\n"
+ },
{
.name = "set-charger-state",
.with_arg = mcetool_do_set_charger_state,