diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index e83b761..34b1f20 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
};
struct pending_req {
- DBusMessage *msg;
+ GDBusPendingPropertySet id;
const char *key;
const char *value;
};
GSList *pending;
};
-static void append_settings(void *key, void *value, void *user_data)
-{
- DBusMessageIter *dict = user_data;
-
- dict_append_entry(dict, key, DBUS_TYPE_STRING, &value);
-}
-
static void append_metadata(void *key, void *value, void *user_data)
{
DBusMessageIter *dict = user_data;
dict_append_entry(dict, key, DBUS_TYPE_STRING, &value);
}
-static DBusMessage *media_player_get_properties(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct media_player *mp = data;
- DBusMessage *reply;
- DBusMessageIter iter, dict;
- uint32_t position;
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return NULL;
-
- dbus_message_iter_init_append(reply, &iter);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &dict);
-
- position = media_player_get_position(mp);
- dict_append_entry(&dict, "Position", DBUS_TYPE_UINT32, &position);
-
- dict_append_entry(&dict, "Status", DBUS_TYPE_STRING, &mp->status);
-
- g_hash_table_foreach(mp->settings, append_settings, &dict);
-
- dbus_message_iter_close_container(&iter, &dict);
-
- return reply;
-}
-
static DBusMessage *media_player_get_track(DBusConnection *conn,
DBusMessage *msg, void *data)
{
return NULL;
}
-static struct pending_req *pending_new(DBusMessage *msg, const char *key,
- const char *value)
+static struct pending_req *pending_new(GDBusPendingPropertySet id,
+ const char *key, const char *value)
{
struct pending_req *p;
p = g_new0(struct pending_req, 1);
- p->msg = dbus_message_ref(msg);
+ p->id = id;
p->key = key;
p->value = value;
return p;
}
-static DBusMessage *player_set_setting(struct media_player *mp,
- DBusMessage *msg, const char *key,
- const char *value)
+static gboolean get_position(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
{
- struct player_callback *cb = mp->cb;
- struct pending_req *p;
+ struct media_player *mp = data;
- if (cb == NULL || cb->cbs->set_setting == NULL)
- return btd_error_not_supported(msg);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &mp->position);
- p = find_pending(mp, key);
- if (p != NULL)
- return btd_error_in_progress(msg);
+ return TRUE;
+}
- if (!cb->cbs->set_setting(mp, key, value, cb->user_data))
- return btd_error_invalid_args(msg);
+static gboolean status_exists(const GDBusPropertyTable *property, void *data)
+{
+ struct media_player *mp = data;
+
+ return mp->status != NULL;
+}
- p = pending_new(msg, key, value);
+static gboolean get_status(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct media_player *mp = data;
- mp->pending = g_slist_append(mp->pending, p);
+ if (mp->status == NULL)
+ return FALSE;
- return NULL;
+ DBG("%s", mp->status);
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &mp->status);
+
+ return TRUE;
}
-static DBusMessage *media_player_set_property(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static gboolean setting_exists(const GDBusPropertyTable *property, void *data)
{
struct media_player *mp = data;
- DBusMessageIter iter;
- DBusMessageIter var;
- const char *key, *value, *curval;
- if (!dbus_message_iter_init(msg, &iter))
- return btd_error_invalid_args(msg);
+ return g_hash_table_contains(mp->settings, property->name);
+}
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return btd_error_invalid_args(msg);
+static gboolean get_setting(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct media_player *mp = data;
+ const char *value;
- dbus_message_iter_get_basic(&iter, &key);
- dbus_message_iter_next(&iter);
+ value = g_hash_table_lookup(mp->settings, property->name);
+ if (value == NULL)
+ return FALSE;
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return btd_error_invalid_args(msg);
+ DBG("%s %s", property->name, value);
- dbus_message_iter_recurse(&iter, &var);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &value);
- if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
- return btd_error_invalid_args(msg);
+ return TRUE;
+}
- dbus_message_iter_get_basic(&var, &value);
+static void player_set_setting(struct media_player *mp,
+ GDBusPendingPropertySet id,
+ const char *key, const char *value)
+{
+ struct player_callback *cb = mp->cb;
+ struct pending_req *p;
- if (g_strcmp0(key, "Equalizer") != 0 &&
- g_strcmp0(key, "Repeat") != 0 &&
- g_strcmp0(key, "Shuffle") != 0 &&
- g_strcmp0(key, "Scan") != 0)
- return btd_error_invalid_args(msg);
+ if (cb == NULL || cb->cbs->set_setting == NULL)
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".NotSupported",
+ "Operation is not supported");
- curval = g_hash_table_lookup(mp->settings, key);
- if (g_strcmp0(curval, value) == 0)
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ p = find_pending(mp, key);
+ if (p != NULL)
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InProgress",
+ "Operation already in progress");
- return player_set_setting(mp, msg, key, value);
+ if (!cb->cbs->set_setting(mp, key, value, cb->user_data))
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InvalidArguments",
+ "Invalid arguments in method call");
+
+ p = pending_new(id, key, value);
+
+ mp->pending = g_slist_append(mp->pending, p);
+}
+
+static void set_setting(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, GDBusPendingPropertySet id,
+ void *data)
+{
+ struct media_player *mp = data;
+ const char *value;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InvalidArguments",
+ "Invalid arguments in method call");
+
+ dbus_message_iter_get_basic(iter, &value);
+
+ player_set_setting(mp, id, property->name, value);
}
static const GDBusMethodTable media_player_methods[] = {
- { GDBUS_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- media_player_get_properties) },
{ GDBUS_METHOD("GetTrack",
NULL, GDBUS_ARGS({ "metadata", "a{sv}" }),
media_player_get_track) },
- { GDBUS_ASYNC_METHOD("SetProperty",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
- NULL, media_player_set_property) },
{ }
};
static const GDBusSignalTable media_player_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
{ GDBUS_SIGNAL("TrackChanged",
GDBUS_ARGS({ "metadata", "a{sv}" })) },
{ }
};
-static void pending_free(void *data)
-{
- struct pending_req *p = data;
-
- dbus_message_unref(p->msg);
- g_free(p);
-}
+static const GDBusPropertyTable media_player_properties[] = {
+ { "Position", "u", get_position },
+ { "Status", "s", get_status, NULL, status_exists },
+ { "Equalizer", "s", get_setting, set_setting, setting_exists },
+ { "Repeat", "s", get_setting, set_setting, setting_exists },
+ { "Shuffle", "s", get_setting, set_setting, setting_exists },
+ { "Scan", "s", get_setting, set_setting, setting_exists },
+ { }
+};
void media_player_destroy(struct media_player *mp)
{
if (mp->process_id > 0)
g_source_remove(mp->process_id);
- g_slist_free_full(mp->pending, pending_free);
+ g_slist_free_full(mp->pending, g_free);
g_timer_destroy(mp->progress);
g_free(mp->cb);
mp->path, MEDIA_PLAYER_INTERFACE,
media_player_methods,
media_player_signals,
- NULL, mp, NULL)) {
+ media_player_properties, mp, NULL)) {
error("D-Bus failed to register %s path", mp->path);
media_player_destroy(mp);
return NULL;
mp->position = position;
g_timer_start(mp->progress);
- emit_property_changed(mp->path, MEDIA_PLAYER_INTERFACE, "Position",
- DBUS_TYPE_UINT32, &mp->position);
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+ MEDIA_PLAYER_INTERFACE, "Position");
}
void media_player_set_setting(struct media_player *mp, const char *key,
{
char *curval;
struct pending_req *p;
- DBusMessage *reply;
DBG("%s: %s", key, value);
if (p == NULL)
return;
- reply = btd_error_failed(p->msg, value);
+ g_dbus_pending_property_error(p->id, ERROR_INTERFACE ".Failed",
+ value);
goto send;
}
goto done;
g_hash_table_replace(mp->settings, g_strdup(key), g_strdup(value));
-
- emit_property_changed(mp->path, MEDIA_PLAYER_INTERFACE, key,
- DBUS_TYPE_STRING, &value);
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+ MEDIA_PLAYER_INTERFACE, key);
done:
p = find_pending(mp, key);
return;
if (strcasecmp(value, p->value) == 0)
- reply = g_dbus_create_reply(p->msg, DBUS_TYPE_INVALID);
+ g_dbus_pending_property_success(p->id);
else
- reply = btd_error_not_supported(p->msg);
+ g_dbus_pending_property_error(p->id,
+ ERROR_INTERFACE ".NotSupported",
+ "Operation is not supported");
send:
- g_dbus_send_message(btd_get_dbus_connection(), reply);
-
mp->pending = g_slist_remove(mp->pending, p);
- pending_free(p);
+ g_free(p);
return;
}
g_free(mp->status);
mp->status = g_strdup(status);
- emit_property_changed(mp->path, MEDIA_PLAYER_INTERFACE, "Status",
- DBUS_TYPE_STRING, &status);
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+ MEDIA_PLAYER_INTERFACE, "Status");
mp->position = media_player_get_position(mp);
g_timer_start(mp->progress);