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