Android source code pit avoidance Guide 9 - AVRCP connection status is abnormal

Keywords: Android bluetooth bt

AVRCP connection status is abnormal

Android version: android-9 (P version)

Problem phenomenon: disconnect the device and fail to issue Bluetooth adapter.action for a long time_ CONNECTION_ STATE_ The changed broadcast switches the connection status to Bluetooth adapter.state_ DISCONNECTED

After checking the log, it can be found that all major protocols have been disconnected. Why didn't the above broadcast be sent in time?

The broadcast is triggered in AdapterProperties.sendConnectionStateChange(). If it is not triggered, it means that the if condition is not satisfied

if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
	int newAdapterState = convertToAdapterState(state);
	int prevAdapterState = convertToAdapterState(prevState);
	setConnectionState(newAdapterState);

	Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
	intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
	intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, newAdapterState);
    intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, prevAdapterState);
	intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
	Log.i(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: " + device + ": " + prevAdapterState
			+ " -> " + newAdapterState);
	if (!isNormalStateTransition(prevState, state)) {
		Log.w(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile="
				+ profile + ", device=" + device + ", " + prevState + " -> " + state);
	}
	mService.sendBroadcastAsUser(intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
}

The updateCountersAndCheckForConnectionStateChange() function returns true only when all connected protocols are disconnected in the device disconnection phase. This indicates that there are still protocols that are not disconnected, and the avrcp protocol is not disconnected in combination with the log basic locking.

The disconnection of AVRCP protocol completely follows the A2DP protocol. The log shows that there is no connection record in the protocol stack when AVRCP is disconnected, btif_rc_get_device_by_handle() returns NULL.

That means avrcp is not connected at all. Why does the Bluetooth service layer save the status of successful avrcp connection?

Continue to analyze the process of active connection of SINK to avrcp after A2DP connection. BTA is received when the state machine of A2DP connection is StateOpening_ AV_ OPEN_ Calling BTA_ in EVT event Avopenrc() triggers the connection of avrcp.

First, SDP service discovery is performed for protocol connection. From the log, you can also see that an l2cap link is created with psm= 0x0001.

When this l2cap link requests a connection, the peer replies to the PEER_CONNECT_RSP_NEG rejected, so the avrcp protocol connection failed

Here's the point. Why did avrcp s report the status of successful connection to the service layer when they failed to connect...

Trace handle_rc_connect() processing function. It is found that there is a problem with the handling of failures in the code. Regardless of success or failure, it will always report the status of successful connection to the upper layer

The problem is clear here. Due to the failure of the above function processing, the connection status of avrcp between the Bluetooth service layer and the protocol stack does not match. Finally, when the device is disconnected, the service layer always thinks that the connection status of avrcp protocol is CONNECTED and never sends BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED disconnects the completed broadcast. Interested partners are welcome to discuss, learn and make progress together!

More interconnected technology, welcome to WeChat official account: Connectivity

Posted by subrata on Wed, 10 Nov 2021 19:42:32 -0800