* [PATCH BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported @ 2026-09-23 8:00 Frédéric Danis 2026-09-23 11:04 ` [BlueZ] " bluez.test.bot 2026-09-23 13:55 ` [PATCH BlueZ] " Luiz Augusto von Dentz 0 siblings, 2 replies; 4+ messages in thread From: Frédéric Danis @ 2026-09-23 8:00 UTC (permalink / raw) To: linux-bluetooth Some remote targets do not support the AVRCP_EVENT_PLAYBACK_POS_CHANGED notification, meaning bluetoothd never learns about track position updates for such devices. When this event is not present in the capabilities reported by the remote, fall back to polling AVRCP_GET_PLAY_STATUS once a second so the media player position stays in sync. Polling is only kept running while playback is actively progressing (playing/forward-seek/ reverse-seek) and is stopped otherwise, and is torn down on session destruction. Assisted-by: Copilot CLI:claude-sonnet-5 --- profiles/audio/avrcp.c | 64 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index df5f97eaf..105538cdc 100644 --- a/profiles/audio/avrcp.c +++ b/profiles/audio/avrcp.c @@ -247,7 +247,9 @@ struct avrcp { unsigned int control_id; unsigned int browsing_id; unsigned int browsing_timer; + unsigned int position_timer; uint16_t supported_events; + bool pos_changed_supported; uint8_t transaction; struct pending_pdu *pending_pdu; }; @@ -341,6 +343,7 @@ static const uint32_t company_ids[] = { static void avrcp_register_notification(struct avrcp *session, uint8_t event); static GList *player_list_settings(struct avrcp_player *player); +static void avrcp_get_play_status(struct avrcp *session); static void avrcp_browsing_record(sdp_record_t *record, sdp_data_t *version) { @@ -2224,6 +2227,56 @@ static const char *status_to_string(uint8_t status) } } +static bool avrcp_poll_play_status(gpointer user_data) +{ + struct avrcp *session = user_data; + + avrcp_get_play_status(session); + + return TRUE; +} + +static void avrcp_stop_pos_polling(struct avrcp *session) +{ + if (session->position_timer == 0) + return; + + timeout_remove(session->position_timer); + session->position_timer = 0; +} + +static void avrcp_start_pos_polling(struct avrcp *session) +{ + if (session->position_timer > 0) + return; + + session->position_timer = timeout_add_seconds(1, + avrcp_poll_play_status, + session, NULL); +} + +/* + * Poll GetPlayStatus once a second to resync position while playing when + * the remote does not support AVRCP_EVENT_PLAYBACK_POS_CHANGED. Polling is + * paused whenever playback is not actively progressing. + */ +static void avrcp_update_pos_polling(struct avrcp *session, uint8_t status) +{ + if (session->pos_changed_supported) + return; + + switch (status) { + case AVRCP_PLAY_STATUS_PLAYING: + case AVRCP_PLAY_STATUS_FWD_SEEK: + case AVRCP_PLAY_STATUS_REV_SEEK: + avrcp_start_pos_polling(session); + break; + default: + avrcp_stop_pos_polling(session); + break; + } +} + static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, uint8_t subunit, uint8_t transaction, uint8_t *operands, size_t operand_count, @@ -2252,6 +2305,8 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, media_player_set_position(mp, position); media_player_set_status(mp, status_to_string(status)); + avrcp_update_pos_polling(session, status); + return FALSE; } @@ -4128,6 +4183,9 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code, } } + session->pos_changed_supported = + !!(events & (1 << AVRCP_EVENT_PLAYBACK_POS_CHANGED)); + if (!session->controller || !session->controller->player) return FALSE; @@ -4140,7 +4198,8 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code, !(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED))) avrcp_list_player_attributes(session); - if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED))) + if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)) || + !session->pos_changed_supported) avrcp_get_play_status(session); if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED))) @@ -4470,6 +4529,9 @@ static void session_destroy(struct avrcp *session, int err) if (session->browsing_timer > 0) timeout_remove(session->browsing_timer); + if (session->position_timer > 0) + timeout_remove(session->position_timer); + if (session->controller != NULL) controller_destroy(session); -- 2.43.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported 2026-09-23 8:00 [PATCH BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported Frédéric Danis @ 2026-09-23 11:04 ` bluez.test.bot 2026-09-23 13:55 ` [PATCH BlueZ] " Luiz Augusto von Dentz 1 sibling, 0 replies; 4+ messages in thread From: bluez.test.bot @ 2026-09-23 11:04 UTC (permalink / raw) To: linux-bluetooth, frederic.danis [-- Attachment #1: Type: text/plain, Size: 7480 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/series/1172004/ ---Test result--- Test Summary: CheckPatch PASS 0.51 seconds GitLint PASS 1.17 seconds BuildEll PASS 19.48 seconds BluezMake PASS 386.90 seconds MakeCheck PASS 2.67 seconds MakeDistcheck PASS 138.47 seconds CheckValgrind PASS 149.37 seconds CheckSmatch PASS 287.84 seconds bluezmakeextell PASS 93.00 seconds TestFunctional FAIL 1132.21 seconds IncrementalBuild PASS 383.61 seconds ScanBuild PASS 1124.56 seconds Details ############################## Test: TestFunctional - FAIL Desc: Run test-functional Output: FAIL functional.test_bap::test_bap_unicast_set_transport_created[hosts9-vm3-legacy]: failed on setup with "pytest_bluezenv.rpc.RemoteError: End Of File (EOF). <pexpect.popen_spawn.PopenSpawn object at 0x7f0ab7b1e7b0> searcher: searcher_re: 0: re.compile(b'Device has been removed|Device 00:AA:01:00:00:42 not available') Remote traceback: Traceback (most recent call last): File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/rpc.py", line 102, in server_stream result = method(*msg["a"], **msg["kw"]) File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/env.py", line 256, in call_plugin return getattr(self.plugins[name], method)(*a, **kw) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^ File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/host_plugins.py", line 441, in expect ret = ctl.expect(*a, **kw) File "/usr/lib/python3/dist-packages/pexpect/spawnbase.py", line 354, in expect return self.expect_list(compiled_pattern_list, ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ timeout, searchwindowsize, async_) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/pexpect/spawnbase.py", line 383, in expect_list return exp.expect_loop(timeout) ~~~~~~~~~~~~~~~^^^^^^^^^ File "/usr/lib/python3/dist-packages/pexpect/expect.py", line 179, in expect_loop return self.eof(e) ~~~~~~~~^^^ File "/usr/lib/python3/dist-packages/pexpect/expect.py", line 122, in eof raise exc pexpect.exceptions.EOF: End Of File (EOF). <pexpect.popen_spawn.PopenSpawn object at 0x7f0ab7b1e7b0> searcher: searcher_re: 0: re.compile(b'Device has been removed|Device 00:AA:01:00:00:42 not available')" FAIL functional.test_bap::test_bap_unicast_set_transport_created[hosts9-vm3-legacy]: failed on teardown with "pytest_bluezenv.plugin.CoredumpWarning: Core dump: test-bluezenv-hosts9.2-bluetoothctl-1790159931-120.core /usr/bin/gdb: warning: Couldn't determine a path for the index cache directory. [New LWP 120] [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `/home/runner/work/bluez/bluez/src/src/client/bluetoothctl -a auto:NoInputNoOutput --init-script /home/runner/work/bluez/bluez/src/src/test/../client/scripts/bap-sink-lc3-right.bt'. Program terminated with signal SIGABRT, Aborted. #0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44 warning: 44 ./nptl/pthread_kill.c: No such file or directory Thread 1 (Thread 0x7fba8f957d40 (LWP 120)): #0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44 tid = <optimized out> ret = 0 pd = <optimized out> old_mask = {__val = {140730558660480}} ret = <optimized out> #1 __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:89 No locals. #2 __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:100 No locals. #3 0x00007fba8ff96b7e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 ret = <optimized out> #4 0x00007fba8ff798ec in __GI_abort () at ./stdlib/abort.c:77 act = {__sigaction_handler = {sa_handler = 0x7c2a8ede1440, sa_sigaction = 0x7c2a8ede1440}, sa_mask = {__val = {140439258023203, 140730558660496, 140439256476592, 7791336406271877491, 140439258023072, 140730558660576, 140439267555473, 140439268605984, 140439246334784, 0, 140439258023072, 4294967295, 140439239786496, 140730558660624, 140439256147459, 140439258023072}}, sa_flags = -1897983936, sa_restorer = 0x7cda8ede01c0} #5 0x00007fba907f7fe2 in ?? () from /usr/lib/x86_64-linux-gnu/libdbus-1.so.3 No symbol table info available. #6 0x00007fba908234c1 in _dbus_warn_check_failed () from /usr/lib/x86_64-linux-gnu/libdbus-1.so.3 No symbol table info available. #7 0x000055a7c4f7200a in cancel_request (conn=<optimized out>, msg=0x7cba8edf1040, user_data=<optimized out>) at client/agent.c:258 No locals. #8 0x000055a7c5006131 in process_message (connection=0x7cda8ede01c0, message=0x7cba8edf1040, method=0x55a7c50e75e0 <auto_methods+320>, iface_user_data=<optimized out>) at gdbus/object.c:293 reply = <optimized out> #9 0x00007fba908040f4 in dbus_connection_dispatch () from /usr/lib/x86_64-linux-gnu/libdbus-1.so.3 No symbol table info available. #10 0x000055a7c4ff5d98 in message_dispatch (data=0x7cda8ede01c0) at gdbus/mainloop.c:59 conn = 0x7cda8ede01c0 #11 0x00007fba9089bb9b in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 No symbol table info available. #12 0x00007fba9089d1d7 in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 No symbol table info available. #13 0x00007fba9089d577 in g_main_loop_run () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 No symbol table info available. #14 0x000055a7c5039539 in mainloop_run () at src/shared/mainloop-glib.c:65 No locals. #15 0x000055a7c5039e6b in mainloop_run_with_signal (func=func@entry=0x55a7c5030eb0 <signal_callback>, user_data=user_data@entry=0x0) at src/shared/mainloop-notify.c:196 data = 0x7bea8ede1810 io = 0x7bfa8ede1f50 ret = <optimized out> #16 0x000055a7c503508c in bt_shell_run () at src/shared/shell.c:1476 status = <optimized out> submenu = <optimized out> #17 0x000055a7c4f5a915 in main (argc=<optimized out>, argv=<optimized out>) at client/main.c:4228 client = 0x7cba8ede0440 status = <optimized out> timeout = <optimized out> timeout_id = <optimized out>" https://github.com/bluez/bluez/pull/2570 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported 2026-09-23 8:00 [PATCH BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported Frédéric Danis 2026-09-23 11:04 ` [BlueZ] " bluez.test.bot @ 2026-09-23 13:55 ` Luiz Augusto von Dentz 2026-09-23 14:27 ` Frédéric Danis 1 sibling, 1 reply; 4+ messages in thread From: Luiz Augusto von Dentz @ 2026-09-23 13:55 UTC (permalink / raw) To: Frédéric Danis; +Cc: linux-bluetooth Hi Frederic, On Wed, Sep 23, 2026 at 4:02 AM Frédéric Danis <frederic.danis@collabora.com> wrote: > > Some remote targets do not support the AVRCP_EVENT_PLAYBACK_POS_CHANGED > notification, meaning bluetoothd never learns about track position > updates for such devices. > > When this event is not present in the capabilities reported by the > remote, fall back to polling AVRCP_GET_PLAY_STATUS once a second so > the media player position stays in sync. Polling is only kept running > while playback is actively progressing (playing/forward-seek/ > reverse-seek) and is stopped otherwise, and is torn down on session > destruction. Back in the days AVRCP was introduced we decided not to poll the status and instead have the upper layer trigger it via https://github.com/bluez/bluez/blob/master/doc/org.bluez.MediaPlayer.rst#uint32-position-readonly, that said I do agree that perhaps it is better to it with directly by bluetoothd since so many years have passed and some manufactorers insist in not having AVRCP_EVENT_PLAYBACK_POS_CHANGED implemented. > Assisted-by: Copilot CLI:claude-sonnet-5 > --- > profiles/audio/avrcp.c | 64 +++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 63 insertions(+), 1 deletion(-) > > diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c > index df5f97eaf..105538cdc 100644 > --- a/profiles/audio/avrcp.c > +++ b/profiles/audio/avrcp.c > @@ -247,7 +247,9 @@ struct avrcp { > unsigned int control_id; > unsigned int browsing_id; > unsigned int browsing_timer; > + unsigned int position_timer; > uint16_t supported_events; > + bool pos_changed_supported; > uint8_t transaction; > struct pending_pdu *pending_pdu; > }; > @@ -341,6 +343,7 @@ static const uint32_t company_ids[] = { > > static void avrcp_register_notification(struct avrcp *session, uint8_t event); > static GList *player_list_settings(struct avrcp_player *player); > +static void avrcp_get_play_status(struct avrcp *session); > > static void avrcp_browsing_record(sdp_record_t *record, sdp_data_t *version) > { > @@ -2224,6 +2227,56 @@ static const char *status_to_string(uint8_t status) > } > } > > +static bool avrcp_poll_play_status(gpointer user_data) > +{ > + struct avrcp *session = user_data; > + > + avrcp_get_play_status(session); > + > + return TRUE; > +} > + > +static void avrcp_stop_pos_polling(struct avrcp *session) > +{ > + if (session->position_timer == 0) > + return; > + > + timeout_remove(session->position_timer); > + session->position_timer = 0; > +} > + > +static void avrcp_start_pos_polling(struct avrcp *session) > +{ > + if (session->position_timer > 0) > + return; > + > + session->position_timer = timeout_add_seconds(1, > + avrcp_poll_play_status, > + session, NULL); > +} > + > +/* > + * Poll GetPlayStatus once a second to resync position while playing when > + * the remote does not support AVRCP_EVENT_PLAYBACK_POS_CHANGED. Polling is > + * paused whenever playback is not actively progressing. > + */ > +static void avrcp_update_pos_polling(struct avrcp *session, uint8_t status) > +{ > + if (session->pos_changed_supported) > + return; > + > + switch (status) { > + case AVRCP_PLAY_STATUS_PLAYING: > + case AVRCP_PLAY_STATUS_FWD_SEEK: > + case AVRCP_PLAY_STATUS_REV_SEEK: > + avrcp_start_pos_polling(session); Btw, if I recall correctly, position tracking really breaks when the user seeks the stream using the player progression bar, which interrupts the continuous timer. So, if the player does either AVRCP_PLAY_STATUS_FWD_SEEK or AVRCP_PLAY_STATUS_REV_SEEK then we can resink the position once, afaik iOS media player doesn't use them either, thus why the whole polling thing is needed to capture non continuguos skips that are not advertised. > + break; > + default: > + avrcp_stop_pos_polling(session); > + break; > + } > +} > + > static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, > uint8_t subunit, uint8_t transaction, > uint8_t *operands, size_t operand_count, > @@ -2252,6 +2305,8 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, > media_player_set_position(mp, position); > media_player_set_status(mp, status_to_string(status)); > > + avrcp_update_pos_polling(session, status); > + > return FALSE; > } > > @@ -4128,6 +4183,9 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code, > } > } > > + session->pos_changed_supported = > + !!(events & (1 << AVRCP_EVENT_PLAYBACK_POS_CHANGED)); > + > if (!session->controller || !session->controller->player) > return FALSE; > > @@ -4140,7 +4198,8 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code, > !(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED))) > avrcp_list_player_attributes(session); > > - if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED))) > + if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)) || > + !session->pos_changed_supported) > avrcp_get_play_status(session); > > if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED))) > @@ -4470,6 +4529,9 @@ static void session_destroy(struct avrcp *session, int err) > if (session->browsing_timer > 0) > timeout_remove(session->browsing_timer); > > + if (session->position_timer > 0) > + timeout_remove(session->position_timer); > + > if (session->controller != NULL) > controller_destroy(session); > > -- > 2.43.0 > > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported 2026-09-23 13:55 ` [PATCH BlueZ] " Luiz Augusto von Dentz @ 2026-09-23 14:27 ` Frédéric Danis 0 siblings, 0 replies; 4+ messages in thread From: Frédéric Danis @ 2026-09-23 14:27 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: linux-bluetooth Hi Luiz, On 23/09/2026 15:55, Luiz Augusto von Dentz wrote: > Hi Frederic, > > On Wed, Sep 23, 2026 at 4:02 AM Frédéric Danis > <frederic.danis@collabora.com> wrote: >> Some remote targets do not support the AVRCP_EVENT_PLAYBACK_POS_CHANGED >> notification, meaning bluetoothd never learns about track position >> updates for such devices. >> >> When this event is not present in the capabilities reported by the >> remote, fall back to polling AVRCP_GET_PLAY_STATUS once a second so >> the media player position stays in sync. Polling is only kept running >> while playback is actively progressing (playing/forward-seek/ >> reverse-seek) and is stopped otherwise, and is torn down on session >> destruction. > Back in the days AVRCP was introduced we decided not to poll the > status and instead have the upper layer trigger it via > https://github.com/bluez/bluez/blob/master/doc/org.bluez.MediaPlayer.rst#uint32-position-readonly, > that said I do agree that perhaps it is better to it with directly by > bluetoothd since so many years have passed and some manufactorers > insist in not having AVRCP_EVENT_PLAYBACK_POS_CHANGED implemented. This property may be cached by the DBus framework used, and so iiuc reading it will not trigger GetPlayStatus. >> Assisted-by: Copilot CLI:claude-sonnet-5 >> --- >> profiles/audio/avrcp.c | 64 +++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 63 insertions(+), 1 deletion(-) >> >> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c >> index df5f97eaf..105538cdc 100644 >> --- a/profiles/audio/avrcp.c >> +++ b/profiles/audio/avrcp.c >> @@ -247,7 +247,9 @@ struct avrcp { >> unsigned int control_id; >> unsigned int browsing_id; >> unsigned int browsing_timer; >> + unsigned int position_timer; >> uint16_t supported_events; >> + bool pos_changed_supported; >> uint8_t transaction; >> struct pending_pdu *pending_pdu; >> }; >> @@ -341,6 +343,7 @@ static const uint32_t company_ids[] = { >> >> static void avrcp_register_notification(struct avrcp *session, uint8_t event); >> static GList *player_list_settings(struct avrcp_player *player); >> +static void avrcp_get_play_status(struct avrcp *session); >> >> static void avrcp_browsing_record(sdp_record_t *record, sdp_data_t *version) >> { >> @@ -2224,6 +2227,56 @@ static const char *status_to_string(uint8_t status) >> } >> } >> >> +static bool avrcp_poll_play_status(gpointer user_data) >> +{ >> + struct avrcp *session = user_data; >> + >> + avrcp_get_play_status(session); >> + >> + return TRUE; >> +} >> + >> +static void avrcp_stop_pos_polling(struct avrcp *session) >> +{ >> + if (session->position_timer == 0) >> + return; >> + >> + timeout_remove(session->position_timer); >> + session->position_timer = 0; >> +} >> + >> +static void avrcp_start_pos_polling(struct avrcp *session) >> +{ >> + if (session->position_timer > 0) >> + return; >> + >> + session->position_timer = timeout_add_seconds(1, >> + avrcp_poll_play_status, >> + session, NULL); >> +} >> + >> +/* >> + * Poll GetPlayStatus once a second to resync position while playing when >> + * the remote does not support AVRCP_EVENT_PLAYBACK_POS_CHANGED. Polling is >> + * paused whenever playback is not actively progressing. >> + */ >> +static void avrcp_update_pos_polling(struct avrcp *session, uint8_t status) >> +{ >> + if (session->pos_changed_supported) >> + return; >> + >> + switch (status) { >> + case AVRCP_PLAY_STATUS_PLAYING: >> + case AVRCP_PLAY_STATUS_FWD_SEEK: >> + case AVRCP_PLAY_STATUS_REV_SEEK: >> + avrcp_start_pos_polling(session); > Btw, if I recall correctly, position tracking really breaks when the > user seeks the stream using the player progression bar, which > interrupts the continuous timer. So, if the player does either > AVRCP_PLAY_STATUS_FWD_SEEK or AVRCP_PLAY_STATUS_REV_SEEK then we can > resink the position once, afaik iOS media player doesn't use them > either, thus why the whole polling thing is needed to capture non > continuguos skips that are not advertised. > >> + break; >> + default: >> + avrcp_stop_pos_polling(session); >> + break; >> + } >> +} >> + >> static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, >> uint8_t subunit, uint8_t transaction, >> uint8_t *operands, size_t operand_count, >> @@ -2252,6 +2305,8 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, >> media_player_set_position(mp, position); >> media_player_set_status(mp, status_to_string(status)); >> >> + avrcp_update_pos_polling(session, status); >> + >> return FALSE; >> } >> >> @@ -4128,6 +4183,9 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code, >> } >> } >> >> + session->pos_changed_supported = >> + !!(events & (1 << AVRCP_EVENT_PLAYBACK_POS_CHANGED)); >> + >> if (!session->controller || !session->controller->player) >> return FALSE; >> >> @@ -4140,7 +4198,8 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code, >> !(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED))) >> avrcp_list_player_attributes(session); >> >> - if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED))) >> + if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)) || >> + !session->pos_changed_supported) >> avrcp_get_play_status(session); >> >> if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED))) >> @@ -4470,6 +4529,9 @@ static void session_destroy(struct avrcp *session, int err) >> if (session->browsing_timer > 0) >> timeout_remove(session->browsing_timer); >> >> + if (session->position_timer > 0) >> + timeout_remove(session->position_timer); >> + >> if (session->controller != NULL) >> controller_destroy(session); >> >> -- >> 2.43.0 >> >> > -- Frédéric Danis Senior Software Engineer Collabora Ltd. Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, United Kingdom Registered in England & Wales, no. 5513718 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-23 14:27 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-23 8:00 [PATCH BlueZ] audio/avrcp: Poll GetPlayStatus when position changed event unsupported Frédéric Danis 2026-09-23 11:04 ` [BlueZ] " bluez.test.bot 2026-09-23 13:55 ` [PATCH BlueZ] " Luiz Augusto von Dentz 2026-09-23 14:27 ` Frédéric Danis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox