[speech] unbind from recognition service

Currently, we only remove the service reference, but rely on the timeout
built into `ServiceConnector` to actually unbind. This is causing a
service leak.

We also move `SpeechRecognizer#destroy()` to be handled on the Handler
(just like all other calls) in order to fix racing.

Bug: 313604307
Bug: 311124261
Test: cts
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3e14c03272a0e1bfb3b50839efcaae88461b730d)
Merged-In: I5384916da98b286f869a32857079087105ca32f9
Change-Id: I5384916da98b286f869a32857079087105ca32f9
diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
index 96f4a01..2c90649 100644
--- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
+++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
@@ -206,22 +206,16 @@
         synchronized (mLock) {
             ClientState clientState = mClients.get(listener.asBinder());
 
-            if (clientState == null) {
-                if (DEBUG) {
-                    Slog.w(TAG, "#cancel called with no preceding #startListening - ignoring.");
-                }
-                return;
+            if (clientState != null) {
+                clientState.mRecordingInProgress = false;
+                // Temporary reference to allow for resetting mDelegatingListener to null.
+                final IRecognitionListener delegatingListener = clientState.mDelegatingListener;
+                run(service -> service.cancel(delegatingListener, isShutdown));
             }
-            clientState.mRecordingInProgress = false;
-
-            // Temporary reference to allow for resetting the hard link mDelegatingListener to null.
-            final IRecognitionListener delegatingListener = clientState.mDelegatingListener;
-            run(service -> service.cancel(delegatingListener, isShutdown));
 
             // If shutdown, remove the client info from the map. Unbind if that was the last client.
             if (isShutdown) {
                 removeClient(listener);
-
                 if (mClients.isEmpty()) {
                     if (DEBUG) {
                         Slog.d(TAG, "Unbinding from the recognition service.");