/*
- * Bluetooth-frwk
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Hocheol Seo <hocheol.seo@samsung.com>
- * Girishashok Joshi <girish.joshi@samsung.com>
- * Chanyeol Park <chanyeol.park@samsung.com>
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
*/
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus.h>
+#include <gio/gio.h>
#include <glib.h>
#include <dlog.h>
#include <string.h>
-#if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
#include <syspopup_caller.h>
-#endif
+#include <dbus/dbus.h>
#include "bluetooth-api.h"
#include "bt-internal-types.h"
-
#include "bt-service-common.h"
#include "bt-service-avrcp.h"
#include "bt-service-event.h"
#include "bt-service-util.h"
#include "bt-service-audio.h"
-struct player_settinngs_t {
- int key;
- const char *property;
-};
-
-static struct player_settinngs_t loopstatus_settings[] = {
+static bt_player_settinngs_t loopstatus_settings[] = {
{ REPEAT_INVALID, "" },
{ REPEAT_MODE_OFF, "None" },
{ REPEAT_SINGLE_TRACK, "Track" },
{ REPEAT_INVALID, "" }
};
-
-static struct player_settinngs_t shuffle_settings[] = {
+static bt_player_settinngs_t shuffle_settings[] = {
{ SHUFFLE_INVALID, "" },
{ SHUFFLE_MODE_OFF, "off" },
{ SHUFFLE_ALL_TRACK, "alltracks" },
{ SHUFFLE_INVALID, "" }
};
-static struct player_settinngs_t player_status[] = {
+static bt_player_settinngs_t player_status[] = {
{ STATUS_STOPPED, "stopped" },
{ STATUS_PLAYING, "playing" },
{ STATUS_PAUSED, "paused" },
{ STATUS_INVALID, "" }
};
-static struct player_settinngs_t repeat_status[] = {
- { REPEAT_INVALID, "" },
- { REPEAT_MODE_OFF, "off" },
- { REPEAT_SINGLE_TRACK, "singletrack" },
- { REPEAT_ALL_TRACK, "alltracks" },
- { REPEAT_GROUP, "group" },
- { REPEAT_INVALID, "" }
-};
+static guint avrcp_reg_id = 0;
+
+/* Introspection data exposed from bt-service */
+static const gchar bt_avrcp_bluez_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.freedesktop.DBus.Properties'>"
+" <method name='Set'>"
+" <arg type='s' name='interface' direction='in'/>"
+" <arg type='s' name='property' direction='in'/>"
+" <arg type='v' name='value' direction='in'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+static gboolean __bt_media_emit_property_changed(GDBusConnection *connection,
+ const char *path, const char *interface, const char *name,
+ const GVariant *variant)
+{
+ GVariantBuilder *builder = NULL;
+ GError *error = NULL;
-static struct player_settinngs_t equalizer_status[] = {
- { EQUALIZER_INVALID, "" },
- { EQUALIZER_OFF, "off" },
- { EQUALIZER_ON, "on" },
- { EQUALIZER_INVALID, "" },
-};
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(builder, "{sv}", name, variant);
-static struct player_settinngs_t scan_status[] = {
- { SCAN_INVALID, "" },
- { SCAN_MODE_OFF, "off" },
- { SCAN_ALL_TRACK, "alltracks" },
- { SCAN_GROUP, "group" },
- { SCAN_INVALID, "" },
-};
+ g_dbus_connection_emit_signal(connection, NULL, path,
+ DBUS_INTERFACE_PROPERTIES,
+ "PropertiesChanged",
+ g_variant_new("(sa{sv})",
+ interface, builder),
+ &error);
-DBusConnection *g_bt_dbus_conn = NULL;
-static char *avrcp_control_path = NULL;
+ g_variant_builder_unref(builder);
+ if (error) {
+ BT_ERR("Could not Emit PropertiesChanged Signal: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ return FALSE;
+ }
-static DBusHandlerResult _bt_avrcp_handle_set_property(DBusConnection *connection,
- DBusMessage *message, void *user_data)
+ return TRUE;
+}
+
+static GQuark __bt_avrcp_error_quark(void)
+{
+ static GQuark quark = 0;
+
+ if (!quark)
+ quark = g_quark_from_static_string("bt-avrcp");
+
+ return quark;
+}
+
+static GError *__bt_avrcp_set_error(bt_avrcp_error_t error)
+{
+ BT_ERR("error[%d]\n", error);
+
+ switch (error) {
+ case BT_AVRCP_ERROR_INVALID_PARAM:
+ return g_error_new(BT_AVRCP_ERROR, error,
+ BT_ERROR_INVALID_PARAM);
+ case BT_AVRCP_ERROR_INVALID_INTERFACE:
+ return g_error_new(BT_AVRCP_ERROR, error,
+ BT_ERROR_INVALID_INTERFACE);
+ case BT_AVRCP_ERROR_INTERNAL:
+ default:
+ return g_error_new(BT_AVRCP_ERROR, error,
+ BT_ERROR_INTERNAL);
+ }
+}
+
+static void __bt_avrcp_agent_method(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
{
BT_DBG("+");
- const gchar *value;
- unsigned int status;
+ BT_INFO("method %s", method_name);
+ BT_INFO("object_path %s", object_path);
+ int ret = BT_AVRCP_ERROR_NONE;
+ GError *err = NULL;
gboolean shuffle_status;
- DBusMessageIter args;
- const char *property = NULL;
- const char *interface = NULL;
- DBusMessage *reply = NULL;
- DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
- DBusMessageIter entry;
- int type;
-
-
- dbus_message_iter_init(message, &args);
- dbus_message_iter_get_basic(&args, &interface);
- dbus_message_iter_next(&args);
-
- if (g_strcmp0(interface, BT_MEDIA_PLAYER_INTERFACE) != 0) {
- result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- goto finish;
+ guint32 status;
+ gchar *interface = NULL;
+ gchar *property = NULL;
+ gchar *loop_status = NULL;
+ GVariant *value = NULL;
+
+ if (g_strcmp0(method_name, "Set") == 0) {
+ g_variant_get(parameters, "(&s&sv)", &interface, &property,
+ &value);
+
+ if (g_strcmp0(interface, BT_MEDIA_PLAYER_INTERFACE) != 0) {
+ ret = BT_AVRCP_ERROR_INVALID_INTERFACE;
+ goto fail;
+ }
}
- dbus_message_iter_get_basic(&args, &property);
- dbus_message_iter_next(&args);
- dbus_message_iter_recurse(&args, &entry);
- type = dbus_message_iter_get_arg_type(&entry);
-
- BT_DBG("property %s\n", property);
+ if (value == NULL) {
+ BT_ERR("value is NULL");
+ goto fail;
+ }
+ BT_DBG("Property: %s\n", property);
if (g_strcmp0(property, "Shuffle") == 0) {
- if (type != DBUS_TYPE_BOOLEAN) {
- BT_DBG("Error");
- reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments");
- dbus_connection_send(connection, reply, NULL);
- result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- goto finish;
+
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
+ BT_ERR("Error");
+ ret = BT_AVRCP_ERROR_INVALID_PARAM;
+ goto fail;
}
- dbus_message_iter_get_basic(&entry, &shuffle_status);
- BT_DBG("value %d\n", shuffle_status);
+
+ shuffle_status = g_variant_get_boolean(value);
+ BT_DBG("Value: %s\n", shuffle_status ? "TRUE" : "FALSE");
if (shuffle_status == TRUE)
status = SHUFFLE_ALL_TRACK;
else
_bt_send_event(BT_AVRCP_EVENT,
BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
- DBUS_TYPE_UINT32, &status,
- DBUS_TYPE_INVALID);
-
+ g_variant_new("(u)", status));
} else if (g_strcmp0(property, "LoopStatus") == 0) {
- if (type != DBUS_TYPE_STRING) {
- BT_DBG("Error");
- reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments");
- dbus_connection_send(connection, reply, NULL);
- result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- goto finish;
+
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+ BT_ERR("Error");
+ ret = BT_AVRCP_ERROR_INVALID_PARAM;
+ goto fail;
}
- dbus_message_iter_get_basic(&entry, &value);
- BT_DBG("value %s\n", value);
- if (g_strcmp0(value, "Track") == 0)
+ loop_status = (gchar *)g_variant_get_string(value, NULL);
+ BT_DBG("Value: %s\n", loop_status);
+
+ if (g_strcmp0(loop_status, "Track") == 0)
status = REPEAT_SINGLE_TRACK;
- else if (g_strcmp0(value, "Playlist") == 0)
+ else if (g_strcmp0(loop_status, "Playlist") == 0)
status = REPEAT_ALL_TRACK;
- else if (g_strcmp0(value, "None") == 0)
+ else if (g_strcmp0(loop_status, "None") == 0)
status = REPEAT_MODE_OFF;
else
status = REPEAT_INVALID;
_bt_send_event(BT_AVRCP_EVENT,
BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
- DBUS_TYPE_UINT32, &status,
- DBUS_TYPE_INVALID);
+ g_variant_new("(u)", status));
}
-finish:
- if (reply)
- dbus_message_unref(reply);
-
- return result;
-}
-
-static DBusHandlerResult _bt_avrcp_message_handle(DBusConnection *conn, DBusMessage *msg, void *user_data)
-{
- BT_DBG("+");
-
- if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "Set"))
- return _bt_avrcp_handle_set_property(conn, msg, user_data);
BT_DBG("-");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ return;
+
+fail:
+ if (value)
+ g_variant_unref(value);
+ err = __bt_avrcp_set_error(ret);
+ g_dbus_method_invocation_return_gerror(invocation, err);
+ g_clear_error(&err);
+ BT_INFO("-");
}
-static DBusObjectPathVTable bt_object_table = {
- .message_function = _bt_avrcp_message_handle,
+static const GDBusInterfaceVTable method_table = {
+ __bt_avrcp_agent_method,
+ NULL,
+ NULL,
};
-gboolean bt_dbus_register_object_path(DBusConnection *connection,
- const char *path)
-{
- if (!dbus_connection_register_object_path(connection, path,
- &bt_object_table, NULL))
- return FALSE;
- return TRUE;
-}
-
-void bt_dbus_unregister_object_path(DBusConnection *connection,
- const char *path)
-{
- dbus_connection_unregister_object_path(connection, path);
-}
-
-static void __bt_media_append_variant(DBusMessageIter *iter,
- int type, void *value)
-{
- char sig[2] = { type, '\0'};
- DBusMessageIter value_iter;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig,
- &value_iter);
-
- dbus_message_iter_append_basic(&value_iter, type, value);
-
- dbus_message_iter_close_container(iter, &value_iter);
-}
-
-static void __bt_media_append_dict_entry(DBusMessageIter *iter,
- const char *key, int type, void *property)
-{
- DBusMessageIter dict_entry;
- const char *str_ptr;
-
- if (type == DBUS_TYPE_STRING) {
- str_ptr = *((const char **)property);
- ret_if(str_ptr == NULL);
- }
-
- dbus_message_iter_open_container(iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &dict_entry);
-
- dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key);
-
- __bt_media_append_variant(&dict_entry, type, property);
-
- dbus_message_iter_close_container(iter, &dict_entry);
-}
-
-static gboolean __bt_media_emit_property_changed(
- DBusConnection *connection,
- const char *path,
- const char *interface,
- const char *name,
- int type,
- void *property)
-{
- DBusMessage *sig;
- DBusMessageIter entry, dict;
- gboolean ret;
-
- sig = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- retv_if(sig == NULL, FALSE);
-
- dbus_message_iter_init_append(sig, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
- dbus_message_iter_open_container(&entry, 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);
-
- __bt_media_append_dict_entry(&dict,
- name, type, property);
-
- dbus_message_iter_close_container(&entry, &dict);
-
- ret = dbus_connection_send(connection, sig, NULL);
- dbus_message_unref(sig);
-
- return ret;
-}
-
-void _bt_set_control_device_path(const char *path)
-{
-
- ret_if(path == NULL);
-
- g_free(avrcp_control_path);
- BT_DBG("control_path = %s", path);
- avrcp_control_path = g_strdup(path);
-}
-
-void _bt_remove_control_device_path(const char *path)
-{
- ret_if(path == NULL);
-
- if (avrcp_control_path &&
- !g_strcmp0(avrcp_control_path, path)) {
- BT_DBG("control_path = %s", path);
- g_free(avrcp_control_path);
- avrcp_control_path = NULL;
- }
-}
-
-static char *__bt_get_control_device_path(void)
+static GDBusNodeInfo *__bt_avrcp_create_method_node_info
+ (const gchar *introspection_data)
{
- char *adapter_path;
- char *control_path;
- char connected_address[BT_ADDRESS_STRING_SIZE + 1];
-
- BT_DBG("+");
-
- retv_if(avrcp_control_path != NULL, avrcp_control_path);
-
- retv_if(!_bt_is_headset_type_connected(BT_AVRCP,
- connected_address), NULL);
-
- BT_DBG("device address = %s", connected_address);
-
- adapter_path = _bt_get_device_object_path(connected_address);
- retv_if(adapter_path == NULL, NULL);
-
- control_path = g_strdup_printf(BT_MEDIA_CONTROL_PATH, adapter_path);
- g_free(adapter_path);
-
- avrcp_control_path = control_path;
- BT_DBG("control_path = %s", control_path);
- return control_path;
-}
-
-static int __bt_media_send_control_msg(const char *name)
-{
- DBusMessage *msg;
- DBusMessage *reply;
- DBusError err;
- DBusConnection *conn;
- char *control_path;
-
- retv_if(name == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- conn = _bt_get_system_conn();
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- control_path = __bt_get_control_device_path();
- retv_if(control_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
- BT_DBG("control_path %s", control_path);
-
- msg = dbus_message_new_method_call(BT_BLUEZ_NAME, control_path,
- BT_PLAYER_CONTROL_INTERFACE, name);
-
- retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
+ GError *err = NULL;
+ GDBusNodeInfo *node_info = NULL;
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn,
- msg, -1, &err);
- dbus_message_unref(msg);
+ if (introspection_data == NULL)
+ return NULL;
- if (!reply) {
- BT_ERR("Error in Sending Control Command");
+ node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
- if (dbus_error_is_set(&err)) {
- BT_ERR("%s", err.message);
- dbus_error_free(&err);
- }
- return BLUETOOTH_ERROR_INTERNAL;
+ if (err) {
+ BT_ERR("Unable to create node: %s", err->message);
+ g_clear_error(&err);
}
- dbus_message_unref(reply);
-
- BT_DBG("-");
- return BLUETOOTH_ERROR_NONE;
+ return node_info;
}
-
int _bt_register_media_player(void)
{
BT_DBG("+");
- DBusMessage *msg;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter property_dict;
- DBusError err;
- char *object;
- char *adapter_path;
- DBusConnection *conn;
- DBusGConnection *gconn;
+ GDBusConnection *g_conn;
+ gchar *adapter_path;
gboolean shuffle_status;
+ gchar *path;
+ GDBusNodeInfo *node_info;
+ GDBusProxy *proxy;
+ GVariantBuilder *builder;
+ GVariant *ret;
+ GError *error = NULL;
media_player_settings_t player_settings = {0,};
player_settings.repeat = REPEAT_MODE_OFF;
-
- player_settings.shuffle = SHUFFLE_MODE_OFF;
player_settings.status = STATUS_STOPPED;
player_settings.position = 0;
+ shuffle_status = FALSE;
+ g_conn = _bt_gdbus_get_system_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
- gconn = _bt_get_system_gconn();
- retv_if(gconn == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- conn = _bt_get_system_conn();
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
- g_bt_dbus_conn = conn;
+ node_info = __bt_avrcp_create_method_node_info(
+ bt_avrcp_bluez_introspection_xml);
+ if (node_info == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+ avrcp_reg_id = g_dbus_connection_register_object(g_conn,
+ BT_MEDIA_OBJECT_PATH,
+ node_info->interfaces[0],
+ &method_table,
+ NULL, NULL, &error);
+ g_dbus_node_info_unref(node_info);
- if (!bt_dbus_register_object_path(conn, BT_MEDIA_OBJECT_PATH)){
- BT_DBG("Could not register interface %s",
- BT_MEDIA_PLAYER_INTERFACE);
+ if (avrcp_reg_id == 0) {
+ BT_ERR("Failed to register: %s", error->message);
+ g_clear_error(&error);
+ return BLUETOOTH_ERROR_INTERNAL;
}
adapter_path = _bt_get_adapter_path();
retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
- msg = dbus_message_new_method_call(BT_BLUEZ_NAME, adapter_path,
- BT_MEDIA_INTERFACE, "RegisterPlayer");
-
+ proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_MEDIA_INTERFACE, NULL, &error);
g_free(adapter_path);
- retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- object = g_strdup(BT_MEDIA_OBJECT_PATH);
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &object);
- g_free(object);
-
- 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, &property_dict);
-
- __bt_media_append_dict_entry(&property_dict,
- "LoopStatus",
- DBUS_TYPE_STRING,
- &loopstatus_settings[player_settings.repeat].property);
-
- if (player_settings.shuffle == SHUFFLE_MODE_OFF)
- shuffle_status = FALSE;
- else
- shuffle_status = TRUE;
-
- __bt_media_append_dict_entry(&property_dict,
- "Shuffle",
- DBUS_TYPE_BOOLEAN,
- &shuffle_status);
+ if (proxy == NULL) {
+ BT_ERR("Unable to create proxy");
+ if (error) {
+ BT_ERR("Error: %s", error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
- __bt_media_append_dict_entry(&property_dict,
- "PlaybackStatus",
- DBUS_TYPE_STRING,
- &player_status[player_settings.status].property);
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(builder, "{sv}", "LoopStatus",
+ g_variant_new("s",
+ loopstatus_settings[player_settings.repeat].property));
+ BT_ERR("LoopStatus: %s", loopstatus_settings[player_settings.repeat].property);
- __bt_media_append_dict_entry(&property_dict,
- "Position",
- DBUS_TYPE_UINT32, &player_settings.position);
+ g_variant_builder_add(builder, "{sv}", "Shuffle",
+ g_variant_new("b", shuffle_status));
- dbus_message_iter_close_container(&iter, &property_dict);
+ g_variant_builder_add(builder, "{sv}", "PlaybackStatus",
+ g_variant_new("s",
+ player_status[player_settings.status].property));
+ BT_ERR("PlaybackStatus: %s", player_status[player_settings.status].property);
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn,
- msg, -1, &err);
- dbus_message_unref(msg);
+ g_variant_builder_add(builder, "{sv}", "Position",
+ g_variant_new("u", player_settings.position));
- if (!reply) {
- BT_ERR("Error in registering the Music Player \n");
+ path = g_strdup(BT_MEDIA_OBJECT_PATH);
+ ret = g_dbus_proxy_call_sync(proxy, "RegisterPlayer",
+ g_variant_new("(oa{sv})", path, builder),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
- if (dbus_error_is_set(&err)) {
- BT_ERR("%s", err.message);
- dbus_error_free(&err);
- return BLUETOOTH_ERROR_INTERNAL;
+ g_object_unref(proxy);
+ g_free(path);
+ g_variant_builder_unref(builder);
+
+ if (ret == NULL) {
+ BT_ERR("Call RegisterPlayer Failed");
+ if (error) {
+ BT_ERR("errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
}
+ return BLUETOOTH_ERROR_INTERNAL;
}
- if (reply)
- dbus_message_unref(reply);
-
- BT_DBG("-");
+ g_variant_unref(ret);
return BLUETOOTH_ERROR_NONE;
}
-int _bt_unregister_media_player(void)
+static void __bt_avrcp_unregister_object_path(void)
{
- BT_DBG("+");
- DBusMessage *msg;
- DBusMessage *reply;
- DBusError err;
- char *object;
- char *adapter_path;
- DBusConnection *conn;
-
- conn = g_bt_dbus_conn;
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- adapter_path = _bt_get_adapter_path();
- retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- msg = dbus_message_new_method_call(BT_BLUEZ_NAME, adapter_path,
- BT_MEDIA_INTERFACE, "UnregisterPlayer");
-
-
- g_free(adapter_path);
-
- retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- object = g_strdup(BT_MEDIA_OBJECT_PATH);
+ GDBusConnection *g_conn;
- dbus_message_append_args(msg,
- DBUS_TYPE_OBJECT_PATH, &object,
- DBUS_TYPE_INVALID);
+ g_conn = _bt_gdbus_get_system_gconn();
+ ret_if(g_conn == NULL);
- g_free(object);
-
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn,
- msg, -1, &err);
- dbus_message_unref(msg);
-
- if (!reply) {
- BT_ERR("Error in unregistering the Music Player \n");
-
- if (dbus_error_is_set(&err)) {
- BT_ERR("%s", err.message);
- dbus_error_free(&err);
- return BLUETOOTH_ERROR_INTERNAL;
- }
- } else {
- dbus_message_unref(reply);
+ if (avrcp_reg_id > 0) {
+ g_dbus_connection_unregister_object(g_conn,
+ avrcp_reg_id);
+ avrcp_reg_id = 0;
}
-
- bt_dbus_unregister_object_path(conn, BT_MEDIA_OBJECT_PATH);
- g_bt_dbus_conn = NULL;
-
- BT_DBG("-");
- return BLUETOOTH_ERROR_NONE;
}
-static void __bt_media_append_metadata_entry(DBusMessageIter *metadata,
- void *key_type, void *value, int type)
+int _bt_unregister_media_player(void)
{
BT_DBG("+");
- DBusMessageIter string_entry;
+ GDBusConnection *g_conn;
+ GDBusProxy *proxy;
+ gchar *adapter_path;
+ GVariant *ret;
+ GError *error = NULL;
+ gchar *path;
+ int result = BLUETOOTH_ERROR_NONE;
- dbus_message_iter_open_container(metadata,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &string_entry);
+ adapter_path = _bt_get_adapter_path();
+ if (adapter_path == NULL) {
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
- dbus_message_iter_append_basic(&string_entry, DBUS_TYPE_STRING, key_type);
+ g_conn = _bt_gdbus_get_system_gconn();
+ if (g_conn == NULL) {
+ BT_ERR("g_conn is NULL");
+ g_free(adapter_path);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
- __bt_media_append_variant(&string_entry, type, value);
+ proxy = g_dbus_proxy_new_sync(g_conn,
+ G_DBUS_PROXY_FLAGS_NONE, NULL,
+ BT_BLUEZ_NAME, adapter_path,
+ BT_MEDIA_INTERFACE, NULL, &error);
+ g_free(adapter_path);
- dbus_message_iter_close_container(metadata, &string_entry);
- BT_DBG("-");
-}
+ if (proxy == NULL) {
+ BT_ERR("Unable to create proxy");
+ if (error) {
+ BT_ERR("Error: %s", error->message);
+ g_clear_error(&error);
+ }
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
-static void __bt_media_append_metadata_array(DBusMessageIter *metadata,
- void *key_type, void *value, int type)
-{
- BT_DBG("+");
- DBusMessageIter string_entry, variant, array;
- char array_sig[3] = { type, DBUS_TYPE_STRING, '\0' };
+ path = g_strdup(BT_MEDIA_OBJECT_PATH);
+ BT_DBG("path is [%s]", path);
- dbus_message_iter_open_container(metadata,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &string_entry);
- dbus_message_iter_append_basic(&string_entry, DBUS_TYPE_STRING, key_type);
+ ret = g_dbus_proxy_call_sync(proxy, "UnregisterPlayer",
+ g_variant_new("(o)", path),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ g_free(path);
+ g_object_unref(proxy);
- dbus_message_iter_open_container(&string_entry, DBUS_TYPE_VARIANT,
- array_sig, &variant);
+ if (ret == NULL) {
+ BT_ERR("UnregisterPlayer failed");
+ if (error) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_variant_unref(ret);
- dbus_message_iter_open_container(&variant, type,
- DBUS_TYPE_STRING_AS_STRING, &array);
- dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, value);
+FAIL:
+ __bt_avrcp_unregister_object_path();
- dbus_message_iter_close_container(&variant, &array);
- dbus_message_iter_close_container(&string_entry, &variant);
- dbus_message_iter_close_container(metadata, &string_entry);
BT_DBG("-");
+ return result;
}
int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
{
BT_DBG("+");
- DBusMessage *sig;
- DBusMessageIter iter;
- DBusMessageIter property_dict, metadata_dict, metadata_variant, metadata;
- DBusConnection *conn;
char *interface = BT_MEDIA_PLAYER_INTERFACE;
- char * metadata_str = "Metadata";
- const char *key_type;
+ GDBusConnection *g_conn;
+ GError *error = NULL;
+ GVariantBuilder *builder = NULL;
+ GVariantBuilder *inner_builder = NULL;
+ GVariant *children[1];
+ gboolean ret;
retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
- conn = g_bt_dbus_conn;
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ g_conn = _bt_gdbus_get_system_gconn();;
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
- sig = dbus_message_new_signal(BT_MEDIA_OBJECT_PATH, DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- retv_if(sig == NULL, FALSE);
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
- dbus_message_iter_init_append(sig, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:title", g_variant_new_string(meta_data->title));
- 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, &property_dict);
+ children[0] = g_variant_new_string(meta_data->artist);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
- dbus_message_iter_open_container(&property_dict,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &metadata_dict);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:album", g_variant_new_string(meta_data->album));
- dbus_message_iter_append_basic(&metadata_dict, DBUS_TYPE_STRING, &metadata_str);
+ children[0] = g_variant_new_string(meta_data->genre);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
- dbus_message_iter_open_container(&metadata_dict, DBUS_TYPE_VARIANT, "a{sv}",
- &metadata_variant);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:totalTracks", g_variant_new_int32(meta_data->total_tracks));
- dbus_message_iter_open_container(&metadata_variant, 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, &metadata);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:trackNumber", g_variant_new_int32(meta_data->number));
- if (meta_data->title) {
- key_type = "xesam:title";
- __bt_media_append_metadata_entry(&metadata, &key_type,
- &meta_data->title, DBUS_TYPE_STRING);
- }
+ g_variant_builder_add(inner_builder, "{sv}",
+ "mpris:length", g_variant_new_int64(meta_data->duration));
- if (meta_data->artist) {
- key_type = "xesam:artist";
- __bt_media_append_metadata_array(&metadata, &key_type,
- &meta_data->artist, DBUS_TYPE_ARRAY);
- }
+ g_variant_builder_add(builder, "{sv}",
+ "Metadata", g_variant_new("a{sv}", inner_builder));
- if (meta_data->album) {
- key_type = "xesam:album";
- __bt_media_append_metadata_entry(&metadata, &key_type,
- &meta_data->album, DBUS_TYPE_STRING);
- }
+ ret = g_dbus_connection_emit_signal(g_conn, NULL, BT_MEDIA_OBJECT_PATH,
+ DBUS_INTERFACE_PROPERTIES,
+ "PropertiesChanged",
+ g_variant_new("(sa{sv})",
+ interface, builder),
+ &error);
- if (meta_data->genre) {
- key_type = "xesam:genre";
- __bt_media_append_metadata_array(&metadata, &key_type,
- &meta_data->genre, DBUS_TYPE_ARRAY);
- }
-
- if (0 != meta_data->total_tracks) {
- key_type = "xesam:totalTracks";
- __bt_media_append_metadata_entry(&metadata, &key_type,
- &meta_data->total_tracks, DBUS_TYPE_INT32);
- }
+ g_variant_builder_unref(inner_builder);
+ g_variant_builder_unref(builder);
- if (0 != meta_data->number) {
- key_type = "xesam:trackNumber";
- __bt_media_append_metadata_entry(&metadata, &key_type,
- &meta_data->number, DBUS_TYPE_INT32);
- }
-
- if (0 != meta_data->duration) {
- key_type = "mpris:length";
- __bt_media_append_metadata_entry(&metadata, &key_type,
- &meta_data->duration, DBUS_TYPE_INT64);
+ if (!ret) {
+ if (error != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
}
- dbus_message_iter_close_container(&metadata_variant, &metadata);
- dbus_message_iter_close_container(&metadata_dict, &metadata_variant);
- dbus_message_iter_close_container(&property_dict, &metadata_dict);
- dbus_message_iter_close_container(&iter, &property_dict);
-
- if (!dbus_connection_send(conn, sig, NULL))
- BT_ERR("Unable to send TrackChanged signal\n");
-
- dbus_message_unref(sig);
BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
}
-
int _bt_avrcp_set_interal_property(int type, media_player_settings_t *properties)
{
BT_DBG("+");
- DBusConnection *conn;
+ GDBusConnection *g_conn;
int value;
media_metadata_attributes_t meta_data;
- dbus_bool_t shuffle;
+ gboolean shuffle;
+ GVariantBuilder *builder = NULL;
+ GVariant *children[1];
- conn = g_bt_dbus_conn;
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ g_conn = _bt_gdbus_get_system_gconn();;
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
switch (type) {
case REPEAT:
value = properties->repeat;
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "LoopStatus",
- DBUS_TYPE_STRING,
- &loopstatus_settings[value].property)) {
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "LoopStatus",
+ g_variant_new_string(loopstatus_settings[value].property))) {
BT_ERR("Error sending the PropertyChanged signal \n");
return BLUETOOTH_ERROR_INTERNAL;
}
case SHUFFLE:
value = properties->shuffle;
if (g_strcmp0(shuffle_settings[value].property, "off") == 0)
- shuffle = 0;
+ shuffle = FALSE;
else
- shuffle = 1;
-
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Shuffle",
- DBUS_TYPE_BOOLEAN,
- &shuffle)) {
- BT_DBG("Error sending the PropertyChanged signal \n");
+ shuffle = TRUE;
+
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "Shuffle",
+ g_variant_new_boolean(shuffle))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
return BLUETOOTH_ERROR_INTERNAL;
}
break;
case STATUS:
value = properties->status;
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "PlaybackStatus",
- DBUS_TYPE_STRING,
- &player_status[value].property)) {
- BT_DBG("Error sending the PropertyChanged signal \n");
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "PlaybackStatus",
+ g_variant_new_string(player_status[value].property))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
return BLUETOOTH_ERROR_INTERNAL;
}
break;
case POSITION:
value = properties->position;
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Position",
- DBUS_TYPE_UINT32,
- &value)) {
- BT_DBG("Error sending the PropertyChanged signal \n");
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "Position",
+ g_variant_new_uint32(value))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
return BLUETOOTH_ERROR_INTERNAL;
}
break;
case METADATA:
meta_data = properties->metadata;
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Metadata",
- DBUS_TYPE_ARRAY,
- &meta_data)) {
- BT_DBG("Error sending the PropertyChanged signal \n");
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:title", g_variant_new_string(meta_data.title));
+
+ children[0] = g_variant_new_string(meta_data.artist);
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
+
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:album", g_variant_new_string(meta_data.album));
+
+ children[0] = g_variant_new_string(meta_data.genre);
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
+ children, 1));
+
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:totalTracks", g_variant_new_int32(meta_data.total_tracks));
+
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:trackNumber", g_variant_new_int32(meta_data.number));
+
+ g_variant_builder_add(builder, "{sv}",
+ "mpris:length", g_variant_new_int64(meta_data.duration));
+
+ if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
+ BT_MEDIA_PLAYER_INTERFACE, "Metadata",
+ g_variant_new("a{sv}", builder))) {
+ BT_ERR("Error sending the PropertyChanged signal \n");
+ g_variant_builder_unref(builder);
return BLUETOOTH_ERROR_INTERNAL;
}
+ g_variant_builder_unref(builder);
break;
default:
- BT_DBG("Invalid Type\n");
+ BT_ERR("Invalid Type\n");
return BLUETOOTH_ERROR_INTERNAL;
}
BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
}
-
-int _bt_avrcp_control_cmd(int type)
-{
- int ret = BLUETOOTH_ERROR_INTERNAL;
- BT_DBG("+");
-
- switch (type) {
- case PLAY:
- ret = __bt_media_send_control_msg("Play");
- break;
- case PAUSE:
- ret = __bt_media_send_control_msg("Pause");
- break;
- case STOP:
- ret = __bt_media_send_control_msg("Stop");
- break;
- case NEXT:
- ret = __bt_media_send_control_msg("Next");
- break;
- case PREVIOUS:
- ret = __bt_media_send_control_msg("Previous");
- break;
- case FAST_FORWARD:
- ret = __bt_media_send_control_msg("FastForward");
- break;
- case REWIND:
- ret = __bt_media_send_control_msg("Rewind");
- break;
- default:
- BT_DBG("Invalid Type\n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
- BT_DBG("-");
- return ret;
-}
-
-DBusGProxy *__bt_get_control_properties_proxy(void)
-{
- DBusGProxy *proxy;
- char *control_path;
- DBusGConnection *conn;
-
- control_path = __bt_get_control_device_path();
- retv_if(control_path == NULL, NULL);
- BT_DBG("control_path = %s", control_path);
-
- conn = _bt_get_system_gconn();
- retv_if(conn == NULL, NULL);
-
- proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
- control_path, BT_PROPERTIES_INTERFACE);
- return proxy;
-}
-
-static int __bt_media_attr_to_event(const char *str)
-{
- if (!strcasecmp(str, "Equalizer"))
- return BLUETOOTH_EVENT_AVRCP_CONTROL_EQUALIZER_STATUS;
- else if (!strcasecmp(str, "Repeat"))
- return BLUETOOTH_EVENT_AVRCP_CONTROL_REPEAT_STATUS;
- else if (!strcasecmp(str, "Shuffle"))
- return BLUETOOTH_EVENT_AVRCP_CONTROL_SHUFFLE_STATUS;
- else if (!strcasecmp(str, "Scan"))
- return BLUETOOTH_EVENT_AVRCP_CONTROL_SCAN_STATUS;
- else if (!strcasecmp(str, "Position"))
- return BLUETOOTH_EVENT_AVRCP_SONG_POSITION_STATUS;
- else if (!strcasecmp(str, "Track"))
- return BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED;
- else if (!strcasecmp(str, "Status"))
- return BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED;
-
- return 0;
-}
-
-static int __bt_media_attr_to_type(const char *str)
-{
- if (!strcasecmp(str, "Equalizer"))
- return EQUALIZER;
- else if (!strcasecmp(str, "Repeat"))
- return REPEAT;
- else if (!strcasecmp(str, "Shuffle"))
- return SHUFFLE;
- else if (!strcasecmp(str, "Scan"))
- return SCAN;
- else if (!strcasecmp(str, "Position"))
- return POSITION;
- else if (!strcasecmp(str, "Track"))
- return METADATA;
- else if (!strcasecmp(str, "Status"))
- return STATUS;
-
- return 0;
-}
-
-static const char *__bt_media_type_to_str(int type)
-{
- switch (type) {
- case EQUALIZER:
- return "Equalizer";
- case REPEAT:
- return "Repeat";
- case SHUFFLE:
- return "Shuffle";
- case SCAN:
- return "Scan";
- case POSITION:
- return "Position";
- case METADATA:
- return "Track";
- case STATUS:
- return "Status";
- }
- return NULL;
-}
-
-static int __bt_media_attrval_to_val(int type, const char *value)
-{
- int ret = 0;
-
- switch (type) {
- case EQUALIZER:
- if (!strcmp(value, "off"))
- ret = EQUALIZER_OFF;
- else if (!strcmp(value, "on"))
- ret = EQUALIZER_ON;
- else
- ret = EQUALIZER_INVALID;
- break;
-
- case REPEAT:
- if (!strcmp(value, "off"))
- ret = REPEAT_MODE_OFF;
- else if (!strcmp(value, "singletrack"))
- ret = REPEAT_SINGLE_TRACK;
- else if (!strcmp(value, "alltracks"))
- ret = REPEAT_ALL_TRACK;
- else if (!strcmp(value, "group"))
- ret = REPEAT_GROUP;
- else
- ret = REPEAT_INVALID;
- break;
-
- case SHUFFLE:
- if (!strcmp(value, "off"))
- ret = SHUFFLE_MODE_OFF;
- else if (!strcmp(value, "alltracks"))
- ret = SHUFFLE_ALL_TRACK;
- else if (!strcmp(value, "group"))
- ret = SHUFFLE_GROUP;
- else
- ret = SHUFFLE_INVALID;
- break;
-
- case SCAN:
- if (!strcmp(value, "off"))
- ret = SCAN_MODE_OFF;
- else if (!strcmp(value, "alltracks"))
- ret = SCAN_ALL_TRACK;
- else if (!strcmp(value, "group"))
- ret = SCAN_GROUP;
- else
- ret = SCAN_INVALID;
- break;
-
- case STATUS:
- if (!strcmp(value, "stopped"))
- ret = STATUS_STOPPED;
- else if (!strcmp(value, "playing"))
- ret = STATUS_PLAYING;
- else if (!strcmp(value, "paused"))
- ret = STATUS_PAUSED;
- else if (!strcmp(value, "forward-seek"))
- ret = STATUS_FORWARD_SEEK;
- else if (!strcmp(value, "reverse-seek"))
- ret = STATUS_REVERSE_SEEK;
- else if (!strcmp(value, "error"))
- ret = STATUS_ERROR;
- else
- ret = STATUS_INVALID;
- }
- return ret;
-}
-
-int _bt_avrcp_control_get_property(int type, unsigned int *value)
-{
- DBusGProxy *proxy;
- char *name = NULL;
- int ret = BLUETOOTH_ERROR_NONE;
- GError *err = NULL;
- GValue attr_value = { 0 };
-
- BT_CHECK_PARAMETER(value, return);
-
- proxy = __bt_get_control_properties_proxy();
- retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
-
- if (!dbus_g_proxy_call(proxy, "Get", &err,
- G_TYPE_STRING, BT_PLAYER_CONTROL_INTERFACE,
- G_TYPE_STRING, __bt_media_type_to_str(type),
- G_TYPE_INVALID,
- G_TYPE_VALUE, &attr_value,
- G_TYPE_INVALID)) {
- if (err != NULL) {
- BT_ERR("Getting property failed: [%s]\n", err->message);
- g_error_free(err);
- }
- g_object_unref(proxy);
- return BLUETOOTH_ERROR_INTERNAL;
- }
- g_object_unref(proxy);
-
- switch (type) {
- case EQUALIZER:
- case REPEAT:
- case SHUFFLE:
- case SCAN:
- case STATUS:
- name = (char *)g_value_get_string(&attr_value);
- *value = __bt_media_attrval_to_val(type, name);
- BT_DBG("Type[%s] and Value[%s]", __bt_media_type_to_str(type), name);
- break;
- case POSITION:
- *value = g_value_get_uint(&attr_value);
- break;
- default:
- BT_DBG("Invalid Type\n");
- ret = BLUETOOTH_ERROR_INTERNAL;
- }
-
- return ret;
-}
-
-int _bt_avrcp_control_set_property(int type, unsigned int value)
-{
- GValue attr_value = { 0 };
- DBusGProxy *proxy;
- GError *error = NULL;
-
- proxy = __bt_get_control_properties_proxy();
-
- retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
- g_value_init(&attr_value, G_TYPE_STRING);
-
- switch (type) {
- case EQUALIZER:
- g_value_set_string(&attr_value, equalizer_status[value].property);
- BT_DBG("equalizer_status %s", equalizer_status[value].property);
- break;
- case REPEAT:
- g_value_set_string(&attr_value, repeat_status[value].property);
- BT_DBG("repeat_status %s", repeat_status[value].property);
- break;
- case SHUFFLE:
- g_value_set_string(&attr_value, shuffle_settings[value].property);
- BT_DBG("shuffle_settings %s", shuffle_settings[value].property);
- break;
- case SCAN:
- g_value_set_string(&attr_value, scan_status[value].property);
- BT_DBG("scan_status %s", scan_status[value].property);
- break;
- default:
- BT_ERR("Invalid property type: %d", type);
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- dbus_g_proxy_call(proxy, "Set", &error,
- G_TYPE_STRING, BT_PLAYER_CONTROL_INTERFACE,
- G_TYPE_STRING, __bt_media_type_to_str(type),
- G_TYPE_VALUE, &attr_value,
- G_TYPE_INVALID, G_TYPE_INVALID);
-
- g_value_unset(&attr_value);
- g_object_unref(proxy);
-
- if (error) {
- BT_ERR("SetProperty Fail: %s", error->message);
- g_error_free(error);
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static gboolean __bt_avrcp_control_parse_metadata(
- char **value_string,
- unsigned int *value_uint,
- int type,
- DBusMessageIter *iter)
-{
- if (dbus_message_iter_get_arg_type(iter) != type)
- return FALSE;
-
- if (type == DBUS_TYPE_STRING) {
- char *value;
- dbus_message_iter_get_basic(iter, &value);
- *value_string = g_strdup(value);
- } else if (type == DBUS_TYPE_UINT32) {
- int value;
- dbus_message_iter_get_basic(iter, &value);
- *value_uint = value;
- } else
- return FALSE;
-
- return TRUE;
-}
-
-
-static int __bt_avrcp_control_parse_properties(
- media_metadata_attributes_t *metadata,
- DBusMessageIter *iter)
-{
- DBusMessageIter dict;
- DBusMessageIter var;
- int ctype;
- char *value_string;
- unsigned int value_uint;
-
- ctype = dbus_message_iter_get_arg_type(iter);
- if (ctype != DBUS_TYPE_ARRAY) {
- BT_ERR("ctype error %d", ctype);
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- dbus_message_iter_recurse(iter, &dict);
-
- while ((ctype = dbus_message_iter_get_arg_type(&dict)) !=
- DBUS_TYPE_INVALID) {
- DBusMessageIter entry;
- const char *key;
-
- if (ctype != DBUS_TYPE_DICT_ENTRY) {
- BT_ERR("ctype error %d", ctype);
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- dbus_message_iter_recurse(&dict, &entry);
- if (dbus_message_iter_get_arg_type(&entry) !=
- DBUS_TYPE_STRING) {
- BT_ERR("ctype not DBUS_TYPE_STRING");
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- dbus_message_iter_get_basic(&entry, &key);
- dbus_message_iter_next(&entry);
-
- if (dbus_message_iter_get_arg_type(&entry) !=
- DBUS_TYPE_VARIANT) {
- BT_ERR("ctype not DBUS_TYPE_VARIANT");
- return FALSE;
- }
-
- dbus_message_iter_recurse(&entry, &var);
-
- BT_ERR("Key value is %s", key);
-
- if (strcasecmp(key, "Title") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_STRING, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- BT_DBG("Value : %s ", value_string);
- metadata->title = value_string;
- } else if (strcasecmp(key, "Artist") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_STRING, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- BT_DBG("Value : %s ", value_string);
- metadata->artist = value_string;
- } else if (strcasecmp(key, "Album") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_STRING, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- BT_DBG("Value : %s ", value_string);
- metadata->album = value_string;
- } else if (strcasecmp(key, "Genre") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_STRING, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- BT_DBG("Value : %s ", value_string);
- metadata->genre = value_string;
- } else if (strcasecmp(key, "Duration") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_UINT32, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- metadata->duration = value_uint;
- } else if (strcasecmp(key, "NumberOfTracks") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_UINT32, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- metadata->total_tracks = value_uint;
- } else if (strcasecmp(key, "TrackNumber") == 0) {
- if (!__bt_avrcp_control_parse_metadata(&value_string,
- &value_uint, DBUS_TYPE_UINT32, &var))
- return BLUETOOTH_ERROR_INTERNAL;
- metadata->number = value_uint;
- } else
- BT_DBG("%s not supported, ignoring", key);
- dbus_message_iter_next(&dict);
- }
-
- if (!metadata->title)
- metadata->title = g_strdup("");
- if (!metadata->artist)
- metadata->artist = g_strdup("");
- if (!metadata->album)
- metadata->album = g_strdup("");
- if (!metadata->genre)
- metadata->genre = g_strdup("");
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-int _bt_avrcp_control_get_track_info(media_metadata_attributes_t *metadata)
-{
- DBusMessage *msg;
- DBusMessage *reply;
- DBusError err;
- DBusConnection *conn;
- char *control_path;
- char *interface_name;
- char *property_name;
- DBusMessageIter arr, iter;
- int ret = BLUETOOTH_ERROR_NONE;
-
- retv_if(metadata == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- conn = _bt_get_system_conn();
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- control_path = __bt_get_control_device_path();
- retv_if(control_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
- BT_DBG("control_path %s", control_path);
-
- msg = dbus_message_new_method_call(BT_BLUEZ_NAME, control_path,
- BT_PROPERTIES_INTERFACE, "Get");
-
- retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- interface_name = g_strdup(BT_PLAYER_CONTROL_INTERFACE);
- property_name = g_strdup("Track");
-
- dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &interface_name,
- DBUS_TYPE_STRING, &property_name,
- DBUS_TYPE_INVALID);
-
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn,
- msg, -1, &err);
-
- g_free(interface_name);
- g_free(property_name);
- dbus_message_unref(msg);
-
- if (!reply) {
- BT_ERR("Error in getting Metadata");
- if (dbus_error_is_set(&err)) {
- BT_ERR("%s", err.message);
- dbus_error_free(&err);
- }
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- dbus_message_iter_init(reply, &iter);
- dbus_message_iter_recurse(&iter, &arr);
-
- ret = __bt_avrcp_control_parse_properties(metadata, &arr);
- dbus_message_unref(reply);
-
- BT_DBG("-");
- return ret;
-}
-
-void _bt_handle_avrcp_control_event(DBusMessageIter *msg_iter, const char *path)
-{
- DBusMessageIter value_iter;
- DBusMessageIter dict_iter;
- DBusMessageIter item_iter;
- const char *property = NULL;
-
- dbus_message_iter_recurse(msg_iter, &item_iter);
-
- if (dbus_message_iter_get_arg_type(&item_iter)
- != DBUS_TYPE_DICT_ENTRY) {
- BT_ERR("This is bad format dbus");
- return;
- }
-
- dbus_message_iter_recurse(&item_iter, &dict_iter);
-
- dbus_message_iter_get_basic(&dict_iter, &property);
- ret_if(property == NULL);
-
- BT_DBG("property : %s ", property);
- ret_if(!dbus_message_iter_next(&dict_iter));
-
- if ((strcasecmp(property, "Equalizer") == 0) ||
- (strcasecmp(property, "Repeat") == 0) ||
- (strcasecmp(property, "Shuffle") == 0) ||
- (strcasecmp(property, "Scan") == 0) ||
- (strcasecmp(property, "Status") == 0)) {
-
- const char *valstr;
- int type, value;
-
- dbus_message_iter_recurse(&dict_iter, &value_iter);
- dbus_message_iter_get_basic(&value_iter, &valstr);
- BT_DBG("Value : %s ", valstr);
- type = __bt_media_attr_to_type(property);
- value = __bt_media_attrval_to_val(type, valstr);
-
- /* Send event to application */
- _bt_send_event(BT_AVRCP_CONTROL_EVENT,
- __bt_media_attr_to_event(property),
- DBUS_TYPE_UINT32, &value,
- DBUS_TYPE_INVALID);
- } else if (strcasecmp(property, "Position") == 0) {
- unsigned int value;
-
- dbus_message_iter_recurse(&dict_iter, &value_iter);
- dbus_message_iter_get_basic(&value_iter, &value);
- BT_DBG("Value : %d ", value);
-
- /* Send event to application */
- _bt_send_event(BT_AVRCP_CONTROL_EVENT,
- __bt_media_attr_to_event(property),
- DBUS_TYPE_UINT32, &value,
- DBUS_TYPE_INVALID);
- } else if (strcasecmp(property, "Track") == 0) {
- int ret = BLUETOOTH_ERROR_NONE;
- media_metadata_attributes_t metadata;
-
- dbus_message_iter_recurse(&dict_iter, &value_iter);
- memset(&metadata, 0x00, sizeof(media_metadata_attributes_t));
-
- ret = __bt_avrcp_control_parse_properties(
- &metadata, &value_iter);
- if (BLUETOOTH_ERROR_NONE != ret)
- return;
-
- /* Send event to application */
- _bt_send_event(BT_AVRCP_CONTROL_EVENT,
- BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED,
- DBUS_TYPE_STRING, &metadata.title,
- DBUS_TYPE_STRING, &metadata.artist,
- DBUS_TYPE_STRING, &metadata.album,
- DBUS_TYPE_STRING, &metadata.genre,
- DBUS_TYPE_UINT32, &metadata.total_tracks,
- DBUS_TYPE_UINT32, &metadata.number,
- DBUS_TYPE_UINT32, &metadata.duration,
- DBUS_TYPE_INVALID);
-
- g_free(metadata.title);
- g_free(metadata.artist);
- g_free(metadata.album);
- g_free(metadata.genre);
- } else {
- BT_DBG("Preprty not handled");
- }
-
- BT_DBG("-");
-}