Initial commit for Android 11, syncing up to v300.f

This commit is contained in:
Andy CrossGate Yan
2020-10-29 03:02:26 +00:00
commit 1bc6933877
78 changed files with 12938 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
From f85268cf7b0e928d741d316b59b3b31773fae7c8 Mon Sep 17 00:00:00 2001
From: Alexander Pohl <pohl199885@gmail.com>
Date: Fri, 15 Jun 2018 19:58:07 +0200
Subject: [PATCH 01/14] Fix WiFi-Display on Huawei devices (EMUI 8.0)
Huaweis media stack doesn't handle intra-refresh-mode, so skip the error instead.
Thanks to Chris Vandomelen for pointing that out.
---
media/libstagefright/ACodec.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 63ab6548b4..e25f8f6558 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4432,9 +4432,8 @@ status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
if (err != OK) {
- ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
- err, intraRefreshMode);
- return err;
+ ALOGE("setupAVCEncoderParameters(): set intra-refresh-mode failed, ignoring..");
+ //return err;
}
}
--
2.17.1

View File

@@ -0,0 +1,36 @@
From 4ab15a33857452d990581a3d0073e35215e1c542 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Sun, 19 Aug 2018 22:59:06 +0200
Subject: [PATCH 02/14] ::Kirin:: Remove lock to prevent self-lock
With Huawei Camera HAL, we get the following call order:
cameraserver CameraService::enumerateProviders (*)
=> HAL ICameraProvider::getVendorTags
=> HAL ICameraProviderCallback::cameraDeviceStatusChange
=> cameraserver CameraService::addState
=> cameraserver CameraService::updateCameraNumAndIds (*)
The two functions marked with (*) take mServiceLock
Hence the safe-lock
Change-Id: I464255b5a3af8d75d72b1772ab55aa655f395a60
---
services/camera/libcameraservice/CameraService.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index af1e01d8e1..05252d6308 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -301,7 +301,7 @@ status_t CameraService::getSystemCameraKind(const String8& cameraId, SystemCamer
}
void CameraService::updateCameraNumAndIds() {
- Mutex::Autolock l(mServiceLock);
+ //Mutex::Autolock l(mServiceLock);
std::pair<int, int> systemAndNonSystemCameras = mCameraProviderManager->getCameraCount();
// Excludes hidden secure cameras
mNumberOfCameras =
--
2.17.1

View File

@@ -0,0 +1,26 @@
From 1083cc0b59ed11aa69af22103ebaf74ae11f272c Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Sun, 19 Aug 2018 23:05:26 +0200
Subject: [PATCH 03/14] We might not have a mFlashlight at this state, but
that's ok
---
services/camera/libcameraservice/CameraService.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 05252d6308..e1d23073f4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -337,7 +337,7 @@ void CameraService::addStates(const String8 id) {
conflicting, deviceKind));
}
- if (mFlashlight->hasFlashUnit(id)) {
+ if (mFlashlight != nullptr && mFlashlight->hasFlashUnit(id)) {
Mutex::Autolock al(mTorchStatusMutex);
mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
--
2.17.1

View File

@@ -0,0 +1,62 @@
From 1c0e912c7bdef868de97dc07dd5227d298cd66a9 Mon Sep 17 00:00:00 2001
From: Artem Borisov <dedsa2002@gmail.com>
Date: Tue, 25 Sep 2018 12:39:22 +0300
Subject: [PATCH 04/14] CameraService: Support calling addStates in
enumerateProviders
Some pre-P camera HALs trigger onDeviceStatusChange callback during HAL init.
This is horribly wrong and causes a race condition between enumerateProviders
and onDeviceStatusChange. While it wasn't really harmful in O, in P call sequence
was changed and now this race condition leads to two problems: null pointer dereference
in addStates because mFlashlight is not initialized at a proper timing; mServiceLock
deadlock because updateCameraNumAndIds and enumerateProviders are called at the same time.
Moving addStates back to enumerateProviders makes the sequence more similar to O, and doesn't
let these two issues to happen.
Enable TARGET_CAMERA_NEEDS_ADD_STATES_IN_ENUMERATE when it is necessary.
@Dil3mm4 edit: Instead of TARGET_CAMERA_NEEDS_ADD_STATES_IN_ENUMERATE let's use a system property to make it more generic and suitable for GSI use.
Change-Id: Ife25b9753fdb679ab0c77f385e1b8527551a4711
---
.../camera/libcameraservice/CameraService.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index e1d23073f4..83dea10f3a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -221,6 +221,20 @@ status_t CameraService::enumerateProviders() {
for (auto& cameraId : deviceIds) {
String8 id8 = String8(cameraId.c_str());
+ if (property_get_bool("persist.sys.camera.huawei", false)) {
+ bool cameraFound = false;
+ {
+ Mutex::Autolock lock(mCameraStatesLock);
+ auto iter = mCameraStates.find(id8);
+ if (iter != mCameraStates.end()) {
+ cameraFound = true;
+ }
+ }
+ if (!cameraFound) {
+ addStates(id8);
+ }
+ }
+
if (getCameraState(id8) == nullptr) {
onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
}
@@ -375,8 +389,10 @@ void CameraService::onDeviceStatusChanged(const String8& id,
ALOGI("%s: Unknown camera ID %s, a new camera is added",
__FUNCTION__, id.string());
+ if (!property_get_bool("persist.sys.camera.huawei", false)) {
// First add as absent to make sure clients are notified below
addStates(id);
+ }
updateStatus(newStatus, id);
} else {
--
2.17.1

View File

@@ -0,0 +1,131 @@
From 3afbad626827104662f61ab04ba3fbe6af32f73f Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Mon, 5 Aug 2019 18:09:50 +0200
Subject: [PATCH 05/14] 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.
Change-Id: Ifea0f88276ec9a0811f3cb1973c4b06f2c82077b
---
.../managerdefinitions/src/Serializer.cpp | 93 +++++++++++++++++++
1 file changed, 93 insertions(+)
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 883e713326..d85dbdf113 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -596,6 +596,98 @@ Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSer
return route;
}
+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:
+ // <route type="mix" sink="Telephony Tx" sources="voice_tx"/>
+ // <route type="mix" sink="primary input" sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic"/>
+ // <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink" />
+ // And no <route type="mix" sink="BT SCO Headset" />
+
+ // Add:
+ // <route type="mix" sink="BT SCO Headset" sources="primary output,deep_buffer,compressed_offload,Telephony Rx"/>
+ bool foundBtScoHeadsetDevice = false;
+ for(const auto& device: devicePorts) {
+ if(device->getTagName() == "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() == "Telephony Tx") {
+ foundTelephony = true;
+ continue;
+ }
+ if(sink->getTagName() == "BT SCO Headset") {
+ foundScoHeadsetRoute = true;
+ break;
+ }
+ for(const auto& source: route->getSources()) {
+ ALOGE("... With source %s\n", source->getTagName().c_str());
+ if(source->getTagName() == "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:
+ // <route type="mix" sink="BT SCO Headset" sources="primary output,deep_buffer,compressed_offload,Telephony Rx"/>
+ AudioRoute *newRoute = new AudioRoute(AUDIO_ROUTE_MIX);
+
+ auto sink = ctx->findPortByTagName("BT SCO Headset");
+ ALOGE("Got sink %p\n", sink.get());
+ newRoute->setSink(sink);
+
+ Vector<sp<PolicyAudioPort>> sources;
+ for(const auto& sourceName: {
+ "primary output",
+ "deep_buffer",
+ "compressed_offload",
+ "Telephony Rx"
+ }) {
+ auto source = ctx->findPortByTagName(sourceName);
+ ALOGE("Got source %p\n", source.get());
+ if (source.get() != nullptr) {
+ sources.add(source);
+ source->addRoute(newRoute);
+ }
+ }
+
+ newRoute->setSources(sources);
+
+ sink->addRoute(newRoute);
+
+ auto ret = routes.add(newRoute);
+ ALOGE("route add returned %zd", ret);
+}
+
Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
{
std::string name = getXmlAttribute(cur, Attributes::name);
@@ -635,6 +727,7 @@ Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrS
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
+ fixupQualcommBtScoRoute(routes, devicePorts, module.get());
module->setRoutes(routes);
for (const xmlNode *children = cur->xmlChildrenNode; children != NULL;
--
2.17.1

View File

@@ -0,0 +1,94 @@
From 4f7930e14f979ec5be530bd630ca9bb664050420 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Tue, 1 Oct 2019 13:35:49 +0200
Subject: [PATCH 06/14] Add (partial, cam id is hardcoded) support for Asus ZF6
motor camera
Change-Id: Iea6e1370780a1d16f728748d1d948d092532d8fe
---
.../camera/libcameraservice/CameraService.cpp | 26 +++++++++++++++++++
.../camera/libcameraservice/CameraService.h | 3 +++
2 files changed, 29 insertions(+)
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 83dea10f3a..37ea512bdd 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -25,6 +25,7 @@
#include <ctime>
#include <string>
#include <sys/types.h>
+#include <sys/wait.h>
#include <inttypes.h>
#include <pthread.h>
@@ -139,6 +140,7 @@ Mutex CameraService::sProxyMutex;
sp<hardware::ICameraServiceProxy> CameraService::sCameraServiceProxy;
CameraService::CameraService() :
+ mPhysicalFrontCamStatus(false),
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0),
mNumberOfCamerasWithoutSystemCamera(0),
@@ -1785,6 +1787,7 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&
mServiceLock.lock();
} else {
// Otherwise, add client to active clients list
+ physicalFrontCam(cameraId == "1");
finishConnectLocked(client, partial);
}
} // lock is destroyed, allow further connect calls
@@ -1866,6 +1869,27 @@ status_t CameraService::addOfflineClient(String8 cameraId, sp<BasicClient> offli
return OK;
}
+void CameraService::physicalFrontCam(bool on) {
+ if(on == mPhysicalFrontCamStatus) return;
+ mPhysicalFrontCamStatus = on;
+
+ if(access("/dev/asusMotoDrv", F_OK) == 0) {
+ int pid = fork();
+ if(pid == 0) {
+ const char* cmd[] = {
+ "/system/bin/asus-motor",
+ "0",
+ NULL
+ };
+ cmd[1] = on ? "0" : "1";
+ execve("/system/bin/asus-motor", (char**)cmd, environ);
+ _exit(1);
+ } else {
+ waitpid(pid, NULL, 0);
+ }
+ }
+}
+
Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
const sp<IBinder>& clientBinder) {
Mutex::Autolock lock(mServiceLock);
@@ -2840,6 +2864,8 @@ binder::Status CameraService::BasicClient::disconnect() {
}
mDisconnected = true;
+ sCameraService->physicalFrontCam(false);
+
sCameraService->removeByClient(this);
sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 4321201100..85b1706996 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -202,6 +202,9 @@ public:
// Register an offline client for a given active camera id
status_t addOfflineClient(String8 cameraId, sp<BasicClient> offlineClient);
+ bool mPhysicalFrontCamStatus;
+ void physicalFrontCam(bool on);
+
/////////////////////////////////////////////////////////////////////
// Client functionality
--
2.17.1

View File

@@ -0,0 +1,59 @@
From 93d21e226a4cac72ebc73f8fcec3001160d8570f Mon Sep 17 00:00:00 2001
From: Peter Cai <peter@typeblog.net>
Date: Thu, 23 Jan 2020 11:13:43 +0800
Subject: [PATCH 07/14] audiopolicy: try again with trimmed audio port name if
not found
* In Spreadtrum BSP, some audio routes may contain ports with extra
spaces at the beginning and the end, causing audiopolicy to refuse to
load and leading to broken audio.
* Fix this by retrying with trimmed port name when not found. Do not
use trimmed name all the time because a white space is a valid
character in port name, and we cannot be sure nobody is using it for
legitimite purposes.
Change-Id: I993708b28e8404bc8c483d71a850ac69382231bd
---
.../managerdefinitions/src/Serializer.cpp | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index d85dbdf113..e25dda07c7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -539,6 +539,17 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
return deviceDesc;
}
+char* trim(char * s) {
+ int l = strlen(s);
+
+ if (l > 0) {
+ while (isspace(s[l - 1])) --l;
+ while (*s && isspace(*s)) ++s, --l;
+ }
+
+ return strndup(s, l);
+}
+
Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
{
std::string type = getXmlAttribute(cur, Attributes::type);
@@ -579,8 +590,11 @@ Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSer
if (strlen(devTag) != 0) {
sp<PolicyAudioPort> source = ctx->findPortByTagName(devTag);
if (source == NULL) {
- ALOGE("%s: no source found with name=%s", __func__, devTag);
- return Status::fromStatusT(BAD_VALUE);
+ source = ctx->findPortByTagName(trim(devTag));
+ if (source == NULL) {
+ ALOGE("%s: no source found with name=%s", __func__, devTag);
+ return Status::fromStatusT(BAD_VALUE);
+ }
}
sources.add(source);
}
--
2.17.1

View File

@@ -0,0 +1,46 @@
From 2c80a9c1453230a62f538fc128f286005d91b802 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Mon, 13 Apr 2020 21:01:16 +0200
Subject: [PATCH 08/14] There are three SCO devices. Fallback from one to the
others if needed
Change-Id: I414dcb6b154855c00cb8520b23dc1069827864b2
---
.../managerdefinitions/src/HwModule.cpp | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index d31e4437e1..b2ca5e85de 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -292,6 +292,27 @@ sp <HwModule> HwModuleCollection::getModuleForDeviceType(audio_devices_t type,
}
}
}
+ //We didn't find one? Ok but all SCOs are equivalent surely?
+ if(type == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
+ type == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
+ type == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
+ ALOGE("Fallback SCO");
+ if(type != AUDIO_DEVICE_OUT_BLUETOOTH_SCO) {
+ auto ret = getModuleForDeviceType(AUDIO_DEVICE_OUT_BLUETOOTH_SCO, encodedFormat);
+ ALOGE("Fallback SCO simple? %s", (ret != nullptr) ? "yes" : "no");
+ if(ret != nullptr) return ret;
+ }
+ if(type != AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
+ auto ret = getModuleForDeviceType(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, encodedFormat);
+ ALOGE("Fallback SCO headset? %s", (ret != nullptr) ? "yes" : "no");
+ if(ret != nullptr) return ret;
+ }
+ if(type != AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
+ auto ret = getModuleForDeviceType(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, encodedFormat);
+ ALOGE("Fallback SCO carkit? %s", (ret != nullptr) ? "yes" : "no");
+ if(ret != nullptr) return ret;
+ }
+ }
return nullptr;
}
--
2.17.1

View File

@@ -0,0 +1,82 @@
From 9ac09c1e3d8408ce08a6e99e6403fb75cccf20ba Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Thu, 14 May 2020 19:54:55 +0200
Subject: [PATCH 10/14] Add persist.sys.phh.samsung.camera_ids property to
access hidden Samsung cameras
Change-Id: I2c7bf535272acc28ed2277e96c78ddd28a0b4593
---
services/camera/libcameraservice/Android.bp | 3 ++-
.../common/CameraProviderManager.cpp | 14 ++++++++++++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 501d92226f..be275e9346 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -127,7 +127,8 @@ cc_library_shared {
"android.hardware.camera.device@3.3",
"android.hardware.camera.device@3.4",
"android.hardware.camera.device@3.5",
- "android.hardware.camera.device@3.6"
+ "android.hardware.camera.device@3.6",
+ "vendor.samsung.hardware.camera.provider@3.0",
],
static_libs: [
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 32d118d6b0..eb27e055ac 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -21,6 +21,7 @@
#include "CameraProviderManager.h"
#include <android/hardware/camera/device/3.5/ICameraDevice.h>
+#include <vendor/samsung/hardware/camera/provider/3.0/ISehCameraProvider.h>
#include <algorithm>
#include <chrono>
@@ -1330,6 +1331,7 @@ status_t CameraProviderManager::ProviderInfo::initialize(
mMinorVersion = 6;
}
}
+
// We need to check again since cast2_6.isOk() succeeds even if the provider
// version isn't actually 2.6.
if (interface2_6 == nullptr){
@@ -1344,6 +1346,9 @@ status_t CameraProviderManager::ProviderInfo::initialize(
}
}
+ auto samsungCast = vendor::samsung::hardware::camera::provider::V3_0::ISehCameraProvider::castFrom(interface);
+ auto samsungProvider = samsungCast.isOk() ? static_cast<sp<vendor::samsung::hardware::camera::provider::V3_0::ISehCameraProvider>>(samsungCast) : nullptr;
+
hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
if (!linked.isOk()) {
ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
@@ -1375,7 +1380,7 @@ status_t CameraProviderManager::ProviderInfo::initialize(
Status status;
// Get initial list of camera devices, if any
std::vector<std::string> devices;
- hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
+ auto cb = [&status, this, &devices](
Status idStatus,
const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
status = idStatus;
@@ -1392,7 +1397,12 @@ status_t CameraProviderManager::ProviderInfo::initialize(
mProviderPublicCameraIds.push_back(id);
}
}
- } });
+ } };
+ hardware::Return<void> ret;
+ if(samsungProvider != nullptr && property_get_bool("persist.sys.phh.samsung.camera_ids", false))
+ ret = samsungProvider->sehGetCameraIdList(cb);
+ else
+ ret = interface->getCameraIdList(cb);
if (!ret.isOk()) {
ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
--
2.17.1

View File

@@ -0,0 +1,45 @@
From 6dff7fa42818b525faa0a80d161ad54055ebc38e Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Tue, 19 May 2020 14:01:14 +0200
Subject: [PATCH 11/14] Add a property to force camera timestamp source
Some devices wrongly report their timesource
Camera's timesource can either be CLOCK_MONOTONIC, or CLOCK_BOOTTIME
The former doesn't increment in sleep, while the later does.
There is a camera HAL property for that, though some devices don't
report it properly.
This issue happens on Xiaomi Redmi 7A, it needs to force the value to 1
Add a property persist.sys.phh.camera.force_timestampsource to force
timestamp source.
---
.../libcameraservice/device3/Camera3Device.cpp | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 4a509aa745..cdf9fc783e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -316,8 +316,16 @@ status_t Camera3Device::initializeCommonLocked() {
// Measure the clock domain offset between camera and video/hw_composer
camera_metadata_entry timestampSource =
mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
- if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
- ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
+ int timestampSourceValue = 0;
+ if ((timestampSource.count > 0 && timestampSource.data.u8[0] ==
+ ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME)) {
+ timestampSourceValue = 1;
+ }
+ int forceTimestampSource = property_get_int32("persist.sys.phh.camera.force_timestampsource", -1);
+ //Don't override if it's -1, default value
+ if(forceTimestampSource == 0) timestampSourceValue = 0;
+ if(forceTimestampSource == 1) timestampSourceValue = 1;
+ if (timestampSourceValue == 1) {
mTimestampOffset = getMonoToBoottimeOffset();
}
--
2.17.1

View File

@@ -0,0 +1,79 @@
From 7f14fcbf4bcf6d8f8c4b89f6ac4b91bc4961ed6f Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Tue, 24 Apr 2018 00:14:28 +0200
Subject: [PATCH 12/14] FIH devices: Fix "Earpiece" audio output
On some FIH devices (confirmed on Razer, and probably on Aquos SS2),
Earpiece is not listed in attachedDevices, and devicePort's profile
mentions it is AUDIO_CHANNEL_IN_MONO, instead of AUDIO_CHANNEL_OUT_MONO.
Detect such cases (output device, but got only AUDIO_CHANNEL_IN_MONO),
and fix both channelMasks and attachedDevices
Change-Id: I4a88ba6d34d0fcd346eeea2ca903772f0271040a
---
.../managerdefinitions/src/Serializer.cpp | 27 ++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index e25dda07c7..a8eb142c81 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -396,15 +396,24 @@ Return<AudioGainTraits::Element> AudioGainTraits::deserialize(const xmlNode *cur
}
}
+static bool fixedEarpieceChannels = false;
Return<AudioProfileTraits::Element> AudioProfileTraits::deserialize(const xmlNode *cur,
- PtrSerializingCtx /*serializingContext*/)
+ PtrSerializingCtx serializingContext)
{
+ bool isOutput = serializingContext != nullptr;
std::string samplingRates = getXmlAttribute(cur, Attributes::samplingRates);
std::string format = getXmlAttribute(cur, Attributes::format);
std::string channels = getXmlAttribute(cur, Attributes::channelMasks);
+ ChannelTraits::Collection channelsMask = channelMasksFromString(channels, ",");
+
+ //Some Foxconn devices have wrong earpiece channel mask, leading to no channel mask
+ if(channelsMask.size() == 1 && *channelsMask.begin() == AUDIO_CHANNEL_IN_MONO && isOutput) {
+ fixedEarpieceChannels = true;
+ channelsMask = channelMasksFromString("AUDIO_CHANNEL_OUT_MONO", ",");
+ }
Element profile = new AudioProfile(formatFromString(format, gDynamicFormat),
- channelMasksFromString(channels, ","),
+ channelsMask,
samplingRatesFromString(samplingRates, ","));
profile->setDynamicFormat(profile->getFormat() == gDynamicFormat);
@@ -517,7 +526,11 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
Element deviceDesc = new DeviceDescriptor(type, name, address, encodedFormats);
AudioProfileTraits::Collection profiles;
- status_t status = deserializeCollection<AudioProfileTraits>(cur, &profiles, NULL);
+ status_t status;
+ if(audio_is_output_devices(type))
+ status = deserializeCollection<AudioProfileTraits>(cur, &profiles, (PtrSerializingCtx)1);
+ else
+ status = deserializeCollection<AudioProfileTraits>(cur, &profiles, NULL);
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
@@ -782,6 +795,14 @@ Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrS
}
}
}
+
+ if(fixedEarpieceChannels) {
+ sp<DeviceDescriptor> device =
+ module->getDeclaredDevices().getDeviceFromTagName("Earpiece");
+ if(device != 0)
+ ctx->addDevice(device);
+ fixedEarpieceChannels = false;
+ }
return module;
}
--
2.17.1

View File

@@ -0,0 +1,32 @@
From 4b6dc11462996df5987ac339bf2fb750f500a067 Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Sat, 12 Sep 2020 12:32:50 +0200
Subject: [PATCH 13/14] [audiopolicy] No longer make re-assigning legacy audio
groups fatal. Mi9 declares AUDIO_STREAM_PATCH and AUDIO_STREAM_REROUTING
which is defined by framework too
Change-Id: I794fe22d63a8af705be4f5f09b9879ecaab3eae5
---
services/audiopolicy/engine/common/src/EngineBase.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 1bc7fe3dcc..fe18d0d794 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -206,9 +206,9 @@ engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
}
if (group.stream != AUDIO_STREAM_DEFAULT) {
// A legacy stream can be assigned once to a volume group
- LOG_ALWAYS_FATAL_IF(checkStreamForGroups(group.stream, mVolumeGroups),
- "stream %s already assigned to a volume group, "
- "review the configuration", toString(group.stream).c_str());
+ if(checkStreamForGroups(group.stream, mVolumeGroups)) {
+ ALOGE("stream %s already assigned to a volume group, review the configuration", toString(group.stream).c_str());
+ }
volumeGroup->addSupportedStream(group.stream);
}
addSupportedAttributesToGroup(group, volumeGroup, strategy);
--
2.17.1

View File

@@ -0,0 +1,341 @@
From d24b9bfa7113578d6a9e7a98a01e0ef6dfb970ea Mon Sep 17 00:00:00 2001
From: Pierre-Hugues Husson <phh@phh.me>
Date: Mon, 25 May 2020 21:26:54 +0200
Subject: [PATCH 14/14] Add persist.sys.phh.disable_a2dp_offload property to
force a2dp offload
Change-Id: Id474540c33c594cc4010a1a398d82bff8aadaeea
---
media/libstagefright/ACodec.cpp | 20 +-
.../managerdefinitions/src/Serializer.cpp | 181 +++++++++++++++++-
.../audiopolicy/enginedefault/src/Engine.cpp | 2 +-
.../managerdefault/AudioPolicyManager.cpp | 3 +
4 files changed, 199 insertions(+), 7 deletions(-)
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e25f8f6558..7ff3c8f61b 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1166,6 +1166,9 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(
return err;
}
+ ALOGE("Window undequeued buffers is %d\n", *minUndequeuedBuffers);
+ ALOGE("Consumerrequested %d\n", def.nBufferCountMin);
+
// FIXME: assume that surface is controlled by app (native window
// returns the number for the case when surface is not controlled by app)
// FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
@@ -1178,22 +1181,29 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(
// 2. try to allocate two (2) additional buffers to reduce starvation from
// the consumer
// plus an extra buffer to account for incorrect minUndequeuedBufs
- for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
- OMX_U32 newBufferCount =
- def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
+ for (int extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
+ int a = def.nBufferCountMin;
+ int b = *minUndequeuedBuffers;
+ int c = extraBuffers;
+ int newBufferCount = a+b+c;
def.nBufferCountActual = newBufferCount;
err = mOMXNode->setParameter(
OMX_IndexParamPortDefinition, &def, sizeof(def));
if (err == OK) {
- *minUndequeuedBuffers += extraBuffers;
+ ALOGE("Managed to allocate %d buffers (%d extra)\n", newBufferCount, extraBuffers);
+ if(extraBuffers > 0) {
+ *minUndequeuedBuffers += extraBuffers;
+ } else {
+ *minUndequeuedBuffers -= -extraBuffers;
+ }
break;
}
ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
mComponentName.c_str(), newBufferCount, err);
/* exit condition */
- if (extraBuffers == 0) {
+ if (extraBuffers == -2 || newBufferCount == 1) {
return err;
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index a8eb142c81..73e4a3e096 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -29,6 +29,7 @@
#include <utils/StrongPointer.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include <cutils/properties.h>
#include "Serializer.h"
#include "TypeConverter.h"
@@ -36,6 +37,8 @@ namespace android {
namespace {
+static bool forceDisableA2dpOffload = false;
+
// TODO(mnaganov): Consider finding an alternative for using HIDL code.
using hardware::Return;
using hardware::Status;
@@ -318,7 +321,7 @@ status_t deserializeCollection(const xmlNode *cur,
return status;
}
} else {
- return BAD_VALUE;
+ ALOGE("Ignoring...");
}
}
}
@@ -734,12 +737,34 @@ Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrS
Element module = new HwModule(name.c_str(), versionMajor, versionMinor);
+ bool isA2dpModule = strcmp(name.c_str(), "a2dp") == 0;
+ bool isPrimaryModule = strcmp(name.c_str(), "primary") == 0;
+
// Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes
MixPortTraits::Collection mixPorts;
status_t status = deserializeCollection<MixPortTraits>(cur, &mixPorts, NULL);
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
+ if(forceDisableA2dpOffload && isA2dpModule) {
+ for(const auto& mixPort: mixPorts) {
+ ALOGE("Disable a2dp offload...? %s", mixPort->getTagName().c_str());
+ //"a2dp" sw module already has a2dp out
+ if(mixPort->getTagName() == "a2dp output") {
+ forceDisableA2dpOffload = false;
+ break;
+ }
+ }
+ }
+ if(forceDisableA2dpOffload && isA2dpModule) {
+ //Add
+ //<mixPort name="a2dp output" role="source"/>
+ auto mixPort = new IOProfile("a2dp output", AUDIO_PORT_ROLE_SOURCE);
+ AudioProfileTraits::Collection profiles;
+ profiles.add(AudioProfile::createFullDynamic());
+ mixPort->setAudioProfiles(profiles);
+ mixPorts.push_back(mixPort);
+ }
module->setProfiles(mixPorts);
DevicePortTraits::Collection devicePorts;
@@ -747,6 +772,90 @@ Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrS
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
+ Vector<std::string> a2dpOuts;
+ a2dpOuts.push_back("BT A2DP Out");
+ a2dpOuts.push_back("BT A2DP Headphones");
+ a2dpOuts.push_back("BT A2DP Speaker");
+ if(forceDisableA2dpOffload) {
+ if(isA2dpModule) {
+ //<devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink" address="lhdc_a2dp">
+ // <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ // samplingRates="44100,48000,96000"
+ // channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ //</devicePort>
+ if(true) {
+ FormatVector formats;
+ //auto devicePortOut = new DeviceDescriptor(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, formats, "BT A2DP Out");
+ auto devicePortOut = new DeviceDescriptor(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "BT A2DP Out");
+ AudioProfileTraits::Collection profiles;
+ ChannelTraits::Collection channels;
+ channels.insert(AUDIO_CHANNEL_OUT_STEREO);
+ SampleRateSet sampleRates;
+ sampleRates.insert(44100);
+ sampleRates.insert(48000);
+ sampleRates.insert(96000);
+ auto profile = new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, channels, sampleRates);
+ profiles.add(profile);
+ devicePortOut->setAudioProfiles(profiles);
+ devicePortOut->setAddress("lhdc_a2dp");
+ devicePorts.add(devicePortOut);
+ }
+ //<devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink" address="lhdc_a2dp">
+ // <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ // samplingRates="44100,48000,96000"
+ // channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ //</devicePort>
+ if(true) {
+ FormatVector formats;
+ auto devicePortOut = new DeviceDescriptor(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, "BT A2DP Headphones");
+ AudioProfileTraits::Collection profiles;
+ ChannelTraits::Collection channels;
+ channels.insert(AUDIO_CHANNEL_OUT_STEREO);
+ SampleRateSet sampleRates;
+ sampleRates.insert(44100);
+ sampleRates.insert(48000);
+ sampleRates.insert(96000);
+ auto profile = new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, channels, sampleRates);
+ profiles.add(profile);
+ devicePortOut->setAudioProfiles(profiles);
+ devicePortOut->setAddress("lhdc_a2dp");
+ devicePorts.add(devicePortOut);
+ }
+ //<devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink" address="lhdc_a2dp">
+ // <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ // samplingRates="44100,48000,96000"
+ // channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ //</devicePort>
+ if(true) {
+ FormatVector formats;
+ auto devicePortOut = new DeviceDescriptor(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, "BT A2DP Speaker");
+ AudioProfileTraits::Collection profiles;
+ ChannelTraits::Collection channels;
+ channels.insert(AUDIO_CHANNEL_OUT_STEREO);
+ SampleRateSet sampleRates;
+ sampleRates.insert(44100);
+ sampleRates.insert(48000);
+ sampleRates.insert(96000);
+ auto profile = new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, channels, sampleRates);
+ profiles.add(profile);
+ devicePortOut->setAudioProfiles(profiles);
+ devicePortOut->setAddress("lhdc_a2dp");
+ devicePorts.add(devicePortOut);
+
+ }
+ } else if(isPrimaryModule) {
+ for(const auto& out: a2dpOuts) {
+ auto iterA = std::find_if(devicePorts.begin(), devicePorts.end(), [out](const auto port) {
+ if(port->getTagName() == out) return true;
+ return false;
+ });
+ if(iterA != devicePorts.end()) {
+ ALOGE("Erasing device port %s", (*iterA)->getTagName().c_str());
+ devicePorts.erase(iterA);
+ }
+ }
+ }
+ }
module->setDeclaredDevices(devicePorts);
RouteTraits::Collection routes;
@@ -754,7 +863,76 @@ Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrS
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
+ if(forceDisableA2dpOffload) {
+ if(strcmp(name.c_str(), "primary") == 0) {
+ for(const auto& out: a2dpOuts) {
+ auto iterA = std::find_if(routes.begin(), routes.end(), [out](const auto route) {
+ if(route->getType() != AUDIO_ROUTE_MIX)
+ return false;
+ auto sink = route->getSink();
+ if(sink->getTagName() == out) {
+ return true;
+ }
+ return false;
+ });
+ if(iterA != routes.end()) {
+ auto sink = (*iterA)->getSink()->getTagName();
+ ALOGE("Erasing route %s", sink.c_str());
+ routes.erase(iterA);
+ }
+ }
+ } else if(isA2dpModule) {
+ //<route type="mix" sink="BT A2DP Out"
+ // sources="a2dp output"/>
+ if(true) {
+ auto newRoute = new AudioRoute(AUDIO_ROUTE_MIX);
+ auto sink = module->findPortByTagName("BT A2DP Out");
+ auto source = module->findPortByTagName("a2dp output");
+ newRoute->setSink(sink);
+ Vector<sp<PolicyAudioPort>> sources;
+ sources.add(source);
+
+ sink->addRoute(newRoute);
+ source->addRoute(newRoute);
+ newRoute->setSources(sources);
+
+ routes.add(newRoute);
+ }
+ //<route type="mix" sink="BT A2DP Headphones"
+ // sources="a2dp output"/>
+ if(true) {
+ auto newRoute = new AudioRoute(AUDIO_ROUTE_MIX);
+ auto sink = module->findPortByTagName("BT A2DP Headphones");
+ auto source = module->findPortByTagName("a2dp output");
+ newRoute->setSink(sink);
+ Vector<sp<PolicyAudioPort>> sources;
+ sources.add(source);
+
+ sink->addRoute(newRoute);
+ source->addRoute(newRoute);
+ newRoute->setSources(sources);
+ routes.add(newRoute);
+ }
+ //<route type="mix" sink="BT A2DP Speaker"
+ // sources="a2dp output"/>
+ if(true) {
+ auto newRoute = new AudioRoute(AUDIO_ROUTE_MIX);
+ auto sink = module->findPortByTagName("BT A2DP Speaker");
+ auto source = module->findPortByTagName("a2dp output");
+ newRoute->setSink(sink);
+ Vector<sp<PolicyAudioPort>> sources;
+ sources.add(source);
+
+ sink->addRoute(newRoute);
+ source->addRoute(newRoute);
+ newRoute->setSources(sources);
+ routes.add(newRoute);
+ }
+ }
+ }
+ ALOGE("Good morning");
fixupQualcommBtScoRoute(routes, devicePorts, module.get());
+ ALOGE("Good morning2");
module->setRoutes(routes);
for (const xmlNode *children = cur->xmlChildrenNode; children != NULL;
@@ -932,6 +1110,7 @@ status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig
status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config)
{
PolicySerializer serializer;
+ forceDisableA2dpOffload = property_get_bool("persist.sys.phh.disable_a2dp_offload", false);
return serializer.deserialize(fileName, config);
}
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index b14d2bbb0b..16a7a4bbac 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -52,7 +52,7 @@ static const std::vector<legacy_strategy_map>& getLegacyStrategy() {
{ "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
{ "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
{ "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
- { "STRATEGY_REROUTING", STRATEGY_REROUTING },
+ //{ "STRATEGY_REROUTING", STRATEGY_REROUTING },
{ "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
{ "STRATEGY_CALL_ASSISTANT", STRATEGY_CALL_ASSISTANT },
};
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index c5c13e9a5a..1c5ed86b86 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -93,6 +93,8 @@ bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
return !(left == right);
}
+static bool forceDisableA2dpOffload = false;
+
// ----------------------------------------------------------------------------
// AudioPolicyInterface implementation
// ----------------------------------------------------------------------------
@@ -4458,6 +4460,7 @@ static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
} else if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false)) {
fileNames.push_back(AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME);
}
+ forceDisableA2dpOffload = property_get_bool("persist.sys.phh.disable_a2dp_offload", false);
fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
for (const char* fileName : fileNames) {
--
2.17.1