@@ -1701,7 +1701,6 @@ static uint8_t avrcp_handle_request_continuing(struct avrcp *session,
if (pending->pdu_id != pdu->params[0])
goto err;
-
len = 0;
pending->attr_ids = player_fill_media_attribute(player,
pending->attr_ids,
@@ -4037,8 +4036,12 @@ static void target_init(struct avrcp *session)
player = g_slist_nth_data(server->players, 0);
if (player != NULL) {
+ uint8_t init_volume;
target->player = player;
player->sessions = g_slist_prepend(player->sessions, session);
+
+ init_volume = media_player_get_device_volume(session->dev);
+ media_transport_update_device_volume(session->dev, init_volume);
}
session->supported_events |= (1 << AVRCP_EVENT_STATUS_CHANGED) |
@@ -4473,6 +4476,27 @@ int avrcp_set_volume(struct btd_device *dev, uint8_t volume, bool notify)
avrcp_handle_set_volume, session);
}
+struct avrcp_player *avrcp_get_target_player_by_device(struct btd_device *dev)
+{
+ struct avrcp_server *server;
+ struct avrcp *session;
+ struct avrcp_data *target;
+
+ server = find_server(servers, device_get_adapter(dev));
+ if (server == NULL)
+ return NULL;
+
+ session = find_session(server->sessions, dev);
+ if (session == NULL)
+ return NULL;
+
+ target = session->target;
+ if (target == NULL)
+ return NULL;
+
+ return target->player;
+}
+
static int avrcp_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
@@ -116,3 +116,5 @@ void avrcp_player_event(struct avrcp_player *player, uint8_t id,
size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands);
size_t avrcp_browsing_general_reject(uint8_t *operands);
+
+struct avrcp_player *avrcp_get_target_player_by_device(struct btd_device *dev);
@@ -239,6 +239,20 @@ static void media_endpoint_exit(DBusConnection *connection, void *user_data)
media_endpoint_remove(endpoint);
}
+static struct media_adapter *find_adapter(struct btd_device *device)
+{
+ GSList *l;
+
+ for (l = adapters; l; l = l->next) {
+ struct media_adapter *adapter = l->data;
+
+ if (adapter->btd_adapter == device_get_adapter(device))
+ return adapter;
+ }
+
+ return NULL;
+}
+
static void clear_configuration(struct media_endpoint *endpoint,
struct media_transport *transport)
{
@@ -426,6 +440,33 @@ struct a2dp_config_data {
a2dp_endpoint_config_t cb;
};
+uint8_t media_player_get_device_volume(struct btd_device *device)
+{
+ struct avrcp_player *target_player;
+ struct media_adapter *adapter;
+ GSList *l;
+
+ if (!device)
+ return UNINITIALIZED_VOLUME_VALUE;
+
+ target_player = avrcp_get_target_player_by_device(device);
+ if (!target_player)
+ return UNINITIALIZED_VOLUME_VALUE;
+
+ adapter = find_adapter(device);
+ if (!adapter)
+ return UNINITIALIZED_VOLUME_VALUE;
+
+ for (l = adapter->players; l; l = l->next) {
+ struct media_player *mp = l->data;
+
+ if (mp->player == target_player)
+ return mp->volume;
+ }
+
+ return UNINITIALIZED_VOLUME_VALUE;
+}
+
static gboolean set_configuration(struct media_endpoint *endpoint,
uint8_t *configuration, size_t size,
media_endpoint_cb_t cb,
@@ -439,6 +480,7 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
const char *path;
DBusMessageIter iter;
struct media_transport *transport;
+ uint8_t init_volume;
transport = find_device_transport(endpoint, device);
@@ -451,6 +493,9 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
if (transport == NULL)
return FALSE;
+ init_volume = media_player_get_device_volume(device);
+ media_transport_update_volume(transport, init_volume);
+
msg = dbus_message_new_method_call(endpoint->sender, endpoint->path,
MEDIA_ENDPOINT_INTERFACE,
"SetConfiguration");
@@ -646,20 +691,6 @@ static gboolean endpoint_init_a2dp_sink(struct media_endpoint *endpoint,
return TRUE;
}
-static struct media_adapter *find_adapter(struct btd_device *device)
-{
- GSList *l;
-
- for (l = adapters; l; l = l->next) {
- struct media_adapter *adapter = l->data;
-
- if (adapter->btd_adapter == device_get_adapter(device))
- return adapter;
- }
-
- return NULL;
-}
-
static bool endpoint_properties_exists(const char *uuid,
struct btd_device *dev,
void *user_data)
@@ -1779,6 +1810,7 @@ static struct media_player *media_player_create(struct media_adapter *adapter,
mp->sender = g_strdup(sender);
mp->path = g_strdup(path);
mp->timer = g_timer_new();
+ mp->volume = UNINITIALIZED_VOLUME_VALUE;
mp->watch = g_dbus_add_disconnect_watch(conn, sender,
media_player_exit, mp,
@@ -33,3 +33,5 @@ void media_unregister(struct btd_adapter *btd_adapter);
struct a2dp_sep *media_endpoint_get_sep(struct media_endpoint *endpoint);
const char *media_endpoint_get_uuid(struct media_endpoint *endpoint);
uint8_t media_endpoint_get_codec(struct media_endpoint *endpoint);
+
+uint8_t media_player_get_device_volume(struct btd_device *device);
@@ -55,8 +55,6 @@
#define MEDIA_TRANSPORT_INTERFACE "org.bluez.MediaTransport1"
-#define UNINITIALIZED_VOLUME_VALUE 128
-
typedef enum {
TRANSPORT_STATE_IDLE, /* Not acquired and suspended */
TRANSPORT_STATE_PENDING, /* Playing but not acquired */
@@ -981,7 +979,7 @@ void media_transport_update_device_volume(struct btd_device *dev,
{
GSList *l;
- if (dev == NULL)
+ if (dev == NULL || !media_transport_volume_valid(volume))
return;
for (l = transports; l; l = l->next) {
@@ -22,6 +22,8 @@
*
*/
+#define UNINITIALIZED_VOLUME_VALUE 128
+
struct media_transport;
struct media_transport *media_transport_create(struct btd_device *device,