audio: check for USB device state when opening in/out stream

Check for USB headset device state when opening in/out stream,
and report error if USB headset is not in connected state. That's
to handle error condition gracefully to avoid further crashes in
audio flinger.

Change-Id: Ib33489fec00ac0b5c500fc1fa2dbeb021b51cbef
CRs-Fixed: 2261252
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index b7bf22a..9338bc9 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1436,7 +1436,7 @@
     struct usb_card_config *usb_card_info = NULL;
     bool usb_connected = false;
 
-    if (str_parms_get_int(parms, "card", &card) >= 0) {
+    if ((parms != NULL) && str_parms_get_int(parms, "card", &card) >= 0) {
         usb_connected = audio_extn_usb_alive(card);
     } else {
         list_for_each(node_i, &usbmod->usb_card_conf_list) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 3152669..f07a3ce 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -5770,6 +5770,14 @@
            ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
            ret = read_hdmi_sink_caps(out);
        } else if (is_usb_dev) {
+            /* Check against usb headset connection state */
+            if (!audio_extn_usb_connected(NULL)) {
+                ALOGD("%s: usb headset unplugged", __func__);
+                ret = -EINVAL;
+                pthread_mutex_unlock(&adev->lock);
+                goto error_open;
+            }
+
             ret = read_usb_sup_params_and_compare(true /*is_playback*/,
                                                   &config->format,
                                                   &out->supported_formats[0],
@@ -6904,6 +6912,16 @@
     }
 
     if (is_usb_dev && may_use_hifi_record) {
+        /* Check against usb headset connection state */
+        pthread_mutex_lock(&adev->lock);
+        if (!audio_extn_usb_connected(NULL)) {
+            ALOGD("%s: usb headset unplugged", __func__);
+            ret = -EINVAL;
+            pthread_mutex_unlock(&adev->lock);
+            goto err_open;
+        }
+        pthread_mutex_unlock(&adev->lock);
+
         /* HiFi record selects an appropriate format, channel, rate combo
            depending on sink capabilities*/
         ret = read_usb_sup_params_and_compare(false /*is_playback*/,