Improve A2DP autoreconnect policy

In aosp/1211209 A2DP reconnect policy changed the expected
behaviour where A2DP devices reconnect automatically after BT module
abruptly disconnected. This an important use case for TVs where for
example BT chip can be turned off when device is in standby.
With this small fix most of the previous functionality is covered
allowing reconnect for the corner case when BT state goes directly from
Connected to Disconnected state.
This allows for an improved user experience by allowing A2DP reconnects
when the user didn't intentionally disconnect the BT device.
Teested with A2DP connected device autoreconnects after ATV standby.
This was already soaked in R and S for TVs.

Change-Id: I903c3219c5d510bca3584fbf4c5ac32aa6f67e18
Test: atest PhonePolicyTest#testDisconnectNoAutoConnect
Tag: #compatibility
Bug: 168681496
Bug: 185467510
diff --git a/src/com/android/bluetooth/btservice/PhonePolicy.java b/src/com/android/bluetooth/btservice/PhonePolicy.java
index 9529c51..286c344 100644
--- a/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -339,7 +339,9 @@
                 connectOtherProfile(device);
             }
             if (nextState == BluetoothProfile.STATE_DISCONNECTED) {
-                if (profileId == BluetoothProfile.A2DP) {
+                if (profileId == BluetoothProfile.A2DP
+                        && (prevState == BluetoothProfile.STATE_CONNECTING
+                        || prevState == BluetoothProfile.STATE_DISCONNECTING)) {
                     mDatabaseManager.setDisconnection(device);
                 }
                 handleAllProfilesDisconnected(device);
diff --git a/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java b/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java
index 0b3d2bb..557a720 100644
--- a/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java
+++ b/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java
@@ -233,7 +233,7 @@
         verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(2)), anyBoolean());
         verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(3)), anyBoolean());
 
-        // Disconnect a2dp for the device
+        // Disconnect a2dp for the device from previous STATE_CONNECTED
         when(mHeadsetService.getConnectionState(connectionOrder.get(1))).thenReturn(
                 BluetoothProfile.STATE_DISCONNECTED);
         intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
@@ -244,6 +244,18 @@
         mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent);
         waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
 
+        // Verify that we do not call setConnection, nor setDisconnection on disconnect
+        // from previous STATE_CONNECTED
+        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setConnection(
+                connectionOrder.get(1), true);
+        verify(mDatabaseManager, never()).setDisconnection(connectionOrder.get(1));
+
+        // Disconnect a2dp for the device from previous STATE_DISCONNECTING
+        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
+                BluetoothProfile.STATE_DISCONNECTING);
+        mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent);
+        waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
+
         // Verify that we do not call setConnection, but instead setDisconnection on disconnect
         verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setConnection(
                 connectionOrder.get(1), true);