Merge "Pal: remove repeated initialization for target_sample_rate"
diff --git a/resource_manager/inc/ResourceManager.h b/resource_manager/inc/ResourceManager.h
index e0c592b..b228ef6 100644
--- a/resource_manager/inc/ResourceManager.h
+++ b/resource_manager/inc/ResourceManager.h
@@ -814,6 +814,13 @@
std::vector<std::pair<int32_t, std::string>> &txBackEndNames) const;
bool updateDeviceConfig(std::shared_ptr<Device> *inDev,
struct pal_device *inDevAttr, const pal_stream_attributes* inStrAttr);
+ int findActiveStreamsNotInDisconnectList(
+ std::vector <std::tuple<Stream *, uint32_t>> &streamDevDisconnectList,
+ std::vector <std::tuple<Stream *, uint32_t>> &streamsSkippingSwitch);
+ int restoreDeviceConfigForUPD(
+ std::vector <std::tuple<Stream *, uint32_t>> &streamDevDisconnect,
+ std::vector <std::tuple<Stream *, struct pal_device *>> &StreamDevConnect,
+ std::vector <std::tuple<Stream *, uint32_t>> &streamsSkippingSwitch);
int32_t forceDeviceSwitch(std::shared_ptr<Device> inDev, struct pal_device *newDevAttr);
int32_t forceDeviceSwitch(std::shared_ptr<Device> inDev, struct pal_device *newDevAttr,
std::vector <Stream *> prevActiveStreams);
diff --git a/resource_manager/src/ResourceManager.cpp b/resource_manager/src/ResourceManager.cpp
index ec4dba3..5cc45d5 100644
--- a/resource_manager/src/ResourceManager.cpp
+++ b/resource_manager/src/ResourceManager.cpp
@@ -7172,6 +7172,15 @@
case PAL_DEVICE_OUT_HANDSET:
case PAL_DEVICE_OUT_SPEAKER:
ret = true;
+ /*
+ * if upd shares BE with handset, while handset doesn't
+ * share BE with speaker, then during device switch
+ * between handset and speaker, upd should still stay
+ * on handset
+ */
+ if (listAllBackEndIds[PAL_DEVICE_OUT_HANDSET].second !=
+ listAllBackEndIds[PAL_DEVICE_OUT_SPEAKER].second)
+ ret = false;
break;
default:
ret = false;
@@ -7196,6 +7205,196 @@
return ret;
}
+/*
+ * Due to compatibility challenges, some streams may not switch to the new device
+ * during device switching.
+ * Example: In the shared backend configuration, the UPD stream prevents switching
+ * to devices other than the handset or speaker.
+ * In this function, we compare the list of streams in streamDevDisconnectList
+ * to the streams that are currently active on that device.
+ * The streamsSkippingSwitch list consists of any stream that is present in the
+ * active streams list but missing from the list of disconnecting streams.
+ */
+int ResourceManager::findActiveStreamsNotInDisconnectList(
+ std::vector <std::tuple<Stream *, uint32_t>> &streamDevDisconnectList,
+ std::vector <std::tuple<Stream *, uint32_t>> &streamsSkippingSwitch)
+{
+ std::set<Stream *> disconnectingStreams;
+ std::vector <std::tuple<Stream *, uint32_t>>::iterator iter;
+ std::shared_ptr<Device> devObj = nullptr;
+ struct pal_device dAttr;
+ std::vector<Stream*> activeStreams;
+ std::vector<Stream*>::iterator sIter;
+ int ret = 0;
+
+ if (streamDevDisconnectList.size() == 0) {
+ PAL_DBG(LOG_TAG, "Empty stream disconnect list");
+ return ret;
+ }
+
+ /*
+ * To facilitate comparisons against the list of active streams simpler,
+ * construct a set of streams that are disconnecting from streamDevDisconnectList
+ */
+ for (iter = streamDevDisconnectList.begin();
+ iter != streamDevDisconnectList.end(); iter++) {
+ disconnectingStreams.insert(std::get<0>(*iter));
+ }
+
+ /*
+ * Instance of a device object from which the active stream list is retrieved.
+ * It's the same device from which streams in 'disconnectingStreams' are
+ * disconnecting.
+ */
+ dAttr.id = (pal_device_id_t)std::get<1>(streamDevDisconnectList[0]);
+ devObj = Device::getInstance(&dAttr, rm);
+ if (devObj == nullptr) {
+ PAL_DBG(LOG_TAG, "Error getting device ( %s ) instance",
+ deviceNameLUT.at(dAttr.id).c_str());
+ return ret;
+ }
+
+ mActiveStreamMutex.lock();
+
+ ret = rm->getActiveStream_l(activeStreams, devObj);
+ if (ret)
+ goto done;
+
+ PAL_DBG(LOG_TAG, "activeStreams size = %d, device: %s", activeStreams.size(),
+ deviceNameLUT.at((pal_device_id_t)devObj->getSndDeviceId()).c_str());
+
+ for (sIter = activeStreams.begin(); sIter != activeStreams.end(); sIter++) {
+ if (disconnectingStreams.find(*sIter) != disconnectingStreams.end())
+ continue;
+
+ /*
+ * Stream that is present in the active streams list but not in the list
+ * of disconnecting streams, contribute to the streamsSkippingSwitch list.
+ */
+ streamsSkippingSwitch.push_back({(*sIter), dAttr.id});
+ }
+
+done:
+ mActiveStreamMutex.unlock();
+ return ret;
+}
+
+/*
+ * For shared backend setup, it's crucial to restore the correct device configuration
+ * for the UPD stream.
+ *
+ * Example 1: As music is being played on the speaker, the UPD stream begins (on
+ * the speaker). The Music stream switches to the new device when a wired headset
+ * or a BT device is connected. In this scenario, the UPD stream will be the only
+ * active stream on Speaker device. Thus, we must ensure to switch it from Speaker
+ * (NLPI) to Handset(LPI).
+ *
+ * Example 2: During a voice call concurrency with the UPD stream, when a wired
+ * headset or a BT device is connected, The voice call stream switches to the new
+ * device and the UPD continues to run on the handset device. In this case, we
+ * configure the handset device to make it compatible to UPD only stream.
+ */
+int ResourceManager::restoreDeviceConfigForUPD(
+ std::vector <std::tuple<Stream *, uint32_t>> &streamDevDisconnect,
+ std::vector <std::tuple<Stream *, struct pal_device *>> &StreamDevConnect,
+ std::vector <std::tuple<Stream *, uint32_t>> &streamsSkippingSwitch)
+{
+ int ret = 0;
+ static struct pal_device dAttr; //struct reference is passed in StreamDevConnect.
+ struct pal_device curDevAttr = {};
+ std::shared_ptr<Device> hs_dev = nullptr;
+ uint32_t devId;
+ Stream *s;
+ struct pal_stream_attributes sAttr;
+
+ if (rm->IsDedicatedBEForUPDEnabled() || rm->IsVirtualPortForUPDEnabled()) {
+ PAL_DBG(LOG_TAG, "This UPD config requires no restoration");
+ return ret;
+ }
+
+ if (streamDevDisconnect.size() == 0) {
+ PAL_DBG(LOG_TAG, "Empty disconnect streams list. UPD backend needs no update");
+ return ret;
+ }
+
+ /*
+ * The streams that are skipping the switch to the new device are obtained
+ * using the findActiveStreamsNotInDisconnectList method if not obtained via
+ * the isValidDevicSwitchForStream path.
+ */
+ if (streamsSkippingSwitch.size() == 0) {
+ ret = findActiveStreamsNotInDisconnectList(streamDevDisconnect,
+ streamsSkippingSwitch);
+ if (ret)
+ goto exit_on_error;
+ }
+
+ /*
+ * The UPD stream is allowed to continue running on the device it is configured
+ * for if the streamsSkippingSwitch size is greater than 1.
+ */
+ if (streamsSkippingSwitch.size() == 0 || streamsSkippingSwitch.size() > 1) {
+ PAL_DBG(LOG_TAG, "UPD backend needs no update");
+ return ret;
+ }
+
+ s = std::get<0>(streamsSkippingSwitch[0]);
+ devId = (pal_device_id_t)std::get<1>(streamsSkippingSwitch[0]);
+
+ ret = s->getStreamAttributes(&sAttr);
+ if (ret)
+ goto exit_on_error;
+
+ if (sAttr.type != PAL_STREAM_ULTRASOUND) {
+ PAL_DBG(LOG_TAG, "Not a UPD stream. No UPD backend to update");
+ return ret;
+ }
+
+ memset(&dAttr, 0, sizeof(struct pal_device));
+
+ dAttr.id = PAL_DEVICE_OUT_HANDSET;
+
+ ret = rm->getDeviceConfig(&dAttr, &sAttr);
+ if (ret) {
+ PAL_ERR(LOG_TAG, "Error getting deviceConfig");
+ goto exit_on_error;
+ }
+
+ hs_dev = Device::getObject(PAL_DEVICE_OUT_HANDSET);
+ if (hs_dev)
+ hs_dev->getDeviceAttributes(&curDevAttr);
+
+ if (!doDevAttrDiffer(&dAttr, &curDevAttr)) {
+ PAL_DBG(LOG_TAG, "No need to update device attr for UPD");
+ return ret;
+ }
+
+ /*
+ * We restore the device configuration appropriately if UPD is the only stream
+ * skipping the switch to the new device and will be the only active stream
+ * still present on the current device.
+ *
+ * If the current device is Speaker, the UPD stream is switched from speaker
+ * (NLPI) to handset (LPI).
+ *
+ * If the current device is handset, the device is configured to limit it's
+ * compatibility to UPD stream only.
+ */
+ PAL_DBG(LOG_TAG, "Skipping UPD stream switch to new device. %s",
+ (devId == PAL_DEVICE_OUT_SPEAKER) ?
+ "Restoring UPD from Speaker to Handset device." :
+ "Restoring UPD updating device config for Handset device.");
+
+ streamDevDisconnect.push_back(streamsSkippingSwitch[0]);
+ StreamDevConnect.push_back({s, &dAttr});
+
+ return ret;
+
+exit_on_error:
+ PAL_ERR(LOG_TAG, "Error updating UPD backend");
+ return ret;
+}
+
int32_t ResourceManager::streamDevDisconnect(std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnectList){
int status = 0;
std::vector <std::tuple<Stream *, uint32_t>>::iterator sIter;
@@ -7533,7 +7732,7 @@
{
int status = 0;
std::vector <Stream *> activeStreams;
- std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnect;
+ std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnect, streamsSkippingSwitch;
std::vector <std::tuple<Stream *, struct pal_device *>> streamDevConnect;
std::vector<Stream*>::iterator sIter;
@@ -7553,13 +7752,24 @@
// create dev switch vectors
for (sIter = activeStreams.begin(); sIter != activeStreams.end(); sIter++) {
- if (!isValidDeviceSwitchForStream((*sIter), newDevAttr->id))
+ if (!isValidDeviceSwitchForStream((*sIter), newDevAttr->id)) {
+ streamsSkippingSwitch.push_back({(*sIter), inDev->getSndDeviceId()});
continue;
+ }
streamDevDisconnect.push_back({(*sIter), inDev->getSndDeviceId()});
streamDevConnect.push_back({(*sIter), newDevAttr});
}
+
mActiveStreamMutex.unlock();
+
+ status = rm->restoreDeviceConfigForUPD(streamDevDisconnect, streamDevConnect,
+ streamsSkippingSwitch);
+ if (status) {
+ PAL_DBG(LOG_TAG, "Error restoring device config for UPD");
+ return status;
+ }
+
status = streamDevSwitch(streamDevDisconnect, streamDevConnect);
if (!status) {
mActiveStreamMutex.lock();
@@ -7585,7 +7795,7 @@
std::vector<Stream*> prevActiveStreams)
{
int status = 0;
- std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnect;
+ std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnect, streamsSkippingSwitch;
std::vector <std::tuple<Stream *, struct pal_device *>> streamDevConnect;
std::vector<Stream*>::iterator sIter;
@@ -7598,14 +7808,25 @@
mActiveStreamMutex.lock();
for (sIter = prevActiveStreams.begin(); sIter != prevActiveStreams.end(); sIter++) {
if (((*sIter) != NULL) && isStreamActive((*sIter), mActiveStreams)) {
- if (!isValidDeviceSwitchForStream((*sIter), newDevAttr->id))
+ if (!isValidDeviceSwitchForStream((*sIter), newDevAttr->id)) {
+ streamsSkippingSwitch.push_back({(*sIter), inDev->getSndDeviceId()});
continue;
+ }
streamDevDisconnect.push_back({(*sIter), inDev->getSndDeviceId()});
streamDevConnect.push_back({(*sIter), newDevAttr});
}
}
+
mActiveStreamMutex.unlock();
+
+ status = rm->restoreDeviceConfigForUPD(streamDevDisconnect, streamDevConnect,
+ streamsSkippingSwitch);
+ if (status) {
+ PAL_DBG(LOG_TAG, "Error restoring device config for UPD");
+ return status;
+ }
+
status = streamDevSwitch(streamDevDisconnect, streamDevConnect);
if (!status) {
mActiveStreamMutex.lock();
diff --git a/stream/src/Stream.cpp b/stream/src/Stream.cpp
index 189431d..414711e 100644
--- a/stream/src/Stream.cpp
+++ b/stream/src/Stream.cpp
@@ -1408,7 +1408,7 @@
bool voice_call_switch = false;
uint32_t force_switch_dev_id = PAL_DEVICE_IN_MAX;
uint32_t curDeviceSlots[PAL_DEVICE_IN_MAX], newDeviceSlots[PAL_DEVICE_IN_MAX];
- std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnect, sharedBEStreamDev;
+ std::vector <std::tuple<Stream *, uint32_t>> streamDevDisconnect, sharedBEStreamDev, streamsSkippingSwitch;
std::vector <std::tuple<Stream *, struct pal_device *>> StreamDevConnect;
struct pal_device dAttr;
struct pal_device_info deviceInfo;
@@ -1777,8 +1777,10 @@
}
if (voice_call_switch) {
for (const auto &elem : sharedBEStreamDev) {
- if (!rm->isValidDeviceSwitchForStream(std::get<0>(elem), newDevices[newDeviceSlots[i]].id))
+ if (!rm->isValidDeviceSwitchForStream(std::get<0>(elem), newDevices[newDeviceSlots[i]].id)) {
+ streamsSkippingSwitch.push_back(elem);
continue;
+ }
streamDevDisconnect.push_back(elem);
StreamDevConnect.push_back({std::get<0>(elem), &newDevices[newDeviceSlots[i]]});
@@ -1840,9 +1842,17 @@
rm->unlockActiveStream();
goto done;
}
+
mStreamMutex.unlock();
rm->unlockActiveStream();
+ status = rm->restoreDeviceConfigForUPD(streamDevDisconnect, StreamDevConnect,
+ streamsSkippingSwitch);
+ if (status) {
+ PAL_ERR(LOG_TAG, "Error restoring device config for UPD");
+ goto done;
+ }
+
status = rm->streamDevSwitch(streamDevDisconnect, StreamDevConnect);
if (status) {
PAL_ERR(LOG_TAG, "Device switch failed");