diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-12-03 12:23:15 +0200 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-12-08 16:10:58 +0200 | 
| commit | 6eb2e31bd10d94d966027d52b00840dcbbf967b3 (patch) | |
| tree | d3b46acd62ff31dd6ba08f45024050388f6324d7 | |
| parent | 3ce142207a553ffa14bbec2145547c867bf31b9f (diff) | |
Implement the missing part of the HAL battery info code
| -rw-r--r-- | audio/telephony-maemo.c | 199 | 
1 files changed, 167 insertions, 32 deletions
| diff --git a/audio/telephony-maemo.c b/audio/telephony-maemo.c index 3bae0b83..060ce3fa 100644 --- a/audio/telephony-maemo.c +++ b/audio/telephony-maemo.c @@ -156,6 +156,9 @@ static GSList *calls = NULL;  static char *subscriber_number = NULL; +static int battchg = -1; +static int battchg_max = -1; +  static gboolean events_enabled = FALSE;  /* Supported set of call hold operations */ @@ -246,7 +249,7 @@ static struct csd_call *find_call_with_status(int status)  	return NULL;  } -static gboolean update_network_indicators(gpointer user_data) +static gboolean update_indicators(gpointer user_data)  {  	if (net.status < NETWORK_REG_STATUS_NOSERV) {  		int signal; @@ -270,6 +273,11 @@ static gboolean update_network_indicators(gpointer user_data)  		break;  	} +	if (battchg_max > 0 && battchg > 0) { +	        int bat = telephony_get_indicator(maemo_indicators, "battchg"); +		telephony_update_indicator(maemo_indicators, "battchg", bat); +	} +  	return FALSE;  } @@ -382,7 +390,7 @@ void telephony_device_connected(void *telephony_device)  {  	debug("telephony-maemo: device %p connected", telephony_device); -	g_timeout_add_seconds(1, update_network_indicators, NULL); +	g_timeout_add_seconds(1, update_indicators, NULL);  }  void telephony_device_disconnected(void *telephony_device) @@ -1071,7 +1079,150 @@ static void handle_signal_strength_change(DBusMessage *msg)  	update_signal_strength(signals_bar);  } -static DBusHandlerResult cs_signal_filter(DBusConnection *conn, +static gboolean iter_get_basic_args(DBusMessageIter *iter, +					int first_arg_type, ...) +{ +	int type; +	va_list ap; + +	va_start(ap, first_arg_type); + +	for (type = first_arg_type; type != DBUS_TYPE_INVALID; +			type = va_arg(ap, int)) { +		void *value = va_arg(ap, void *); +		int real_type = dbus_message_iter_get_arg_type(iter); + +		if (real_type != type) { +			error("iter_get_basic_args: expected %c but got %c", +					(char) type, (char) real_type); +			break; +		} + +		dbus_message_iter_get_basic(iter, value); +		dbus_message_iter_next(iter); +	} + +	va_end(ap); + +	return type == DBUS_TYPE_INVALID ? TRUE : FALSE; +} + +static void hal_battery_level_reply(DBusPendingCall *call, void *user_data) +{ +	DBusError err; +	DBusMessage *reply; +	dbus_int32_t level; +	int *value = user_data; + +	reply = dbus_pending_call_steal_reply(call); + +	dbus_error_init(&err); +	if (dbus_set_error_from_message(&err, reply)) { +		error("hald replied with an error: %s, %s", +				err.name, err.message); +		dbus_error_free(&err); +		goto done; +	} + +	dbus_message_get_args(reply, NULL, +				DBUS_TYPE_INT32, &level, +				DBUS_TYPE_INVALID); + +	*value = (int) level; + +	if (value == &battchg_max) +		debug("battery.charge_level.last_full is %d", *value); +	else +		debug("battery.charge_level.current is %d", *value); + +	if (battchg_max > 0 && battchg > 0) { +		int battchg_norm; + +		battchg_norm = battchg * 5 / battchg_max; + +		telephony_update_indicator(maemo_indicators, "battchg", battchg_norm); +	} +done: +	dbus_message_unref(reply); +} + +static void hal_get_integer(const char *path, const char *key, void *user_data) +{ +	DBusMessage *msg; +	DBusPendingCall *call; + +	msg = dbus_message_new_method_call("org.freedesktop.Hal", path, +						"org.freedesktop.Hal.Device", +						"GetPropertyInteger"); +	if (!msg) { +		error("Unable to allocate new D-Bus message"); +		return; +	} + +	dbus_message_append_args(msg, DBUS_TYPE_STRING, &key, +							DBUS_TYPE_INVALID); + +	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) { +		error("Sending GetPropertyInteger failed"); +		dbus_message_unref(msg); +		return; +	} + +	dbus_pending_call_set_notify(call, hal_battery_level_reply, +						user_data, NULL); +	dbus_pending_call_unref(call); +	dbus_message_unref(msg); +} + +static void handle_hal_property_modified(DBusMessage *msg) +{ +	DBusMessageIter iter, array; +	dbus_int32_t num_changes; +	const char *path; + +	path = dbus_message_get_path(msg); + +	dbus_message_iter_init(msg, &iter); + +	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) { +		error("Unexpected signature in hal PropertyModified signal"); +		return; +	} + +	dbus_message_iter_get_basic(&iter, &num_changes); +	dbus_message_iter_next(&iter); + +	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { +		error("Unexpected signature in hal PropertyModified signal"); +		return; +	} + +	dbus_message_iter_recurse(&iter, &array); + +	while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) { +		DBusMessageIter prop; +		const char *name; +		dbus_bool_t added, removed; + +		dbus_message_iter_recurse(&array, &prop); + +		if (!iter_get_basic_args(&prop, +					DBUS_TYPE_STRING, &name, +					DBUS_TYPE_BOOLEAN, &added, +					DBUS_TYPE_BOOLEAN, &removed, +					DBUS_TYPE_INVALID)) { +			error("Invalid hal PropertyModified parameters"); +			break; +		} + +		if (g_str_equal(name, "battery.charge_level.last_full")) +			hal_get_integer(path, name, &battchg_max); +		else if (g_str_equal(name, "battery.charge_level.current")) +			hal_get_integer(path, name, &battchg); +	} +} + +static DBusHandlerResult signal_filter(DBusConnection *conn,  						DBusMessage *msg, void *data)  {  	const char *interface = dbus_message_get_interface(msg); @@ -1097,38 +1248,13 @@ static DBusHandlerResult cs_signal_filter(DBusConnection *conn,  	else if (dbus_message_is_signal(msg, NETWORK_INTERFACE,  					"signal_strength_change"))  		handle_signal_strength_change(msg); +	else if (dbus_message_is_signal(msg, "org.freedesktop.Hal.Device", +					"PropertyModified")) +		handle_hal_property_modified(msg);  	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;  } -static gboolean iter_get_basic_args(DBusMessageIter *iter, -					int first_arg_type, ...) -{ -	int type; -	va_list ap; - -	va_start(ap, first_arg_type); - -	for (type = first_arg_type; type != DBUS_TYPE_INVALID; -			type = va_arg(ap, int)) { -		void *value = va_arg(ap, void *); -		int real_type = dbus_message_iter_get_arg_type(iter); - -		if (real_type != type) { -			error("iter_get_basic_args: expected %c but got %c", -					(char) type, (char) real_type); -			break; -		} - -		dbus_message_iter_get_basic(iter, value); -		dbus_message_iter_next(iter); -	} - -	va_end(ap); - -	return type == DBUS_TYPE_INVALID ? TRUE : FALSE; -} -  static void csd_call_free(struct csd_call *call)  {  	if (!call) @@ -1382,6 +1508,7 @@ static void hal_find_device_reply(DBusPendingCall *call, void *user_data)  	DBusMessage *reply;  	DBusMessageIter iter, sub;;  	const char *path; +	char match_string[128];  	int type;  	reply = dbus_pending_call_steal_reply(call); @@ -1414,6 +1541,14 @@ static void hal_find_device_reply(DBusPendingCall *call, void *user_data)  	debug("telephony-maemo: found battery device at %s", path); +	snprintf(match_string, sizeof(match_string), +			"type=signal,interface=org.freedesktop.Hal.Device," +				"path=%s,member=PropertyModified", path); +	dbus_bus_add_match(connection, match_string, NULL); + +	hal_get_integer(path, "battery.charge_level.last_full", &battchg_max); +	hal_get_integer(path, "battery.charge_level.current", &battchg); +  done:  	dbus_message_unref(reply);  } @@ -1427,7 +1562,7 @@ int telephony_init(void)  	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); -	if (!dbus_connection_add_filter(connection, cs_signal_filter, +	if (!dbus_connection_add_filter(connection, signal_filter,  						NULL, NULL)) {  		error("Can't add signal filter");  		return -EIO; | 
