Fix issue 2516842 Device runtime restarts while pairing and connecting A2DP HS.
There are several problems in liba2dp.c:
1 There is a bug in bluetooth_parse_capabilities(): the capabilities field pointer increment
in the while loop is wrong and in case the first capabilities field is not the one we need
we end up reading undefined data.
2 In the same while loop there is no protection for infinite looping if the length of the
capabilities field is 0.
3 When start or configure fail, we just reset state to A2DP_STATE_INITIALIZED to force a new
configuration attempt. This is bad as we don't close the connection and configure expects a
closed connection. Subsequent configure attempts will fail reading sbc capabilites.
4 When there is a problem executing a command in a2dp_thread() loop, we do not reset current command
which prevents from executing the same command again.
Here is what happens in this issue:
There is an error in the A2DP start request because the headset has been disconnected and we go back to configure.
Because of problem 3, the connection is still opened when we run configure again and the 1st capabilitites
field lock indicator is set. We try to read next field and because of problems 1 & 2 we end up looping here for ever.
As data->mutex is locked, it cannot be acquired by pthread_cond_timedwait() trying to exit in
wait_for_start() and the timeout mechanism fails. We stay locked here with A2dpAudioInterface::A2dpAudioStreamOut::mLock also
locked as we are in A2dpAudioInterface::A2dpAudioStreamOut:write().
When system_server tries to disable bluetooth A2DP, A2dpAudioInterface::A2dpAudioStreamOut::setBluetoothEnabled()
tries to acquire mLock and system_server is also deadlocked.
1 file changed