From 98da0c108bc8d428d0b5885c27dd7490107467c1 Mon Sep 17 00:00:00 2001 From: Hyuk Lee Date: Tue, 27 Jun 2017 13:34:33 +0900 Subject: [PATCH] Add the SetAbsoluteVolume API for AVRCP controller Change-Id: I14dffc525cf62a2059e30b21dec7bf9e16c56a69 Signed-off-by: Hyuk Lee --- bt-api/bt-avrcp.c | 31 ++++++ bt-service/bt-request-handler.c | 15 +++ bt-service/bt-service-avrcp-controller.c | 119 +++++++++++++++++++++++ bt-service/include/bt-service-avrcp-controller.h | 3 + include/bluetooth-media-control.h | 23 +++++ include/bt-internal-types.h | 1 + 6 files changed, 192 insertions(+) diff --git a/bt-api/bt-avrcp.c b/bt-api/bt-avrcp.c index 3196a90..02a6cf6 100644 --- a/bt-api/bt-avrcp.c +++ b/bt-api/bt-avrcp.c @@ -456,6 +456,37 @@ BT_EXPORT_API int bluetooth_media_control_get_property( return result; } +BT_EXPORT_API int bluetooth_media_transport_set_property( + media_transport_property_type type, + unsigned int value) +{ + int result; + + BT_CHECK_ENABLED(return); + +#ifdef TIZEN_FEATURE_BT_DPM + if (_bt_check_dpm(BT_DPM_AVRCP, NULL) == BT_DPM_RESTRICTED) { + BT_ERR("Not allow to use AVRCP profile"); + return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION; + } +#endif + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, &type, sizeof(int)); + g_array_append_vals(in_param2, &value, sizeof(unsigned int)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, + BT_AVRCP_TRANSPORT_SET_PROPERTY, + in_param1, in_param2, in_param3, + in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + BT_EXPORT_API int bluetooth_media_control_get_track_info( media_metadata_attributes_t *metadata) { diff --git a/bt-service/bt-request-handler.c b/bt-service/bt-request-handler.c index 069adcf..ba994ba 100644 --- a/bt-service/bt-request-handler.c +++ b/bt-service/bt-request-handler.c @@ -1422,6 +1422,19 @@ int __bt_bluez_request(int function_name, break; } + case BT_AVRCP_TRANSPORT_SET_PROPERTY: { + int type; + unsigned int value; + + __bt_service_get_parameters(in_param1, + &type, sizeof(int)); + __bt_service_get_parameters(in_param2, + &value, sizeof(unsigned int)); + + result = _bt_avrcp_transport_set_property(type, value); + + break; + } case BT_AVRCP_GET_TRACK_INFO: { media_metadata_t meta_data; media_metadata_attributes_t metadata; @@ -3261,6 +3274,8 @@ gboolean __bt_service_check_privilege(int function_name, case BT_AVRCP_CONTROL_GET_PROPERTY: case BT_AVRCP_GET_TRACK_INFO: + case BT_AVRCP_TRANSPORT_SET_PROPERTY: + case BT_SET_CONTENT_PROTECT: case BT_BOND_DEVICE_BY_TYPE: diff --git a/bt-service/bt-service-avrcp-controller.c b/bt-service/bt-service-avrcp-controller.c index 9c87873..39085ed 100644 --- a/bt-service/bt-service-avrcp-controller.c +++ b/bt-service/bt-service-avrcp-controller.c @@ -54,6 +54,7 @@ static bt_player_settinngs_t shuffle_settings[] = { }; static char *avrcp_control_path = NULL; +static char *avrcp_transport_path = NULL; void _bt_set_control_device_path(const char *path) { @@ -104,6 +105,33 @@ static char *__bt_get_control_device_path(void) return control_path; } +static char *__bt_get_transport_device_path(void) +{ + char *adapter_path; + char *transport_path; + char connected_address[BT_ADDRESS_STRING_SIZE + 1]; + + BT_DBG("+"); + + if (avrcp_transport_path != NULL) + return avrcp_transport_path; + + retv_if(!_bt_is_headset_type_connected(BT_AVRCP, + connected_address), NULL); + + BT_DBG("device address = %s", connected_address); + + adapter_path = _bt_get_device_object_path(connected_address); + retv_if(adapter_path == NULL, NULL); + + transport_path = g_strdup_printf(BT_MEDIA_TRANSPORT_PATH, adapter_path); + g_free(adapter_path); + + avrcp_transport_path = transport_path; + BT_DBG("transport_path = %s", transport_path); + return transport_path; +} + static int __bt_media_send_control_msg(const char *name) { GVariant *reply = NULL; @@ -226,6 +254,36 @@ GDBusProxy *__bt_get_control_properties_proxy(void) return proxy; } +GDBusProxy *__bt_get_transport_properties_proxy(void) +{ + GDBusProxy *proxy = NULL; + GError *error = NULL; + char *transport_path = NULL; + GDBusConnection *conn = NULL; + + transport_path = __bt_get_transport_device_path(); + retv_if(transport_path == NULL, NULL); + BT_DBG("transport_path = %s", transport_path); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, NULL); + + proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_BLUEZ_NAME, transport_path, + BT_PROPERTIES_INTERFACE, NULL, &error); + if (proxy == NULL) { + BT_ERR("Unable to allocate new proxy"); + if (error) { + BT_ERR("%s", error->message); + g_clear_error(&error); + } + return NULL; + } + + return proxy; +} + static int __bt_media_attr_to_event(const char *str) { if (!strcasecmp(str, "Equalizer")) @@ -287,6 +345,17 @@ static const char *__bt_media_type_to_str(int type) return NULL; } +static const char *__bt_transport_type_to_str(int type) +{ + switch (type) { + case DELAY: + return "Delay"; + case VOLUME: + return "Volume"; + } + return NULL; +} + static int __bt_media_attrval_to_val(int type, const char *value) { int ret = 0; @@ -466,6 +535,56 @@ int _bt_avrcp_control_set_property(int type, unsigned int value) return BLUETOOTH_ERROR_NONE; } +int _bt_avrcp_transport_set_property(int type, unsigned int value) +{ + GValue *attr_value = NULL; + GDBusProxy *proxy = NULL; + GError *error = NULL; + GVariant *reply, *param; + uint16_t property_level = (uint16_t)value; + + g_value_init(attr_value, G_TYPE_STRING); + + switch (type) { + case DELAY: + param = g_variant_new("q", property_level); + BT_INFO("delay level %d", property_level); + break; + case VOLUME: + param = g_variant_new("q", property_level); + BT_INFO("volume level %d", property_level); + break; + default: + BT_ERR("Invalid property type: %d", type); + g_value_unset(attr_value); + return BLUETOOTH_ERROR_INTERNAL; + } + + proxy = __bt_get_transport_properties_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED); + + reply = g_dbus_proxy_call_sync(proxy, + "Set", g_variant_new("(ssv)", BT_MEDIATRANSPORT_INTERFACE, __bt_transport_type_to_str(type), param), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + g_object_unref(proxy); + g_variant_unref(param); + + if (!reply) { + BT_ERR("Can't get managed objects"); + if (error) { + BT_ERR("SetProperty Fail: %s", error->message); + g_clear_error(&error); + return BLUETOOTH_ERROR_INTERNAL; + } + } + + g_variant_unref(reply); + g_value_unset(attr_value); + + return BLUETOOTH_ERROR_NONE; +} + static int __bt_avrcp_control_parse_properties( media_metadata_attributes_t *metadata, GVariant *item) diff --git a/bt-service/include/bt-service-avrcp-controller.h b/bt-service/include/bt-service-avrcp-controller.h index 81aaa0f..722f408 100755 --- a/bt-service/include/bt-service-avrcp-controller.h +++ b/bt-service/include/bt-service-avrcp-controller.h @@ -32,6 +32,7 @@ extern "C" { #define BT_MEDIA_CONTROL_PATH "%s/player0" +#define BT_MEDIA_TRANSPORT_PATH "%s/fd0" int _bt_avrcp_control_cmd(int type); @@ -39,6 +40,8 @@ int _bt_avrcp_control_set_property(int type, unsigned int value); int _bt_avrcp_control_get_property(int type, unsigned int *value); +int _bt_avrcp_transport_set_property(int type, unsigned int value); + int _bt_avrcp_control_get_track_info(media_metadata_attributes_t *metadata); void _bt_handle_avrcp_control_event(GVariant *reply, const char *path); diff --git a/include/bluetooth-media-control.h b/include/bluetooth-media-control.h index 93a8b62..42faf8e 100644 --- a/include/bluetooth-media-control.h +++ b/include/bluetooth-media-control.h @@ -40,6 +40,11 @@ typedef enum { } media_player_property_type; typedef enum { + DELAY = 0x01, + VOLUME +} media_transport_property_type; + +typedef enum { EQUALIZER_OFF = 0x01, EQUALIZER_ON, EQUALIZER_INVALID, @@ -332,6 +337,24 @@ int bluetooth_media_control_set_property(media_player_property_type type, unsign int bluetooth_media_control_get_property(media_player_property_type type, unsigned int *value); /** + * @fn int bluetooth_media_transport_set_property(media_transport_property_type type, unsigned int value) + * @brief Notifies the remote bluetooth target with change in audio transport settings + * + * This function is a asynchronous call. + * No event for this api. + * + * @return BT_MEDIA_TRANSPORT_SUCCESS - Success \n + * BT_MEDIA_TRANSPORT_ERROR - Error \n + * + * @exception None + * @param[in] setting - The audio transport properties + * + * @remark None + * @see None + */ +int bluetooth_media_transport_set_property(media_transport_property_type type, unsigned int value); + +/** * @fn int bluetooth_media_control_get_track_info(media_metadata_attributes_t *metadata) * @brief reads the track metadata from the remote target player. * diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index 597384b..1592689 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -256,6 +256,7 @@ typedef enum { BT_AVRCP_CONTROL_SET_PROPERTY, BT_AVRCP_CONTROL_GET_PROPERTY, BT_AVRCP_GET_TRACK_INFO, + BT_AVRCP_TRANSPORT_SET_PROPERTY, BT_OPP_PUSH_FILES = BT_FUNC_OPP_BASE, BT_OPP_CANCEL_PUSH, BT_OPP_IS_PUSHING_FILES, -- 2.7.4