From 91ab9729aa4f4ca4d2a017062408795051a24059 Mon Sep 17 00:00:00 2001 From: Pierre-Hugues Husson Date: Mon, 5 Aug 2019 18:09:50 +0200 Subject: [PATCH 11/11] Fix BT in-call on CAF devices See https://github.com/phhusson/treble_experimentations/issues/374 In Qualcomm's BSP audio_policy_configuration.xml, one route is missing, from primary output and telephony to BT SCO. Add it if we detect telephony and bt sco, but no such route. --- .../managerdefinitions/src/Serializer.cpp | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp index 1c5967141..024f122f8 100644 --- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp @@ -424,6 +424,96 @@ status_t RouteTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrEle return NO_ERROR; } +static void fixupQualcommBtScoRoute(RouteTraits::Collection& routes, DevicePortTraits::Collection& devicePorts, HwModule* ctx) { + // On many Qualcomm devices, there is a BT SCO Headset Mic => primary input mix + // But Telephony Rx => BT SCO Headset route is missing + // When we detect such case, add the missing route + + // If we have: + // + // + // + // And no + + // Add: + // + bool foundBtScoHeadsetDevice = false; + for(const auto& device: devicePorts) { + if(device->getTagName() == String8("BT SCO Headset")) { + foundBtScoHeadsetDevice = true; + break; + } + } + if(!foundBtScoHeadsetDevice) { + ALOGE("No BT SCO Headset device found, don't patch policy"); + return; + } + + bool foundTelephony = false; + bool foundBtScoInput = false; + bool foundScoHeadsetRoute = false; + for(const auto& route: routes) { + ALOGE("Looking at route %d\n", route->getType()); + if(route->getType() != AUDIO_ROUTE_MIX) + continue; + auto sink = route->getSink(); + ALOGE("... With sink %s\n", sink->getTagName().c_str()); + if(sink->getTagName() == String8("Telephony Tx")) { + foundTelephony = true; + continue; + } + if(sink->getTagName() == String8("BT SCO Headset")) { + foundScoHeadsetRoute = true; + break; + } + for(const auto& source: route->getSources()) { + ALOGE("... With source %s\n", source->getTagName().c_str()); + if(source->getTagName() == String8("BT SCO Headset Mic")) { + foundBtScoInput = true; + break; + } + } + } + //The route we want to add is already there + ALOGE("Done looking for existing routes"); + if(foundScoHeadsetRoute) + return; + + ALOGE("No existing route found... %d %d", foundTelephony ? 1 : 0, foundBtScoInput ? 1 : 0); + //We couldn't find the routes we assume are required for the function we want to add + if(!foundTelephony || !foundBtScoInput) + return; + ALOGE("Adding our own."); + + // Add: + // + AudioRoute *newRoute = new AudioRoute(AUDIO_ROUTE_MIX); + + auto sink = ctx->findPortByTagName(String8("BT SCO Headset")); + ALOGE("Got sink %p\n", sink.get()); + newRoute->setSink(sink); + + AudioPortVector sources; + for(const auto& sourceName: { + "primary output", + "deep_buffer", + "compressed_offload", + "Telephony Rx" + }) { + auto source = ctx->findPortByTagName(String8(sourceName)); + ALOGE("Got source %p\n", source.get()); + sources.add(source); + source->addRoute(newRoute); + } + + newRoute->setSources(sources); + + sink->addRoute(newRoute); + + auto ret = routes.add(newRoute); + ALOGE("route add returned %zd", ret); +} + const char *const ModuleTraits::childAttachedDevicesTag = "attachedDevices"; const char *const ModuleTraits::childAttachedDeviceTag = "item"; const char *const ModuleTraits::childDefaultOutputDeviceTag = "defaultOutputDevice"; @@ -465,6 +555,7 @@ status_t ModuleTraits::deserialize(xmlDocPtr doc, const xmlNode *root, PtrElemen RouteTraits::Collection routes; deserializeCollection(doc, root, routes, module.get()); + fixupQualcommBtScoRoute(routes, devicePorts, module.get()); module->setRoutes(routes); const xmlNode *children = root->xmlChildrenNode; -- 2.17.1