Merge the code from tizen_2.4
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-avrcp.c
1 /*
2  * Bluetooth-frwk
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  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <gio/gio.h>
25 #include <glib.h>
26 #include <dlog.h>
27 #include <string.h>
28 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
29 #include <syspopup_caller.h>
30 #endif
31 #include <dbus/dbus.h>
32
33 #include "bluetooth-api.h"
34 #include "bt-internal-types.h"
35 #include "bt-service-common.h"
36 #include "bt-service-avrcp.h"
37 #include "bt-service-event.h"
38 #include "bt-service-util.h"
39 #include "bt-service-audio.h"
40
41 static bt_player_settinngs_t loopstatus_settings[] = {
42         { REPEAT_INVALID, "" },
43         { REPEAT_MODE_OFF, "None" },
44         { REPEAT_SINGLE_TRACK, "Track" },
45         { REPEAT_ALL_TRACK, "Playlist" },
46         { REPEAT_INVALID, "" }
47 };
48
49 static bt_player_settinngs_t shuffle_settings[] = {
50         { SHUFFLE_INVALID, "" },
51         { SHUFFLE_MODE_OFF, "off" },
52         { SHUFFLE_ALL_TRACK, "alltracks" },
53         { SHUFFLE_GROUP, "group" },
54         { SHUFFLE_INVALID, "" }
55 };
56
57 static bt_player_settinngs_t player_status[] = {
58         { STATUS_STOPPED, "stopped" },
59         { STATUS_PLAYING, "playing" },
60         { STATUS_PAUSED, "paused" },
61         { STATUS_FORWARD_SEEK, "forward-seek" },
62         { STATUS_REVERSE_SEEK, "reverse-seek" },
63         { STATUS_ERROR, "error" },
64         { STATUS_INVALID, "" }
65 };
66
67 GDBusConnection *bt_gdbus_conn = NULL;
68 static guint avrcp_reg_id = 0;
69 static GDBusProxy *service_gproxy = NULL;
70
71 /* Introspection data exposed from bt-service */
72 static const gchar bt_avrcp_bluez_introspection_xml[] =
73 "<node name='/'>"
74 " <interface name='org.freedesktop.DBus.Properties'>"
75 "     <method name='Set'>"
76 "          <arg type='s' name='interface' direction='in'/>"
77 "          <arg type='s' name='property' direction='in'/>"
78 "          <arg type='v' name='value' direction='in'/>"
79 "     </method>"
80 " </interface>"
81 "</node>";
82
83 static gboolean __bt_media_emit_property_changed(GDBusConnection *connection,
84                 const char *path, const char *interface, const char *name,
85                 const GVariant *variant)
86 {
87         GVariantBuilder *builder = NULL;
88         GError *error = NULL;
89
90         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
91         g_variant_builder_add(builder, "{sv}", name, variant);
92
93         g_dbus_connection_emit_signal(connection, NULL, path,
94                                 DBUS_INTERFACE_PROPERTIES,
95                                 "PropertiesChanged",
96                                 g_variant_new("(sa{sv})",
97                                 interface, builder),
98                                 &error);
99
100         g_variant_builder_unref(builder);
101         if (error) {
102                 BT_ERR("Could not Emit PropertiesChanged Signal: errCode[%x], message[%s]",
103                         error->code, error->message);
104                 g_clear_error(&error);
105                 return FALSE;
106         }
107
108         return TRUE;
109 }
110
111 static GQuark __bt_avrcp_error_quark(void)
112 {
113         static GQuark quark = 0;
114
115         if (!quark)
116                 quark = g_quark_from_static_string("bt-avrcp");
117
118         return quark;
119 }
120
121 static GError *__bt_avrcp_set_error(bt_avrcp_error_t error)
122 {
123         BT_ERR("error[%d]\n", error);
124
125         switch (error) {
126         case BT_AVRCP_ERROR_INVALID_PARAM:
127                 return g_error_new(BT_AVRCP_ERROR, error,
128                                 BT_ERROR_INVALID_PARAM);
129         case BT_AVRCP_ERROR_INVALID_INTERFACE:
130                 return g_error_new(BT_AVRCP_ERROR, error,
131                                 BT_ERROR_INVALID_INTERFACE);
132         case BT_AVRCP_ERROR_INTERNAL:
133         default:
134                 return g_error_new(BT_AVRCP_ERROR, error,
135                                 BT_ERROR_INTERNAL);
136         }
137 }
138
139 static void __bt_avrcp_agent_method(GDBusConnection *connection,
140                 const gchar *sender,
141                 const gchar *object_path,
142                 const gchar *interface_name,
143                 const gchar *method_name,
144                 GVariant *parameters,
145                 GDBusMethodInvocation *invocation,
146                 gpointer user_data)
147 {
148         BT_DBG("+");
149         BT_INFO("method %s", method_name);
150         BT_INFO("object_path %s", object_path);
151         int ret = BT_AVRCP_ERROR_NONE;
152         GError *err = NULL;
153         gboolean shuffle_status;
154         guint32 status;
155         gchar *interface = NULL;
156         gchar *property = NULL;
157         gchar *loop_status = NULL;
158         GVariant *value = NULL;
159
160         if (g_strcmp0(method_name, "Set") == 0) {
161                 g_variant_get(parameters, "(&s&sv)", &interface, &property,
162                                 &value);
163
164                 if (g_strcmp0(interface, BT_MEDIA_PLAYER_INTERFACE) != 0) {
165                         ret = BT_AVRCP_ERROR_INVALID_INTERFACE;
166                         goto fail;
167                 }
168         }
169
170         if (value == NULL) {
171                 BT_ERR("value is NULL");
172                 goto fail;
173         }
174
175         BT_DBG("Property: %s\n", property);
176         if (g_strcmp0(property, "Shuffle") == 0) {
177
178                 if (!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
179                         BT_ERR("Error");
180                         ret = BT_AVRCP_ERROR_INVALID_PARAM;
181                         goto fail;
182                 }
183
184                 shuffle_status = g_variant_get_boolean(value);
185                 BT_DBG("Value: %s\n", shuffle_status ? "TRUE" : "FALSE");
186                 if (shuffle_status == TRUE)
187                         status = SHUFFLE_ALL_TRACK;
188                 else
189                         status = SHUFFLE_MODE_OFF;
190
191                 _bt_send_event(BT_AVRCP_EVENT,
192                                 BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
193                                 g_variant_new("(u)", status));
194         } else if (g_strcmp0(property, "LoopStatus") == 0) {
195
196                 if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
197                         BT_ERR("Error");
198                         ret = BT_AVRCP_ERROR_INVALID_PARAM;
199                         goto fail;
200                 }
201
202                 loop_status = (gchar *)g_variant_get_string(value, NULL);
203                 BT_DBG("Value: %s\n", loop_status);
204
205                 if (g_strcmp0(loop_status, "Track") == 0)
206                         status = REPEAT_SINGLE_TRACK;
207                 else if (g_strcmp0(loop_status, "Playlist") == 0)
208                         status = REPEAT_ALL_TRACK;
209                 else if (g_strcmp0(loop_status, "None") == 0)
210                         status = REPEAT_MODE_OFF;
211                 else
212                         status = REPEAT_INVALID;
213
214                 _bt_send_event(BT_AVRCP_EVENT,
215                                 BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
216                                 g_variant_new("(u)", status));
217         }
218
219         BT_DBG("-");
220         return;
221
222 fail:
223         if (value)
224                 g_variant_unref(value);
225         err = __bt_avrcp_set_error(ret);
226         g_dbus_method_invocation_return_gerror(invocation, err);
227         g_clear_error(&err);
228         BT_INFO("-");
229 }
230
231 static const GDBusInterfaceVTable method_table = {
232         __bt_avrcp_agent_method,
233         NULL,
234         NULL,
235 };
236
237 static GDBusNodeInfo *__bt_avrcp_create_method_node_info
238                                 (const gchar *introspection_data)
239 {
240         GError *err = NULL;
241         GDBusNodeInfo *node_info = NULL;
242
243         if (introspection_data == NULL)
244                 return NULL;
245
246         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
247
248         if (err) {
249                 BT_ERR("Unable to create node: %s", err->message);
250                 g_clear_error(&err);
251         }
252
253         return node_info;
254 }
255
256 static GDBusProxy *__bt_avrcp_gdbus_init_service_proxy(void)
257 {
258         BT_DBG("+");
259         GDBusProxy *proxy;
260         GError *err = NULL;
261         char *adapter_path;
262
263         if (bt_gdbus_conn == NULL)
264                 bt_gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
265
266         if (!bt_gdbus_conn) {
267                 if (err) {
268                         BT_ERR("Unable to connect to gdbus: %s", err->message);
269                         g_clear_error(&err);
270                 }
271                 return NULL;
272         }
273
274         adapter_path = _bt_get_adapter_path();
275         retv_if(adapter_path == NULL, NULL);
276
277         proxy =  g_dbus_proxy_new_sync(bt_gdbus_conn,
278                         G_DBUS_PROXY_FLAGS_NONE, NULL,
279                         BT_BLUEZ_NAME, adapter_path,
280                         BT_MEDIA_INTERFACE, NULL, &err);
281         g_free(adapter_path);
282
283         if (!proxy) {
284                 BT_ERR("Unable to create proxy");
285                 if (err) {
286                         BT_ERR("Error: %s", err->message);
287                         g_clear_error(&err);
288                 }
289                 return NULL;
290         }
291
292         BT_DBG("-");;
293         return proxy;
294 }
295
296 static GDBusProxy *__bt_avrcp_gdbus_get_service_proxy(void)
297 {
298         return (service_gproxy) ? service_gproxy :
299                         __bt_avrcp_gdbus_init_service_proxy();
300 }
301
302 int _bt_register_media_player(void)
303 {
304         BT_DBG("+");
305         gchar *adapter_path;
306         gboolean shuffle_status;
307         gchar *path;
308         GDBusConnection *conn;
309         GDBusNodeInfo *node_info;
310         GDBusProxy *proxy;
311         GVariantBuilder *builder;
312         GVariant *ret;
313         GError *error = NULL;
314
315         media_player_settings_t player_settings = {0,};
316
317         player_settings.repeat  = REPEAT_MODE_OFF;
318         player_settings.status = STATUS_STOPPED;
319         player_settings.position = 0;
320         shuffle_status = FALSE;
321
322         conn = _bt_get_system_gconn();
323         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
324         bt_gdbus_conn = conn;
325
326         node_info = __bt_avrcp_create_method_node_info(
327                                 bt_avrcp_bluez_introspection_xml);
328         if (node_info == NULL)
329                 return BLUETOOTH_ERROR_INTERNAL;
330
331         avrcp_reg_id = g_dbus_connection_register_object(bt_gdbus_conn,
332                                         BT_MEDIA_OBJECT_PATH,
333                                         node_info->interfaces[0],
334                                         &method_table,
335                                         NULL, NULL, &error);
336         g_dbus_node_info_unref(node_info);
337
338         if (avrcp_reg_id == 0) {
339                 BT_ERR("Failed to register: %s", error->message);
340                 g_clear_error(&error);
341                 return BLUETOOTH_ERROR_INTERNAL;
342         }
343
344         adapter_path = _bt_get_adapter_path();
345         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
346
347         proxy =  g_dbus_proxy_new_sync(conn,
348                         G_DBUS_PROXY_FLAGS_NONE, NULL,
349                         BT_BLUEZ_NAME, adapter_path,
350                         BT_MEDIA_INTERFACE, NULL, &error);
351         g_free(adapter_path);
352
353         if (proxy == NULL) {
354                 BT_ERR("Unable to create proxy");
355                 if (error) {
356                         BT_ERR("Error: %s", error->message);
357                         g_clear_error(&error);
358                 }
359                 return BLUETOOTH_ERROR_INTERNAL;
360         }
361
362         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
363
364         g_variant_builder_add(builder, "{sv}", "LoopStatus",
365                         g_variant_new("s",
366                         loopstatus_settings[player_settings.repeat].property));
367         BT_ERR("LoopStatus: %s", loopstatus_settings[player_settings.repeat].property);
368
369         g_variant_builder_add(builder, "{sv}", "Shuffle",
370                         g_variant_new("b", shuffle_status));
371
372         g_variant_builder_add(builder, "{sv}", "PlaybackStatus",
373                         g_variant_new("s",
374                         player_status[player_settings.status].property));
375         BT_ERR("PlaybackStatus: %s", player_status[player_settings.status].property);
376
377         g_variant_builder_add(builder, "{sv}", "Position",
378                         g_variant_new("u", player_settings.position));
379
380         path = g_strdup(BT_MEDIA_OBJECT_PATH);
381         ret = g_dbus_proxy_call_sync(proxy, "RegisterPlayer",
382                         g_variant_new("(oa{sv})", path, builder),
383                         G_DBUS_CALL_FLAGS_NONE, -1,
384                         NULL, &error);
385
386         g_object_unref(proxy);
387         g_free(path);
388         g_variant_builder_unref(builder);
389
390         if (ret == NULL) {
391                 BT_ERR("Call RegisterPlayer Failed");
392                 if (error) {
393                         BT_ERR("errCode[%x], message[%s]",
394                                         error->code, error->message);
395                         g_clear_error(&error);
396                 }
397                 return BLUETOOTH_ERROR_INTERNAL;
398         }
399
400         g_variant_unref(ret);
401         return BLUETOOTH_ERROR_NONE;
402 }
403
404 static void __bt_avrcp_unregister_object_path(void)
405 {
406         if (avrcp_reg_id > 0) {
407                 g_dbus_connection_unregister_object(bt_gdbus_conn,
408                                                         avrcp_reg_id);
409                 avrcp_reg_id = 0;
410         }
411 }
412
413 int _bt_unregister_media_player(void)
414 {
415         BT_DBG("+");
416         GDBusProxy *proxy;
417         GVariant *ret;
418         GError *error = NULL;
419         GDBusConnection *conn;
420         gchar *path;
421
422         conn = bt_gdbus_conn;
423         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
424
425         proxy = __bt_avrcp_gdbus_get_service_proxy();
426         if (proxy == NULL)
427                 return BLUETOOTH_ERROR_INTERNAL;
428
429         path = g_strdup(BT_MEDIA_OBJECT_PATH);
430         BT_DBG("path is [%s]", path);
431
432         ret = g_dbus_proxy_call_sync(proxy, "UnregisterPlayer",
433                         g_variant_new("(o)", path),
434                         G_DBUS_CALL_FLAGS_NONE, -1,
435                         NULL, &error);
436         g_free(path);
437
438         if (ret == NULL) {
439                 BT_ERR("UnregisterPlayer failed");
440                 if (error) {
441                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
442                                         error->code, error->message);
443                         g_clear_error(&error);
444                 }
445                 return BLUETOOTH_ERROR_INTERNAL;
446         }
447
448         __bt_avrcp_unregister_object_path();
449
450         g_variant_unref(ret);
451         g_object_unref(bt_gdbus_conn);
452         bt_gdbus_conn = NULL;
453
454         BT_DBG("-");
455         return BLUETOOTH_ERROR_NONE;
456 }
457
458 int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
459 {
460         BT_DBG("+");
461         char *interface = BT_MEDIA_PLAYER_INTERFACE;
462         GDBusConnection *conn;
463         GError *error = NULL;
464         GVariantBuilder *builder = NULL;
465         GVariantBuilder *inner_builder = NULL;
466         GVariant *children[1];
467         gboolean ret;
468
469         retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
470
471         conn = bt_gdbus_conn;
472         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
473
474         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
475         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
476
477         g_variant_builder_add(inner_builder, "{sv}",
478                 "xesam:title", g_variant_new_string(meta_data->title));
479
480         children[0] = g_variant_new_string(meta_data->artist);
481         g_variant_builder_add(inner_builder, "{sv}",
482                 "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
483                 children, 1));
484
485         g_variant_builder_add(inner_builder, "{sv}",
486                 "xesam:album", g_variant_new_string(meta_data->album));
487
488         children[0] = g_variant_new_string(meta_data->genre);
489         g_variant_builder_add(inner_builder, "{sv}",
490                 "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
491                 children, 1));
492
493         g_variant_builder_add(inner_builder, "{sv}",
494                 "xesam:totalTracks", g_variant_new_int32(meta_data->total_tracks));
495
496         g_variant_builder_add(inner_builder, "{sv}",
497                 "xesam:trackNumber", g_variant_new_int32(meta_data->number));
498
499         g_variant_builder_add(inner_builder, "{sv}",
500                 "mpris:lenght", g_variant_new_int64(meta_data->duration));
501
502         g_variant_builder_add(builder, "{sv}",
503                 "Metadata", g_variant_new("a{sv}", inner_builder));
504
505         ret = g_dbus_connection_emit_signal(conn, NULL, BT_MEDIA_OBJECT_PATH,
506                                 DBUS_INTERFACE_PROPERTIES,
507                                 "PropertiesChanged",
508                                 g_variant_new("(sa{sv})",
509                                 interface, builder),
510                                 &error);
511
512         g_variant_builder_unref(inner_builder);
513         g_variant_builder_unref(builder);
514
515         if (!ret) {
516                 if (error != NULL) {
517                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
518                                 error->code, error->message);
519                         g_clear_error(&error);
520                 }
521         }
522
523         BT_DBG("-");
524         return BLUETOOTH_ERROR_NONE;
525 }
526
527 int _bt_avrcp_set_interal_property(int type, media_player_settings_t *properties)
528 {
529         BT_DBG("+");
530         GDBusConnection *conn;
531         int value;
532         media_metadata_attributes_t meta_data;
533         gboolean shuffle;
534         GVariantBuilder *builder = NULL;
535         GVariant *children[1];
536
537         conn = bt_gdbus_conn;
538         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
539
540         switch (type) {
541         case REPEAT:
542                 value = properties->repeat;
543                 if (!__bt_media_emit_property_changed(conn, BT_MEDIA_OBJECT_PATH,
544                                 BT_MEDIA_PLAYER_INTERFACE, "LoopStatus",
545                                 g_variant_new_string(loopstatus_settings[value].property))) {
546                         BT_ERR("Error sending the PropertyChanged signal \n");
547                         return BLUETOOTH_ERROR_INTERNAL;
548                 }
549                 break;
550         case SHUFFLE:
551                 value = properties->shuffle;
552                 if (g_strcmp0(shuffle_settings[value].property, "off") == 0)
553                         shuffle = FALSE;
554                 else
555                         shuffle = TRUE;
556
557                 if (!__bt_media_emit_property_changed(conn, BT_MEDIA_OBJECT_PATH,
558                                 BT_MEDIA_PLAYER_INTERFACE, "Shuffle",
559                                 g_variant_new_boolean(shuffle))) {
560                         BT_ERR("Error sending the PropertyChanged signal \n");
561                         return BLUETOOTH_ERROR_INTERNAL;
562                 }
563                 break;
564         case STATUS:
565                 value = properties->status;
566                 if (!__bt_media_emit_property_changed(conn, BT_MEDIA_OBJECT_PATH,
567                                 BT_MEDIA_PLAYER_INTERFACE, "PlaybackStatus",
568                                 g_variant_new_string(player_status[value].property))) {
569                         BT_ERR("Error sending the PropertyChanged signal \n");
570                         return BLUETOOTH_ERROR_INTERNAL;
571                 }
572                 break;
573         case POSITION:
574                 value = properties->position;
575                 if (!__bt_media_emit_property_changed(conn, BT_MEDIA_OBJECT_PATH,
576                                 BT_MEDIA_PLAYER_INTERFACE, "Position",
577                                 g_variant_new_uint32(value))) {
578                         BT_ERR("Error sending the PropertyChanged signal \n");
579                         return BLUETOOTH_ERROR_INTERNAL;
580                 }
581                 break;
582         case METADATA:
583                 meta_data = properties->metadata;
584
585                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
586                 g_variant_builder_add(builder, "{sv}",
587                                 "xesam:title", g_variant_new_string(meta_data.title));
588
589                 children[0] = g_variant_new_string(meta_data.artist);
590                 g_variant_builder_add(builder, "{sv}",
591                                 "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
592                                                 children, 1));
593
594                 g_variant_builder_add(builder, "{sv}",
595                                 "xesam:album", g_variant_new_string(meta_data.album));
596
597                 children[0] = g_variant_new_string(meta_data.genre);
598                 g_variant_builder_add(builder, "{sv}",
599                                 "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
600                                                 children, 1));
601
602                 g_variant_builder_add(builder, "{sv}",
603                                 "xesam:totalTracks", g_variant_new_int32(meta_data.total_tracks));
604
605                 g_variant_builder_add(builder, "{sv}",
606                                 "xesam:trackNumber", g_variant_new_int32(meta_data.number));
607
608                 g_variant_builder_add(builder, "{sv}",
609                                 "mpris:lenght", g_variant_new_int64(meta_data.duration));
610
611                 if (!__bt_media_emit_property_changed(conn, BT_MEDIA_OBJECT_PATH,
612                                 BT_MEDIA_PLAYER_INTERFACE, "Metadata",
613                                 g_variant_new("a{sv}", builder))) {
614                         BT_ERR("Error sending the PropertyChanged signal \n");
615                         g_variant_builder_unref(builder);
616                         return BLUETOOTH_ERROR_INTERNAL;
617                 }
618                 g_variant_builder_unref(builder);
619                 break;
620         default:
621                 BT_ERR("Invalid Type\n");
622                 return BLUETOOTH_ERROR_INTERNAL;
623         }
624         BT_DBG("-");
625         return BLUETOOTH_ERROR_NONE;
626 }
627
628 int _bt_avrcp_set_properties(media_player_settings_t *properties)
629 {
630         BT_DBG("+");
631
632         if (_bt_avrcp_set_interal_property(REPEAT,
633                                 properties) != BLUETOOTH_ERROR_NONE) {
634                         return BLUETOOTH_ERROR_INTERNAL;
635         }
636         if (_bt_avrcp_set_interal_property(SHUFFLE,
637                         properties) != BLUETOOTH_ERROR_NONE) {
638                 return BLUETOOTH_ERROR_INTERNAL;
639         }
640
641         if (_bt_avrcp_set_interal_property(STATUS,
642                         properties) != BLUETOOTH_ERROR_NONE) {
643                 return BLUETOOTH_ERROR_INTERNAL;
644         }
645
646         if (_bt_avrcp_set_interal_property(POSITION,
647                         properties) != BLUETOOTH_ERROR_NONE) {
648                 return BLUETOOTH_ERROR_INTERNAL;
649         }
650
651         if (_bt_avrcp_set_interal_property(METADATA,
652                         properties) != BLUETOOTH_ERROR_NONE) {
653                 return BLUETOOTH_ERROR_INTERNAL;
654         }
655         BT_DBG("-");
656         return BLUETOOTH_ERROR_NONE;
657 }
658
659 int _bt_avrcp_set_property(int type, unsigned int value)
660 {
661         BT_DBG("+");
662         media_player_settings_t properties;
663
664         switch (type) {
665         case REPEAT:
666                 properties.repeat = value;
667                 break;
668         case SHUFFLE:
669                 properties.shuffle = value;
670                 break;
671         case STATUS:
672                 properties.status = value;
673                 break;
674         case POSITION:
675                 properties.position = value;
676                 break;
677         default:
678                 BT_DBG("Invalid Type\n");
679                 return BLUETOOTH_ERROR_INTERNAL;
680         }
681
682         if (_bt_avrcp_set_interal_property(type,
683                         &properties) != BLUETOOTH_ERROR_NONE)
684                 return BLUETOOTH_ERROR_INTERNAL;
685
686         BT_DBG("-");
687
688         return BLUETOOTH_ERROR_NONE;
689 }