Deadlock when closing library
This is a customer problem report:

> We have seen some ANRs related to ably in our Android app.

> This is not a new issue but we never looked at it properly before.

> This is the log:

```at
- waiting to lock <0x0333b0a8> (a io.ably.lib.transport.ConnectionManager) held by thread 63

  at io.ably.lib.transport.ConnectionManager.requestState (ConnectionManager.java:307)
  at io.ably.lib.transport.ConnectionManager.close (ConnectionManager.java:221)
  at io.ably.lib.realtime.Connection.close (Connection.java:71)
  at io.ably.lib.realtime.AblyRealtime.close (AblyRealtime.java:70)
  at com.hubspot.android.conversations.realtime.ably.AblyRealTimeClient.close (AblyRealTimeClient.kt:83)
  at com.hubspot.android.conversations.realtime.PubSubV2ClientImpl.close (PubSubV2ClientImpl.kt:51)
  at com.hubspot.android.conversations.realtime.PubSubLifecycleObserverImpl.disconnect (PubSubLifecycleObserverImpl.kt:34)
  at com.hubspot.android.conversations.realtime.PubSubLifecycleObserverImpl_LifecycleAdapter.callMethods (PubSubLifecycleObserverImpl_LifecycleAdapter.java:33)```

> We call the close in the Android lifecycle observer (ProcessLifecycleOwner)

```@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun disconnect() {
  pubSubV2Client.close()
}```

> And this method will only call close if the connection is not closed or initialized:

```if (realtime.connection.state != ConnectionState.closed && realtime.connection.state != ConnectionState.initialized) {
  Logger.debugLog("Closing connection state: ${realtime.connection.state}")
  realtime.close()
}
```

> Do you know what could be the issue here?

On the face of it, something is holding the `ConnectionManager` lock long-term. We don't know if this is somehow connected with the lifecycle event or not.



┆Issue is synchronized with this [Jira Bug](https://ably.atlassian.net/browse/SDK-428) by [Unito](https://www.unito.io)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7af6d94d..5a6006fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
 # Change Log
 
+## [1.2.31](https://github.com/ably/ably-java/tree/v1.2.31)
+
+[Full Changelog](https://github.com/ably/ably-java/compare/v1.2.30...v1.2.31)
+
+**Fixed bugs:**
+
+- Update error code for channel attachment timed out [\#959](https://github.com/ably/ably-java/issues/959)
+- Update error code for message decoding failure [\#958](https://github.com/ably/ably-java/issues/958)
+- Fix incremental backoff while reconnecting [\#954](https://github.com/ably/ably-java/issues/954)
+- Add `suspendedRetryTimeout` and `httpMaxRetryDuration` client options [\#956](https://github.com/ably/ably-java/issues/956)
+
+**Merged pull requests:**
+
+- fix: use appropriate error code for channel attachment timeout [\#961](https://github.com/ably/ably-java/pull/961) ([AndyTWF](https://github.com/AndyTWF))
+- fix: use error code 40013 for message decoding failures [\#960](https://github.com/ably/ably-java/pull/960) ([AndyTWF](https://github.com/AndyTWF))
+- Fix incremental backoff jitter [\#955](https://github.com/ably/ably-java/pull/955) ([sacOO7](https://github.com/sacOO7))
+- Add missing clientOptions [\#957](https://github.com/ably/ably-java/pull/957) ([sacOO7](https://github.com/sacOO7))
+
 ## [1.2.30](https://github.com/ably/ably-java/tree/v1.2.30)
 
 [Full Changelog](https://github.com/ably/ably-java/compare/v1.2.29...v1.2.30)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bc017fb2..ed48565d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -191,7 +191,7 @@ You may wish to make changes to Ably Java or Ably Android, and test it immediate
 - Open the directory printed from the output of that command. Inside that folder, get the `ably-android-x.y.z.aar`, and place it your Android project's `libs/` directory. Create this directory if it doesn't exist.
 - Add an `implementation` dependency on the `.aar`:
 ```groovy
-implementation files('libs/ably-android-1.2.30.aar')
+implementation files('libs/ably-android-1.2.31.aar')
 ```
 - Add the `implementation` (not `testImplementation`) dependencies found in `dependencies.gradle` to your project. This is because the `.aar` does not contain dependencies.
 - Build/run your application.
diff --git a/README.md b/README.md
index ce1e3848..f1298d02 100644
--- a/README.md
+++ b/README.md
@@ -20,13 +20,13 @@ Include the library by adding an `implementation` reference to `dependencies` bl
 For [Java](https://mvnrepository.com/artifact/io.ably/ably-java/latest):
 
 ```groovy
-implementation 'io.ably:ably-java:1.2.30'
+implementation 'io.ably:ably-java:1.2.31'
 ```
 
 For [Android](https://mvnrepository.com/artifact/io.ably/ably-android/latest):
 
 ```groovy
-implementation 'io.ably:ably-android:1.2.30'
+implementation 'io.ably:ably-android:1.2.31'
 ```
 
 The library is hosted on [Maven Central](https://mvnrepository.com/repos/central), so you need to ensure that the repository is referenced also; IDEs will typically include this by default:
diff --git a/android/build.gradle b/android/build.gradle
index 87d7ba09..f5b4cfbb 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -31,7 +31,7 @@ android {
         minSdkVersion 19
         targetSdkVersion 30
         // This MUST be incremented by 1 on each ably-java release
-        versionCode 5
+        versionCode 6
         versionName version
         setProperty('archivesBaseName', "ably-android-$versionName")
         testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
diff --git a/common.gradle b/common.gradle
index 926dcab6..76f80dd4 100644
--- a/common.gradle
+++ b/common.gradle
@@ -3,7 +3,7 @@ repositories {
 }
 
 group = 'io.ably'
-version = '1.2.30'
+version = '1.2.31'
 description = 'Ably java client library'
 
 tasks.withType(Javadoc) {
diff --git a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeHttpHeaderTest.java b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeHttpHeaderTest.java
index 91152a13..e3f13b0c 100644
--- a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeHttpHeaderTest.java
+++ b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeHttpHeaderTest.java
@@ -88,7 +88,7 @@ public class RealtimeHttpHeaderTest extends ParameterizedTest {
              * Defaults.ABLY_AGENT_PARAM, as ultimately the request param has been derived from those values.
              */
             assertEquals("Verify correct lib version", requestParameters.get("agent"),
-                    Collections.singletonList("ably-java/1.2.30 jre/" + System.getProperty("java.version")));
+                    Collections.singletonList("ably-java/1.2.31 jre/" + System.getProperty("java.version")));
 
             /* Spec RTN2a */
             assertEquals("Verify correct format", requestParameters.get("format"),
['README.md', 'android/build.gradle', 'CHANGELOG.md', 'CONTRIBUTING.md', 'lib/src/test/java/io/ably/lib/test/realtime/RealtimeHttpHeaderTest.java', 'common.gradle']