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