pal: retry all active streams with BT_IN suspendedDevIds in a2dpCaptureResume
-In a corner case of HFP voip call and IN_A2DP LEA stereo record
concurrency where LEA recording is not restored after stop VoIP
call because IN_A2DP was not in ready state during explicit
switch from APM and resulted record stream associated with SCO
device never routed back to IN_A2DP.
-Thus when a2dpCaptureResume=false setparam receives, add IN_A2DP
device as a suspendDevId for all active streams associated
with SCO_IN path and route them later to IN_A2DP device accordingly.
Change-Id: I5fdd92af312ec30cb45390b7737d62ae67dc9b1c
(cherry picked from commit f8267d37c9d9869826e873e2b746e889175fe8ec)
diff --git a/resource_manager/src/ResourceManager.cpp b/resource_manager/src/ResourceManager.cpp
index 61d7ed2..ffd926e 100644
--- a/resource_manager/src/ResourceManager.cpp
+++ b/resource_manager/src/ResourceManager.cpp
@@ -8983,7 +8983,7 @@
}
getOrphanStream_l(orphanStreams, retryStreams);
- if (activeStreams.empty() && orphanStreams.empty()) {
+ if (activeStreams.empty() && orphanStreams.empty() && retryStreams.empty()) {
PAL_DBG(LOG_TAG, "no active streams found");
mActiveStreamMutex.unlock();
goto exit;
@@ -9009,6 +9009,24 @@
}
}
+ // retry all streams which failed to switch to desired device previously.
+ for (sIter = retryStreams.begin(); sIter != retryStreams.end(); sIter++) {
+ (*sIter)->lockStreamMutex();
+ if (std::find((*sIter)->suspendedDevIds.begin(), (*sIter)->suspendedDevIds.end(),
+ a2dpDattr.id) != (*sIter)->suspendedDevIds.end()) {
+ std::vector<std::shared_ptr<Device>> devices;
+ (*sIter)->getAssociatedDevices(devices);
+ if (devices.size() > 0) {
+ for (auto device : devices) {
+ streamDevDisconnect.push_back({ (*sIter), device->getSndDeviceId() });
+ }
+ }
+ restoredStreams.push_back((*sIter));
+ streamDevConnect.push_back({ (*sIter), &a2dpDattr });
+ }
+ (*sIter)->unlockStreamMutex();
+ }
+
if (restoredStreams.empty()) {
PAL_DBG(LOG_TAG, "no streams to be restored");
mActiveStreamMutex.unlock();
@@ -9981,6 +9999,11 @@
struct pal_stream_attributes sAttr;
Stream* stream = NULL;
std::vector<Stream*> activestreams;
+ struct pal_device sco_tx_dattr;
+ std::shared_ptr<Device> sco_tx_dev = nullptr;
+ std::vector<Stream*>::iterator sIter;
+ pal_stream_type_t streamType;
+
mActiveStreamMutex.lock();
sco_rx_dattr.id = PAL_DEVICE_OUT_BLUETOOTH_SCO;
@@ -10001,6 +10024,26 @@
mActiveStreamMutex.lock();
}
}
+
+ /* Handle bt sco running usecase */
+ sco_tx_dattr.id = PAL_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+ if (isDeviceAvailable(sco_tx_dattr.id)) {
+ sco_tx_dev = Device::getInstance(&sco_tx_dattr, rm);
+ getActiveStream_l(activestreams, sco_tx_dev);
+ for (sIter = activestreams.begin(); sIter != activestreams.end(); sIter++) {
+ status = (*sIter)->getStreamType(&streamType);
+ if (0 != status) {
+ PAL_ERR(LOG_TAG, "getStreamType failed with status = %d", status);
+ continue;
+ }
+ if ((streamType == PAL_STREAM_VOIP_TX) ||
+ (streamType == PAL_STREAM_DEEP_BUFFER)) {
+ (*sIter)->suspendedDevIds.clear();
+ (*sIter)->suspendedDevIds.push_back(a2dp_dattr.id);
+ PAL_DBG(LOG_TAG, "a2dp resumed, mark sco streams as to route them later");
+ }
+ }
+ }
mActiveStreamMutex.unlock();
}