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