431bdb1241cfa8381f18d19ed5f1c716a084dca6
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-avrcp-controller.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include "bt-internal-types.h"
19 #include "bt-service-common.h"
20 #include "bt-service-avrcp-controller.h"
21 #include "bt-service-audio.h"
22 #include "bt-service-event.h"
23
24 static bt_player_settinngs_t repeat_status[] = {
25         { REPEAT_INVALID, "" },
26         { REPEAT_MODE_OFF, "off" },
27         { REPEAT_SINGLE_TRACK, "singletrack" },
28         { REPEAT_ALL_TRACK, "alltracks" },
29         { REPEAT_GROUP, "group" },
30         { REPEAT_INVALID, "" }
31 };
32
33 static bt_player_settinngs_t equalizer_status[] = {
34         { EQUALIZER_INVALID, "" },
35         { EQUALIZER_OFF, "off" },
36         { EQUALIZER_ON, "on" },
37         { EQUALIZER_INVALID, "" },
38 };
39
40 static bt_player_settinngs_t scan_status[] = {
41         { SCAN_INVALID, "" },
42         { SCAN_MODE_OFF, "off" },
43         { SCAN_ALL_TRACK, "alltracks" },
44         { SCAN_GROUP, "group" },
45         { SCAN_INVALID, "" },
46 };
47
48 static bt_player_settinngs_t shuffle_settings[] = {
49         { SHUFFLE_INVALID, "" },
50         { SHUFFLE_MODE_OFF, "off" },
51         { SHUFFLE_ALL_TRACK, "alltracks" },
52         { SHUFFLE_GROUP, "group" },
53         { SHUFFLE_INVALID, "" }
54 };
55
56 static char *avrcp_control_path = NULL;
57
58 void _bt_set_control_device_path(const char *path)
59 {
60
61         ret_if(path == NULL);
62
63         g_free(avrcp_control_path);
64         BT_DBG("control_path = %s", path);
65         avrcp_control_path = g_strdup(path);
66 }
67
68 void _bt_remove_control_device_path(const char *path)
69 {
70         ret_if(path == NULL);
71
72         if (avrcp_control_path &&
73                         !g_strcmp0(avrcp_control_path, path)) {
74                 BT_DBG("control_path = %s", path);
75                 g_free(avrcp_control_path);
76                 avrcp_control_path = NULL;
77         }
78 }
79
80 static char *__bt_get_control_device_path(void)
81 {
82         char *adapter_path;
83         char *control_path;
84         char connected_address[BT_ADDRESS_STRING_SIZE + 1];
85
86         BT_DBG("+");
87
88         if (avrcp_control_path != NULL)
89                 return avrcp_control_path;
90
91         retv_if(!_bt_is_headset_type_connected(BT_AVRCP,
92                         connected_address), NULL);
93
94         BT_DBG("device address = %s", connected_address);
95
96         adapter_path = _bt_get_device_object_path(connected_address);
97         retv_if(adapter_path == NULL, NULL);
98
99         control_path = g_strdup_printf(BT_MEDIA_CONTROL_PATH, adapter_path);
100         g_free(adapter_path);
101
102         avrcp_control_path = control_path;
103         BT_DBG("control_path = %s", control_path);
104         return control_path;
105 }
106
107 static int __bt_media_send_control_msg(const char *name)
108 {
109         GVariant *reply = NULL;
110         GError *err = NULL;
111         GDBusConnection *conn = NULL;
112         GDBusProxy *proxy = NULL;
113         char *control_path = NULL;
114
115         retv_if(name == NULL, BLUETOOTH_ERROR_INTERNAL);
116
117         BT_INFO("Command [%s]", name);
118
119         conn = _bt_gdbus_get_system_gconn();
120         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
121
122         control_path = __bt_get_control_device_path();
123         retv_if(control_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
124         BT_DBG("control_path %s", control_path);
125
126         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
127                         BT_BLUEZ_NAME, control_path,
128                         BT_PLAYER_CONTROL_INTERFACE, NULL, &err);
129         if (proxy == NULL) {
130                 BT_ERR("Unable to allocate new proxy \n");
131                 if (err) {
132                         BT_ERR("%s", err->message);
133                         g_clear_error(&err);
134                 }
135                 return BLUETOOTH_ERROR_INTERNAL;
136         }
137
138         reply = g_dbus_proxy_call_sync(proxy, name, NULL,
139                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
140
141         g_object_unref(proxy);
142
143         if (!reply) {
144                 BT_ERR("Error returned in method call");
145                 if (err) {
146                         BT_ERR("%s", err->message);
147                         g_clear_error(&err);
148                 }
149                 return BLUETOOTH_ERROR_INTERNAL;
150         }
151
152         g_variant_unref(reply);
153
154         BT_DBG("-");
155         return BLUETOOTH_ERROR_NONE;
156 }
157
158 int _bt_avrcp_control_cmd(int type)
159 {
160         int ret = BLUETOOTH_ERROR_INTERNAL;
161         BT_DBG("+");
162
163         switch (type) {
164         case PLAY:
165                 ret = __bt_media_send_control_msg("Play");
166                 break;
167         case PAUSE:
168                 ret = __bt_media_send_control_msg("Pause");
169                 break;
170         case STOP:
171                 ret = __bt_media_send_control_msg("Stop");
172                 break;
173         case NEXT:
174                 ret = __bt_media_send_control_msg("Next");
175                 break;
176         case PREVIOUS:
177                 ret = __bt_media_send_control_msg("Previous");
178                 break;
179         case PRESS_FAST_FORWARD:
180                 ret = __bt_media_send_control_msg("PressFastForward");
181                 break;
182         case RELEASE_FAST_FORWARD:
183                 ret = __bt_media_send_control_msg("ReleaseFastForward");
184                 break;
185         case PRESS_REWIND:
186                 ret = __bt_media_send_control_msg("PressRewind");
187                 break;
188         case RELEASE_REWIND:
189                 ret = __bt_media_send_control_msg("ReleaseRewind");
190                 break;
191         case VOLUME_UP:
192                 ret = __bt_media_send_control_msg("VolumeUp");
193                 break;
194         case VOLUME_DOWN:
195                 ret = __bt_media_send_control_msg("VolumeDown");
196                 break;
197         default:
198                 BT_DBG("Invalid Type\n");
199                 return BLUETOOTH_ERROR_INTERNAL;
200         }
201         BT_DBG("-");
202         return ret;
203 }
204
205 GDBusProxy *__bt_get_control_properties_proxy(void)
206 {
207         GDBusProxy *proxy = NULL;
208         GError *error = NULL;
209         char *control_path = NULL;
210         GDBusConnection *conn = NULL;
211
212         control_path = __bt_get_control_device_path();
213         retv_if(control_path == NULL, NULL);
214         BT_DBG("control_path = %s", control_path);
215
216         conn = _bt_gdbus_get_system_gconn();
217         retv_if(conn == NULL, NULL);
218
219         proxy = g_dbus_proxy_new_sync(conn,
220                         G_DBUS_PROXY_FLAGS_NONE, NULL,
221                         BT_BLUEZ_NAME, control_path,
222                         BT_PROPERTIES_INTERFACE, NULL, &error);
223         if (proxy == NULL) {
224                 BT_ERR("Unable to allocate new proxy");
225                 if (error) {
226                         BT_ERR("%s", error->message);
227                         g_clear_error(&error);
228                 }
229                 return NULL;
230         }
231
232         return proxy;
233 }
234
235 static int __bt_media_attr_to_event(const char *str)
236 {
237         if (!strcasecmp(str, "Equalizer"))
238                 return BLUETOOTH_EVENT_AVRCP_CONTROL_EQUALIZER_STATUS;
239         else if (!strcasecmp(str, "Repeat"))
240                 return BLUETOOTH_EVENT_AVRCP_CONTROL_REPEAT_STATUS;
241         else if (!strcasecmp(str, "Shuffle"))
242                 return BLUETOOTH_EVENT_AVRCP_CONTROL_SHUFFLE_STATUS;
243         else if (!strcasecmp(str, "Scan"))
244                 return BLUETOOTH_EVENT_AVRCP_CONTROL_SCAN_STATUS;
245         else if (!strcasecmp(str, "Position"))
246                 return BLUETOOTH_EVENT_AVRCP_SONG_POSITION_STATUS;
247         else if (!strcasecmp(str, "Track"))
248                 return BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED;
249         else if (!strcasecmp(str, "Status"))
250                 return BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED;
251
252         return 0;
253 }
254
255 static int __bt_media_attr_to_type(const char *str)
256 {
257         if (!strcasecmp(str, "Equalizer"))
258                 return EQUALIZER;
259         else if (!strcasecmp(str, "Repeat"))
260                 return REPEAT;
261         else if (!strcasecmp(str, "Shuffle"))
262                 return SHUFFLE;
263         else if (!strcasecmp(str, "Scan"))
264                 return SCAN;
265         else if (!strcasecmp(str, "Position"))
266                 return POSITION;
267         else if (!strcasecmp(str, "Track"))
268                 return METADATA;
269         else if (!strcasecmp(str, "Status"))
270                 return STATUS;
271
272         return 0;
273 }
274
275 static const char *__bt_media_type_to_str(int type)
276 {
277         switch (type) {
278         case EQUALIZER:
279                 return "Equalizer";
280         case REPEAT:
281                 return "Repeat";
282         case SHUFFLE:
283                 return "Shuffle";
284         case SCAN:
285                 return "Scan";
286         case POSITION:
287                 return "Position";
288         case METADATA:
289                 return "Track";
290         case STATUS:
291                 return "Status";
292         }
293         return NULL;
294 }
295
296 static int __bt_media_attrval_to_val(int type, const char *value)
297 {
298         int ret = 0;
299
300         switch (type) {
301         case EQUALIZER:
302                 if (!strcmp(value, "off"))
303                         ret = EQUALIZER_OFF;
304                 else if (!strcmp(value, "on"))
305                         ret = EQUALIZER_ON;
306                 else
307                         ret = EQUALIZER_INVALID;
308                 break;
309
310         case REPEAT:
311                 if (!strcmp(value, "off"))
312                         ret = REPEAT_MODE_OFF;
313                 else if (!strcmp(value, "singletrack"))
314                         ret = REPEAT_SINGLE_TRACK;
315                 else if (!strcmp(value, "alltracks"))
316                         ret = REPEAT_ALL_TRACK;
317                 else if (!strcmp(value, "group"))
318                         ret = REPEAT_GROUP;
319                 else
320                         ret = REPEAT_INVALID;
321                 break;
322
323         case SHUFFLE:
324                 if (!strcmp(value, "off"))
325                         ret = SHUFFLE_MODE_OFF;
326                 else if (!strcmp(value, "alltracks"))
327                         ret = SHUFFLE_ALL_TRACK;
328                 else if (!strcmp(value, "group"))
329                         ret = SHUFFLE_GROUP;
330                 else
331                         ret = SHUFFLE_INVALID;
332                 break;
333
334         case SCAN:
335                 if (!strcmp(value, "off"))
336                         ret = SCAN_MODE_OFF;
337                 else if (!strcmp(value, "alltracks"))
338                         ret = SCAN_ALL_TRACK;
339                 else if (!strcmp(value, "group"))
340                         ret = SCAN_GROUP;
341                 else
342                         ret = SCAN_INVALID;
343                 break;
344
345         case STATUS:
346                 if (!strcmp(value, "stopped"))
347                         ret = STATUS_STOPPED;
348                 else if (!strcmp(value, "playing"))
349                         ret = STATUS_PLAYING;
350                 else if (!strcmp(value, "paused"))
351                         ret = STATUS_PAUSED;
352                 else if (!strcmp(value, "forward-seek"))
353                         ret = STATUS_FORWARD_SEEK;
354                 else if (!strcmp(value, "reverse-seek"))
355                         ret = STATUS_REVERSE_SEEK;
356                 else if (!strcmp(value, "error"))
357                         ret = STATUS_ERROR;
358                 else
359                         ret = STATUS_INVALID;
360         }
361         return ret;
362 }
363
364 int _bt_avrcp_control_get_property(int type, unsigned int *value)
365 {
366         GDBusProxy *proxy = NULL;
367         char *name = NULL;
368         int ret = BLUETOOTH_ERROR_NONE;
369         GError *err = NULL;
370         GVariant *reply = NULL;
371         GVariant *temp = NULL;
372
373         BT_CHECK_PARAMETER(value, return);
374
375         proxy = __bt_get_control_properties_proxy();
376         retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
377
378         reply = g_dbus_proxy_call_sync(proxy,
379                                         "Get", g_variant_new("(ss)", BT_PLAYER_CONTROL_INTERFACE, __bt_media_type_to_str(type)),
380                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
381
382         g_object_unref(proxy);
383
384         if (!reply) {
385                 BT_ERR("Can't get managed objects");
386                 if (err) {
387                         BT_ERR("%s", err->message);
388                         g_clear_error(&err);
389                 }
390                 return BLUETOOTH_ERROR_INTERNAL;
391         } else {
392                         switch (type) {
393                         case EQUALIZER:
394                         case REPEAT:
395                         case SHUFFLE:
396                         case SCAN:
397                         case STATUS:
398                                 name = (char *)g_variant_get_data(reply);
399                                 if (name)
400                                         *value = __bt_media_attrval_to_val(type, name);
401                                 BT_INFO("Type[%s] and Value[%s]", __bt_media_type_to_str(type), name);
402                                 break;
403                         case POSITION:
404                                 g_variant_get(reply, "(v)", &temp);
405                                 *value = g_variant_get_uint32(temp);
406                                 g_variant_unref(temp);
407                                 BT_INFO("Type[%s] and Value[%d]", __bt_media_type_to_str(type), *value);
408                                 break;
409                         default:
410                                 BT_ERR("Invalid Type [%d]", type);
411                                 ret =  BLUETOOTH_ERROR_INTERNAL;
412                         }
413                 }
414         g_variant_unref(reply);
415         return ret;
416 }
417
418 int _bt_avrcp_control_set_property(int type, unsigned int value)
419 {
420         GValue *attr_value = NULL;
421         GDBusProxy *proxy = NULL;
422         GError *error = NULL;
423         GVariant *reply, *param;
424
425         g_value_init(attr_value, G_TYPE_STRING);
426
427         switch (type) {
428         case EQUALIZER:
429                 param = g_variant_new("s", equalizer_status[value].property);
430                 BT_INFO("equalizer_status %s", equalizer_status[value].property);
431                 break;
432         case REPEAT:
433                 param = g_variant_new("s", repeat_status[value].property);
434                 BT_INFO("repeat_status %s", repeat_status[value].property);
435                 break;
436         case SHUFFLE:
437                 param = g_variant_new("s", shuffle_settings[value].property);
438                 BT_INFO("shuffle_settings %s", shuffle_settings[value].property);
439                 break;
440         case SCAN:
441                 param = g_variant_new("s", scan_status[value].property);
442                 BT_INFO("scan_status %s", scan_status[value].property);
443                 break;
444         default:
445                 BT_ERR("Invalid property type: %d", type);
446                 g_value_unset(attr_value);
447                 return BLUETOOTH_ERROR_INTERNAL;
448         }
449
450         proxy = __bt_get_control_properties_proxy();
451         retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
452
453         reply = g_dbus_proxy_call_sync(proxy,
454                                         "Set", g_variant_new("(ssv)", BT_PLAYER_CONTROL_INTERFACE, __bt_media_type_to_str(type), param),
455                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
456
457         g_object_unref(proxy);
458         g_variant_unref(param);
459
460         if (!reply) {
461                 BT_ERR("Can't get managed objects");
462                 if (error) {
463                         BT_ERR("SetProperty Fail: %s", error->message);
464                         g_clear_error(&error);
465                         return BLUETOOTH_ERROR_INTERNAL;
466                 }
467         }
468
469         g_variant_unref(reply);
470         g_value_unset(attr_value);
471
472         return BLUETOOTH_ERROR_NONE;
473 }
474
475 static int __bt_avrcp_control_parse_properties(
476                                 media_metadata_attributes_t *metadata,
477                                 GVariant *item)
478 {
479         GVariant *value = NULL;
480         GVariantIter iter;
481         char *value_string = NULL;
482         unsigned int value_uint;
483         const char *key = NULL;
484
485         g_variant_iter_init(&iter, item);
486         while (g_variant_iter_loop(&iter, "{sv}", &key, &value)) {
487                 if (strcasecmp(key, "Title") == 0) {
488                         value_string = (char *)g_variant_get_string(value, NULL);
489                         BT_DBG("Value : %s ", value_string);
490                         metadata->title = g_strdup(value_string);
491                 } else if (strcasecmp(key, "Artist") == 0) {
492                         value_string = (char *)g_variant_get_string(value, NULL);
493                         BT_DBG("Value : %s ", value_string);
494                         metadata->artist = g_strdup(value_string);
495                 } else if (strcasecmp(key, "Album") == 0) {
496                         value_string = (char *)g_variant_get_string(value, NULL);
497                         BT_DBG("Value : %s ", value_string);
498                         metadata->album = g_strdup(value_string);
499                 } else if (strcasecmp(key, "Genre") == 0) {
500                         value_string = (char *)g_variant_get_string(value, NULL);
501                         BT_DBG("Value : %s ", value_string);
502                         metadata->genre = g_strdup(value_string);
503                 } else if (strcasecmp(key, "Duration") == 0) {
504                         value_uint = g_variant_get_uint32(value);
505                         BT_DBG("Duration : %d", value_uint);
506                         metadata->duration = value_uint;
507                 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
508                         value_uint = g_variant_get_uint32(value);
509                         metadata->total_tracks = value_uint;
510                 } else if (strcasecmp(key, "TrackNumber") == 0) {
511                         value_uint = g_variant_get_uint32(value);
512                         metadata->number = value_uint;
513                 } else
514                         BT_DBG("%s not supported, ignoring", key);
515         }
516
517         if (!metadata->title)
518                 metadata->title = g_strdup("");
519         if (!metadata->artist)
520                 metadata->artist = g_strdup("");
521         if (!metadata->album)
522                 metadata->album = g_strdup("");
523         if (!metadata->genre)
524                 metadata->genre = g_strdup("");
525
526         return BLUETOOTH_ERROR_NONE;
527
528 }
529
530 int _bt_avrcp_control_get_track_info(media_metadata_attributes_t *metadata)
531 {
532         GDBusProxy *proxy = NULL;
533         GVariant *reply = NULL;
534         GVariant *item = NULL;
535         GError *err = NULL;
536         GDBusConnection *conn = NULL;
537         char *control_path = NULL;
538         char *interface_name = NULL;
539         char *property_name = NULL;
540         GVariant *parameters = NULL;
541         int ret = BLUETOOTH_ERROR_NONE;
542
543         retv_if(metadata == NULL, BLUETOOTH_ERROR_INTERNAL);
544
545         conn = _bt_gdbus_get_system_gconn();
546         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
547
548         control_path = __bt_get_control_device_path();
549         retv_if(control_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
550         BT_DBG("control_path %s", control_path);
551
552         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
553                         BT_BLUEZ_NAME, control_path,
554                         BT_PROPERTIES_INTERFACE, NULL, &err);
555         if (proxy == NULL) {
556                 BT_ERR("Unable to allocate new proxy \n");
557                 if (err) {
558                         BT_ERR("%s", err->message);
559                         g_clear_error(&err);
560                 }
561                 return BLUETOOTH_ERROR_INTERNAL;
562         }
563
564         interface_name = g_strdup(BT_PLAYER_CONTROL_INTERFACE);
565         property_name = g_strdup("Track");
566
567         parameters = g_variant_new("(ss)", interface_name, property_name);
568
569         g_free(interface_name);
570         g_free(property_name);
571
572         reply = g_dbus_proxy_call_sync(proxy, "Get", parameters,
573                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
574
575         g_object_unref(proxy);
576
577         if (!reply) {
578                 BT_ERR("Error returned in method call");
579                 if (err) {
580                         BT_ERR("%s", err->message);
581                         g_clear_error(&err);
582                 }
583                 return BLUETOOTH_ERROR_INTERNAL;
584         }
585
586         g_variant_get(reply, "(v)", &item);
587
588         ret = __bt_avrcp_control_parse_properties(metadata, item);
589
590         g_variant_unref(reply);
591         BT_DBG("-");
592         return ret;
593 }
594
595 void _bt_handle_avrcp_control_event(GVariant *reply, const char *path)
596 {
597         GVariant *param = NULL;
598         const char *property = NULL;
599
600         if (!reply) {
601                 BT_ERR("Error returned in method call\n");
602                 return;
603         }
604
605         GVariantIter iter;
606         GVariant *value = NULL;
607         g_variant_iter_init(&iter, reply);
608         while (g_variant_iter_loop(&iter, "{sv}", &property,
609                                 &value)) {
610                 if ((strcasecmp(property, "Equalizer") == 0) ||
611                         (strcasecmp(property, "Repeat") == 0) ||
612                         (strcasecmp(property, "Shuffle") == 0) ||
613                         (strcasecmp(property, "Scan") == 0) ||
614                         (strcasecmp(property, "Status") == 0)) {
615                                 const char *valstr;
616                                 unsigned int type, val = 0;
617
618                                 valstr = g_variant_get_string(value, NULL);
619                                 BT_DBG("Value : %s ", valstr);
620                                 type = __bt_media_attr_to_type(property);
621                                 if (valstr)
622                                         val = __bt_media_attrval_to_val(type, valstr);
623
624                                 /* Send event to application */
625                                 param = g_variant_new("(u)", val);
626                                 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
627                                         __bt_media_attr_to_event(property), param);
628                 } else if (strcasecmp(property, "Position") == 0) {
629                         unsigned int val;
630
631                         val = g_variant_get_uint32(value);
632                         BT_DBG("Value : %d ", val);
633
634                         /* Send event to application */
635                         param = g_variant_new("(u)", val);
636                         _bt_send_event(BT_AVRCP_CONTROL_EVENT,
637                                 __bt_media_attr_to_event(property), param);
638                 } else if (strcasecmp(property, "Track") == 0) {
639                         int ret = BLUETOOTH_ERROR_NONE;
640                         media_metadata_attributes_t metadata;
641
642                         memset(&metadata, 0x00, sizeof(media_metadata_attributes_t));
643
644                         ret = __bt_avrcp_control_parse_properties(
645                                                                 &metadata, value);
646                         if (BLUETOOTH_ERROR_NONE != ret) {
647                                 /* Free key and value because of break unless free not required */
648                                 free((char *)property);
649                                 g_variant_unref(value);
650                                 g_free((char *)metadata.title);
651                                 g_free((char *)metadata.artist);
652                                 g_free((char *)metadata.album);
653                                 g_free((char *)metadata.genre);
654                                 break;
655                         }
656
657                                 /* Send event to application */
658                         param = g_variant_new("(ssssuuu)",
659                                                         metadata.title,
660                                                         metadata.artist,
661                                                         metadata.album,
662                                                         metadata.genre,
663                                                         metadata.total_tracks,
664                                                         metadata.number,
665                                                         metadata.duration);
666                         _bt_send_event(BT_AVRCP_CONTROL_EVENT,
667                                 BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED, param);
668
669                         g_free((char *)metadata.title);
670                         g_free((char *)metadata.artist);
671                         g_free((char *)metadata.album);
672                         g_free((char *)metadata.genre);
673                 } else {
674                         BT_DBG("Property not handled");
675                 }
676         }
677
678         BT_DBG("-");
679 }