/*
- * bluetooth-frwk
- *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * 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.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
*
*/
-#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>
#include <syspopup_caller.h>
+#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 equalizer_settings[] = {
- { EQUALIZER_INVALID, "" },
- { EQUALIZER_OFF, "off" },
- { EQUALIZER_ON, "on" },
- { EQUALIZER_INVALID, "" }
-};
-
-static struct player_settinngs_t repeat_settings[] = {
+static bt_player_settinngs_t loopstatus_settings[] = {
{ REPEAT_INVALID, "" },
- { REPEAT_MODE_OFF, "off" },
- { REPEAT_SINGLE_TRACK, "singletrack" },
- { REPEAT_ALL_TRACK, "alltracks" },
- { REPEAT_GROUP, "group" },
+ { REPEAT_MODE_OFF, "None" },
+ { REPEAT_SINGLE_TRACK, "Track" },
+ { REPEAT_ALL_TRACK, "Playlist" },
{ 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 scan_settings[] = {
- { SCAN_INVALID, "" },
- { SCAN_MODE_OFF, "off" },
- { SCAN_ALL_TRACK, "alltracks" },
- { SCAN_GROUP, "group" },
- { SCAN_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, "" }
};
-typedef struct {
- GObject parent;
-} BtMediaAgent;
-
-typedef struct {
- GObjectClass parent;
-} BtMediaAgentClass;
-
-GType bt_media_agent_get_type(void);
-
-#define BT_MEDIA_TYPE_AGENT (bt_media_agent_get_type())
-#define BT_MEDIA_GET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), BT_MEDIA_TYPE_AGENT, BtMediaAgent))
-#define BT_MEDIA_IS_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), BT_MEDIA_TYPE_AGENT))
-#define BT_MEDIA_AGENT_CLASS(class) (G_TYPE_CHECK_CLASS_CAST((class), BT_MEDIA_TYPE_AGENT, \
- BtMediaAgentClass))
-#define BT_MEDIA_GET_AGENT_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), BT_MEDIA_TYPE_AGENT, \
- BtMediaAgentClass))
-#define BT_MEDIA_IS_AGENT_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE((class), BT_MEDIA_TYPE_AGENT))
-
-G_DEFINE_TYPE(BtMediaAgent, bt_media_agent, G_TYPE_OBJECT)
-
-static gboolean bt_media_agent_set_property(BtMediaAgent *agent,
- const char *property, GValue *value,
- DBusGMethodInvocation *context);
-
-static BtMediaAgent *bt_media_obj = NULL;
-
-#include "bt-media-agent-method.h"
-
-typedef enum {
- BT_MEDIA_AGENT_ERROR_INVALID_PARAM,
- BT_MEDIA_AGENT_ERROR_NOT_AVAILABLE,
- BT_MEDIA_AGENT_ERROR_BUSY,
-} BtMediaAgentError;
-
-#define BT_MEDIA_AGENT_ERROR (bt_media_agent_error_quark())
-
-static GQuark bt_media_agent_error_quark(void)
+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)
{
- static GQuark quark = 0;
- if (!quark)
- quark = g_quark_from_static_string("agent");
-
- return quark;
-}
-
-#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+ GVariantBuilder *builder = NULL;
+ GError *error = NULL;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(builder, "{sv}", name, variant);
+
+ g_dbus_connection_emit_signal(connection, NULL, path,
+ DBUS_INTERFACE_PROPERTIES,
+ "PropertiesChanged",
+ g_variant_new("(sa{sv})",
+ interface, builder),
+ &error);
+
+ 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 GError *bt_media_agent_error(BtMediaAgentError error, const char *err_msg)
-{
- return g_error_new(BT_MEDIA_AGENT_ERROR, error, err_msg, NULL);
+ return TRUE;
}
-static void bt_media_agent_init(BtMediaAgent *agent)
+static GQuark __bt_avrcp_error_quark(void)
{
- BT_DBG("agent %p\n", agent);
-}
+ static GQuark quark = 0;
-static void bt_media_agent_finalize(GObject *agent)
-{
- BT_DBG("Free agent %p\n", agent);
+ if (!quark)
+ quark = g_quark_from_static_string("bt-avrcp");
- G_OBJECT_CLASS(bt_media_agent_parent_class)->finalize(agent);
+ return quark;
}
-static void bt_media_agent_class_init(BtMediaAgentClass *klass)
+static GError *__bt_avrcp_set_error(bt_avrcp_error_t error)
{
- GObjectClass *object_class = (GObjectClass *) klass;
-
- BT_DBG("class %p\n", klass);
-
- object_class->finalize = bt_media_agent_finalize;
-
- dbus_g_object_type_install_info(BT_MEDIA_TYPE_AGENT,
- &dbus_glib_bt_media_agent_object_info);
+ 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 BtMediaAgent *__bt_media_agent_new(void)
+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)
{
- BtMediaAgent *agent;
-
- agent = BT_MEDIA_GET_AGENT(g_object_new(BT_MEDIA_TYPE_AGENT, NULL));
-
- BT_DBG("agent %p\n", agent);
-
- return agent;
-}
+ BT_DBG("+");
+ 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;
+ 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;
+ }
+ }
-static gboolean bt_media_agent_set_property(BtMediaAgent *agent,
- const char *property, GValue *val,
- DBusGMethodInvocation *context)
-{
- GError *error;
- const gchar *value;
- unsigned int status;
-
- BT_DBG("property %s\n", property);
-
- if (!(G_VALUE_TYPE (val) == G_TYPE_STRING)) {
- error = bt_media_agent_error(
- BT_MEDIA_AGENT_ERROR_INVALID_PARAM,
- "Invalid Arguments");
- dbus_g_method_return_error(context, error);
- g_error_free(error);
- return FALSE;
+ if (value == NULL) {
+ BT_ERR("value is NULL");
+ goto fail;
}
- value = g_value_get_string (val);
- BT_DBG("value %s\n", value);
+ BT_DBG("Property: %s\n", property);
if (g_strcmp0(property, "Shuffle") == 0) {
- if (g_strcmp0(value, "alltracks") == 0)
+
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
+ BT_ERR("Error");
+ ret = BT_AVRCP_ERROR_INVALID_PARAM;
+ goto fail;
+ }
+
+ 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 if (g_strcmp0(value, "group") == 0)
- status = SHUFFLE_GROUP;
- else if (g_strcmp0(value, "off") == 0)
- status = SHUFFLE_MODE_OFF;
else
- status = SHUFFLE_INVALID;
+ status = SHUFFLE_MODE_OFF;
_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) {
- } else if (g_strcmp0(property, "Equalizer") == 0) {
- status = (g_strcmp0(value, "off") == 0) ? EQUALIZER_OFF : EQUALIZER_ON;
+ if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+ BT_ERR("Error");
+ ret = BT_AVRCP_ERROR_INVALID_PARAM;
+ goto fail;
+ }
- _bt_send_event(BT_AVRCP_EVENT,
- BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS,
- DBUS_TYPE_UINT32, &status,
- DBUS_TYPE_INVALID);
+ loop_status = (gchar *)g_variant_get_string(value, NULL);
+ BT_DBG("Value: %s\n", loop_status);
- } else if (g_strcmp0(property, "Repeat") == 0) {
- if (g_strcmp0(value, "singletrack") == 0)
+ if (g_strcmp0(loop_status, "Track") == 0)
status = REPEAT_SINGLE_TRACK;
- else if (g_strcmp0(value, "alltracks") == 0)
+ else if (g_strcmp0(loop_status, "Playlist") == 0)
status = REPEAT_ALL_TRACK;
- else if (g_strcmp0(value, "group") == 0)
- status = REPEAT_GROUP;
- else if (g_strcmp0(value, "off") == 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);
- } else if (g_strcmp0(property, "Scan") == 0) {
- if (g_strcmp0(value, "alltracks") == 0)
- status = SCAN_ALL_TRACK;
- else if (g_strcmp0(value, "group") == 0)
- status = SCAN_GROUP;
- else if (g_strcmp0(value, "off") == 0)
- status = SCAN_MODE_OFF;
- else
- status = SCAN_INVALID;
-
- _bt_send_event(BT_AVRCP_EVENT,
- BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS,
- DBUS_TYPE_UINT32, &status,
- DBUS_TYPE_INVALID);
- }
- dbus_g_method_return(context);
- return TRUE;
-
-}
-
-static void __bt_media_append_variant(DBusMessageIter *iter,
- int type, void *value)
-{
- const char *sig;
- DBusMessageIter value_iter;
-
- switch (type) {
- case DBUS_TYPE_BOOLEAN:
- sig = DBUS_TYPE_BOOLEAN_AS_STRING;
- break;
- case DBUS_TYPE_STRING:
- sig = DBUS_TYPE_STRING_AS_STRING;
- break;
- case DBUS_TYPE_BYTE:
- sig = DBUS_TYPE_BYTE_AS_STRING;
- break;
- case DBUS_TYPE_UINT16:
- sig = DBUS_TYPE_UINT16_AS_STRING;
- break;
- case DBUS_TYPE_UINT32:
- sig = DBUS_TYPE_UINT32_AS_STRING;
- break;
- case DBUS_TYPE_INT16:
- sig = DBUS_TYPE_INT16_AS_STRING;
- break;
- case DBUS_TYPE_INT32:
- sig = DBUS_TYPE_INT32_AS_STRING;
- break;
- case DBUS_TYPE_OBJECT_PATH:
- sig = DBUS_TYPE_OBJECT_PATH_AS_STRING;
- break;
- default:
- sig = DBUS_TYPE_VARIANT_AS_STRING;
- break;
+ g_variant_new("(u)", status));
}
- dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig,
- &value_iter);
-
- dbus_message_iter_append_basic(&value_iter, type, value);
+ BT_DBG("-");
+ return;
- dbus_message_iter_close_container(iter, &value_iter);
+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 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;
- gboolean ret;
-
- sig = dbus_message_new_signal(path, interface,
- "PropertyChanged");
- retv_if(sig == NULL, FALSE);
-
- dbus_message_iter_init_append(sig, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
-
- __bt_media_append_variant(&entry, type, property);
-
- ret = dbus_connection_send(connection, sig, NULL);
- dbus_message_unref(sig);
-
- return ret;
-}
+static const GDBusInterfaceVTable method_table = {
+ __bt_avrcp_agent_method,
+ NULL,
+ NULL,
+};
-static void __bt_media_append_dict_entry(DBusMessageIter *iter,
- const char *key, int type, void *property)
+static GDBusNodeInfo *__bt_avrcp_create_method_node_info
+ (const gchar *introspection_data)
{
- DBusMessageIter dict_entry;
- const char *str_ptr;
-
- if (type == DBUS_TYPE_STRING) {
- str_ptr = *((const char **)property);
- ret_if(str_ptr == NULL);
- }
+ GError *err = NULL;
+ GDBusNodeInfo *node_info = NULL;
- dbus_message_iter_open_container(iter,
- DBUS_TYPE_DICT_ENTRY,
- NULL, &dict_entry);
+ if (introspection_data == NULL)
+ return NULL;
- dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key);
+ node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
- __bt_media_append_variant(&dict_entry, type, property);
+ if (err) {
+ BT_ERR("Unable to create node: %s", err->message);
+ g_clear_error(&err);
+ }
- dbus_message_iter_close_container(iter, &dict_entry);
+ return node_info;
}
int _bt_register_media_player(void)
{
- DBusMessage *msg;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter property_dict;
- DBusMessageIter metadata_dict;
- DBusError err;
- char *object;
- char *adapter_path;
- DBusConnection *conn;
- DBusGConnection *gconn;
+ BT_DBG("+");
+ 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,};
- media_metadata_attributes_t metadata = {0,};
- player_settings.equalizer = EQUALIZER_OFF;
player_settings.repeat = REPEAT_MODE_OFF;
- player_settings.shuffle = SHUFFLE_MODE_OFF;
- player_settings.scan = SCAN_MODE_OFF;
player_settings.status = STATUS_STOPPED;
player_settings.position = 0;
+ shuffle_status = FALSE;
- metadata.title = "\0";
- metadata.artist = "\0";
- metadata.album = "\0";
- metadata.genre = "\0";
- metadata.total_tracks = 0;
- metadata.number = 0;
- metadata.duration = 0;
-
- 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_conn = _bt_gdbus_get_system_gconn();
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
- if (!bt_media_obj) {
- bt_media_obj = __bt_media_agent_new();
+ node_info = __bt_avrcp_create_method_node_info(
+ bt_avrcp_bluez_introspection_xml);
+ if (node_info == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
- retv_if(bt_media_obj == NULL, 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);
- dbus_g_connection_register_g_object(gconn,
- BT_MEDIA_OBJECT_PATH,
- G_OBJECT(bt_media_obj));
+ 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,
- "Equalizer",
- DBUS_TYPE_STRING,
- &equalizer_settings[player_settings.equalizer].property);
-
- __bt_media_append_dict_entry(&property_dict,
- "Repeat",
- DBUS_TYPE_STRING,
- &repeat_settings[player_settings.repeat].property);
+ 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,
- "Shuffle",
- DBUS_TYPE_STRING,
- &shuffle_settings[player_settings.shuffle].property);
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
- __bt_media_append_dict_entry(&property_dict,
- "Scan",
- DBUS_TYPE_STRING,
- &scan_settings[player_settings.scan].property);
+ 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,
- "Status",
- DBUS_TYPE_STRING,
- &player_status[player_settings.status].property);
+ g_variant_builder_add(builder, "{sv}", "Shuffle",
+ g_variant_new("b", shuffle_status));
- __bt_media_append_dict_entry(&property_dict,
- "Position",
- DBUS_TYPE_UINT32, &player_settings.position);
+ 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_message_iter_close_container(&iter, &property_dict);
+ g_variant_builder_add(builder, "{sv}", "Position",
+ g_variant_new("u", player_settings.position));
- dbus_message_iter_init_append(msg, &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, &metadata_dict);
+ 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);
- __bt_media_append_dict_entry(&metadata_dict,
- "Title",
- DBUS_TYPE_STRING, &metadata.title);
+ g_object_unref(proxy);
+ g_free(path);
+ g_variant_builder_unref(builder);
- __bt_media_append_dict_entry(&metadata_dict,
- "Artist",
- DBUS_TYPE_STRING, &metadata.artist);
+ 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;
+ }
- __bt_media_append_dict_entry(&metadata_dict,
- "Album",
- DBUS_TYPE_STRING, &metadata.album);
+ g_variant_unref(ret);
+ return BLUETOOTH_ERROR_NONE;
+}
- __bt_media_append_dict_entry(&metadata_dict,
- "Genre",
- DBUS_TYPE_STRING, &metadata.genre);
+static void __bt_avrcp_unregister_object_path(void)
+{
+ GDBusConnection *g_conn;
- __bt_media_append_dict_entry(&metadata_dict,
- "NumberOfTracks",
- DBUS_TYPE_UINT32, &metadata.total_tracks);
+ g_conn = _bt_gdbus_get_system_gconn();
+ ret_if(g_conn == NULL);
- __bt_media_append_dict_entry(&metadata_dict,
- "Number",
- DBUS_TYPE_UINT32, &metadata.number);
+ if (avrcp_reg_id > 0) {
+ g_dbus_connection_unregister_object(g_conn,
+ avrcp_reg_id);
+ avrcp_reg_id = 0;
+ }
+}
- __bt_media_append_dict_entry(&metadata_dict,
- "Duration",
- DBUS_TYPE_UINT32, &metadata.duration);
+int _bt_unregister_media_player(void)
+{
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ GDBusProxy *proxy;
+ gchar *adapter_path;
+ GVariant *ret;
+ GError *error = NULL;
+ gchar *path;
+ int result = BLUETOOTH_ERROR_NONE;
- dbus_message_iter_close_container(&iter, &metadata_dict);
+ adapter_path = _bt_get_adapter_path();
+ if (adapter_path == NULL) {
+ result = BLUETOOTH_ERROR_INTERNAL;
+ goto FAIL;
+ }
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn,
- msg, -1, &err);
- dbus_message_unref(msg);
+ 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;
+ }
- if (!reply) {
- BT_ERR("Error in registering the Music Player \n");
+ 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);
- if (dbus_error_is_set(&err)) {
- BT_ERR("%s", err.message);
- dbus_error_free(&err);
- return BLUETOOTH_ERROR_INTERNAL;
+ 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;
+ }
- if (bt_media_obj) {
- dbus_g_connection_unregister_g_object(gconn,
- G_OBJECT(bt_media_obj));
- g_object_unref(bt_media_obj);
- bt_media_obj = NULL;
+ path = g_strdup(BT_MEDIA_OBJECT_PATH);
+ BT_DBG("path is [%s]", path);
+
+ 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);
+
+ 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);
- if (reply)
- dbus_message_unref(reply);
+FAIL:
+ __bt_avrcp_unregister_object_path();
- return BLUETOOTH_ERROR_NONE;
+ BT_DBG("-");
+ return result;
}
-int _bt_unregister_media_player(void)
+int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
{
- DBusMessage *msg;
- DBusMessage *reply;
- DBusError err;
- char *object;
- char *adapter_path;
- DBusConnection *conn;
+ BT_DBG("+");
+ char *interface = BT_MEDIA_PLAYER_INTERFACE;
+ GDBusConnection *g_conn;
+ GError *error = NULL;
+ GVariantBuilder *builder = NULL;
+ GVariantBuilder *inner_builder = NULL;
+ GVariant *children[1];
+ gboolean ret;
- conn = _bt_get_system_conn();
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
- adapter_path = _bt_get_adapter_path();
- retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
+ g_conn = _bt_gdbus_get_system_gconn();;
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
- msg = dbus_message_new_method_call(BT_BLUEZ_NAME, adapter_path,
- BT_MEDIA_INTERFACE, "UnregisterPlayer");
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
- retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:title", g_variant_new_string(meta_data->title));
- object = g_strdup(BT_MEDIA_OBJECT_PATH);
+ 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_append_args(msg,
- DBUS_TYPE_OBJECT_PATH, &object,
- DBUS_TYPE_INVALID);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:album", g_variant_new_string(meta_data->album));
- g_free(object);
+ 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_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn,
- msg, -1, &err);
- dbus_message_unref(msg);
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:totalTracks", g_variant_new_int32(meta_data->total_tracks));
- if (!reply) {
- BT_ERR("Error in unregistering the Music Player \n");
+ g_variant_builder_add(inner_builder, "{sv}",
+ "xesam:trackNumber", g_variant_new_int32(meta_data->number));
- if (dbus_error_is_set(&err)) {
- BT_DBG("%s", err.message);
- dbus_error_free(&err);
- return BLUETOOTH_ERROR_INTERNAL;
- }
- } else {
- dbus_message_unref(reply);
- }
+ g_variant_builder_add(inner_builder, "{sv}",
+ "mpris:length", g_variant_new_int64(meta_data->duration));
+
+ g_variant_builder_add(builder, "{sv}",
+ "Metadata", g_variant_new("a{sv}", inner_builder));
+
+ 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 (bt_media_obj) {
- dbus_g_connection_unregister_g_object(_bt_get_system_gconn(),
- G_OBJECT(bt_media_obj));
- g_object_unref(bt_media_obj);
- bt_media_obj = NULL;
+ g_variant_builder_unref(inner_builder);
+ g_variant_builder_unref(builder);
+
+ if (!ret) {
+ if (error != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
}
+ BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
}
-int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
+int _bt_avrcp_set_interal_property(int type, media_player_settings_t *properties)
{
- DBusMessage *signal;
- DBusMessageIter iter;
- DBusMessageIter metadata_dict;
- DBusConnection *conn;
-
- retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- conn = _bt_get_system_conn();
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
-
- signal = dbus_message_new_signal(BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE, "TrackChanged");
+ BT_DBG("+");
+ GDBusConnection *g_conn;
+ int value;
+ media_metadata_attributes_t meta_data;
+ gboolean shuffle;
+ GVariantBuilder *builder = NULL;
+ GVariant *children[1];
- retv_if(signal == NULL, BLUETOOTH_ERROR_INTERNAL);
+ g_conn = _bt_gdbus_get_system_gconn();;
+ retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
- dbus_message_iter_init_append(signal, &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, &metadata_dict);
-
- if (meta_data->title) {
- __bt_media_append_dict_entry(&metadata_dict,
- "Title",
- DBUS_TYPE_STRING, &meta_data->title);
- }
-
- if (meta_data->artist) {
- __bt_media_append_dict_entry(&metadata_dict,
- "Artist",
- DBUS_TYPE_STRING, &meta_data->artist);
- }
+ switch (type) {
+ case REPEAT:
+ value = properties->repeat;
+ 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;
+ }
+ break;
+ case SHUFFLE:
+ value = properties->shuffle;
+ if (g_strcmp0(shuffle_settings[value].property, "off") == 0)
+ shuffle = FALSE;
+ else
+ shuffle = TRUE;
- if (meta_data->album) {
- __bt_media_append_dict_entry(&metadata_dict,
- "Album",
- DBUS_TYPE_STRING, &meta_data->album);
- }
+ 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(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(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 (meta_data->genre) {
- __bt_media_append_dict_entry(&metadata_dict,
- "Genre",
- DBUS_TYPE_STRING, &meta_data->genre);
- }
+ 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));
- if (0 != meta_data->total_tracks)
- __bt_media_append_dict_entry(&metadata_dict,
- "NumberOfTracks",
- DBUS_TYPE_UINT32, &meta_data->total_tracks);
+ 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));
- if (0 != meta_data->number)
- __bt_media_append_dict_entry(&metadata_dict,
- "Number",
- DBUS_TYPE_UINT32, &meta_data->number);
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:album", g_variant_new_string(meta_data.album));
- if (0 != meta_data->duration)
- __bt_media_append_dict_entry(&metadata_dict,
- "Duration",
- DBUS_TYPE_UINT32, &meta_data->duration);
+ 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));
- dbus_message_iter_close_container(&iter, &metadata_dict);
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:totalTracks", g_variant_new_int32(meta_data.total_tracks));
- if (!dbus_connection_send(conn, signal, NULL))
- BT_ERR("Unable to send TrackChanged signal\n");
+ g_variant_builder_add(builder, "{sv}",
+ "xesam:trackNumber", g_variant_new_int32(meta_data.number));
- dbus_message_unref(signal);
+ 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_ERR("Invalid Type\n");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
}
-
int _bt_avrcp_set_properties(media_player_settings_t *properties)
{
- if (_bt_avrcp_set_property(EQUALIZER,
- properties->equalizer) != BLUETOOTH_ERROR_NONE) {
- return BLUETOOTH_ERROR_INTERNAL;
- }
+ BT_DBG("+");
- if (_bt_avrcp_set_property(REPEAT,
- properties->repeat) != BLUETOOTH_ERROR_NONE) {
- return BLUETOOTH_ERROR_INTERNAL;
+ if (_bt_avrcp_set_interal_property(REPEAT,
+ properties) != BLUETOOTH_ERROR_NONE) {
+ return BLUETOOTH_ERROR_INTERNAL;
}
-
- if (_bt_avrcp_set_property(SHUFFLE,
- properties->shuffle) != BLUETOOTH_ERROR_NONE) {
+ if (_bt_avrcp_set_interal_property(SHUFFLE,
+ properties) != BLUETOOTH_ERROR_NONE) {
return BLUETOOTH_ERROR_INTERNAL;
}
- if (_bt_avrcp_set_property(SCAN,
- properties->scan) != BLUETOOTH_ERROR_NONE) {
+ if (_bt_avrcp_set_interal_property(STATUS,
+ properties) != BLUETOOTH_ERROR_NONE) {
return BLUETOOTH_ERROR_INTERNAL;
}
- if (_bt_avrcp_set_property(STATUS,
- properties->status) != BLUETOOTH_ERROR_NONE) {
+ if (_bt_avrcp_set_interal_property(POSITION,
+ properties) != BLUETOOTH_ERROR_NONE) {
return BLUETOOTH_ERROR_INTERNAL;
}
- if (_bt_avrcp_set_property(POSITION,
- properties->position) != BLUETOOTH_ERROR_NONE) {
+ if (_bt_avrcp_set_interal_property(METADATA,
+ properties) != BLUETOOTH_ERROR_NONE) {
return BLUETOOTH_ERROR_INTERNAL;
}
-
+ BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
}
int _bt_avrcp_set_property(int type, unsigned int value)
{
- DBusConnection *conn;
-
- conn = _bt_get_system_conn();
- retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+ BT_DBG("+");
+ media_player_settings_t properties;
switch (type) {
- case EQUALIZER:
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Equalizer",
- DBUS_TYPE_STRING,
- &equalizer_settings[value].property)) {
- BT_ERR("Error sending the PropertyChanged signal \n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
- break;
case REPEAT:
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Repeat",
- DBUS_TYPE_STRING,
- &repeat_settings[value].property)) {
- BT_ERR("Error sending the PropertyChanged signal \n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
+ properties.repeat = value;
break;
case SHUFFLE:
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Shuffle",
- DBUS_TYPE_STRING,
- &shuffle_settings[value].property)) {
- BT_ERR("Error sending the PropertyChanged signal \n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
- break;
- case SCAN:
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Scan",
- DBUS_TYPE_STRING,
- &scan_settings[value].property)) {
- BT_ERR("Error sending the PropertyChanged signal \n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
+ properties.shuffle = value;
break;
case STATUS:
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Status",
- DBUS_TYPE_STRING,
- &player_status[value].property)) {
- BT_ERR("Error sending the PropertyChanged signal \n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
+ properties.status = value;
break;
case POSITION:
- if (!__bt_media_emit_property_changed(
- conn,
- BT_MEDIA_OBJECT_PATH,
- BT_MEDIA_PLAYER_INTERFACE,
- "Position",
- DBUS_TYPE_UINT32,
- &value)) {
- BT_ERR("Error sending the PropertyChanged signal \n");
- return BLUETOOTH_ERROR_INTERNAL;
- }
+ properties.position = value;
break;
default:
- BT_ERR("Invalid Type\n");
+ BT_DBG("Invalid Type\n");
return BLUETOOTH_ERROR_INTERNAL;
}
+ if (_bt_avrcp_set_interal_property(type,
+ &properties) != BLUETOOTH_ERROR_NONE)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ BT_DBG("-");
+
return BLUETOOTH_ERROR_NONE;
}
-