Re-merge the codes
[framework/connectivity/bluetooth-frwk.git] / lib / bluetooth-control-api.c
1 /*
2  *   bluetooth-media-control
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:     Hocheol Seo <hocheol.seo@samsung.com>
7  *              Girishashok Joshi <girish.joshi@samsung.com>
8  *              Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  */
24
25 #include <stdio.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <malloc.h>
30 #include <sys/types.h>
31 #include <glib.h>
32 #include <string.h>
33
34 #include "bluetooth-control-api.h"
35
36 #define BLUEZ_SERVICE   "org.bluez"
37 #define BLUEZ_MANAGER_INTERFACE "org.bluez.Manager"
38
39 #define BLUEZ_MEDIA_INTERFACE   "org.bluez.Media"
40 #define BLUEZ_MEDIA_PLAYER_OBJECT_PATH  "/Musicplayer"
41
42
43 #define BLUEZ_MEDIA_PLAYER_INTERFACE    "org.bluez.MediaPlayer"
44
45 #ifndef BT_EXPORT_API
46 #define BT_EXPORT_API __attribute__((visibility("default")))
47 #endif
48
49 #define BT_CONTROL "BT_CONTROL"
50 #define DBG(fmt, args...) SLOG(LOG_DEBUG, BT_CONTROL, \
51                                 "%s():%d "fmt, __func__, __LINE__, ##args)
52 #define ERR(fmt, args...) SLOG(LOG_ERROR, BT_CONTROL, \
53                                 "%s():%d "fmt, __func__, __LINE__, ##args)
54
55 typedef struct {
56         DBusGConnection *avrcp_conn;
57         char avrcp_obj_path[MEDIA_OBJECT_PATH_LENGTH];
58 } avrcp_dbus_info_t;
59
60 static avrcp_dbus_info_t g_avrcp_dbus_info;
61 static DBusConnection *g_avrcp_connection = NULL;
62
63 struct player_settinngs_t {
64         int key;
65         const char *property;
66 };
67
68 static struct player_settinngs_t equilizer_settings[] = {
69         { EQUILIZER_OFF, "off" },
70         { EQUILIZER_ON, "on" },
71         { EQUILIZER_INVALID, "" }
72 };
73
74 static struct player_settinngs_t repeat_settings[] = {
75         { REPEAT_MODE_OFF, "off" },
76         { REPEAT_SINGLE_TRACK, "singletrack" },
77         { REPEAT_ALL_TRACK, "alltracks" },
78         { REPEAT_GROUP, "group" },
79         { REPEAT_INVALID, "" }
80 };
81
82 static struct player_settinngs_t shuffle_settings[] = {
83         { SHUFFLE_MODE_OFF, "off" },
84         { SHUFFLE_ALL_TRACK, "alltracks" },
85         { SHUFFLE_GROUP, "group" },
86         { SHUFFLE_INVALID, "" }
87 };
88
89 static struct player_settinngs_t scan_settings[] = {
90         { SCAN_MODE_OFF, "off" },
91         { SCAN_ALL_TRACK, "alltracks" },
92         { SCAN_GROUP, "group" },
93         { SCAN_INVALID, "" }
94 };
95
96 static struct player_settinngs_t player_status[] = {
97         { STATUS_PLAYING, "playing" },
98         { STATUS_STOPPED, "stopped" },
99         { STATUS_PAUSED, "paused" },
100         { STATUS_FORWARD_SEEK, "forward-seek" },
101         { STATUS_REVERSE_SEEK, "reverse-seek" },
102         { STATUS_ERROR, "error" },
103         { STATUS_INVALID, "" }
104 };
105
106 static int __bluetooth_media_get_avrcp_adapter_path(
107                 DBusGConnection *gconn, char *path)
108 {
109         GError *err = NULL;
110         DBusGProxy *manager_proxy = NULL;
111         char *adapter_path = NULL;
112         int ret = 0;
113
114         DBG("__bluetooth_media_get_avrcp_adapter_path +\n");
115
116         manager_proxy = dbus_g_proxy_new_for_name(gconn, BLUEZ_SERVICE, "/",
117                                         BLUEZ_MANAGER_INTERFACE);
118
119         if (manager_proxy == NULL) {
120                 DBG("Could not create a dbus proxy\n");
121                 return BLUETOOTH_CONTROL_ERROR;
122         }
123
124         if (!dbus_g_proxy_call(manager_proxy, "DefaultAdapter", &err,
125                                G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
126                                &adapter_path, G_TYPE_INVALID)) {
127                 DBG("Getting DefaultAdapter failed: [%s]\n", err->message);
128                 g_error_free(err);
129                 ret = BLUETOOTH_CONTROL_ERROR;
130                 goto done;
131         }
132
133         if (strlen(adapter_path) >= MEDIA_OBJECT_PATH_LENGTH) {
134                 DBG("Path too long.\n");
135                 ret = BLUETOOTH_CONTROL_ERROR;
136                 goto done;
137         }
138         DBG("path = %s\n", adapter_path);
139         g_strlcpy(path, adapter_path, MEDIA_OBJECT_PATH_LENGTH);
140
141 done:
142         g_object_unref(manager_proxy);
143
144         DBG("Adapter [%s]\n", path);
145
146         DBG("__bluetooth_media_get_avrcp_adapter_path -\n");
147         return ret;
148 }
149
150 static void __bluetooth_media_append_variant(DBusMessageIter *iter,
151                         int type, void *val)
152 {
153         DBusMessageIter value_iter;
154         const char *contained_signature;
155
156         switch (type) {
157         case DBUS_TYPE_BYTE:
158                 contained_signature = DBUS_TYPE_BYTE_AS_STRING;
159                 break;
160         case DBUS_TYPE_STRING:
161                 contained_signature = DBUS_TYPE_STRING_AS_STRING;
162                 break;
163         case DBUS_TYPE_BOOLEAN:
164                 contained_signature = DBUS_TYPE_BOOLEAN_AS_STRING;
165                 break;
166         case DBUS_TYPE_INT16:
167                 contained_signature = DBUS_TYPE_INT16_AS_STRING;
168                 break;
169         case DBUS_TYPE_UINT16:
170                 contained_signature = DBUS_TYPE_UINT16_AS_STRING;
171                 break;
172         case DBUS_TYPE_INT32:
173                 contained_signature = DBUS_TYPE_INT32_AS_STRING;
174                 break;
175         case DBUS_TYPE_UINT32:
176                 contained_signature = DBUS_TYPE_UINT32_AS_STRING;
177                 break;
178         case DBUS_TYPE_OBJECT_PATH:
179                 contained_signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
180                 break;
181         default:
182                 contained_signature = DBUS_TYPE_VARIANT_AS_STRING;
183                 break;
184         }
185
186         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
187                         contained_signature, &value_iter);
188         dbus_message_iter_append_basic(&value_iter, type, val);
189         dbus_message_iter_close_container(iter, &value_iter);
190 }
191
192 static void __bluetooth_media_append_dict_entry(DBusMessageIter *dict,
193                         const char *key, int type, void *property)
194 {
195         DBusMessageIter iter;
196
197         if (type == DBUS_TYPE_STRING) {
198                 const char *str_ptr = *((const char **)property);
199                 if (!str_ptr)
200                         return;
201         }
202
203         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
204                                 NULL, &iter);
205         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
206
207         __bluetooth_media_append_variant(&iter, type, property);
208
209         dbus_message_iter_close_container(dict, &iter);
210 }
211
212 static dbus_bool_t __bluetooth_media_emit_property_changed(
213                                 DBusConnection *conn, const char *path,
214                                 const char *interface, const char *name,
215                                 int type, void *value)
216 {
217         DBusMessage *message = NULL;
218         DBusMessageIter iter;
219         dbus_bool_t result;
220
221         message = dbus_message_new_signal(path, interface, "PropertyChanged");
222
223         if (!message)
224                 return FALSE;
225
226         dbus_message_iter_init_append(message, &iter);
227         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
228
229         __bluetooth_media_append_variant(&iter, type, value);
230
231         result = dbus_connection_send(conn, message, NULL);
232         dbus_message_unref(message);
233
234         return result;
235 }
236
237 static void __bluetooth_handle_trackchanged(
238                                         DBusMessage *msg)
239 {
240         const char *path = dbus_message_get_path(msg);
241         media_metadata_attributes_t metadata = {0,};
242         DBusMessage *signal = NULL;
243         DBusMessageIter iter;
244         DBusMessageIter metadata_dict;
245
246         DBG("Path = %s\n", path);
247
248         if (!dbus_message_get_args(msg, NULL,
249                 DBUS_TYPE_STRING, &metadata.title,
250                 DBUS_TYPE_STRING, &metadata.artist,
251                 DBUS_TYPE_STRING, &metadata.album,
252                 DBUS_TYPE_STRING, &metadata.genre,
253                 DBUS_TYPE_UINT32, &metadata.total_tracks,
254                 DBUS_TYPE_UINT32, &metadata.number,
255                 DBUS_TYPE_UINT32, &metadata.duration,
256                 DBUS_TYPE_INVALID)) {
257                 DBG("Unexpected parameters in signal");
258                 return;
259         }
260
261         signal = dbus_message_new_signal(BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
262                         BLUEZ_MEDIA_PLAYER_INTERFACE, "TrackChanged");
263         if (!signal) {
264                 DBG("Unable to allocate TrackChanged signal\n");
265                 return;
266         }
267
268         dbus_message_iter_init_append(signal, &iter);
269
270         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
271                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
272                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
273                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &metadata_dict);
274
275         if (NULL != metadata.title) {
276                 __bluetooth_media_append_dict_entry(&metadata_dict,
277                         "Title",
278                         DBUS_TYPE_STRING, &metadata.title);
279         }
280
281         if (NULL != metadata.artist) {
282                 __bluetooth_media_append_dict_entry(&metadata_dict,
283                         "Artist",
284                         DBUS_TYPE_STRING, &metadata.artist);
285         }
286
287         if (NULL != metadata.album) {
288                 __bluetooth_media_append_dict_entry(&metadata_dict,
289                         "Album",
290                         DBUS_TYPE_STRING, &metadata.album);
291         }
292
293         if (NULL != metadata.genre) {
294                 __bluetooth_media_append_dict_entry(&metadata_dict,
295                         "Genre",
296                         DBUS_TYPE_STRING, &metadata.genre);
297         }
298
299         if (0 != metadata.total_tracks)
300                 __bluetooth_media_append_dict_entry(&metadata_dict,
301                         "NumberOfTracks",
302                         DBUS_TYPE_UINT32, &metadata.total_tracks);
303
304         if (0 != metadata.number)
305                 __bluetooth_media_append_dict_entry(&metadata_dict,
306                         "Number",
307                         DBUS_TYPE_UINT32, &metadata.number);
308
309         if (0 != metadata.duration)
310                 __bluetooth_media_append_dict_entry(&metadata_dict,
311                         "Duration",
312                         DBUS_TYPE_UINT32, &metadata.duration);
313
314         dbus_message_iter_close_container(&iter, &metadata_dict);
315
316         if (!dbus_connection_send(g_avrcp_connection, signal, NULL))
317                 DBG("Unable to send TrackChanged signal\n");
318         dbus_message_unref(signal);
319
320 }
321
322 static void __bluetooth_handle_property_changed(
323                                         DBusMessage *msg)
324 {
325         const char *path = dbus_message_get_path(msg);
326         unsigned int type;
327         unsigned int value;
328         DBG("Path = %s\n", path);
329
330         if (!dbus_message_get_args(msg, NULL,
331                                 DBUS_TYPE_UINT32, &type,
332                                 DBUS_TYPE_UINT32, &value,
333                                 DBUS_TYPE_INVALID)) {
334                 DBG("Unexpected parameters in signal");
335                 return;
336         }
337
338         DBG("type = [%d] and value = [%d]\n", type, value);
339
340         switch (type) {
341         case EQUILIZER:
342                 if (!__bluetooth_media_emit_property_changed(
343                         g_avrcp_connection,
344                         BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
345                         BLUEZ_MEDIA_PLAYER_INTERFACE,
346                         "Equalizer",
347                         DBUS_TYPE_STRING,
348                         &equilizer_settings[value].property)) {
349                         DBG("Error sending the PropertyChanged signal \n");
350                 }
351                 break;
352         case REPEAT:
353                 if (!__bluetooth_media_emit_property_changed(
354                         g_avrcp_connection,
355                         BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
356                         BLUEZ_MEDIA_PLAYER_INTERFACE,
357                         "Repeat",
358                         DBUS_TYPE_STRING,
359                         &repeat_settings[value].property)) {
360                         DBG("Error sending the PropertyChanged signal \n");
361                 }
362                 break;
363         case SHUFFLE:
364                 if (!__bluetooth_media_emit_property_changed(
365                         g_avrcp_connection,
366                         BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
367                         BLUEZ_MEDIA_PLAYER_INTERFACE,
368                         "Shuffle",
369                         DBUS_TYPE_STRING,
370                         &shuffle_settings[value].property)) {
371                         DBG("Error sending the PropertyChanged signal \n");
372                 }
373                 break;
374         case SCAN:
375                 if (!__bluetooth_media_emit_property_changed(
376                         g_avrcp_connection,
377                         BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
378                         BLUEZ_MEDIA_PLAYER_INTERFACE,
379                         "Scan",
380                         DBUS_TYPE_STRING,
381                         &scan_settings[value].property)) {
382                         DBG("Error sending the PropertyChanged signal \n");
383                 }
384                 break;
385         case STATUS:
386                 if (!__bluetooth_media_emit_property_changed(
387                         g_avrcp_connection,
388                         BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
389                         BLUEZ_MEDIA_PLAYER_INTERFACE,
390                         "Status",
391                         DBUS_TYPE_STRING,
392                         &player_status[value].property)) {
393                         DBG("Error sending the PropertyChanged signal \n");
394                 }
395                 break;
396         case POSITION:
397                 if (!__bluetooth_media_emit_property_changed(
398                         g_avrcp_connection,
399                         BLUEZ_MEDIA_PLAYER_OBJECT_PATH,
400                         BLUEZ_MEDIA_PLAYER_INTERFACE,
401                         "Position",
402                         DBUS_TYPE_UINT32,
403                         &value)) {
404                         DBG("Error sending the PropertyChanged signal \n");
405                 }
406                 break;
407         default:
408                 DBG("Invalid Type\n");
409                 break;
410         }
411 }
412
413 static DBusHandlerResult __bluetooth_media_event_filter(
414                                         DBusConnection *sys_conn,
415                                         DBusMessage *msg, void *data)
416 {
417         if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
418                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
419
420         if (dbus_message_is_signal(msg, BT_MEDIA_PLAYER_DBUS_INTERFACE,
421                                         "TrackChanged")) {
422                 __bluetooth_handle_trackchanged(msg);
423         } else if (dbus_message_is_signal(msg, BT_MEDIA_PLAYER_DBUS_INTERFACE,
424                                         "PropertyChanged")) {
425                 __bluetooth_handle_property_changed(msg);
426         }
427
428         return DBUS_HANDLER_RESULT_HANDLED;
429 }
430
431 BT_EXPORT_API int bluetooth_media_init(void)
432 {
433         GError *err = NULL;
434         char default_obj_path[MEDIA_OBJECT_PATH_LENGTH] = {0,};
435         DBusError dbus_error;
436
437         DBG("bluetooth_media_init +\n");
438
439         g_avrcp_dbus_info.avrcp_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err);
440
441         if (!g_avrcp_dbus_info.avrcp_conn) {
442                 DBG("Can not get DBUS Gconnection [%s]\n", err->message);
443                 g_error_free(err);
444                 return BLUETOOTH_CONTROL_ERROR;
445         }
446
447         DBG("bluetooth_media_init\n");
448
449         g_avrcp_connection = dbus_g_connection_get_connection(
450                                                 g_avrcp_dbus_info.avrcp_conn);
451
452         dbus_error_init(&dbus_error);
453
454         dbus_connection_add_filter(g_avrcp_connection,
455                                 __bluetooth_media_event_filter, NULL, NULL);
456
457         dbus_bus_add_match(g_avrcp_connection,
458                         "type='signal',interface="  \
459                         BT_MEDIA_PLAYER_DBUS_INTERFACE,
460                         &dbus_error);
461
462         if (dbus_error_is_set(&dbus_error)) {
463                 DBG("Fail to add dbus filter signal\n");
464                 dbus_error_free(&dbus_error);
465                 return BLUETOOTH_CONTROL_ERROR;
466         }
467
468         if (__bluetooth_media_get_avrcp_adapter_path(
469                 g_avrcp_dbus_info.avrcp_conn,
470                  default_obj_path) < 0) {
471                 DBG("Could not get adapter path\n");
472                 goto error;
473         }
474
475         DBG("bluetooth_media_init\n");
476
477         if (default_obj_path != NULL)
478                 g_strlcpy(g_avrcp_dbus_info.avrcp_obj_path, default_obj_path,
479                         MEDIA_OBJECT_PATH_LENGTH);
480         else
481                 goto error;
482
483         DBG("bluetooth_media_init -\n");
484         return BLUETOOTH_CONTROL_SUCCESS;
485
486 error:
487         dbus_g_connection_unref(g_avrcp_dbus_info.avrcp_conn);
488         g_avrcp_dbus_info.avrcp_conn = NULL;
489         g_avrcp_connection = NULL;
490         return BLUETOOTH_CONTROL_ERROR;
491 }
492
493 BT_EXPORT_API int bluetooth_media_register_player(void)
494 {
495         DBusMessage *msg = NULL;
496         DBusMessage *reply = NULL;
497         DBusMessageIter iter;
498         DBusMessageIter property_dict;
499         DBusMessageIter metadata_dict;
500         DBusError err;
501
502
503         media_player_settings_t player_settings = {0,};
504         media_metadata_attributes_t metadata = {0,};
505
506         player_settings.equilizer = EQUILIZER_OFF;
507         player_settings.repeat  = REPEAT_MODE_OFF;
508         player_settings.shuffle = SHUFFLE_MODE_OFF;
509         player_settings.scan = SCAN_MODE_OFF;
510         player_settings.status = STATUS_STOPPED;
511         player_settings.position = 0;
512
513         metadata.title = "\0";
514         metadata.artist = "\0";
515         metadata.album = "\0";
516         metadata.genre = "\0";
517
518         if (strlen(g_avrcp_dbus_info.avrcp_obj_path) <= 0)
519                 return BLUETOOTH_CONTROL_ERROR;
520
521         const char *object = g_strdup(BLUEZ_MEDIA_PLAYER_OBJECT_PATH);
522
523         DBG("bluetooth_media_register_player +\n");
524
525         msg = dbus_message_new_method_call(
526                                 BLUEZ_SERVICE,
527                                 g_avrcp_dbus_info.avrcp_obj_path,
528                                 BLUEZ_MEDIA_INTERFACE,
529                                 "RegisterPlayer");
530         if (!msg) {
531                 DBG("dbus_message_new_method_call failed\n");
532                 g_free((void *)object);
533                 return BLUETOOTH_CONTROL_ERROR;
534         }
535
536         DBG("object = [%s] \n", object);
537
538         dbus_message_iter_init_append(msg, &iter);
539         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &object);
540         g_free((void *)object);
541
542         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
543                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
544                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
545                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &property_dict);
546
547         if (player_settings.equilizer < EQUILIZER_INVALID) {
548                 __bluetooth_media_append_dict_entry(&property_dict,
549                         "Equalizer",
550                         DBUS_TYPE_STRING,
551                         &equilizer_settings[
552                                 player_settings.equilizer].property);
553         }
554
555         if (player_settings.repeat < REPEAT_INVALID) {
556                 __bluetooth_media_append_dict_entry(&property_dict,
557                         "Repeat",
558                         DBUS_TYPE_STRING,
559                         &repeat_settings[player_settings.repeat].property);
560         }
561
562         if (player_settings.shuffle < SHUFFLE_INVALID) {
563                 __bluetooth_media_append_dict_entry(&property_dict,
564                         "Shuffle",
565                         DBUS_TYPE_STRING,
566                         &shuffle_settings[player_settings.shuffle].property);
567         }
568
569         if (player_settings.scan < SCAN_INVALID) {
570                 __bluetooth_media_append_dict_entry(&property_dict,
571                         "Scan",
572                         DBUS_TYPE_STRING,
573                         &scan_settings[player_settings.scan].property);
574         }
575
576         if (player_settings.status < STATUS_INVALID) {
577                 __bluetooth_media_append_dict_entry(&property_dict,
578                         "Status",
579                         DBUS_TYPE_STRING,
580                         &player_status[player_settings.status].property);
581         }
582
583         if (0 != player_settings.position)
584                 __bluetooth_media_append_dict_entry(&property_dict,
585                         "Position",
586                         DBUS_TYPE_UINT32, &player_settings.position);
587
588         dbus_message_iter_close_container(&iter, &property_dict);
589
590         dbus_message_iter_init_append(msg, &iter);
591         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
592                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
593                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
594                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &metadata_dict);
595
596         if (NULL != metadata.title) {
597                 __bluetooth_media_append_dict_entry(&metadata_dict,
598                         "Title",
599                         DBUS_TYPE_STRING, &metadata.title);
600         }
601
602         if (NULL != metadata.artist) {
603                 __bluetooth_media_append_dict_entry(&metadata_dict,
604                         "Artist",
605                         DBUS_TYPE_STRING, &metadata.artist);
606         }
607
608         if (NULL != metadata.album) {
609                 __bluetooth_media_append_dict_entry(&metadata_dict,
610                         "Album",
611                         DBUS_TYPE_STRING, &metadata.album);
612         }
613
614         if (NULL != metadata.genre) {
615                 __bluetooth_media_append_dict_entry(&metadata_dict,
616                         "Genre",
617                         DBUS_TYPE_STRING, &metadata.genre);
618         }
619
620         if (0 != metadata.total_tracks)
621                 __bluetooth_media_append_dict_entry(&metadata_dict,
622                         "NumberOfTracks",
623                         DBUS_TYPE_UINT32, &metadata.total_tracks);
624
625         if (0 != metadata.number)
626                 __bluetooth_media_append_dict_entry(&metadata_dict,
627                         "Number",
628                         DBUS_TYPE_UINT32, &metadata.number);
629
630         if (0 != metadata.duration)
631                 __bluetooth_media_append_dict_entry(&metadata_dict,
632                         "Duration",
633                         DBUS_TYPE_UINT32, &metadata.duration);
634
635         dbus_message_iter_close_container(&iter, &metadata_dict);
636
637         dbus_error_init(&err);
638         reply = dbus_connection_send_with_reply_and_block(g_avrcp_connection,
639                                 msg, -1, &err);
640         dbus_message_unref(msg);
641
642         if (!reply) {
643                 DBG("Error in registering the Music Player \n");
644
645                 if (dbus_error_is_set(&err)) {
646                         DBG("%s", err.message);
647                         dbus_error_free(&err);
648                         return BLUETOOTH_CONTROL_ERROR;
649                 }
650         }
651
652         if (reply)
653                 dbus_message_unref(reply);
654
655         DBG("bluetooth_media_register_player -\n");
656
657         return BLUETOOTH_CONTROL_SUCCESS;
658 }
659
660 BT_EXPORT_API int bluetooth_media_unregister_player(void)
661 {
662         DBusMessage *msg = NULL;
663         DBusMessage *reply = NULL;
664         DBusError err;
665         const char *object = g_strdup(BLUEZ_MEDIA_PLAYER_OBJECT_PATH);
666
667         DBG("bluetooth_media_unregister_player +\n");
668
669         msg = dbus_message_new_method_call(BLUEZ_SERVICE,
670                                         g_avrcp_dbus_info.avrcp_obj_path,
671                                         BLUEZ_MEDIA_INTERFACE,
672                                         "UnregisterPlayer");
673
674         if (NULL == msg) {
675                 g_free((void *)object);
676                 return BLUETOOTH_CONTROL_ERROR;
677         }
678
679         dbus_message_append_args(msg,
680                                 DBUS_TYPE_OBJECT_PATH, &object,
681                                 DBUS_TYPE_INVALID);
682
683         dbus_error_init(&err);
684         reply = dbus_connection_send_with_reply_and_block(g_avrcp_connection,
685                                 msg, -1, &err);
686         dbus_message_unref(msg);
687         g_free((void *)object);
688
689         if (!reply) {
690                 DBG("Error in unregistering the Music Player \n");
691
692                 if (dbus_error_is_set(&err)) {
693                         DBG("%s", err.message);
694                         dbus_error_free(&err);
695                         return BLUETOOTH_CONTROL_ERROR;
696                 }
697         } else
698                 dbus_message_unref(reply);
699
700         DBG("bluetooth_media_unregister_player -\n");
701         return BLUETOOTH_CONTROL_SUCCESS;
702 }
703
704 BT_EXPORT_API int bluetooth_media_deinit(void)
705 {
706         DBG("bluetooth_media_deinit +\n");
707
708         if (g_avrcp_dbus_info.avrcp_conn) {
709                 dbus_g_connection_unref(g_avrcp_dbus_info.avrcp_conn);
710                 g_avrcp_dbus_info.avrcp_conn = NULL;
711         }
712
713         DBG("bluetooth_media_deinit -\n");
714         return BLUETOOTH_CONTROL_SUCCESS;
715 }