Merge "Biquad filter integration to LVM : Continuation"
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index c15c5a5..78974ae 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1361,31 +1361,11 @@
it->second.isSequenceCompleted = true;
}
- if (it->second.isSequenceCompleted && hasCallback) {
- auto cbIt = mSequenceCallbackMap.find(sequenceId);
- CallbackHolder cbh = cbIt->second;
-
- // send seq complete callback
- sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
- msg->setPointer(kContextKey, cbh.mContext);
- msg->setObject(kSessionSpKey, cbh.mSession);
- msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
- msg->setInt32(kSequenceIdKey, sequenceId);
- msg->setInt64(kFrameNumberKey, lastFrameNumber);
-
- // Clear the session sp before we send out the message
- // This will guarantee the rare case where the message is processed
- // before cbh goes out of scope and causing we call the session
- // destructor while holding device lock
- cbh.mSession.clear();
- postSessionMsgAndCleanup(msg);
- }
}
if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
- if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
- mSequenceCallbackMap.erase(sequenceId);
- }
+ sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
+
it = mSequenceLastFrameNumberMap.erase(it);
ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
} else {
@@ -1412,13 +1392,7 @@
lastCompletedRegularFrameNumber);
if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
if (it->second.isSequenceCompleted) {
- // Check if there is callback for this sequence
- // This should not happen because we always register callback (with nullptr inside)
- if (mSequenceCallbackMap.count(sequenceId) == 0) {
- ALOGW("No callback found for sequenceId %d", sequenceId);
- } else {
- mSequenceCallbackMap.erase(sequenceId);
- }
+ sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
it = mSequenceLastFrameNumberMap.erase(it);
ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
@@ -1709,5 +1683,33 @@
return ret;
}
+void
+CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
+ auto cbIt = mSequenceCallbackMap.find(sequenceId);
+ if (cbIt != mSequenceCallbackMap.end()) {
+ CallbackHolder cbh = cbIt->second;
+ mSequenceCallbackMap.erase(cbIt);
+
+ // send seq complete callback
+ sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
+ msg->setPointer(kContextKey, cbh.mContext);
+ msg->setObject(kSessionSpKey, cbh.mSession);
+ msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
+ msg->setInt32(kSequenceIdKey, sequenceId);
+ msg->setInt64(kFrameNumberKey, lastFrameNumber);
+
+ // Clear the session sp before we send out the message
+ // This will guarantee the rare case where the message is processed
+ // before cbh goes out of scope and causing we call the session
+ // destructor while holding device lock
+ cbh.mSession.clear();
+ postSessionMsgAndCleanup(msg);
+ } else {
+ // Check if there is callback for this sequence
+ // This should not happen because we always register callback (with nullptr inside)
+ ALOGW("No callback found for sequenceId %d", sequenceId);
+ }
+}
+
} // namespace acam
} // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index d937865..3073dfb 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -354,6 +354,7 @@
void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
void checkAndFireSequenceCompleteLocked();
void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber);
+ void sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber);
// Misc variables
int32_t mShadingMapSize[2]; // const after constructor
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 1700a95..55a32ae 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -11,7 +11,7 @@
}
-cc_library_shared {
+cc_library {
name: "libmediadrm",
srcs: [
diff --git a/drm/libmediadrm/fuzzer/Android.bp b/drm/libmediadrm/fuzzer/Android.bp
new file mode 100644
index 0000000..6f2d054
--- /dev/null
+++ b/drm/libmediadrm/fuzzer/Android.bp
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+ name: "mediadrm_fuzzer",
+ srcs: [
+ "mediadrm_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libmediadrm",
+ "liblog",
+ "resourcemanager_aidl_interface-ndk_platform",
+ ],
+ header_libs: [
+ "libmedia_headers",
+ "libmediadrm_headers",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ "libbinder_ndk",
+ "libcutils",
+ "libdl",
+ "libmedia",
+ "libmediadrmmetrics_lite",
+ "libmediametrics#1",
+ "libmediautils",
+ "libstagefright_foundation",
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "android.hardware.drm@1.3",
+ "libhidlallocatorutils",
+ "libhidlbase",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
diff --git a/drm/libmediadrm/fuzzer/README.md b/drm/libmediadrm/fuzzer/README.md
new file mode 100644
index 0000000..3c95cd7
--- /dev/null
+++ b/drm/libmediadrm/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzer for libmediadrm
+
+## Plugin Design Considerations
+The fuzzer plugin for libmediadrm is designed based on the understanding of the
+library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+libmediadrm supports the following parameters:
+1. Security Level (parameter name: `securityLevel`)
+2. Mime Type (parameter name: `mimeType`)
+3. Key Type (parameter name: `keyType`)
+4. Crypto Mode (parameter name: `cryptoMode`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `securityLevel` | 0.`DrmPlugin::kSecurityLevelUnknown` 1.`DrmPlugin::kSecurityLevelMax` 2.`DrmPlugin::kSecurityLevelSwSecureCrypto` 3.`DrmPlugin::kSecurityLevelSwSecureDecode` 4.`DrmPlugin::kSecurityLevelHwSecureCrypto` 5.`DrmPlugin::kSecurityLevelHwSecureDecode` 6.`DrmPlugin::kSecurityLevelHwSecureAll`| Value obtained from FuzzedDataProvider in the range 0 to 6|
+| `mimeType` | 0.`video/mp4` 1.`video/mpeg` 2.`video/x-flv` 3.`video/mj2` 4.`video/3gp2` 5.`video/3gpp` 6.`video/3gpp2` 7.`audio/mp4` 8.`audio/mpeg` 9.`audio/aac` 10.`audio/3gp2` 11.`audio/3gpp` 12.`audio/3gpp2` 13.`video/unknown`| Value obtained from FuzzedDataProvider in the range 0 to 13|
+| `keyType` | 0.`DrmPlugin::kKeyType_Offline` 1.`DrmPlugin::kKeyType_Streaming` 2.`DrmPlugin::kKeyType_Release` | Value obtained from FuzzedDataProvider in the range 0 to 2|
+| `cryptoMode` | 0.`CryptoPlugin::kMode_Unencrypted` 1.`CryptoPlugin::kMode_AES_CTR` 2.`CryptoPlugin::kMode_AES_WV` 3.`CryptoPlugin::kMode_AES_CBC` | Value obtained from FuzzedDataProvider in the range 0 to 3|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the drm module.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build mediadrm_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mediadrm_fuzzer
+```
+#### Steps to run
+Create a directory CORPUS_DIR
+```
+ $ adb shell mkdir CORPUS_DIR
+```
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/${TARGET_ARCH}/mediadrm_fuzzer/mediadrm_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/drm/libmediadrm/fuzzer/mediadrm_fuzzer.cpp b/drm/libmediadrm/fuzzer/mediadrm_fuzzer.cpp
new file mode 100644
index 0000000..8df0477
--- /dev/null
+++ b/drm/libmediadrm/fuzzer/mediadrm_fuzzer.cpp
@@ -0,0 +1,458 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <binder/MemoryDealer.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <mediadrm/CryptoHal.h>
+#include <mediadrm/DrmHal.h>
+#include <utils/String8.h>
+#include "fuzzer/FuzzedDataProvider.h"
+
+#define AES_BLOCK_SIZE 16
+#define UNUSED_PARAM __attribute__((unused))
+
+using namespace std;
+using namespace android;
+using android::hardware::fromHeap;
+using ::android::os::PersistableBundle;
+using drm::V1_0::BufferType;
+
+enum {
+ INVALID_UUID = 0,
+ PSSH_BOX_UUID,
+ CLEARKEY_UUID,
+};
+
+static const uint8_t kInvalidUUID[16] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
+ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
+
+static const uint8_t kCommonPsshBoxUUID[16] = {0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,
+ 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B};
+
+static const uint8_t kClearKeyUUID[16] = {0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9,
+ 0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E};
+
+static const uint32_t kUUID[] = {INVALID_UUID, PSSH_BOX_UUID, CLEARKEY_UUID};
+
+const DrmPlugin::SecurityLevel kSecurityLevel[] = {
+ DrmPlugin::kSecurityLevelUnknown, DrmPlugin::kSecurityLevelMax,
+ DrmPlugin::kSecurityLevelSwSecureCrypto, DrmPlugin::kSecurityLevelSwSecureDecode,
+ DrmPlugin::kSecurityLevelHwSecureCrypto, DrmPlugin::kSecurityLevelHwSecureDecode,
+ DrmPlugin::kSecurityLevelHwSecureAll};
+
+const char *kMimeType[] = {"video/mp4", "video/mpeg", "video/x-flv", "video/mj2",
+ "video/3gp2", "video/3gpp", "video/3gpp2", "audio/mp4",
+ "audio/mpeg", "audio/aac", "audio/3gp2", "audio/3gpp",
+ "audio/3gpp2", "video/unknown", "audio/unknown"};
+
+const DrmPlugin::KeyType kKeyType[] = {DrmPlugin::kKeyType_Offline, DrmPlugin::kKeyType_Streaming,
+ DrmPlugin::kKeyType_Release};
+
+const CryptoPlugin::Mode kCryptoMode[] = {CryptoPlugin::kMode_Unencrypted,
+ CryptoPlugin::kMode_AES_CTR, CryptoPlugin::kMode_AES_WV,
+ CryptoPlugin::kMode_AES_CBC};
+
+const char *kCipherAlgorithm[] = {"AES/CBC/NoPadding", ""};
+const char *kMacAlgorithm[] = {"HmacSHA256", ""};
+const char *kRSAAlgorithm[] = {"RSASSA-PSS-SHA1", ""};
+const size_t kNumSecurityLevel = size(kSecurityLevel);
+const size_t kNumMimeType = size(kMimeType);
+const size_t kNumKeyType = size(kKeyType);
+const size_t kNumCryptoMode = size(kCryptoMode);
+const size_t kNumUUID = size(kUUID);
+const size_t kMaxStringLength = 100;
+const size_t kMaxSubSamples = 10;
+const size_t kMaxNumBytes = 1000;
+
+struct DrmListener : virtual public IDrmClient {
+ public:
+ void sendEvent(DrmPlugin::EventType eventType UNUSED_PARAM,
+ const hardware::hidl_vec<uint8_t> &sessionId UNUSED_PARAM,
+ const hardware::hidl_vec<uint8_t> &data UNUSED_PARAM) override {}
+
+ void sendExpirationUpdate(const hardware::hidl_vec<uint8_t> &sessionId UNUSED_PARAM,
+ int64_t expiryTimeInMS UNUSED_PARAM) override {}
+
+ void sendKeysChange(const hardware::hidl_vec<uint8_t> &sessionId UNUSED_PARAM,
+ const std::vector<DrmKeyStatus> &keyStatusList UNUSED_PARAM,
+ bool hasNewUsableKey UNUSED_PARAM) override {}
+
+ void sendSessionLostState(const hardware::hidl_vec<uint8_t> &) override {}
+ DrmListener() {}
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(DrmListener);
+};
+
+class DrmFuzzer {
+ public:
+ void process(const uint8_t *data, size_t size);
+
+ private:
+ void invokeDrm(const uint8_t *data, size_t size);
+ bool initDrm();
+ void invokeDrmCreatePlugin();
+ void invokeDrmOpenSession();
+ void invokeDrmSetListener();
+ void invokeDrmSetAlgorithmAPI();
+ void invokeDrmPropertyAPI();
+ void invokeDrmDecryptEncryptAPI(const uint8_t *data, size_t size);
+ void invokeDrmSecureStopAPI();
+ void invokeDrmOfflineLicenseAPI();
+ void invokeDrmCloseSession();
+ void invokeDrmDestroyPlugin();
+ void invokeCrypto(const uint8_t *data);
+ bool initCrypto();
+ void invokeCryptoCreatePlugin();
+ void invokeCryptoDecrypt(const uint8_t *data);
+ void invokeCryptoDestroyPlugin();
+ sp<DrmHal> mDrm = nullptr;
+ sp<CryptoHal> mCrypto = nullptr;
+ Vector<uint8_t> mSessionId = {};
+ FuzzedDataProvider *mFuzzedDataProvider = nullptr;
+};
+
+bool DrmFuzzer::initDrm() {
+ mDrm = new DrmHal();
+ if (!mDrm) {
+ return false;
+ }
+ return true;
+}
+
+void DrmFuzzer::invokeDrmCreatePlugin() {
+ mDrm->initCheck();
+ String8 packageName(mFuzzedDataProvider->ConsumeRandomLengthString(kMaxStringLength).c_str());
+ uint32_t uuidEnum = kUUID[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumUUID - 1)];
+ switch (uuidEnum) {
+ case INVALID_UUID:
+ mDrm->createPlugin(kInvalidUUID, packageName);
+ break;
+ case PSSH_BOX_UUID:
+ mDrm->createPlugin(kCommonPsshBoxUUID, packageName);
+ break;
+ case CLEARKEY_UUID:
+ mDrm->createPlugin(kClearKeyUUID, packageName);
+ break;
+ default:
+ break;
+ }
+}
+
+void DrmFuzzer::invokeDrmDestroyPlugin() { mDrm->destroyPlugin(); }
+
+void DrmFuzzer::invokeDrmOpenSession() {
+ DrmPlugin::SecurityLevel securityLevel;
+ bool shouldPassRandomSecurityLevel = mFuzzedDataProvider->ConsumeBool();
+ if (shouldPassRandomSecurityLevel) {
+ securityLevel =
+ static_cast<DrmPlugin::SecurityLevel>(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+ } else {
+ securityLevel = kSecurityLevel[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kNumSecurityLevel - 1)];
+ }
+ mDrm->openSession(securityLevel, mSessionId);
+}
+
+void DrmFuzzer::invokeDrmCloseSession() { mDrm->closeSession(mSessionId); }
+
+void DrmFuzzer::invokeDrmSetListener() {
+ sp<DrmListener> listener = new DrmListener();
+ mDrm->setListener(listener);
+}
+
+void DrmFuzzer::invokeDrmSetAlgorithmAPI() {
+ mDrm->setCipherAlgorithm(mSessionId,
+ String8(kCipherAlgorithm[mFuzzedDataProvider->ConsumeBool()]));
+ mDrm->setMacAlgorithm(mSessionId, String8(kMacAlgorithm[mFuzzedDataProvider->ConsumeBool()]));
+}
+
+void DrmFuzzer::invokeDrmPropertyAPI() {
+ mDrm->setPropertyString(String8("property"), String8("value"));
+ String8 stringValue;
+ mDrm->getPropertyString(String8("property"), stringValue);
+ Vector<uint8_t> value = {};
+ mDrm->setPropertyByteArray(String8("property"), value);
+ Vector<uint8_t> byteValue;
+ mDrm->getPropertyByteArray(String8("property"), byteValue);
+}
+
+void DrmFuzzer::invokeDrmDecryptEncryptAPI(const uint8_t *data, size_t size) {
+ uint32_t openSessions = 0;
+ uint32_t maxSessions = 0;
+ mDrm->getNumberOfSessions(&openSessions, &maxSessions);
+
+ DrmPlugin::HdcpLevel connected;
+ DrmPlugin::HdcpLevel max;
+ mDrm->getHdcpLevels(&connected, &max);
+
+ DrmPlugin::SecurityLevel securityLevel;
+ mDrm->getSecurityLevel(mSessionId, &securityLevel);
+
+ // isCryptoSchemeSupported() shall fill isSupported
+ bool isSupported;
+ String8 mimeType(
+ kMimeType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumMimeType - 1)]);
+ mDrm->isCryptoSchemeSupported(kClearKeyUUID, mimeType, securityLevel, &isSupported);
+
+ // getProvisionRequest() shall fill legacyRequest and legacyDefaultUrl
+ String8 certificateType(
+ mFuzzedDataProvider->ConsumeRandomLengthString(kMaxStringLength).c_str());
+ String8 certAuthority(mFuzzedDataProvider->ConsumeRandomLengthString(kMaxStringLength).c_str());
+ Vector<uint8_t> legacyRequest = {};
+ String8 legacyDefaultUrl;
+ mDrm->getProvisionRequest(certificateType, certAuthority, legacyRequest, legacyDefaultUrl);
+
+ // provideProvisionResponse() shall fill certificate and wrappedKey
+ Vector<uint8_t> provisionResponse = {};
+ Vector<uint8_t> certificate = {};
+ Vector<uint8_t> wrappedKey = {};
+ mDrm->provideProvisionResponse(provisionResponse, certificate, wrappedKey);
+
+ // getKeyRequest() shall fill keyRequest, defaultUrl and keyRequestType
+ Vector<uint8_t> initData = {};
+ initData.appendArray(data, size);
+ DrmPlugin::KeyType keyType;
+ bool shouldPassRandomKeyType = mFuzzedDataProvider->ConsumeBool();
+ if (shouldPassRandomKeyType) {
+ keyType = static_cast<DrmPlugin::KeyType>(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+ } else {
+ keyType = kKeyType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumKeyType - 1)];
+ }
+ KeyedVector<String8, String8> mdOptionalParameters = {};
+ Vector<uint8_t> keyRequest = {};
+ String8 defaultUrl;
+ DrmPlugin::KeyRequestType keyRequestType;
+ mDrm->getKeyRequest(mSessionId, initData, mimeType, keyType, mdOptionalParameters, keyRequest,
+ defaultUrl, &keyRequestType);
+
+ // provideKeyResponse() shall fill keySetId
+ Vector<uint8_t> keyResponse = {};
+ keyResponse.appendArray(data, size);
+ Vector<uint8_t> keySetId = {};
+ mDrm->provideKeyResponse(mSessionId, keyResponse, keySetId);
+
+ // restoreKeys
+ mDrm->restoreKeys(mSessionId, keySetId);
+
+ // queryKeyStatus() shall fill infoMap
+ KeyedVector<String8, String8> infoMap = {};
+ mDrm->queryKeyStatus(mSessionId, infoMap);
+
+ // decrypt() shall fill outputVec
+ Vector<uint8_t> keyIdVec = {};
+ keyIdVec.appendArray(data, size);
+
+ Vector<uint8_t> inputVec = {};
+ inputVec.appendArray(data, size);
+
+ Vector<uint8_t> ivVec = {};
+ ivVec.appendArray(data, size);
+
+ Vector<uint8_t> outputVec = {};
+ mDrm->decrypt(mSessionId, keyIdVec, inputVec, ivVec, outputVec);
+
+ // encrypt() shall fill outputVec
+ mDrm->encrypt(mSessionId, keyIdVec, inputVec, ivVec, outputVec);
+
+ // sign() shall fill signature
+ Vector<uint8_t> message = {};
+ message.appendArray(data, size);
+ Vector<uint8_t> signature = {};
+ mDrm->sign(mSessionId, keyIdVec, message, signature);
+
+ // verify() shall fill match
+ bool match;
+ mDrm->verify(mSessionId, keyIdVec, message, signature, match);
+
+ // signRSA() shall fill signature
+ mDrm->signRSA(mSessionId, String8(kRSAAlgorithm[mFuzzedDataProvider->ConsumeBool()]), message,
+ wrappedKey, signature);
+
+ mDrm->removeKeys(mSessionId);
+}
+
+void DrmFuzzer::invokeDrmSecureStopAPI() {
+ // getSecureStops() shall fill secureStops
+ List<Vector<uint8_t>> secureStops = {};
+ mDrm->getSecureStops(secureStops);
+
+ // getSecureStopIds() shall fill secureStopIds
+ List<Vector<uint8_t>> secureStopIds = {};
+ mDrm->getSecureStopIds(secureStopIds);
+
+ // getSecureStop() shall fill secureStop
+ Vector<uint8_t> ssid = {};
+ Vector<uint8_t> secureStop = {};
+ mDrm->getSecureStop(ssid, secureStop);
+
+ mDrm->removeSecureStop(ssid);
+
+ mDrm->releaseSecureStops(ssid);
+
+ mDrm->removeAllSecureStops();
+}
+
+void DrmFuzzer::invokeDrmOfflineLicenseAPI() {
+ // getOfflineLicenseKeySetIds() shall keySetIds
+ List<Vector<uint8_t>> keySetIds = {};
+ mDrm->getOfflineLicenseKeySetIds(keySetIds);
+
+ // getOfflineLicenseState() shall fill state
+ Vector<uint8_t> const keySetIdOfflineLicense = {};
+ DrmPlugin::OfflineLicenseState state;
+ mDrm->getOfflineLicenseState(keySetIdOfflineLicense, &state);
+
+ mDrm->removeOfflineLicense(keySetIdOfflineLicense);
+}
+
+bool DrmFuzzer::initCrypto() {
+ mCrypto = new CryptoHal();
+ if (!mCrypto) {
+ return false;
+ }
+ return true;
+}
+
+void DrmFuzzer::invokeCryptoCreatePlugin() {
+ mCrypto->initCheck();
+
+ mCrypto->isCryptoSchemeSupported(kClearKeyUUID);
+ mCrypto->createPlugin(kClearKeyUUID, NULL, 0);
+}
+
+void DrmFuzzer::invokeCryptoDestroyPlugin() { mCrypto->destroyPlugin(); }
+
+void DrmFuzzer::invokeCryptoDecrypt(const uint8_t *data) {
+ mCrypto->requiresSecureDecoderComponent(
+ kMimeType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumMimeType - 1)]);
+
+ uint32_t width = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+ uint32_t height = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+ mCrypto->notifyResolution(width, height);
+
+ mCrypto->setMediaDrmSession(mSessionId);
+
+ const CryptoPlugin::Pattern pattern = {0, 0};
+
+ size_t totalSize = 0;
+ size_t numSubSamples = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(1, kMaxSubSamples);
+
+ CryptoPlugin::SubSample subSamples[numSubSamples];
+
+ for (size_t i = 0; i < numSubSamples; ++i) {
+ uint32_t clearBytes =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxNumBytes);
+ uint32_t encryptedBytes =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxNumBytes);
+ subSamples[i].mNumBytesOfClearData = clearBytes;
+ subSamples[i].mNumBytesOfEncryptedData = encryptedBytes;
+ totalSize += subSamples[i].mNumBytesOfClearData;
+ totalSize += subSamples[i].mNumBytesOfEncryptedData;
+ }
+
+ size_t heapSize = totalSize * 2;
+ sp<MemoryDealer> dealer = new MemoryDealer(heapSize, "DrmFuzzerMemory");
+ if (!dealer) {
+ return;
+ }
+
+ sp<HidlMemory> heap = fromHeap(dealer->getMemoryHeap());
+ if (!heap) {
+ return;
+ }
+ int heapSeqNum = mCrypto->setHeap(heap);
+ if (heapSeqNum < 0) {
+ return;
+ }
+
+ const size_t segmentIndex = 0;
+ const uint8_t keyId[AES_BLOCK_SIZE] = {};
+ memcpy((void *)keyId, data, AES_BLOCK_SIZE);
+
+ const uint8_t iv[AES_BLOCK_SIZE] = {};
+ memset((void *)iv, 0, AES_BLOCK_SIZE);
+
+ const SharedBuffer sourceBuffer = {.bufferId = segmentIndex, .offset = 0, .size = totalSize};
+
+ const DestinationBuffer destBuffer = {
+ .type = BufferType::SHARED_MEMORY,
+ {.bufferId = segmentIndex, .offset = totalSize, .size = totalSize},
+ .secureMemory = nullptr};
+
+ const uint64_t offset = 0;
+ AString *errorDetailMsg = nullptr;
+ CryptoPlugin::Mode mode;
+ bool shouldPassRandomCryptoMode = mFuzzedDataProvider->ConsumeBool();
+ if (shouldPassRandomCryptoMode) {
+ mode = static_cast<CryptoPlugin::Mode>(mFuzzedDataProvider->ConsumeIntegral<size_t>());
+ } else {
+ mode =
+ kCryptoMode[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kNumCryptoMode - 1)];
+ }
+ mCrypto->decrypt(keyId, iv, mode, pattern, sourceBuffer, offset, subSamples, numSubSamples,
+ destBuffer, errorDetailMsg);
+
+ if (heapSeqNum >= 0) {
+ mCrypto->unsetHeap(heapSeqNum);
+ }
+ heap.clear();
+}
+
+void DrmFuzzer::invokeDrm(const uint8_t *data, size_t size) {
+ if (!initDrm()) {
+ return;
+ }
+ invokeDrmCreatePlugin();
+ invokeDrmOpenSession();
+ invokeDrmSetAlgorithmAPI();
+ invokeDrmSetListener();
+ invokeDrmPropertyAPI();
+ invokeDrmDecryptEncryptAPI(data, size);
+ invokeDrmSecureStopAPI();
+ invokeDrmOfflineLicenseAPI();
+ invokeDrmCloseSession();
+ invokeDrmDestroyPlugin();
+}
+
+void DrmFuzzer::invokeCrypto(const uint8_t *data) {
+ if (!initCrypto()) {
+ return;
+ }
+ invokeCryptoCreatePlugin();
+ invokeCryptoDecrypt(data);
+ invokeCryptoDestroyPlugin();
+}
+
+void DrmFuzzer::process(const uint8_t *data, size_t size) {
+ mFuzzedDataProvider = new FuzzedDataProvider(data, size);
+ invokeDrm(data, size);
+ invokeCrypto(data);
+ delete mFuzzedDataProvider;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < AES_BLOCK_SIZE) {
+ return 0;
+ }
+ DrmFuzzer drmFuzzer;
+ drmFuzzer.process(data, size);
+ return 0;
+}
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 12ed725..b520c17 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -734,7 +734,7 @@
}
if (timestampMax < timestamp) timestampMax = timestamp;
}
- timestampOffset = timestampMax;
+ timestampOffset = timestampMax + 33333;
eleInfo.close();
// Reset Total frames before second decode loop
diff --git a/media/codecs/mp3dec/Android.bp b/media/codecs/mp3dec/Android.bp
index 1acf0a6..f84da21 100644
--- a/media/codecs/mp3dec/Android.bp
+++ b/media/codecs/mp3dec/Android.bp
@@ -1,3 +1,18 @@
+cc_library_headers {
+ name: "libstagefright_mp3dec_headers",
+ vendor_available: true,
+ min_sdk_version: "29",
+ host_supported:true,
+ export_include_dirs: [
+ "include",
+ "src",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ ],
+}
+
cc_library_static {
name: "libstagefright_mp3dec",
vendor_available: true,
@@ -65,10 +80,8 @@
include_dirs: ["frameworks/av/media/libstagefright/include"],
- export_include_dirs: [
- "include",
- "src",
- ],
+ header_libs: ["libstagefright_mp3dec_headers"],
+ export_header_lib_headers: ["libstagefright_mp3dec_headers"],
cflags: [
"-DOSCL_UNUSED_ARG(x)=(void)(x)",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 3aa60da..edb0889 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1363,7 +1363,7 @@
return aps->registerPolicyMixes(mixes, registration);
}
-status_t AudioSystem::setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+status_t AudioSystem::setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -1377,7 +1377,7 @@
}
status_t AudioSystem::setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices)
+ const AudioDeviceTypeAddrVector& devices)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -1604,33 +1604,88 @@
return aps->isCallScreenModeSupported();
}
-status_t AudioSystem::setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device)
+status_t AudioSystem::setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
- return aps->setPreferredDeviceForStrategy(strategy, device);
+ return aps->setDevicesRoleForStrategy(strategy, role, devices);
}
-status_t AudioSystem::removePreferredDeviceForStrategy(product_strategy_t strategy)
+status_t AudioSystem::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
- return aps->removePreferredDeviceForStrategy(strategy);
+ return aps->removeDevicesRoleForStrategy(strategy, role);
}
-status_t AudioSystem::getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device)
+status_t AudioSystem::getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
- return aps->getPreferredDeviceForStrategy(strategy, device);
+ return aps->getDevicesForRoleAndStrategy(strategy, role, devices);
+}
+
+status_t AudioSystem::setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) {
+ return PERMISSION_DENIED;
+ }
+ return aps->setDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioSystem::addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) {
+ return PERMISSION_DENIED;
+ }
+ return aps->addDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioSystem::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) {
+ return PERMISSION_DENIED;
+ }
+ return aps->removeDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioSystem::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) {
+ return PERMISSION_DENIED;
+ }
+ return aps->clearDevicesRoleForCapturePreset(audioSource, role);
+}
+
+status_t AudioSystem::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) {
+ return PERMISSION_DENIED;
+ }
+ return aps->getDevicesForRoleAndCapturePreset(audioSource, role, devices);
}
class CaptureStateListenerImpl : public media::BnCaptureStateListener,
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index c9bb0aa..23b5ae1 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -112,13 +112,18 @@
MOVE_EFFECTS_TO_IO,
SET_RTT_ENABLED,
IS_CALL_SCREEN_MODE_SUPPORTED,
- SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
- REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
- GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+ SET_DEVICES_ROLE_FOR_PRODUCT_STRATEGY,
+ REMOVE_DEVICES_ROLE_FOR_PRODUCT_STRATEGY,
+ GET_DEVICES_FOR_ROLE_AND_PRODUCT_STRATEGY,
GET_DEVICES_FOR_ATTRIBUTES,
AUDIO_MODULES_UPDATED, // oneway
SET_CURRENT_IME_UID,
REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER,
+ SET_DEVICES_ROLE_FOR_CAPTURE_PRESET,
+ ADD_DEVICES_ROLE_FOR_CAPTURE_PRESET,
+ REMOVE_DEVICES_ROLE_FOR_CAPTURE_PRESET,
+ CLEAR_DEVICES_ROLE_FOR_CAPTURE_PRESET,
+ GET_DEVICES_FOR_ROLE_AND_CAPTURE_PRESET,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -1173,31 +1178,18 @@
return reply.readBool();
}
- virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+ virtual status_t setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32((int32_t) uid);
- size_t size = devices.size();
- size_t sizePosition = data.dataPosition();
- data.writeInt32((int32_t) size);
- size_t finalSize = size;
- for (size_t i = 0; i < size; i++) {
- size_t position = data.dataPosition();
- if (devices[i].writeToParcel(&data) != NO_ERROR) {
- data.setDataPosition(position);
- finalSize--;
- }
- }
- if (size != finalSize) {
- size_t position = data.dataPosition();
- data.setDataPosition(sizePosition);
- data.writeInt32(finalSize);
- data.setDataPosition(position);
+ status_t status = data.writeParcelableVector(devices);
+ if (status != NO_ERROR) {
+ return status;
}
- status_t status = remote()->transact(SET_UID_DEVICE_AFFINITY, data, &reply);
+ status = remote()->transact(SET_UID_DEVICE_AFFINITY, data, &reply);
if (status == NO_ERROR) {
status = (status_t)reply.readInt32();
}
@@ -1218,51 +1210,37 @@
return status;
}
- virtual status_t setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ virtual status_t setUserIdDeviceAffinities(int userId, const AudioDeviceTypeAddrVector& devices)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
- data.writeInt32((int32_t) userId);
- size_t size = devices.size();
- size_t sizePosition = data.dataPosition();
- data.writeInt32((int32_t) size);
- size_t finalSize = size;
- for (size_t i = 0; i < size; i++) {
- size_t position = data.dataPosition();
- if (devices[i].writeToParcel(&data) != NO_ERROR) {
- data.setDataPosition(position);
- finalSize--;
- }
- }
- if (size != finalSize) {
- size_t position = data.dataPosition();
- data.setDataPosition(sizePosition);
- data.writeInt32(finalSize);
- data.setDataPosition(position);
- }
-
- status_t status = remote()->transact(SET_USERID_DEVICE_AFFINITY, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t)reply.readInt32();
- }
+ data.writeInt32((int32_t) userId);
+ status_t status = data.writeParcelableVector(devices);
+ if (status != NO_ERROR) {
return status;
}
- virtual status_t removeUserIdDeviceAffinities(int userId) {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-
- data.writeInt32((int32_t) userId);
-
- status_t status =
- remote()->transact(REMOVE_USERID_DEVICE_AFFINITY, data, &reply);
- if (status == NO_ERROR) {
- status = (status_t) reply.readInt32();
- }
- return status;
+ status = remote()->transact(SET_USERID_DEVICE_AFFINITY, data, &reply);
+ if (status == NO_ERROR) {
+ status = (status_t)reply.readInt32();
}
+ return status;
+ }
+
+ virtual status_t removeUserIdDeviceAffinities(int userId) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+ data.writeInt32((int32_t) userId);
+
+ status_t status =
+ remote()->transact(REMOVE_USERID_DEVICE_AFFINITY, data, &reply);
+ if (status == NO_ERROR) {
+ status = (status_t) reply.readInt32();
+ }
+ return status;
+ }
virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies)
{
@@ -1384,17 +1362,31 @@
return reply.readBool();
}
- virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device)
+ virtual status_t setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role, const AudioDeviceTypeAddrVector &devices)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeUint32(static_cast<uint32_t>(strategy));
- status_t status = device.writeToParcel(&data);
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = data.writeParcelableVector(devices);
if (status != NO_ERROR) {
return BAD_VALUE;
}
- status = remote()->transact(SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+ status = remote()->transact(SET_DEVICES_ROLE_FOR_PRODUCT_STRATEGY, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeUint32(static_cast<uint32_t>(strategy));
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = remote()->transact(REMOVE_DEVICES_ROLE_FOR_PRODUCT_STRATEGY,
data, &reply);
if (status != NO_ERROR) {
return status;
@@ -1402,31 +1394,108 @@
return static_cast<status_t>(reply.readInt32());
}
- virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy)
+ virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role, AudioDeviceTypeAddrVector &devices)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeUint32(static_cast<uint32_t>(strategy));
- status_t status = remote()->transact(REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
- data, &reply);
- if (status != NO_ERROR) {
- return status;
- }
- return static_cast<status_t>(reply.readInt32());
- }
-
- virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
- data.writeUint32(static_cast<uint32_t>(strategy));
- status_t status = remote()->transact(GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = remote()->transact(GET_DEVICES_FOR_ROLE_AND_PRODUCT_STRATEGY,
data, &reply);
if (status != NO_ERROR) {
return status;
}
- status = device.readFromParcel(&reply);
+ status = reply.readParcelableVector(&devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector &devices) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeUint32(static_cast<uint32_t>(audioSource));
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = data.writeParcelableVector(devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(SET_DEVICES_ROLE_FOR_CAPTURE_PRESET, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector &devices)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeUint32(static_cast<uint32_t>(audioSource));
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = data.writeParcelableVector(devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(ADD_DEVICES_ROLE_FOR_CAPTURE_PRESET, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeUint32(static_cast<uint32_t>(audioSource));
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = data.writeParcelableVector(devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(REMOVE_DEVICES_ROLE_FOR_CAPTURE_PRESET,
+ data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t clearDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeUint32(static_cast<uint32_t>(audioSource));
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = remote()->transact(CLEAR_DEVICES_ROLE_FOR_CAPTURE_PRESET,
+ data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast<status_t>(reply.readInt32());
+ }
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeUint32(static_cast<uint32_t>(audioSource));
+ data.writeUint32(static_cast<uint32_t>(role));
+ status_t status = remote()->transact(GET_DEVICES_FOR_ROLE_AND_CAPTURE_PRESET,
+ data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = reply.readParcelableVector(&devices);
if (status != NO_ERROR) {
return status;
}
@@ -1561,15 +1630,20 @@
case RELEASE_SOUNDTRIGGER_SESSION:
case SET_RTT_ENABLED:
case IS_CALL_SCREEN_MODE_SUPPORTED:
- case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
+ case SET_DEVICES_ROLE_FOR_PRODUCT_STRATEGY:
case SET_SUPPORTED_SYSTEM_USAGES:
- case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
- case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
+ case REMOVE_DEVICES_ROLE_FOR_PRODUCT_STRATEGY:
+ case GET_DEVICES_FOR_ROLE_AND_PRODUCT_STRATEGY:
case GET_DEVICES_FOR_ATTRIBUTES:
case SET_ALLOWED_CAPTURE_POLICY:
case AUDIO_MODULES_UPDATED:
case SET_CURRENT_IME_UID:
- case REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER: {
+ case REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER:
+ case SET_DEVICES_ROLE_FOR_CAPTURE_PRESET:
+ case ADD_DEVICES_ROLE_FOR_CAPTURE_PRESET:
+ case REMOVE_DEVICES_ROLE_FOR_CAPTURE_PRESET:
+ case CLEAR_DEVICES_ROLE_FOR_CAPTURE_PRESET:
+ case GET_DEVICES_FOR_ROLE_AND_CAPTURE_PRESET: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@@ -2460,15 +2534,12 @@
case SET_UID_DEVICE_AFFINITY: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
const uid_t uid = (uid_t) data.readInt32();
- Vector<AudioDeviceTypeAddr> devices;
- size_t size = (size_t)data.readInt32();
- for (size_t i = 0; i < size; i++) {
- AudioDeviceTypeAddr device;
- if (device.readFromParcel((Parcel*)&data) == NO_ERROR) {
- devices.add(device);
- }
+ AudioDeviceTypeAddrVector devices;
+ status_t status = data.readParcelableVector(&devices);
+ if (status != NO_ERROR) {
+ return status;
}
- status_t status = setUidDeviceAffinities(uid, devices);
+ status = setUidDeviceAffinities(uid, devices);
reply->writeInt32(status);
return NO_ERROR;
}
@@ -2484,15 +2555,12 @@
case SET_USERID_DEVICE_AFFINITY: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
const int userId = (int) data.readInt32();
- Vector<AudioDeviceTypeAddr> devices;
- size_t size = (size_t)data.readInt32();
- for (size_t i = 0; i < size; i++) {
- AudioDeviceTypeAddr device;
- if (device.readFromParcel((Parcel*)&data) == NO_ERROR) {
- devices.add(device);
- }
+ AudioDeviceTypeAddrVector devices;
+ status_t status = data.readParcelableVector(&devices);
+ if (status != NO_ERROR) {
+ return status;
}
- status_t status = setUserIdDeviceAffinities(userId, devices);
+ status = setUserIdDeviceAffinities(userId, devices);
reply->writeInt32(status);
return NO_ERROR;
}
@@ -2649,33 +2717,36 @@
return NO_ERROR;
}
- case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
+ case SET_DEVICES_ROLE_FOR_PRODUCT_STRATEGY: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
product_strategy_t strategy = (product_strategy_t) data.readUint32();
- AudioDeviceTypeAddr device;
- status_t status = device.readFromParcel((Parcel*)&data);
+ device_role_t role = (device_role_t) data.readUint32();
+ AudioDeviceTypeAddrVector devices;
+ status_t status = data.readParcelableVector(&devices);
if (status != NO_ERROR) {
return status;
}
- status = setPreferredDeviceForStrategy(strategy, device);
+ status = setDevicesRoleForStrategy(strategy, role, devices);
reply->writeInt32(status);
return NO_ERROR;
}
- case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
+ case REMOVE_DEVICES_ROLE_FOR_PRODUCT_STRATEGY: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
product_strategy_t strategy = (product_strategy_t) data.readUint32();
- status_t status = removePreferredDeviceForStrategy(strategy);
+ device_role_t role = (device_role_t) data.readUint32();
+ status_t status = removeDevicesRoleForStrategy(strategy, role);
reply->writeInt32(status);
return NO_ERROR;
}
- case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: {
+ case GET_DEVICES_FOR_ROLE_AND_PRODUCT_STRATEGY: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
product_strategy_t strategy = (product_strategy_t) data.readUint32();
- AudioDeviceTypeAddr device;
- status_t status = getPreferredDeviceForStrategy(strategy, device);
- status_t marshall_status = device.writeToParcel(reply);
+ device_role_t role = (device_role_t) data.readUint32();
+ AudioDeviceTypeAddrVector devices;
+ status_t status = getDevicesForRoleAndStrategy(strategy, role, devices);
+ status_t marshall_status = reply->writeParcelableVector(devices);
if (marshall_status != NO_ERROR) {
return marshall_status;
}
@@ -2757,6 +2828,71 @@
return NO_ERROR;
} break;
+ case SET_DEVICES_ROLE_FOR_CAPTURE_PRESET: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_source_t audioSource = (audio_source_t) data.readUint32();
+ device_role_t role = (device_role_t) data.readUint32();
+ AudioDeviceTypeAddrVector devices;
+ status_t status = data.readParcelableVector(&devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = setDevicesRoleForCapturePreset(audioSource, role, devices);
+ reply->writeInt32(status);
+ return NO_ERROR;
+ }
+
+ case ADD_DEVICES_ROLE_FOR_CAPTURE_PRESET: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_source_t audioSource = (audio_source_t) data.readUint32();
+ device_role_t role = (device_role_t) data.readUint32();
+ AudioDeviceTypeAddrVector devices;
+ status_t status = data.readParcelableVector(&devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = addDevicesRoleForCapturePreset(audioSource, role, devices);
+ reply->writeInt32(status);
+ return NO_ERROR;
+ }
+
+ case REMOVE_DEVICES_ROLE_FOR_CAPTURE_PRESET: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_source_t audioSource = (audio_source_t) data.readUint32();
+ device_role_t role = (device_role_t) data.readUint32();
+ AudioDeviceTypeAddrVector devices;
+ status_t status = data.readParcelableVector(&devices);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = removeDevicesRoleForCapturePreset(audioSource, role, devices);
+ reply->writeInt32(status);
+ return NO_ERROR;
+ }
+
+ case CLEAR_DEVICES_ROLE_FOR_CAPTURE_PRESET: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_source_t audioSource = (audio_source_t) data.readUint32();
+ device_role_t role = (device_role_t) data.readUint32();
+ status_t status = clearDevicesRoleForCapturePreset(audioSource, role);
+ reply->writeInt32(status);
+ return NO_ERROR;
+ }
+
+ case GET_DEVICES_FOR_ROLE_AND_CAPTURE_PRESET: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_source_t audioSource = (audio_source_t) data.readUint32();
+ device_role_t role = (device_role_t) data.readUint32();
+ AudioDeviceTypeAddrVector devices;
+ status_t status = getDevicesForRoleAndCapturePreset(audioSource, role, devices);
+ status_t marshall_status = reply->writeParcelableVector(devices);
+ if (marshall_status != NO_ERROR) {
+ return marshall_status;
+ }
+ reply->writeInt32(status);
+ return NO_ERROR;
+ }
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 19c2cbd..848743a 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -361,11 +361,11 @@
static status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
- static status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+ static status_t setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices);
static status_t removeUidDeviceAffinities(uid_t uid);
- static status_t setUserIdDeviceAffinities(int userId, const Vector<AudioDeviceTypeAddr>& devices);
+ static status_t setUserIdDeviceAffinities(int userId, const AudioDeviceTypeAddrVector& devices);
static status_t removeUserIdDeviceAffinities(int userId);
@@ -425,13 +425,29 @@
*/
static status_t setAudioHalPids(const std::vector<pid_t>& pids);
- static status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device);
+ static status_t setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role, const AudioDeviceTypeAddrVector &devices);
- static status_t removePreferredDeviceForStrategy(product_strategy_t strategy);
+ static status_t removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role);
- static status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device);
+ static status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role, AudioDeviceTypeAddrVector &devices);
+
+ static status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector &devices);
+
+ static status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector &devices);
+
+ static status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices);
+
+ static status_t clearDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role);
+
+ static status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices);
static status_t getDeviceForStrategy(product_strategy_t strategy,
AudioDeviceTypeAddr &device);
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index bb1c07f..2d5f687 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -196,13 +196,13 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration) = 0;
- virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+ virtual status_t setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices)
= 0;
virtual status_t removeUidDeviceAffinities(uid_t uid) = 0;
virtual status_t setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices) = 0;
+ const AudioDeviceTypeAddrVector& devices) = 0;
virtual status_t removeUserIdDeviceAffinities(int userId) = 0;
@@ -241,13 +241,35 @@
virtual bool isCallScreenModeSupported() = 0;
- virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device) = 0;
+ virtual status_t setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
- virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0;
+ virtual status_t removeDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role) = 0;
- virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device) = 0;
+ virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices) = 0;
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) = 0;
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices) = 0;
// The return code here is only intended to represent transport errors. The
// actual server implementation should always return NO_ERROR.
diff --git a/media/libaudiofoundation/AudioDeviceTypeAddr.cpp b/media/libaudiofoundation/AudioDeviceTypeAddr.cpp
index d65d6ac..a47337b 100644
--- a/media/libaudiofoundation/AudioDeviceTypeAddr.cpp
+++ b/media/libaudiofoundation/AudioDeviceTypeAddr.cpp
@@ -16,12 +16,57 @@
#include <media/AudioDeviceTypeAddr.h>
+#include <arpa/inet.h>
+#include <iostream>
+#include <regex>
+#include <set>
+#include <sstream>
+
namespace android {
+namespace {
+
+static const std::string SUPPRESSED = "SUPPRESSED";
+static const std::regex MAC_ADDRESS_REGEX("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
+
+bool isSenstiveAddress(const std::string &address) {
+ if (std::regex_match(address, MAC_ADDRESS_REGEX)) {
+ return true;
+ }
+
+ sockaddr_storage ss4;
+ if (inet_pton(AF_INET, address.c_str(), &ss4) > 0) {
+ return true;
+ }
+
+ sockaddr_storage ss6;
+ if (inet_pton(AF_INET6, address.c_str(), &ss6) > 0) {
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+AudioDeviceTypeAddr::AudioDeviceTypeAddr(audio_devices_t type, const std::string &address) :
+ mType(type), mAddress(address) {
+ mIsAddressSensitive = isSenstiveAddress(mAddress);
+}
+
const char* AudioDeviceTypeAddr::getAddress() const {
return mAddress.c_str();
}
+const std::string& AudioDeviceTypeAddr::address() const {
+ return mAddress;
+}
+
+void AudioDeviceTypeAddr::setAddress(const std::string& address) {
+ mAddress = address;
+ mIsAddressSensitive = isSenstiveAddress(mAddress);
+}
+
bool AudioDeviceTypeAddr::equals(const AudioDeviceTypeAddr& other) const {
return mType == other.mType && mAddress == other.mAddress;
}
@@ -36,9 +81,27 @@
return false;
}
+bool AudioDeviceTypeAddr::operator==(const AudioDeviceTypeAddr &rhs) const {
+ return equals(rhs);
+}
+
+bool AudioDeviceTypeAddr::operator!=(const AudioDeviceTypeAddr &rhs) const {
+ return !operator==(rhs);
+}
+
void AudioDeviceTypeAddr::reset() {
mType = AUDIO_DEVICE_NONE;
- mAddress = "";
+ setAddress("");
+}
+
+std::string AudioDeviceTypeAddr::toString(bool includeSensitiveInfo) const {
+ std::stringstream sstream;
+ sstream << "type:0x" << std::hex << mType;
+ // IP and MAC address are sensitive information. The sensitive information will be suppressed
+ // is `includeSensitiveInfo` is false.
+ sstream << ",@:"
+ << (!includeSensitiveInfo && mIsAddressSensitive ? SUPPRESSED : mAddress);
+ return sstream.str();
}
status_t AudioDeviceTypeAddr::readFromParcel(const Parcel *parcel) {
@@ -66,4 +129,30 @@
return deviceTypes;
}
+AudioDeviceTypeAddrVector excludeDeviceTypeAddrsFrom(
+ const AudioDeviceTypeAddrVector& devices,
+ const AudioDeviceTypeAddrVector& devicesToExclude) {
+ std::set<AudioDeviceTypeAddr> devicesToExcludeSet(
+ devicesToExclude.begin(), devicesToExclude.end());
+ AudioDeviceTypeAddrVector remainedDevices;
+ for (const auto& device : devices) {
+ if (devicesToExcludeSet.count(device) == 0) {
+ remainedDevices.push_back(device);
+ }
+ }
+ return remainedDevices;
}
+
+std::string dumpAudioDeviceTypeAddrVector(const AudioDeviceTypeAddrVector& deviceTypeAddrs,
+ bool includeSensitiveInfo) {
+ std::stringstream stream;
+ for (auto it = deviceTypeAddrs.begin(); it != deviceTypeAddrs.end(); ++it) {
+ if (it != deviceTypeAddrs.begin()) {
+ stream << " ";
+ }
+ stream << it->toString(includeSensitiveInfo);
+ }
+ return stream.str();
+}
+
+} // namespace android
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index e9b589d..16cf71a 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -22,9 +22,6 @@
#include <media/DeviceDescriptorBase.h>
#include <media/TypeConverter.h>
-#include <arpa/inet.h>
-#include <regex>
-
namespace android {
DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type) :
@@ -37,46 +34,19 @@
{
}
-namespace {
-
-static const std::string SUPPRESSED = "SUPPRESSED";
-static const std::regex MAC_ADDRESS_REGEX("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
-
-bool isAddressSensitive(const std::string &address) {
- if (std::regex_match(address, MAC_ADDRESS_REGEX)) {
- return true;
- }
-
- sockaddr_storage ss4;
- if (inet_pton(AF_INET, address.c_str(), &ss4) > 0) {
- return true;
- }
-
- sockaddr_storage ss6;
- if (inet_pton(AF_INET6, address.c_str(), &ss6) > 0) {
- return true;
- }
-
- return false;
-}
-
-} // namespace
-
DeviceDescriptorBase::DeviceDescriptorBase(const AudioDeviceTypeAddr &deviceTypeAddr) :
AudioPort("", AUDIO_PORT_TYPE_DEVICE,
audio_is_output_device(deviceTypeAddr.mType) ? AUDIO_PORT_ROLE_SINK :
AUDIO_PORT_ROLE_SOURCE),
mDeviceTypeAddr(deviceTypeAddr)
{
- if (mDeviceTypeAddr.mAddress.empty() && audio_is_remote_submix_device(mDeviceTypeAddr.mType)) {
- mDeviceTypeAddr.mAddress = "0";
+ if (mDeviceTypeAddr.address().empty() && audio_is_remote_submix_device(mDeviceTypeAddr.mType)) {
+ mDeviceTypeAddr.setAddress("0");
}
- mIsAddressSensitive = isAddressSensitive(mDeviceTypeAddr.mAddress);
}
void DeviceDescriptorBase::setAddress(const std::string &address) {
- mDeviceTypeAddr.mAddress = address;
- mIsAddressSensitive = isAddressSensitive(address);
+ mDeviceTypeAddr.setAddress(address);
}
void DeviceDescriptorBase::toAudioPortConfig(struct audio_port_config *dstConfig,
@@ -157,7 +127,7 @@
"%*s- supported encapsulation metadata types: %u",
spaces, "", mEncapsulationMetadataTypes));
- if (mDeviceTypeAddr.mAddress.size() != 0) {
+ if (mDeviceTypeAddr.address().size() != 0) {
dst->append(base::StringPrintf(
"%*s- address: %-32s\n", spaces, "", mDeviceTypeAddr.getAddress()));
}
@@ -166,14 +136,7 @@
std::string DeviceDescriptorBase::toString(bool includeSensitiveInfo) const
{
- std::stringstream sstream;
- sstream << "type:0x" << std::hex << type();
- // IP and MAC address are sensitive information. The sensitive information will be suppressed
- // is `includeSensitiveInfo` is false.
- sstream << ",@:"
- << (!includeSensitiveInfo && mIsAddressSensitive ? SUPPRESSED
- : mDeviceTypeAddr.mAddress);
- return sstream.str();
+ return mDeviceTypeAddr.toString(includeSensitiveInfo);
}
void DeviceDescriptorBase::log() const
diff --git a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
index 60ea78e..7497faf 100644
--- a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
+++ b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h
@@ -27,28 +27,43 @@
namespace android {
-struct AudioDeviceTypeAddr : public Parcelable {
+class AudioDeviceTypeAddr : public Parcelable {
+public:
AudioDeviceTypeAddr() = default;
- AudioDeviceTypeAddr(audio_devices_t type, const std::string& address) :
- mType(type), mAddress(address) {}
+ AudioDeviceTypeAddr(audio_devices_t type, const std::string& address);
const char* getAddress() const;
+ const std::string& address() const;
+
+ void setAddress(const std::string& address);
+
+ bool isAddressSensitive();
+
bool equals(const AudioDeviceTypeAddr& other) const;
AudioDeviceTypeAddr& operator= (const AudioDeviceTypeAddr&) = default;
bool operator<(const AudioDeviceTypeAddr& other) const;
+ bool operator==(const AudioDeviceTypeAddr& rhs) const;
+
+ bool operator!=(const AudioDeviceTypeAddr& rhs) const;
+
void reset();
+ std::string toString(bool includeSensitiveInfo=false) const;
+
status_t readFromParcel(const Parcel *parcel) override;
status_t writeToParcel(Parcel *parcel) const override;
audio_devices_t mType = AUDIO_DEVICE_NONE;
+
+private:
std::string mAddress;
+ bool mIsAddressSensitive;
};
using AudioDeviceTypeAddrVector = std::vector<AudioDeviceTypeAddr>;
@@ -58,4 +73,15 @@
*/
DeviceTypeSet getAudioDeviceTypes(const AudioDeviceTypeAddrVector& deviceTypeAddrs);
-}
+/**
+ * Return a collection of AudioDeviceTypeAddrs that are shown in `devices` but not
+ * in `devicesToExclude`
+ */
+AudioDeviceTypeAddrVector excludeDeviceTypeAddrsFrom(
+ const AudioDeviceTypeAddrVector& devices,
+ const AudioDeviceTypeAddrVector& devicesToExclude);
+
+std::string dumpAudioDeviceTypeAddrVector(const AudioDeviceTypeAddrVector& deviceTypeAddrs,
+ bool includeSensitiveInfo=false);
+
+} // namespace android
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index c143c7e..0cbd1de 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -41,7 +41,7 @@
virtual ~DeviceDescriptorBase() {}
audio_devices_t type() const { return mDeviceTypeAddr.mType; }
- std::string address() const { return mDeviceTypeAddr.mAddress; }
+ const std::string& address() const { return mDeviceTypeAddr.address(); }
void setAddress(const std::string &address);
const AudioDeviceTypeAddr& getDeviceTypeAddr() const { return mDeviceTypeAddr; }
@@ -77,7 +77,6 @@
protected:
AudioDeviceTypeAddr mDeviceTypeAddr;
- bool mIsAddressSensitive;
uint32_t mEncapsulationModes = 0;
uint32_t mEncapsulationMetadataTypes = 0;
};
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 7d0d83d..12d70c3 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -212,7 +212,7 @@
const struct audio_config *config, size_t *size) {
if (mDevice == 0) return NO_INIT;
AudioConfig hidlConfig;
- HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+ HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Result retval;
Return<void> ret = mDevice->getInputBufferSize(
hidlConfig,
@@ -237,7 +237,7 @@
status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
if (status != OK) return status;
AudioConfig hidlConfig;
- HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+ HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
Result retval = Result::NOT_INITIALIZED;
Return<void> ret = mDevice->openOutputStream(
handle,
@@ -272,7 +272,7 @@
status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
if (status != OK) return status;
AudioConfig hidlConfig;
- HidlUtils::audioConfigFromHal(*config, &hidlConfig);
+ HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Result retval = Result::NOT_INITIALIZED;
#if MAJOR_VERSION == 2
auto sinkMetadata = AudioSource(source);
diff --git a/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh b/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh
index d0faebe..8aadfbf 100755
--- a/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/downmix/tests/build_and_run_all_unit_tests.sh
@@ -39,8 +39,7 @@
echo "testing Downmix"
adb shell mkdir $testdir
-adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw \
-$testdir
+adb push $ANDROID_BUILD_TOP/frameworks/av/media/libeffects/res/raw/sinesweepraw.raw $testdir
adb push $OUT/testcases/downmixtest/arm64/downmixtest $testdir
#run the downmix test application for test.
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index dbe0d62..34cad1f 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -204,10 +204,12 @@
"Reverb/lib",
"Common/lib",
],
-
+ static_libs: [
+ "libaudioutils",
+ ],
cppflags: [
+ "-DBIQUAD_OPT",
"-fvisibility=hidden",
-
"-Wall",
"-Werror",
],
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
index bccbe86..f4e625f 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Control.cpp
@@ -21,6 +21,9 @@
/* */
/****************************************************************************************/
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
#include "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "VectorArithmetic.h"
@@ -179,6 +182,9 @@
LVM_UINT16 i; /* Filter band index */
LVEQNB_BiquadType_en BiquadType; /* Filter biquad type */
+#ifdef BIQUAD_OPT
+ pInstance->gain.resize(pInstance->Params.NBands);
+#endif
/*
* Set the coefficients for each band by the init function
*/
@@ -198,8 +204,19 @@
/*
* Set the coefficients
*/
+#ifdef BIQUAD_OPT
+ pInstance->gain[i] = Coefficients.G;
+ std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+ Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+ -(Coefficients.B2)};
+ pInstance->eqBiquad[i]
+ .setCoefficients<
+ std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+ coefs);
+#else
PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState_Float[i],
&pInstance->pEQNB_Taps_Float[i], &Coefficients);
+#endif
break;
}
default:
@@ -220,6 +237,11 @@
/* */
/************************************************************************************/
void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t* pInstance) {
+#ifdef BIQUAD_OPT
+ for (size_t i = 0; i < pInstance->eqBiquad.size(); i++) {
+ pInstance->eqBiquad[i].clear();
+ }
+#else
LVM_FLOAT* pTapAddress;
LVM_INT16 NumTaps;
@@ -233,6 +255,7 @@
pTapAddress, /* Destination */
NumTaps); /* Number of words */
}
+#endif
}
/****************************************************************************************/
/* */
@@ -310,6 +333,16 @@
(OperatingModeSave == LVEQNB_ON && pInstance->bInOperatingModeTransition &&
LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0);
+#ifdef BIQUAD_OPT
+ /*
+ * Create biquad instance
+ */
+ pInstance->eqBiquad.resize(
+ pParams->NBands, android::audio_utils::BiquadFilter<LVM_FLOAT>(
+ (FCC_1 == pParams->NrChannels) ? FCC_2 : pParams->NrChannels));
+ LVEQNB_ClearFilterHistory(pInstance);
+#endif
+
if (bChange || modeChange) {
/*
* If the sample rate has changed clear the history
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
index 1d2a5f5..57df4db 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.cpp
@@ -62,6 +62,9 @@
pInstance->pScratch = pScratch;
/* Equaliser Biquad Instance */
+#ifdef BIQUAD_OPT
+ LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions));
+#else
LVM_UINT32 MemSize = pCapabilities->MaxBands * sizeof(*(pInstance->pEQNB_FilterState_Float));
pInstance->pEQNB_FilterState_Float = (Biquad_FLOAT_Instance_t*)calloc(1, MemSize);
if (pInstance->pEQNB_FilterState_Float == LVM_NULL) {
@@ -75,6 +78,7 @@
}
MemSize = (pCapabilities->MaxBands * sizeof(*(pInstance->pBandDefinitions)));
+#endif
pInstance->pBandDefinitions = (LVEQNB_BandDef_t*)calloc(1, MemSize);
if (pInstance->pBandDefinitions == LVM_NULL) {
return LVEQNB_NULLADDRESS;
@@ -105,10 +109,11 @@
*/
LVEQNB_SetFilters(pInstance, /* Set the filter types */
&pInstance->Params);
-
+#ifndef BIQUAD_OPT
LVEQNB_SetCoefficients(pInstance); /* Set the filter coefficients */
LVEQNB_ClearFilterHistory(pInstance); /* Clear the filter history */
+#endif
/*
* Initialise the bypass variables
@@ -154,6 +159,7 @@
}
pInstance = (LVEQNB_Instance_t*)*phInstance;
+#ifndef BIQUAD_OPT
/* Equaliser Biquad Instance */
if (pInstance->pEQNB_FilterState_Float != LVM_NULL) {
free(pInstance->pEQNB_FilterState_Float);
@@ -163,6 +169,7 @@
free(pInstance->pEQNB_Taps_Float);
pInstance->pEQNB_Taps_Float = LVM_NULL;
}
+#endif
if (pInstance->pBandDefinitions != LVM_NULL) {
free(pInstance->pBandDefinitions);
pInstance->pBandDefinitions = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
index 83a3449..32bad29 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Private.h
@@ -24,6 +24,9 @@
/* */
/****************************************************************************************/
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
#include "LVEQNB.h" /* Calling or Application layer definitions */
#include "BIQUAD.h"
#include "LVC_Mixer.h"
@@ -69,8 +72,14 @@
/* Aligned memory pointers */
LVM_FLOAT* pFastTemporary; /* Fast temporary data base address */
+#ifdef BIQUAD_OPT
+ std::vector<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+ eqBiquad; /* Biquad filter instances */
+ std::vector<LVM_FLOAT> gain; /* Gain values for all bands*/
+#else
Biquad_2I_Order2_FLOAT_Taps_t* pEQNB_Taps_Float; /* Equaliser Taps */
Biquad_FLOAT_Instance_t* pEQNB_FilterState_Float; /* State for each filter band */
+#endif
/* Filter definitions and call back */
LVM_UINT16 NBands; /* Number of bands */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
index d2a26db..3f0be7c 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.cpp
@@ -104,19 +104,30 @@
* Check if band is non-zero dB gain
*/
if (pInstance->pBandDefinitions[i].Gain != 0) {
+#ifndef BIQUAD_OPT
/*
* Get the address of the biquad instance
*/
Biquad_FLOAT_Instance_t* pBiquad = &pInstance->pEQNB_FilterState_Float[i];
+#endif
/*
* Select single or double precision as required
*/
switch (pInstance->pBiquadType[i]) {
case LVEQNB_SinglePrecision_Float: {
+#ifdef BIQUAD_OPT
+ LVM_FLOAT* pTemp = pScratch + NrSamples;
+ pInstance->eqBiquad[i].process(pTemp, pScratch, NrFrames);
+ const auto gain = pInstance->gain[i];
+ for (unsigned j = 0; j < NrSamples; ++j) {
+ pScratch[j] += pTemp[j] * gain;
+ }
+#else
PK_Mc_D32F32C14G11_TRC_WRA_01(pBiquad, pScratch, pScratch,
(LVM_INT16)NrFrames,
(LVM_INT16)NrChannels);
+#endif
break;
}
default:
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
index 737ef01..be846eb 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
@@ -20,6 +20,10 @@
/* Includes */
/* */
/****************************************************************************************/
+
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
#include "LVREV_Private.h"
#include "Filter.h"
@@ -71,10 +75,17 @@
Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
LVM_FO_HPF(Omega, &Coeffs);
+#ifdef BIQUAD_OPT
+ const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+ Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+ pPrivate->pRevHPFBiquad.reset(
+ new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->HPCoefs, &pPrivate->pFastData->HPTaps,
&Coeffs);
LoadConst_Float(0, (LVM_FLOAT*)&pPrivate->pFastData->HPTaps,
sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+#endif
}
/*
@@ -99,10 +110,17 @@
LVM_FO_LPF(Omega, &Coeffs);
}
}
+#ifdef BIQUAD_OPT
+ const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+ Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+ pPrivate->pRevLPFBiquad.reset(
+ new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->LPCoefs, &pPrivate->pFastData->LPTaps,
&Coeffs);
LoadConst_Float(0, (LVM_FLOAT*)&pPrivate->pFastData->LPTaps,
sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
+#endif
}
/*
@@ -231,8 +249,15 @@
Coeffs.A1 = 0;
Coeffs.B1 = 0;
}
+#ifdef BIQUAD_OPT
+ const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+ Coeffs.A0, Coeffs.A1, 0.0, -(Coeffs.B1), 0.0};
+ pPrivate->revLPFBiquad[i].reset(
+ new android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1, coefs));
+#else
FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i],
&pPrivate->pFastData->RevLPTaps[i], &Coeffs);
+#endif
}
}
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
index 5c83ce5..f542a2b 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
@@ -56,13 +56,24 @@
* Clear all filter tap data, delay-lines and other signal related data
*/
+#ifdef BIQUAD_OPT
+ pLVREV_Private->pRevHPFBiquad->clear();
+ pLVREV_Private->pRevLPFBiquad->clear();
+#else
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->HPTaps, 2);
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->LPTaps, 2);
+#endif
if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4) {
+#ifdef BIQUAD_OPT
+ for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
+ pLVREV_Private->revLPFBiquad[i]->clear();
+ }
+#else
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+#endif
LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
@@ -71,15 +82,25 @@
}
if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_2) {
+#ifdef BIQUAD_OPT
+ for (int i = 0; i < LVREV_DELAYLINES_2; i++) {
+ pLVREV_Private->revLPFBiquad[i]->clear();
+ }
+#else
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+#endif
LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
}
if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_1) {
+#ifdef BIQUAD_OPT
+ pLVREV_Private->revLPFBiquad[0]->clear();
+#else
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+#endif
LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
}
return LVREV_SUCCESS;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
index b5db23b..6ed0605 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
@@ -134,9 +134,11 @@
/*
* Set the data, coefficient and temporary memory pointers
*/
+#ifndef BIQUAD_OPT
/* Fast data memory base address */
pLVREV_Private->pFastData =
(LVREV_FastData_st*)InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
+#endif
if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
pLVREV_Private->pDelay_T[3] =
(LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
@@ -194,9 +196,11 @@
pLVREV_Private->T[3] = LVREV_MAX_T3_DELAY;
pLVREV_Private->AB_Selection = 1; /* Select smoothing A to B */
+#ifndef BIQUAD_OPT
/* Fast coefficient memory base address */
pLVREV_Private->pFastCoef =
(LVREV_FastCoef_st*)InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
+#endif
/* General purpose scratch */
pLVREV_Private->pScratch =
(LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
@@ -308,6 +312,17 @@
pLVREV_Private->A_DelaySize[3] = LVREV_MAX_AP3_DELAY;
pLVREV_Private->B_DelaySize[3] = LVREV_MAX_AP3_DELAY;
+#ifdef BIQUAD_OPT
+ pLVREV_Private->pRevHPFBiquad.reset(
+ new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+ pLVREV_Private->pRevLPFBiquad.reset(
+ new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+ for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
+ pLVREV_Private->revLPFBiquad[i].reset(
+ new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
+ }
+#endif
+
LVREV_ClearAudioBuffers(*phInstance);
return LVREV_SUCCESS;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
index 2c1e04d..e8b2019 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
@@ -139,7 +139,9 @@
/*
* Persistent fast data memory
*/
+#ifndef BIQUAD_OPT
InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
+#endif
if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
@@ -163,7 +165,9 @@
/*
* Persistent fast coefficient memory
*/
+#ifndef BIQUAD_OPT
InstAlloc_AddMember(&FastCoef, sizeof(LVREV_FastCoef_st));
+#endif
pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Size = InstAlloc_GetTotal(&FastCoef);
pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].Type = LVM_PERSISTENT_FAST_COEF;
pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index b6edb03..e52a1ca 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -23,6 +23,10 @@
/* Includes */
/* */
/****************************************************************************************/
+
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
#include "LVREV.h"
#include "LVREV_Tables.h"
#include "BIQUAD.h"
@@ -101,12 +105,12 @@
/* */
/****************************************************************************************/
+#ifndef BIQUAD_OPT
/* Fast data structure */
typedef struct {
Biquad_1I_Order1_FLOAT_Taps_t HPTaps; /* High pass filter taps */
Biquad_1I_Order1_FLOAT_Taps_t LPTaps; /* Low pass filter taps */
Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[4]; /* Reverb low pass filters taps */
-
} LVREV_FastData_st;
/* Fast coefficient structure */
@@ -114,8 +118,9 @@
Biquad_FLOAT_Instance_t HPCoefs; /* High pass filter coefficients */
Biquad_FLOAT_Instance_t LPCoefs; /* Low pass filter coefficients */
Biquad_FLOAT_Instance_t RevLPCoefs[4]; /* Reverb low pass filters coefficients */
-
} LVREV_FastCoef_st;
+#endif
+
typedef struct {
/* General */
LVREV_InstanceParams_st InstanceParams; /* Initialisation time instance parameters */
@@ -134,8 +139,17 @@
processing */
/* Aligned memory pointers */
- LVREV_FastData_st* pFastData; /* Fast data memory base address */
- LVREV_FastCoef_st* pFastCoef; /* Fast coefficient memory base address */
+#ifdef BIQUAD_OPT
+ std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+ pRevHPFBiquad; /* Biquad filter instance for HPF */
+ std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+ pRevLPFBiquad; /* Biquad filter instance for LPF */
+ std::array<std::unique_ptr<android::audio_utils::BiquadFilter<LVM_FLOAT>>, LVREV_DELAYLINES_4>
+ revLPFBiquad; /* Biquad filter instance for Reverb LPF */
+#else
+ LVREV_FastData_st* pFastData; /* Fast data memory base address */
+ LVREV_FastCoef_st* pFastCoef; /* Fast coefficient memory base address */
+#endif
LVM_FLOAT* pScratchDelayLine[4]; /* Delay line scratch memory */
LVM_FLOAT* pScratch; /* Multi ussge scratch */
LVM_FLOAT* pInputSave; /* Reverb block input save for dry/wet
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
index ed3b89c..e4f939f 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Process.cpp
@@ -204,11 +204,20 @@
/*
* High pass filter
*/
+#ifdef BIQUAD_OPT
+ pPrivate->pRevHPFBiquad->process(pTemp, pTemp, NumSamples);
+#else
FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->HPCoefs, pTemp, pTemp, (LVM_INT16)NumSamples);
+#endif
+
/*
* Low pass filter
*/
+#ifdef BIQUAD_OPT
+ pPrivate->pRevLPFBiquad->process(pTemp, pTemp, NumSamples);
+#else
FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->LPCoefs, pTemp, pTemp, (LVM_INT16)NumSamples);
+#endif
/*
* Process all delay lines
@@ -253,8 +262,12 @@
/*
* Low pass filter
*/
+#ifdef BIQUAD_OPT
+ pPrivate->revLPFBiquad[j]->process(pDelayLine, pDelayLine, NumSamples);
+#else
FO_1I_D32F32C31_TRC_WRA_01(&pPrivate->pFastCoef->RevLPCoefs[j], pDelayLine, pDelayLine,
(LVM_INT16)NumSamples);
+#endif
}
/*
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
index a97acc9..e96263c 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -23,7 +23,7 @@
echo "========================================"
echo "testing lvm"
adb shell mkdir -p $testdir
-adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw $testdir
+adb push $ANDROID_BUILD_TOP/frameworks/av/media/libeffects/res/raw/sinesweepraw.raw $testdir
adb push $OUT/testcases/snr/arm64/snr $testdir
E_VAL=1
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
index 0c3b0b5..86b21ae 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
@@ -23,7 +23,7 @@
echo "========================================"
echo "testing reverb"
adb shell mkdir -p $testdir
-adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw $testdir
+adb push $ANDROID_BUILD_TOP/frameworks/av/media/libeffects/res/raw/sinesweepraw.raw $testdir
E_VAL=1
cmds="adb push $OUT/testcases/reverb_test/arm/reverb_test $testdir"
diff --git a/media/libeffects/lvm/tests/reverb_test.cpp b/media/libeffects/lvm/tests/reverb_test.cpp
index 7cbca9b..b7704ff 100644
--- a/media/libeffects/lvm/tests/reverb_test.cpp
+++ b/media/libeffects/lvm/tests/reverb_test.cpp
@@ -340,7 +340,7 @@
const int outChannelCount = (channelCount == 1 ? 2 : channelCount);
std::vector<short> in(frameLength * maxChannelCount);
- std::vector<short> out(frameLength * maxChannelCount);
+ std::vector<short> out(frameLength * outChannelCount);
std::vector<float> floatIn(frameLength * channelCount);
std::vector<float> floatOut(frameLength * outChannelCount);
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index 5217cf9..681e247 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -1,35 +1,5 @@
// audio preprocessing wrapper
cc_library_shared {
- name: "libaudiopreprocessing_legacy",
-
- vendor: true,
-
- relative_install_path: "soundfx",
-
- srcs: ["PreProcessing.cpp"],
-
- shared_libs: [
- "libwebrtc_audio_preprocessing",
- "libspeexresampler",
- "libutils",
- "liblog",
- ],
-
- cflags: [
- "-DWEBRTC_POSIX",
- "-DWEBRTC_LEGACY",
- "-fvisibility=hidden",
- "-Wall",
- "-Werror",
- ],
-
- header_libs: [
- "libaudioeffects",
- "libhardware_headers",
- ],
-}
-
-cc_library_shared {
name: "libaudiopreprocessing",
vendor: true,
relative_install_path: "soundfx",
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 1a5547b..03ccc34 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -23,15 +23,10 @@
#include <hardware/audio_effect.h>
#include <utils/Log.h>
#include <utils/Timers.h>
-#ifndef WEBRTC_LEGACY
#include <audio_effects/effect_agc2.h>
-#endif
#include <audio_effects/effect_ns.h>
#include <audio_processing.h>
#include <module_common_types.h>
-#ifdef WEBRTC_LEGACY
-#include "speex/speex_resampler.h"
-#endif
// undefine to perform multi channels API functional tests
//#define DUAL_MIC_TEST
@@ -46,9 +41,7 @@
// types of pre processing modules
enum preproc_id {
PREPROC_AGC, // Automatic Gain Control
-#ifndef WEBRTC_LEGACY
PREPROC_AGC2, // Automatic Gain Control 2
-#endif
PREPROC_AEC, // Acoustic Echo Canceler
PREPROC_NS, // Noise Suppressor
PREPROC_NUM_EFFECTS
@@ -110,10 +103,8 @@
int id; // audio session ID
int io; // handle of input stream this session is on
webrtc::AudioProcessing* apm; // handle on webRTC audio processing module (APM)
-#ifndef WEBRTC_LEGACY
// Audio Processing module builder
webrtc::AudioProcessingBuilder ap_builder;
-#endif
size_t apmFrameCount; // buffer size for webRTC process (10 ms)
uint32_t apmSamplingRate; // webRTC APM sampling rate (8/16 or 32 kHz)
size_t frameCount; // buffer size before input resampler ( <=> apmFrameCount)
@@ -124,42 +115,25 @@
uint32_t enabledMsk; // bit field containing IDs of enabled pre processors
uint32_t processedMsk; // bit field containing IDs of pre processors already
// processed in current round
-#ifdef WEBRTC_LEGACY
- webrtc::AudioFrame* procFrame; // audio frame passed to webRTC AMP ProcessStream()
-#else
// audio config strucutre
webrtc::AudioProcessing::Config config;
webrtc::StreamConfig inputConfig; // input stream configuration
webrtc::StreamConfig outputConfig; // output stream configuration
-#endif
int16_t* inBuf; // input buffer used when resampling
size_t inBufSize; // input buffer size in frames
size_t framesIn; // number of frames in input buffer
-#ifdef WEBRTC_LEGACY
- SpeexResamplerState* inResampler; // handle on input speex resampler
-#endif
int16_t* outBuf; // output buffer used when resampling
size_t outBufSize; // output buffer size in frames
size_t framesOut; // number of frames in output buffer
-#ifdef WEBRTC_LEGACY
- SpeexResamplerState* outResampler; // handle on output speex resampler
-#endif
uint32_t revChannelCount; // number of channels on reverse stream
uint32_t revEnabledMsk; // bit field containing IDs of enabled pre processors
// with reverse channel
uint32_t revProcessedMsk; // bit field containing IDs of pre processors with reverse
// channel already processed in current round
-#ifdef WEBRTC_LEGACY
- webrtc::AudioFrame* revFrame; // audio frame passed to webRTC AMP AnalyzeReverseStream()
-#else
webrtc::StreamConfig revConfig; // reverse stream configuration.
-#endif
int16_t* revBuf; // reverse channel input buffer
size_t revBufSize; // reverse channel input buffer size
size_t framesRev; // number of frames in reverse channel input buffer
-#ifdef WEBRTC_LEGACY
- SpeexResamplerState* revResampler; // handle on reverse channel input speex resampler
-#endif
};
#ifdef DUAL_MIC_TEST
@@ -213,7 +187,6 @@
"Automatic Gain Control",
"The Android Open Source Project"};
-#ifndef WEBRTC_LEGACY
// Automatic Gain Control 2
static const effect_descriptor_t sAgc2Descriptor = {
{0xae3c653b, 0xbe18, 0x4ab8, 0x8938, {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}}, // type
@@ -224,7 +197,6 @@
0, // FIXME indicate memory usage
"Automatic Gain Control 2",
"The Android Open Source Project"};
-#endif
// Acoustic Echo Cancellation
static const effect_descriptor_t sAecDescriptor = {
@@ -249,9 +221,7 @@
"The Android Open Source Project"};
static const effect_descriptor_t* sDescriptors[PREPROC_NUM_EFFECTS] = {&sAgcDescriptor,
-#ifndef WEBRTC_LEGACY
&sAgc2Descriptor,
-#endif
&sAecDescriptor,
&sNsDescriptor};
@@ -260,9 +230,7 @@
//------------------------------------------------------------------------------
const effect_uuid_t* const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {FX_IID_AGC,
-#ifndef WEBRTC_LEGACY
FX_IID_AGC2,
-#endif
FX_IID_AEC, FX_IID_NS};
const effect_uuid_t* ProcIdToUuid(int procId) {
@@ -297,7 +265,6 @@
static const int kAgcDefaultCompGain = 9;
static const bool kAgcDefaultLimiter = true;
-#ifndef WEBRTC_LEGACY
int Agc2Init(preproc_effect_t* effect) {
ALOGV("Agc2Init");
effect->session->config = effect->session->apm->GetConfig();
@@ -308,48 +275,27 @@
effect->session->apm->ApplyConfig(effect->session->config);
return 0;
}
-#endif
int AgcInit(preproc_effect_t* effect) {
ALOGV("AgcInit");
-#ifdef WEBRTC_LEGACY
- webrtc::GainControl* agc = static_cast<webrtc::GainControl*>(effect->engine);
- agc->set_mode(webrtc::GainControl::kFixedDigital);
- agc->set_target_level_dbfs(kAgcDefaultTargetLevel);
- agc->set_compression_gain_db(kAgcDefaultCompGain);
- agc->enable_limiter(kAgcDefaultLimiter);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.gain_controller1.target_level_dbfs = kAgcDefaultTargetLevel;
effect->session->config.gain_controller1.compression_gain_db = kAgcDefaultCompGain;
effect->session->config.gain_controller1.enable_limiter = kAgcDefaultLimiter;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
return 0;
}
-#ifndef WEBRTC_LEGACY
int Agc2Create(preproc_effect_t* effect) {
Agc2Init(effect);
return 0;
}
-#endif
int AgcCreate(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- webrtc::GainControl* agc = effect->session->apm->gain_control();
- ALOGV("AgcCreate got agc %p", agc);
- if (agc == NULL) {
- ALOGW("AgcCreate Error");
- return -ENOMEM;
- }
- effect->engine = static_cast<preproc_fx_handle_t>(agc);
-#endif
AgcInit(effect);
return 0;
}
-#ifndef WEBRTC_LEGACY
int Agc2GetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
int status = 0;
uint32_t param = *(uint32_t*)pParam;
@@ -422,15 +368,11 @@
return status;
}
-#endif
int AgcGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
int status = 0;
uint32_t param = *(uint32_t*)pParam;
t_agc_settings* pProperties = (t_agc_settings*)pValue;
-#ifdef WEBRTC_LEGACY
- webrtc::GainControl* agc = static_cast<webrtc::GainControl*>(effect->engine);
-#endif
switch (param) {
case AGC_PARAM_TARGET_LEVEL:
@@ -459,32 +401,6 @@
break;
}
-#ifdef WEBRTC_LEGACY
- switch (param) {
- case AGC_PARAM_TARGET_LEVEL:
- *(int16_t*)pValue = (int16_t)(agc->target_level_dbfs() * -100);
- ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t*)pValue);
- break;
- case AGC_PARAM_COMP_GAIN:
- *(int16_t*)pValue = (int16_t)(agc->compression_gain_db() * 100);
- ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t*)pValue);
- break;
- case AGC_PARAM_LIMITER_ENA:
- *(bool*)pValue = (bool)agc->is_limiter_enabled();
- ALOGV("AgcGetParameter() limiter enabled %s",
- (*(int16_t*)pValue != 0) ? "true" : "false");
- break;
- case AGC_PARAM_PROPERTIES:
- pProperties->targetLevel = (int16_t)(agc->target_level_dbfs() * -100);
- pProperties->compGain = (int16_t)(agc->compression_gain_db() * 100);
- pProperties->limiterEnabled = (bool)agc->is_limiter_enabled();
- break;
- default:
- ALOGW("AgcGetParameter() unknown param %d", param);
- status = -EINVAL;
- break;
- }
-#else
effect->session->config = effect->session->apm->GetConfig();
switch (param) {
case AGC_PARAM_TARGET_LEVEL:
@@ -515,11 +431,9 @@
status = -EINVAL;
break;
}
-#endif
return status;
}
-#ifndef WEBRTC_LEGACY
int Agc2SetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
int status = 0;
uint32_t param = *(uint32_t*)pParam;
@@ -567,43 +481,9 @@
return status;
}
-#endif
int AgcSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
int status = 0;
-#ifdef WEBRTC_LEGACY
- uint32_t param = *(uint32_t*)pParam;
- t_agc_settings* pProperties = (t_agc_settings*)pValue;
- webrtc::GainControl* agc = static_cast<webrtc::GainControl*>(effect->engine);
-
- switch (param) {
- case AGC_PARAM_TARGET_LEVEL:
- ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t*)pValue);
- status = agc->set_target_level_dbfs(-(*(int16_t*)pValue / 100));
- break;
- case AGC_PARAM_COMP_GAIN:
- ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t*)pValue);
- status = agc->set_compression_gain_db(*(int16_t*)pValue / 100);
- break;
- case AGC_PARAM_LIMITER_ENA:
- ALOGV("AgcSetParameter() limiter enabled %s", *(bool*)pValue ? "true" : "false");
- status = agc->enable_limiter(*(bool*)pValue);
- break;
- case AGC_PARAM_PROPERTIES:
- ALOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
- pProperties->targetLevel, pProperties->compGain, pProperties->limiterEnabled);
- status = agc->set_target_level_dbfs(-(pProperties->targetLevel / 100));
- if (status != 0) break;
- status = agc->set_compression_gain_db(pProperties->compGain / 100);
- if (status != 0) break;
- status = agc->enable_limiter(pProperties->limiterEnabled);
- break;
- default:
- ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
- status = -EINVAL;
- break;
- }
-#else
uint32_t param = *(uint32_t*)pParam;
t_agc_settings* pProperties = (t_agc_settings*)pValue;
effect->session->config = effect->session->apm->GetConfig();
@@ -637,96 +517,57 @@
break;
}
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
ALOGV("AgcSetParameter() done status %d", status);
return status;
}
-#ifndef WEBRTC_LEGACY
void Agc2Enable(preproc_effect_t* effect) {
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.gain_controller2.enabled = true;
effect->session->apm->ApplyConfig(effect->session->config);
}
-#endif
void AgcEnable(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- webrtc::GainControl* agc = static_cast<webrtc::GainControl*>(effect->engine);
- ALOGV("AgcEnable agc %p", agc);
- agc->Enable(true);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.gain_controller1.enabled = true;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
}
-#ifndef WEBRTC_LEGACY
void Agc2Disable(preproc_effect_t* effect) {
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.gain_controller2.enabled = false;
effect->session->apm->ApplyConfig(effect->session->config);
}
-#endif
void AgcDisable(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- ALOGV("AgcDisable");
- webrtc::GainControl* agc = static_cast<webrtc::GainControl*>(effect->engine);
- agc->Enable(false);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.gain_controller1.enabled = false;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
}
static const preproc_ops_t sAgcOps = {AgcCreate, AgcInit, NULL, AgcEnable, AgcDisable,
AgcSetParameter, AgcGetParameter, NULL};
-#ifndef WEBRTC_LEGACY
static const preproc_ops_t sAgc2Ops = {Agc2Create, Agc2Init, NULL,
Agc2Enable, Agc2Disable, Agc2SetParameter,
Agc2GetParameter, NULL};
-#endif
//------------------------------------------------------------------------------
// Acoustic Echo Canceler (AEC)
//------------------------------------------------------------------------------
-#ifdef WEBRTC_LEGACY
-static const webrtc::EchoControlMobile::RoutingMode kAecDefaultMode =
- webrtc::EchoControlMobile::kEarpiece;
-static const bool kAecDefaultComfortNoise = true;
-#endif
int AecInit(preproc_effect_t* effect) {
ALOGV("AecInit");
-#ifdef WEBRTC_LEGACY
- webrtc::EchoControlMobile* aec = static_cast<webrtc::EchoControlMobile*>(effect->engine);
- aec->set_routing_mode(kAecDefaultMode);
- aec->enable_comfort_noise(kAecDefaultComfortNoise);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.echo_canceller.mobile_mode = true;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
return 0;
}
int AecCreate(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- webrtc::EchoControlMobile* aec = effect->session->apm->echo_control_mobile();
- ALOGV("AecCreate got aec %p", aec);
- if (aec == NULL) {
- ALOGW("AgcCreate Error");
- return -ENOMEM;
- }
- effect->engine = static_cast<preproc_fx_handle_t>(aec);
-#endif
AecInit(effect);
return 0;
}
@@ -744,13 +585,11 @@
*(uint32_t*)pValue = 1000 * effect->session->apm->stream_delay_ms();
ALOGV("AecGetParameter() echo delay %d us", *(uint32_t*)pValue);
break;
-#ifndef WEBRTC_LEGACY
case AEC_PARAM_MOBILE_MODE:
effect->session->config = effect->session->apm->GetConfig();
*(uint32_t*)pValue = effect->session->config.echo_canceller.mobile_mode;
ALOGV("AecGetParameter() mobile mode %d us", *(uint32_t*)pValue);
break;
-#endif
default:
ALOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
status = -EINVAL;
@@ -770,14 +609,12 @@
status = effect->session->apm->set_stream_delay_ms(value / 1000);
ALOGV("AecSetParameter() echo delay %d us, status %d", value, status);
break;
-#ifndef WEBRTC_LEGACY
case AEC_PARAM_MOBILE_MODE:
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.echo_canceller.mobile_mode = value;
ALOGV("AecSetParameter() mobile mode %d us", value);
effect->session->apm->ApplyConfig(effect->session->config);
break;
-#endif
default:
ALOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
status = -EINVAL;
@@ -787,57 +624,24 @@
}
void AecEnable(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- webrtc::EchoControlMobile* aec = static_cast<webrtc::EchoControlMobile*>(effect->engine);
- ALOGV("AecEnable aec %p", aec);
- aec->Enable(true);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.echo_canceller.enabled = true;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
}
void AecDisable(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- ALOGV("AecDisable");
- webrtc::EchoControlMobile* aec = static_cast<webrtc::EchoControlMobile*>(effect->engine);
- aec->Enable(false);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.echo_canceller.enabled = false;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
}
int AecSetDevice(preproc_effect_t* effect, uint32_t device) {
ALOGV("AecSetDevice %08x", device);
-#ifdef WEBRTC_LEGACY
- webrtc::EchoControlMobile* aec = static_cast<webrtc::EchoControlMobile*>(effect->engine);
- webrtc::EchoControlMobile::RoutingMode mode =
- webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;
-#endif
if (audio_is_input_device(device)) {
return 0;
}
-#ifdef WEBRTC_LEGACY
- switch (device) {
- case AUDIO_DEVICE_OUT_EARPIECE:
- mode = webrtc::EchoControlMobile::kEarpiece;
- break;
- case AUDIO_DEVICE_OUT_SPEAKER:
- mode = webrtc::EchoControlMobile::kSpeakerphone;
- break;
- case AUDIO_DEVICE_OUT_WIRED_HEADSET:
- case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
- case AUDIO_DEVICE_OUT_USB_HEADSET:
- default:
- break;
- }
- aec->set_routing_mode(mode);
-#endif
return 0;
}
@@ -849,49 +653,19 @@
// Noise Suppression (NS)
//------------------------------------------------------------------------------
-#ifdef WEBRTC_LEGACY
-static const webrtc::NoiseSuppression::Level kNsDefaultLevel = webrtc::NoiseSuppression::kModerate;
-#else
static const webrtc::AudioProcessing::Config::NoiseSuppression::Level kNsDefaultLevel =
webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
-#endif
int NsInit(preproc_effect_t* effect) {
ALOGV("NsInit");
-#ifdef WEBRTC_LEGACY
- webrtc::NoiseSuppression* ns = static_cast<webrtc::NoiseSuppression*>(effect->engine);
- ns->set_level(kNsDefaultLevel);
- webrtc::Config config;
- std::vector<webrtc::Point> geometry;
- // TODO(aluebs): Make the geometry settable.
- geometry.push_back(webrtc::Point(-0.03f, 0.f, 0.f));
- geometry.push_back(webrtc::Point(-0.01f, 0.f, 0.f));
- geometry.push_back(webrtc::Point(0.01f, 0.f, 0.f));
- geometry.push_back(webrtc::Point(0.03f, 0.f, 0.f));
- // The geometry needs to be set with Beamforming enabled.
- config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry));
- effect->session->apm->SetExtraOptions(config);
- config.Set<webrtc::Beamforming>(new webrtc::Beamforming(false, geometry));
- effect->session->apm->SetExtraOptions(config);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.noise_suppression.level = kNsDefaultLevel;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
effect->type = NS_TYPE_SINGLE_CHANNEL;
return 0;
}
int NsCreate(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- webrtc::NoiseSuppression* ns = effect->session->apm->noise_suppression();
- ALOGV("NsCreate got ns %p", ns);
- if (ns == NULL) {
- ALOGW("AgcCreate Error");
- return -ENOMEM;
- }
- effect->engine = static_cast<preproc_fx_handle_t>(ns);
-#endif
NsInit(effect);
return 0;
}
@@ -904,31 +678,6 @@
int NsSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
int status = 0;
-#ifdef WEBRTC_LEGACY
- webrtc::NoiseSuppression* ns = static_cast<webrtc::NoiseSuppression*>(effect->engine);
- uint32_t param = *(uint32_t*)pParam;
- uint32_t value = *(uint32_t*)pValue;
- switch (param) {
- case NS_PARAM_LEVEL:
- ns->set_level((webrtc::NoiseSuppression::Level)value);
- ALOGV("NsSetParameter() level %d", value);
- break;
- case NS_PARAM_TYPE: {
- webrtc::Config config;
- std::vector<webrtc::Point> geometry;
- bool is_beamforming_enabled = value == NS_TYPE_MULTI_CHANNEL && ns->is_enabled();
- config.Set<webrtc::Beamforming>(
- new webrtc::Beamforming(is_beamforming_enabled, geometry));
- effect->session->apm->SetExtraOptions(config);
- effect->type = value;
- ALOGV("NsSetParameter() type %d", value);
- break;
- }
- default:
- ALOGW("NsSetParameter() unknown param %08x value %08x", param, value);
- status = -EINVAL;
- }
-#else
uint32_t param = *(uint32_t*)pParam;
uint32_t value = *(uint32_t*)pValue;
effect->session->config = effect->session->apm->GetConfig();
@@ -943,52 +692,28 @@
status = -EINVAL;
}
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
return status;
}
void NsEnable(preproc_effect_t* effect) {
-#ifdef WEBRTC_LEGACY
- webrtc::NoiseSuppression* ns = static_cast<webrtc::NoiseSuppression*>(effect->engine);
- ALOGV("NsEnable ns %p", ns);
- ns->Enable(true);
- if (effect->type == NS_TYPE_MULTI_CHANNEL) {
- webrtc::Config config;
- std::vector<webrtc::Point> geometry;
- config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry));
- effect->session->apm->SetExtraOptions(config);
- }
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.noise_suppression.enabled = true;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
}
void NsDisable(preproc_effect_t* effect) {
ALOGV("NsDisable");
-#ifdef WEBRTC_LEGACY
- webrtc::NoiseSuppression* ns = static_cast<webrtc::NoiseSuppression*>(effect->engine);
- ns->Enable(false);
- webrtc::Config config;
- std::vector<webrtc::Point> geometry;
- config.Set<webrtc::Beamforming>(new webrtc::Beamforming(false, geometry));
- effect->session->apm->SetExtraOptions(config);
-#else
effect->session->config = effect->session->apm->GetConfig();
effect->session->config.noise_suppression.enabled = false;
effect->session->apm->ApplyConfig(effect->session->config);
-#endif
}
static const preproc_ops_t sNsOps = {NsCreate, NsInit, NULL, NsEnable,
NsDisable, NsSetParameter, NsGetParameter, NULL};
static const preproc_ops_t* sPreProcOps[PREPROC_NUM_EFFECTS] = {&sAgcOps,
-#ifndef WEBRTC_LEGACY
&sAgc2Ops,
-#endif
&sAecOps, &sNsOps};
//------------------------------------------------------------------------------
@@ -1119,9 +844,6 @@
session->id = 0;
session->io = 0;
session->createdMsk = 0;
-#ifdef WEBRTC_LEGACY
- session->apm = NULL;
-#endif
for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) {
status = Effect_Init(&session->effects[i], i);
}
@@ -1135,75 +857,32 @@
ALOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk);
if (session->createdMsk == 0) {
-#ifdef WEBRTC_LEGACY
- session->apm = webrtc::AudioProcessing::Create();
- if (session->apm == NULL) {
- ALOGW("Session_CreateEffect could not get apm engine");
- goto error;
- }
- const webrtc::ProcessingConfig processing_config = {
- {{kPreprocDefaultSr, kPreProcDefaultCnl},
- {kPreprocDefaultSr, kPreProcDefaultCnl},
- {kPreprocDefaultSr, kPreProcDefaultCnl},
- {kPreprocDefaultSr, kPreProcDefaultCnl}}};
- session->apm->Initialize(processing_config);
- session->procFrame = new webrtc::AudioFrame();
- if (session->procFrame == NULL) {
- ALOGW("Session_CreateEffect could not allocate audio frame");
- goto error;
- }
- session->revFrame = new webrtc::AudioFrame();
- if (session->revFrame == NULL) {
- ALOGW("Session_CreateEffect could not allocate reverse audio frame");
- goto error;
- }
-#else
session->apm = session->ap_builder.Create();
if (session->apm == NULL) {
ALOGW("Session_CreateEffect could not get apm engine");
goto error;
}
-#endif
session->apmSamplingRate = kPreprocDefaultSr;
session->apmFrameCount = (kPreprocDefaultSr) / 100;
session->frameCount = session->apmFrameCount;
session->samplingRate = kPreprocDefaultSr;
session->inChannelCount = kPreProcDefaultCnl;
session->outChannelCount = kPreProcDefaultCnl;
-#ifdef WEBRTC_LEGACY
- session->procFrame->sample_rate_hz_ = kPreprocDefaultSr;
- session->procFrame->num_channels_ = kPreProcDefaultCnl;
-#else
session->inputConfig.set_sample_rate_hz(kPreprocDefaultSr);
session->inputConfig.set_num_channels(kPreProcDefaultCnl);
session->outputConfig.set_sample_rate_hz(kPreprocDefaultSr);
session->outputConfig.set_num_channels(kPreProcDefaultCnl);
-#endif
session->revChannelCount = kPreProcDefaultCnl;
-#ifdef WEBRTC_LEGACY
- session->revFrame->sample_rate_hz_ = kPreprocDefaultSr;
- session->revFrame->num_channels_ = kPreProcDefaultCnl;
-#else
session->revConfig.set_sample_rate_hz(kPreprocDefaultSr);
session->revConfig.set_num_channels(kPreProcDefaultCnl);
-#endif
session->enabledMsk = 0;
session->processedMsk = 0;
session->revEnabledMsk = 0;
session->revProcessedMsk = 0;
-#ifdef WEBRTC_LEGACY
- session->inResampler = NULL;
-#endif
session->inBuf = NULL;
session->inBufSize = 0;
-#ifdef WEBRTC_LEGACY
- session->outResampler = NULL;
-#endif
session->outBuf = NULL;
session->outBufSize = 0;
-#ifdef WEBRTC_LEGACY
- session->revResampler = NULL;
-#endif
session->revBuf = NULL;
session->revBufSize = 0;
}
@@ -1217,17 +896,8 @@
error:
if (session->createdMsk == 0) {
-#ifdef WEBRTC_LEGACY
- delete session->revFrame;
- session->revFrame = NULL;
- delete session->procFrame;
- session->procFrame = NULL;
- delete session->apm;
- session->apm = NULL; // NOLINT(clang-analyzer-cplusplus.NewDelete)
-#else
delete session->apm;
session->apm = NULL;
-#endif
}
return status;
}
@@ -1236,29 +906,8 @@
ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
session->createdMsk &= ~(1 << fx->procId);
if (session->createdMsk == 0) {
-#ifdef WEBRTC_LEGACY
delete session->apm;
session->apm = NULL;
- delete session->procFrame;
- session->procFrame = NULL;
- delete session->revFrame;
- session->revFrame = NULL;
- if (session->inResampler != NULL) {
- speex_resampler_destroy(session->inResampler);
- session->inResampler = NULL;
- }
- if (session->outResampler != NULL) {
- speex_resampler_destroy(session->outResampler);
- session->outResampler = NULL;
- }
- if (session->revResampler != NULL) {
- speex_resampler_destroy(session->revResampler);
- session->revResampler = NULL;
- }
-#else
- delete session->apm;
- session->apm = NULL;
-#endif
delete session->inBuf;
session->inBuf = NULL;
delete session->outBuf;
@@ -1284,9 +933,6 @@
ALOGV("Session_SetConfig sr %d cnl %08x", config->inputCfg.samplingRate,
config->inputCfg.channels);
-#ifdef WEBRTC_LEGACY
- int status;
-#endif
// AEC implementation is limited to 16kHz
if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
@@ -1297,51 +943,25 @@
session->apmSamplingRate = 8000;
}
-#ifdef WEBRTC_LEGACY
- const webrtc::ProcessingConfig processing_config = {
- {{static_cast<int>(session->apmSamplingRate), inCnl},
- {static_cast<int>(session->apmSamplingRate), outCnl},
- {static_cast<int>(session->apmSamplingRate), inCnl},
- {static_cast<int>(session->apmSamplingRate), inCnl}}};
- status = session->apm->Initialize(processing_config);
- if (status < 0) {
- return -EINVAL;
- }
-#endif
session->samplingRate = config->inputCfg.samplingRate;
session->apmFrameCount = session->apmSamplingRate / 100;
if (session->samplingRate == session->apmSamplingRate) {
session->frameCount = session->apmFrameCount;
} else {
-#ifdef WEBRTC_LEGACY
- session->frameCount =
- (session->apmFrameCount * session->samplingRate) / session->apmSamplingRate + 1;
-#else
session->frameCount =
(session->apmFrameCount * session->samplingRate) / session->apmSamplingRate;
-#endif
}
session->inChannelCount = inCnl;
session->outChannelCount = outCnl;
-#ifdef WEBRTC_LEGACY
- session->procFrame->num_channels_ = inCnl;
- session->procFrame->sample_rate_hz_ = session->apmSamplingRate;
-#else
session->inputConfig.set_sample_rate_hz(session->samplingRate);
session->inputConfig.set_num_channels(inCnl);
session->outputConfig.set_sample_rate_hz(session->samplingRate);
session->outputConfig.set_num_channels(inCnl);
-#endif
session->revChannelCount = inCnl;
-#ifdef WEBRTC_LEGACY
- session->revFrame->num_channels_ = inCnl;
- session->revFrame->sample_rate_hz_ = session->apmSamplingRate;
-#else
session->revConfig.set_sample_rate_hz(session->samplingRate);
session->revConfig.set_num_channels(inCnl);
-#endif
// force process buffer reallocation
session->inBufSize = 0;
@@ -1349,53 +969,6 @@
session->framesIn = 0;
session->framesOut = 0;
-#ifdef WEBRTC_LEGACY
- if (session->inResampler != NULL) {
- speex_resampler_destroy(session->inResampler);
- session->inResampler = NULL;
- }
- if (session->outResampler != NULL) {
- speex_resampler_destroy(session->outResampler);
- session->outResampler = NULL;
- }
- if (session->revResampler != NULL) {
- speex_resampler_destroy(session->revResampler);
- session->revResampler = NULL;
- }
- if (session->samplingRate != session->apmSamplingRate) {
- int error;
- session->inResampler =
- speex_resampler_init(session->inChannelCount, session->samplingRate,
- session->apmSamplingRate, RESAMPLER_QUALITY, &error);
- if (session->inResampler == NULL) {
- ALOGW("Session_SetConfig Cannot create speex resampler: %s",
- speex_resampler_strerror(error));
- return -EINVAL;
- }
- session->outResampler =
- speex_resampler_init(session->outChannelCount, session->apmSamplingRate,
- session->samplingRate, RESAMPLER_QUALITY, &error);
- if (session->outResampler == NULL) {
- ALOGW("Session_SetConfig Cannot create speex resampler: %s",
- speex_resampler_strerror(error));
- speex_resampler_destroy(session->inResampler);
- session->inResampler = NULL;
- return -EINVAL;
- }
- session->revResampler =
- speex_resampler_init(session->inChannelCount, session->samplingRate,
- session->apmSamplingRate, RESAMPLER_QUALITY, &error);
- if (session->revResampler == NULL) {
- ALOGW("Session_SetConfig Cannot create speex resampler: %s",
- speex_resampler_strerror(error));
- speex_resampler_destroy(session->inResampler);
- session->inResampler = NULL;
- speex_resampler_destroy(session->outResampler);
- session->outResampler = NULL;
- return -EINVAL;
- }
- }
-#endif
session->state = PREPROC_SESSION_STATE_CONFIG;
return 0;
@@ -1430,22 +1003,7 @@
return -EINVAL;
}
uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
-#ifdef WEBRTC_LEGACY
- const webrtc::ProcessingConfig processing_config = {
- {{static_cast<int>(session->apmSamplingRate), session->inChannelCount},
- {static_cast<int>(session->apmSamplingRate), session->outChannelCount},
- {static_cast<int>(session->apmSamplingRate), inCnl},
- {static_cast<int>(session->apmSamplingRate), inCnl}}};
- int status = session->apm->Initialize(processing_config);
- if (status < 0) {
- return -EINVAL;
- }
-#endif
session->revChannelCount = inCnl;
-#ifdef WEBRTC_LEGACY
- session->revFrame->num_channels_ = inCnl;
- session->revFrame->sample_rate_hz_ = session->apmSamplingRate;
-#endif
// force process buffer reallocation
session->revBufSize = 0;
session->framesRev = 0;
@@ -1467,24 +1025,10 @@
if (enabled) {
if (session->enabledMsk == 0) {
session->framesIn = 0;
-#ifdef WEBRTC_LEGACY
- if (session->inResampler != NULL) {
- speex_resampler_reset_mem(session->inResampler);
- }
- session->framesOut = 0;
- if (session->outResampler != NULL) {
- speex_resampler_reset_mem(session->outResampler);
- }
-#endif
}
session->enabledMsk |= (1 << procId);
if (HasReverseStream(procId)) {
session->framesRev = 0;
-#ifdef WEBRTC_LEGACY
- if (session->revResampler != NULL) {
- speex_resampler_reset_mem(session->revResampler);
- }
-#endif
session->revEnabledMsk |= (1 << procId);
}
} else {
@@ -1600,82 +1144,6 @@
return 0;
}
-#ifdef WEBRTC_LEGACY
- if (session->inResampler != NULL) {
- size_t fr = session->frameCount - session->framesIn;
- if (inBuffer->frameCount < fr) {
- fr = inBuffer->frameCount;
- }
- if (session->inBufSize < session->framesIn + fr) {
- int16_t* buf;
- session->inBufSize = session->framesIn + fr;
- buf = (int16_t*)realloc(
- session->inBuf,
- session->inBufSize * session->inChannelCount * sizeof(int16_t));
- if (buf == NULL) {
- session->framesIn = 0;
- free(session->inBuf);
- session->inBuf = NULL;
- return -ENOMEM;
- }
- session->inBuf = buf;
- }
- memcpy(session->inBuf + session->framesIn * session->inChannelCount, inBuffer->s16,
- fr * session->inChannelCount * sizeof(int16_t));
-#ifdef DUAL_MIC_TEST
- pthread_mutex_lock(&gPcmDumpLock);
- if (gPcmDumpFh != NULL) {
- fwrite(inBuffer->raw, fr * session->inChannelCount * sizeof(int16_t), 1,
- gPcmDumpFh);
- }
- pthread_mutex_unlock(&gPcmDumpLock);
-#endif
-
- session->framesIn += fr;
- inBuffer->frameCount = fr;
- if (session->framesIn < session->frameCount) {
- return 0;
- }
- spx_uint32_t frIn = session->framesIn;
- spx_uint32_t frOut = session->apmFrameCount;
- if (session->inChannelCount == 1) {
- speex_resampler_process_int(session->inResampler, 0, session->inBuf, &frIn,
- session->procFrame->data_, &frOut);
- } else {
- speex_resampler_process_interleaved_int(session->inResampler, session->inBuf, &frIn,
- session->procFrame->data_, &frOut);
- }
- memmove(session->inBuf, session->inBuf + frIn * session->inChannelCount,
- (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t));
- session->framesIn -= frIn;
- } else {
- size_t fr = session->frameCount - session->framesIn;
- if (inBuffer->frameCount < fr) {
- fr = inBuffer->frameCount;
- }
- memcpy(session->procFrame->data_ + session->framesIn * session->inChannelCount,
- inBuffer->s16, fr * session->inChannelCount * sizeof(int16_t));
-
-#ifdef DUAL_MIC_TEST
- pthread_mutex_lock(&gPcmDumpLock);
- if (gPcmDumpFh != NULL) {
- fwrite(inBuffer->raw, fr * session->inChannelCount * sizeof(int16_t), 1,
- gPcmDumpFh);
- }
- pthread_mutex_unlock(&gPcmDumpLock);
-#endif
-
- session->framesIn += fr;
- inBuffer->frameCount = fr;
- if (session->framesIn < session->frameCount) {
- return 0;
- }
- session->framesIn = 0;
- }
- session->procFrame->samples_per_channel_ = session->apmFrameCount;
-
- effect->session->apm->ProcessStream(session->procFrame);
-#else
size_t fr = session->frameCount - session->framesIn;
if (inBuffer->frameCount < fr) {
fr = inBuffer->frameCount;
@@ -1696,7 +1164,6 @@
return status;
}
outBuffer->frameCount = inBuffer->frameCount;
-#endif
if (session->outBufSize < session->framesOut + session->frameCount) {
int16_t* buf;
@@ -1713,30 +1180,7 @@
session->outBuf = buf;
}
-#ifdef WEBRTC_LEGACY
- if (session->outResampler != NULL) {
- spx_uint32_t frIn = session->apmFrameCount;
- spx_uint32_t frOut = session->frameCount;
- if (session->inChannelCount == 1) {
- speex_resampler_process_int(
- session->outResampler, 0, session->procFrame->data_, &frIn,
- session->outBuf + session->framesOut * session->outChannelCount, &frOut);
- } else {
- speex_resampler_process_interleaved_int(
- session->outResampler, session->procFrame->data_, &frIn,
- session->outBuf + session->framesOut * session->outChannelCount, &frOut);
- }
- session->framesOut += frOut;
- } else {
- memcpy(session->outBuf + session->framesOut * session->outChannelCount,
- session->procFrame->data_,
- session->frameCount * session->outChannelCount * sizeof(int16_t));
- session->framesOut += session->frameCount;
- }
- size_t fr = session->framesOut;
-#else
fr = session->framesOut;
-#endif
if (framesRq - framesWr < fr) {
fr = framesRq - framesWr;
}
@@ -2129,63 +1573,6 @@
if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) {
effect->session->revProcessedMsk = 0;
-#ifdef WEBRTC_LEGACY
- if (session->revResampler != NULL) {
- size_t fr = session->frameCount - session->framesRev;
- if (inBuffer->frameCount < fr) {
- fr = inBuffer->frameCount;
- }
- if (session->revBufSize < session->framesRev + fr) {
- int16_t* buf;
- session->revBufSize = session->framesRev + fr;
- buf = (int16_t*)realloc(
- session->revBuf,
- session->revBufSize * session->inChannelCount * sizeof(int16_t));
- if (buf == NULL) {
- session->framesRev = 0;
- free(session->revBuf);
- session->revBuf = NULL;
- return -ENOMEM;
- }
- session->revBuf = buf;
- }
- memcpy(session->revBuf + session->framesRev * session->inChannelCount, inBuffer->s16,
- fr * session->inChannelCount * sizeof(int16_t));
-
- session->framesRev += fr;
- inBuffer->frameCount = fr;
- if (session->framesRev < session->frameCount) {
- return 0;
- }
- spx_uint32_t frIn = session->framesRev;
- spx_uint32_t frOut = session->apmFrameCount;
- if (session->inChannelCount == 1) {
- speex_resampler_process_int(session->revResampler, 0, session->revBuf, &frIn,
- session->revFrame->data_, &frOut);
- } else {
- speex_resampler_process_interleaved_int(session->revResampler, session->revBuf,
- &frIn, session->revFrame->data_, &frOut);
- }
- memmove(session->revBuf, session->revBuf + frIn * session->inChannelCount,
- (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t));
- session->framesRev -= frIn;
- } else {
- size_t fr = session->frameCount - session->framesRev;
- if (inBuffer->frameCount < fr) {
- fr = inBuffer->frameCount;
- }
- memcpy(session->revFrame->data_ + session->framesRev * session->inChannelCount,
- inBuffer->s16, fr * session->inChannelCount * sizeof(int16_t));
- session->framesRev += fr;
- inBuffer->frameCount = fr;
- if (session->framesRev < session->frameCount) {
- return 0;
- }
- session->framesRev = 0;
- }
- session->revFrame->samples_per_channel_ = session->apmFrameCount;
- effect->session->apm->AnalyzeReverseStream(session->revFrame);
-#else
size_t fr = session->frameCount - session->framesRev;
if (inBuffer->frameCount < fr) {
fr = inBuffer->frameCount;
@@ -2205,7 +1592,6 @@
ALOGE("Process Reverse Stream failed with error %d\n", status);
return status;
}
-#endif
return 0;
} else {
return -ENODATA;
diff --git a/media/libeffects/preprocessing/benchmarks/Android.bp b/media/libeffects/preprocessing/benchmarks/Android.bp
index 2808293..262fd19 100644
--- a/media/libeffects/preprocessing/benchmarks/Android.bp
+++ b/media/libeffects/preprocessing/benchmarks/Android.bp
@@ -1,31 +1,4 @@
cc_benchmark {
- name: "preprocessing_legacy_benchmark",
- vendor: true,
- relative_install_path: "soundfx",
- srcs: ["preprocessing_benchmark.cpp"],
- shared_libs: [
- "libaudiopreprocessing_legacy",
- "libaudioutils",
- "liblog",
- "libutils",
- "libwebrtc_audio_preprocessing",
- ],
- cflags: [
- "-DWEBRTC_POSIX",
- "-DWEBRTC_LEGACY",
- "-fvisibility=default",
- "-Wall",
- "-Werror",
- "-Wextra",
- ],
- header_libs: [
- "libaudioeffects",
- "libhardware_headers",
- "libwebrtc_absl_headers",
- ],
-}
-
-cc_benchmark {
name: "preprocessing_benchmark",
vendor: true,
relative_install_path: "soundfx",
diff --git a/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp b/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp
index 3a0ad6d..694a6c4 100644
--- a/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp
+++ b/media/libeffects/preprocessing/benchmarks/preprocessing_benchmark.cpp
@@ -54,9 +54,7 @@
#include <cstdlib>
#include <random>
#include <vector>
-#ifndef WEBRTC_LEGACY
#include <audio_effects/effect_agc2.h>
-#endif
#include <audio_effects/effect_ns.h>
#include <benchmark/benchmark.h>
#include <hardware/audio_effect.h>
@@ -76,10 +74,8 @@
{0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
// ns uuid
{0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
-#ifndef WEBRTC_LEGACY
// agc2 uuid
{0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}},
-#endif
};
constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
constexpr audio_channel_mask_t kChMasks[] = {
@@ -93,9 +89,7 @@
PREPROC_AGC, // Automatic Gain Control
PREPROC_AEC, // Acoustic Echo Canceler
PREPROC_NS, // Noise Suppressor
-#ifndef WEBRTC_LEGACY
PREPROC_AGC2, // Automatic Gain Control 2
-#endif
PREPROC_NUM_EFFECTS
};
diff --git a/media/libeffects/preprocessing/tests/Android.bp b/media/libeffects/preprocessing/tests/Android.bp
index 045b0d3..b439880 100644
--- a/media/libeffects/preprocessing/tests/Android.bp
+++ b/media/libeffects/preprocessing/tests/Android.bp
@@ -1,37 +1,5 @@
// audio preprocessing unit test
cc_test {
- name: "AudioPreProcessingLegacyTest",
-
- vendor: true,
-
- relative_install_path: "soundfx",
-
- srcs: ["PreProcessingTest.cpp"],
-
- shared_libs: [
- "libaudiopreprocessing_legacy",
- "libaudioutils",
- "liblog",
- "libutils",
- "libwebrtc_audio_preprocessing",
- ],
-
- cflags: [
- "-DWEBRTC_POSIX",
- "-DWEBRTC_LEGACY",
- "-fvisibility=default",
- "-Wall",
- "-Werror",
- "-Wextra",
- ],
-
- header_libs: [
- "libaudioeffects",
- "libhardware_headers",
- ],
-}
-
-cc_test {
name: "AudioPreProcessingTest",
vendor: true,
diff --git a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
index 65b9469..5f223c9 100644
--- a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
+++ b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
@@ -22,9 +22,7 @@
#include <audio_effects/effect_aec.h>
#include <audio_effects/effect_agc.h>
-#ifndef WEBRTC_LEGACY
#include <audio_effects/effect_agc2.h>
-#endif
#include <audio_effects/effect_ns.h>
#include <log/log.h>
@@ -38,9 +36,7 @@
// types of pre processing modules
enum PreProcId {
PREPROC_AGC, // Automatic Gain Control
-#ifndef WEBRTC_LEGACY
PREPROC_AGC2, // Automatic Gain Control 2
-#endif
PREPROC_AEC, // Acoustic Echo Canceler
PREPROC_NS, // Noise Suppressor
PREPROC_NUM_EFFECTS
@@ -57,11 +53,9 @@
ARG_AGC_COMP_LVL,
ARG_AEC_DELAY,
ARG_NS_LVL,
-#ifndef WEBRTC_LEGACY
ARG_AGC2_GAIN,
ARG_AGC2_LVL,
ARG_AGC2_SAT_MGN
-#endif
};
struct preProcConfigParams_t {
@@ -70,19 +64,15 @@
int nsLevel = 0; // a value between 0-3
int agcTargetLevel = 3; // in dB
int agcCompLevel = 9; // in dB
-#ifndef WEBRTC_LEGACY
float agc2Gain = 0.f; // in dB
float agc2SaturationMargin = 2.f; // in dB
int agc2Level = 0; // either kRms(0) or kPeak(1)
-#endif
int aecDelay = 0; // in ms
};
const effect_uuid_t kPreProcUuids[PREPROC_NUM_EFFECTS] = {
{0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // agc uuid
-#ifndef WEBRTC_LEGACY
{0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}}, // agc2 uuid
-#endif
{0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // aec uuid
{0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // ns uuid
};
@@ -138,24 +128,20 @@
printf("\n Enable Noise Suppression, default disabled");
printf("\n --agc");
printf("\n Enable Gain Control, default disabled");
-#ifndef WEBRTC_LEGACY
printf("\n --agc2");
printf("\n Enable Gain Controller 2, default disabled");
-#endif
printf("\n --ns_lvl <ns_level>");
printf("\n Noise Suppression level in dB, default value 0dB");
printf("\n --agc_tgt_lvl <target_level>");
printf("\n AGC Target Level in dB, default value 3dB");
printf("\n --agc_comp_lvl <comp_level>");
printf("\n AGC Comp Level in dB, default value 9dB");
-#ifndef WEBRTC_LEGACY
printf("\n --agc2_gain <fixed_digital_gain>");
printf("\n AGC Fixed Digital Gain in dB, default value 0dB");
printf("\n --agc2_lvl <level_estimator>");
printf("\n AGC Adaptive Digital Level Estimator, default value kRms");
printf("\n --agc2_sat_mgn <saturation_margin>");
printf("\n AGC Adaptive Digital Saturation Margin in dB, default value 2dB");
-#endif
printf("\n --aec_delay <delay>");
printf("\n AEC delay value in ms, default value 0ms");
printf("\n");
@@ -217,18 +203,14 @@
{"ch_mask", required_argument, nullptr, ARG_CH_MASK},
{"agc_tgt_lvl", required_argument, nullptr, ARG_AGC_TGT_LVL},
{"agc_comp_lvl", required_argument, nullptr, ARG_AGC_COMP_LVL},
-#ifndef WEBRTC_LEGACY
{"agc2_gain", required_argument, nullptr, ARG_AGC2_GAIN},
{"agc2_lvl", required_argument, nullptr, ARG_AGC2_LVL},
{"agc2_sat_mgn", required_argument, nullptr, ARG_AGC2_SAT_MGN},
-#endif
{"aec_delay", required_argument, nullptr, ARG_AEC_DELAY},
{"ns_lvl", required_argument, nullptr, ARG_NS_LVL},
{"aec", no_argument, &effectEn[PREPROC_AEC], 1},
{"agc", no_argument, &effectEn[PREPROC_AGC], 1},
-#ifndef WEBRTC_LEGACY
{"agc2", no_argument, &effectEn[PREPROC_AGC2], 1},
-#endif
{"ns", no_argument, &effectEn[PREPROC_NS], 1},
{nullptr, 0, nullptr, 0},
};
@@ -277,7 +259,6 @@
preProcCfgParams.agcCompLevel = atoi(optarg);
break;
}
-#ifndef WEBRTC_LEGACY
case ARG_AGC2_GAIN: {
preProcCfgParams.agc2Gain = atof(optarg);
break;
@@ -290,7 +271,6 @@
preProcCfgParams.agc2SaturationMargin = atof(optarg);
break;
}
-#endif
case ARG_AEC_DELAY: {
preProcCfgParams.aecDelay = atoi(optarg);
break;
@@ -387,7 +367,6 @@
return EXIT_FAILURE;
}
}
-#ifndef WEBRTC_LEGACY
if (effectEn[PREPROC_AGC2]) {
if (int status = preProcSetConfigParam(AGC2_PARAM_FIXED_DIGITAL_GAIN,
(float)preProcCfgParams.agc2Gain,
@@ -411,7 +390,6 @@
return EXIT_FAILURE;
}
}
-#endif
if (effectEn[PREPROC_NS]) {
if (int status = preProcSetConfigParam(NS_PARAM_LEVEL, (uint32_t)preProcCfgParams.nsLevel,
effectHandle[PREPROC_NS]);
diff --git a/media/libeffects/res/raw/sinesweepraw.raw b/media/libeffects/res/raw/sinesweepraw.raw
new file mode 100644
index 0000000..c0d48ce
--- /dev/null
+++ b/media/libeffects/res/raw/sinesweepraw.raw
Binary files differ
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index da272e3..f682b6e 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -21,6 +21,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <algorithm>
#include <media/MidiIoWrapper.h>
#include <media/MediaExtractorPluginApi.h>
@@ -33,6 +34,8 @@
}
namespace android {
+int MidiIoWrapper::sCacheBufferSize = 0;
+Mutex MidiIoWrapper::mCacheLock;
MidiIoWrapper::MidiIoWrapper(const char *path) {
ALOGV("MidiIoWrapper(%s)", path);
@@ -40,6 +43,8 @@
mBase = 0;
mLength = lseek(mFd, 0, SEEK_END);
mDataSource = nullptr;
+ mCacheBuffer = NULL;
+ mCacheBufRangeLength = 0;
}
MidiIoWrapper::MidiIoWrapper(int fd, off64_t offset, int64_t size) {
@@ -48,6 +53,8 @@
mBase = offset;
mLength = size;
mDataSource = nullptr;
+ mCacheBuffer = NULL;
+ mCacheBufRangeLength = 0;
}
class MidiIoWrapper::DataSourceUnwrapper {
@@ -97,6 +104,8 @@
} else {
mLength = 0;
}
+ mCacheBuffer = NULL;
+ mCacheBufRangeLength = 0;
}
MidiIoWrapper::~MidiIoWrapper() {
@@ -105,11 +114,80 @@
close(mFd);
}
delete mDataSource;
+
+ if (NULL != mCacheBuffer) {
+ delete [] mCacheBuffer;
+ mCacheBuffer = NULL;
+ {
+ Mutex::Autolock _l(mCacheLock);
+ sCacheBufferSize -= mLength;
+ }
+ }
}
int MidiIoWrapper::readAt(void *buffer, int offset, int size) {
ALOGV("readAt(%p, %d, %d)", buffer, offset, size);
+ if (offset < 0) {
+ return UNKNOWN_ERROR;
+ }
+
+ if (offset + size > mLength) {
+ size = mLength - offset;
+ }
+
+ if (mCacheBuffer == NULL) {
+ Mutex::Autolock _l(mCacheLock);
+ if (sCacheBufferSize + mLength <= kTotalCacheSize) {
+ mCacheBuffer = new (std::nothrow) unsigned char[mLength];
+ if (NULL != mCacheBuffer) {
+ sCacheBufferSize += mLength;
+ ALOGV("sCacheBufferSize : %d", sCacheBufferSize);
+ } else {
+ ALOGE("failed to allocate memory for mCacheBuffer");
+ }
+ } else {
+ ALOGV("not allocate memory for mCacheBuffer");
+ }
+ }
+
+ if (mCacheBuffer != NULL) {
+ if (mCacheBufRangeLength > 0 && mCacheBufRangeLength >= (offset + size)) {
+ /* Use buffered data */
+ memcpy(buffer, (void*)(mCacheBuffer + offset), size);
+ return size;
+ } else {
+ /* Buffer new data */
+ int64_t beyondCacheBufRangeLength = (offset + size) - mCacheBufRangeLength;
+ int64_t numRequiredBytesToCache =
+ std::max((int64_t)kSingleCacheSize, beyondCacheBufRangeLength);
+ int64_t availableReadLength = mLength - mCacheBufRangeLength;
+ int64_t readSize = std::min(availableReadLength, numRequiredBytesToCache);
+ int actualNumBytesRead =
+ unbufferedReadAt(mCacheBuffer + mCacheBufRangeLength,
+ mCacheBufRangeLength, readSize);
+ if(actualNumBytesRead > 0) {
+ mCacheBufRangeLength += actualNumBytesRead;
+ if (offset >= mCacheBufRangeLength) {
+ return 0;
+ } else if (offset + size >= mCacheBufRangeLength) {
+ memcpy(buffer, (void*)(mCacheBuffer + offset), mCacheBufRangeLength - offset);
+ return mCacheBufRangeLength - offset;
+ } else {
+ memcpy(buffer, (void*)(mCacheBuffer + offset), size);
+ return size;
+ }
+ } else {
+ return actualNumBytesRead;
+ }
+ }
+ } else {
+ return unbufferedReadAt(buffer, offset, size);
+ }
+}
+
+int MidiIoWrapper::unbufferedReadAt(void *buffer, int offset, int size) {
+ ALOGV("unbufferedReadAt(%p, %d, %d)", buffer, offset, size);
if (mDataSource != NULL) {
return mDataSource->readAt(offset, buffer, size);
}
diff --git a/media/libmedia/include/media/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h
index 0cdd4ad..5fa745c 100644
--- a/media/libmedia/include/media/MidiIoWrapper.h
+++ b/media/libmedia/include/media/MidiIoWrapper.h
@@ -18,6 +18,7 @@
#define MIDI_IO_WRAPPER_H_
#include <libsonivox/eas_types.h>
+#include <utils/Mutex.h>
namespace android {
@@ -32,17 +33,27 @@
~MidiIoWrapper();
int readAt(void *buffer, int offset, int size);
+ int unbufferedReadAt(void *buffer, int offset, int size);
int size();
EAS_FILE_LOCATOR getLocator();
private:
+ enum {
+ kTotalCacheSize = 1024 * 1024 + 512 * 1024,
+ kSingleCacheSize = 65536,
+ };
+
int mFd;
off64_t mBase;
int64_t mLength;
class DataSourceUnwrapper;
DataSourceUnwrapper *mDataSource;
EAS_FILE mEasFile;
+ unsigned char *mCacheBuffer;
+ int64_t mCacheBufRangeLength;
+ static int sCacheBufferSize;
+ static Mutex mCacheLock;
};
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index bc84d78..edbd99e 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -7035,10 +7035,9 @@
return err;
}
- using hardware::media::omx::V1_0::utils::TWOmxNode;
err = statusFromBinderStatus(
mCodec->mGraphicBufferSource->configure(
- new TWOmxNode(mCodec->mOMXNode),
+ mCodec->mOMXNode->getHalInterface<IOmxNode>(),
static_cast<hardware::graphics::common::V1_0::Dataspace>(dataSpace)));
if (err != OK) {
ALOGE("[%s] Unable to configure for node (err %d)",
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index a3a4aba..4fe871f 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -4083,7 +4083,15 @@
}
}
}
- mBufferChannel->renderOutputBuffer(buffer, renderTimeNs);
+ status_t err = mBufferChannel->renderOutputBuffer(buffer, renderTimeNs);
+
+ if (err == NO_INIT) {
+ ALOGE("rendering to non-initilized(obsolete) surface");
+ return err;
+ }
+ if (err != OK) {
+ ALOGI("rendring output error %d", err);
+ }
} else {
mBufferChannel->discardBuffer(buffer);
}
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 5509512..e97f6eb 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -813,6 +813,10 @@
baseSize = U32_AT(&mParent.mData[mOffset + 4]);
}
+ if (baseSize == 0) {
+ return;
+ }
+
// Prevent integer overflow when adding
if (SIZE_MAX - 10 <= baseSize) {
return;
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 6a4706d..7b36875 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -121,7 +121,7 @@
unsigned start = (unsigned)((rand()* 1000LL)/RAND_MAX) + 15550;
start &= ~1;
- for (unsigned port = start; port < 65536; port += 2) {
+ for (unsigned port = start; port < 65535; port += 2) {
struct sockaddr_in addr;
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
addr.sin_family = AF_INET;
@@ -139,6 +139,13 @@
(const struct sockaddr *)&addr, sizeof(addr)) == 0) {
*rtpPort = port;
return;
+ } else {
+ // we should recreate a RTP socket to avoid bind other port in same RTP socket
+ close(*rtpSocket);
+
+ *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ CHECK_GE(*rtpSocket, 0);
+ bumpSocketBufferSize(*rtpSocket);
}
}
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 7699700..1b1717f 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -266,7 +266,7 @@
return NO_ERROR;
}
-sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
+sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() {
const sp<IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) {
ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
@@ -283,27 +283,27 @@
std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
if (mPackageManager == nullptr) {
/** Can not fetch package manager at construction it may not yet be registered. */
- mPackageManager = retreivePackageManager();
+ mPackageManager = retrievePackageManager();
if (mPackageManager == nullptr) {
ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
return std::nullopt;
}
}
+ // Retrieve package names for the UID and transform to a std::vector<std::string>.
+ Vector<String16> str16PackageNames;
+ PermissionController{}.getPackagesForUid(uid, str16PackageNames);
std::vector<std::string> packageNames;
- auto status = mPackageManager->getNamesForUids({(int32_t)uid}, &packageNames);
- if (!status.isOk()) {
- ALOGW("%s: Playback capture is denied for uid %u as the package names could not be "
- "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
- return std::nullopt;
+ for (const auto& str16PackageName : str16PackageNames) {
+ packageNames.emplace_back(String8(str16PackageName).string());
}
if (packageNames.empty()) {
ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
- "from the package manager: %s", __func__, uid, status.toString8().c_str());
+ "from the package manager.", __func__, uid);
return std::nullopt;
}
std::vector<bool> isAllowed;
- status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
+ auto status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
if (!status.isOk()) {
ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be "
"retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 431dd7a..c7d49fd 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -110,7 +110,7 @@
private:
static constexpr const char* nativePackageManagerName = "package_native";
std::optional<bool> doIsAllowed(uid_t uid);
- sp<content::pm::IPackageManagerNative> retreivePackageManager();
+ sp<content::pm::IPackageManagerNative> retrievePackageManager();
sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
uint_t mPackageManagerErrors = 0;
struct Package {
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 529b87c..eebaa7e 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -2994,7 +2994,7 @@
__func__, port->type, port->ext.device.type,
port->ext.device.address, port->id, patch.isSoftware());
if (port->type != AUDIO_PORT_TYPE_DEVICE || port->ext.device.type != mDevice.mType
- || port->ext.device.address != mDevice.mAddress) {
+ || port->ext.device.address != mDevice.address()) {
return NAME_NOT_FOUND;
}
status_t status = NAME_NOT_FOUND;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 510d74c..0b4198c 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -8564,7 +8564,7 @@
// store new device and send to effects
mInDeviceTypeAddr.mType = patch->sources[0].ext.device.type;
- mInDeviceTypeAddr.mAddress = patch->sources[0].ext.device.address;
+ mInDeviceTypeAddr.setAddress(patch->sources[0].ext.device.address);
audio_port_handle_t deviceId = patch->sources[0].id;
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setInputDevice_l(inDeviceTypeAddr());
@@ -9206,7 +9206,7 @@
deviceId = patch->sources[0].id;
numDevices = mPatch.num_sources;
sourceDeviceTypeAddr.mType = patch->sources[0].ext.device.type;
- sourceDeviceTypeAddr.mAddress = patch->sources[0].ext.device.address;
+ sourceDeviceTypeAddr.setAddress(patch->sources[0].ext.device.address);
}
for (size_t i = 0; i < mEffectChains.size(); i++) {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 8d0e5db..93819f5 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -250,12 +250,12 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes) = 0;
virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes) = 0;
- virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+ virtual status_t setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices)
= 0;
virtual status_t removeUidDeviceAffinities(uid_t uid) = 0;
virtual status_t setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices) = 0;
+ const AudioDeviceTypeAddrVector& devices) = 0;
virtual status_t removeUserIdDeviceAffinities(int userId) = 0;
virtual status_t startAudioSource(const struct audio_port_config *source,
@@ -295,13 +295,36 @@
virtual bool isCallScreenModeSupported() = 0;
- virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device) = 0;
+ virtual status_t setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
- virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0;
+ virtual status_t removeDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role) = 0;
- virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device) = 0;
+
+ virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices) = 0;
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) = 0;
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices) = 0;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index b82305d..c6bdb04 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -101,7 +101,7 @@
* An example of failure is when there are already rules in place to restrict
* a mix to the given uid (i.e. when a MATCH_UID rule was set for it).
*/
- status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+ status_t setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices);
status_t removeUidDeviceAffinities(uid_t uid);
status_t getDevicesForUid(uid_t uid, Vector<AudioDeviceTypeAddr>& devices) const;
@@ -115,7 +115,7 @@
* An example of failure is when there are already rules in place to restrict
* a mix to the given userId (i.e. when a MATCH_USERID rule was set for it).
*/
- status_t setUserIdDeviceAffinities(int userId, const Vector<AudioDeviceTypeAddr>& devices);
+ status_t setUserIdDeviceAffinities(int userId, const AudioDeviceTypeAddrVector& devices);
status_t removeUserIdDeviceAffinities(int userId);
status_t getDevicesForUserId(int userId, Vector<AudioDeviceTypeAddr>& devices) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 016aaa5..ca29591 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -151,6 +151,15 @@
// 4) the combination of all devices is invalid for selection
sp<DeviceDescriptor> getDeviceForOpening() const;
+ // Return the device descriptor that matches the given AudioDeviceTypeAddr
+ sp<DeviceDescriptor> getDeviceFromDeviceTypeAddr(
+ const AudioDeviceTypeAddr& deviceTypeAddr) const;
+
+ // Return the device vector that contains device descriptor whose AudioDeviceTypeAddr appears
+ // in the given AudioDeviceTypeAddrVector
+ DeviceVector getDevicesFromDeviceTypeAddrVec(
+ const AudioDeviceTypeAddrVector& deviceTypeAddrVector) const;
+
// If there are devices with the given type and the devices to add is not empty,
// remove all the devices with the given type and add all the devices to add.
void replaceDevicesByType(audio_devices_t typeToRemove, const DeviceVector &devicesToAdd);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index b6de4be..fc1d0e2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -463,7 +463,7 @@
}
status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid,
- const Vector<AudioDeviceTypeAddr>& devices) {
+ const AudioDeviceTypeAddrVector& devices) {
// verify feasibility: for each player mix: if it already contains a
// "match uid" rule for this uid, return an error
// (adding a uid-device affinity would result in contradictory rules)
@@ -565,7 +565,7 @@
}
status_t AudioPolicyMixCollection::setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices) {
+ const AudioDeviceTypeAddrVector& devices) {
// verify feasibility: for each player mix: if it already contains a
// "match userId" rule for this userId, return an error
// (adding a userId-device affinity would result in contradictory rules)
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 3d97440..8545f8e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -393,6 +393,24 @@
return nullptr;
}
+sp<DeviceDescriptor> DeviceVector::getDeviceFromDeviceTypeAddr(
+ const AudioDeviceTypeAddr& deviceTypeAddr) const {
+ return getDevice(deviceTypeAddr.mType, String8(deviceTypeAddr.getAddress()),
+ AUDIO_FORMAT_DEFAULT);
+}
+
+DeviceVector DeviceVector::getDevicesFromDeviceTypeAddrVec(
+ const AudioDeviceTypeAddrVector& deviceTypeAddrVector) const {
+ DeviceVector devices;
+ for (const auto& deviceTypeAddr : deviceTypeAddrVector) {
+ sp<DeviceDescriptor> device = getDeviceFromDeviceTypeAddr(deviceTypeAddr);
+ if (device != nullptr) {
+ devices.add(device);
+ }
+ }
+ return devices;
+}
+
void DeviceVector::replaceDevicesByType(
audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) {
DeviceVector devicesToRemove = getDevicesFromType(typeToRemove);
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 7f339dc..4510f63 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -93,13 +93,13 @@
void dump(String8 *dst) const override;
- status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device) override;
+ status_t setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) override;
- status_t removePreferredDeviceForStrategy(product_strategy_t strategy) override;
+ status_t removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) override;
- status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device) const override;
+ status_t getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
+ AudioDeviceTypeAddrVector &devices) const override;
engineConfig::ParsingResult loadAudioPolicyEngineConfig();
@@ -127,11 +127,36 @@
status_t restoreOriginVolumeCurve(audio_stream_type_t stream);
+ status_t setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) override;
+
+ status_t addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) override;
+
+ /**
+ * Remove devices role for capture preset. When `forceMatched` is true, the devices to be
+ * removed must all show as role for the capture preset. Otherwise, only devices that has shown
+ * as role for the capture preset will be remove.
+ */
+ status_t doRemoveDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices,
+ bool forceMatched=true);
+
+ status_t removeDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices) override;
+
+ status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) override;
+
+ status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices) const override;
+
private:
AudioPolicyManagerObserver *mApmObserver = nullptr;
ProductStrategyMap mProductStrategies;
ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices;
+ CapturePresetDevicesRoleMap mCapturePresetDevicesRole;
VolumeGroupMap mVolumeGroups;
LastRemovableMediaDevices mLastRemovableMediaDevices;
audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index 3ebe7d1..c505456 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -28,8 +28,11 @@
#include <utils/String8.h>
#include <media/AudioAttributes.h>
#include <media/AudioContainers.h>
+#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioPolicy.h>
+#include <vector>
+
namespace android {
/**
@@ -164,7 +167,8 @@
product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE;
};
-class ProductStrategyPreferredRoutingMap : public std::map<product_strategy_t, AudioDeviceTypeAddr>
+class ProductStrategyPreferredRoutingMap : public std::map<product_strategy_t,
+ AudioDeviceTypeAddrVector>
{
public:
void dump(String8 *dst, int spaces = 0) const;
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 1bc7fe3..1875c10 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -19,6 +19,7 @@
#include "EngineBase.h"
#include "EngineDefaultConfig.h"
+#include "../include/EngineBase.h"
#include <TypeConverter.h>
namespace android {
@@ -339,8 +340,8 @@
return NO_ERROR;
}
-status_t EngineBase::setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device)
+status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
{
// verify strategy exists
if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
@@ -348,11 +349,24 @@
return BAD_VALUE;
}
- mProductStrategyPreferredDevices[strategy] = device;
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ mProductStrategyPreferredDevices[strategy] = devices;
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support set devices role as disabled for strategy.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it is no need to set device role as none for a strategy.
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
return NO_ERROR;
}
-status_t EngineBase::removePreferredDeviceForStrategy(product_strategy_t strategy)
+status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role)
{
// verify strategy exists
if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
@@ -360,29 +374,218 @@
return BAD_VALUE;
}
- if (mProductStrategyPreferredDevices.erase(strategy) == 0) {
- // no preferred device was set
- return NAME_NOT_FOUND;
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ if (mProductStrategyPreferredDevices.erase(strategy) == 0) {
+ // no preferred device was set
+ return NAME_NOT_FOUND;
+ }
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support remove devices role as disabled for strategy.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it makes no sense to remove devices with
+ // role as DEVICE_ROLE_NONE for a strategy
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
}
return NO_ERROR;
}
-status_t EngineBase::getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device) const
+status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
+ AudioDeviceTypeAddrVector &devices) const
{
// verify strategy exists
if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
ALOGE("%s unknown strategy %u", __func__, strategy);
return BAD_VALUE;
}
- // preferred device for this strategy?
- auto devIt = mProductStrategyPreferredDevices.find(strategy);
- if (devIt == mProductStrategyPreferredDevices.end()) {
- ALOGV("%s no preferred device for strategy %u", __func__, strategy);
- return NAME_NOT_FOUND;
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED: {
+ // preferred device for this strategy?
+ auto devIt = mProductStrategyPreferredDevices.find(strategy);
+ if (devIt == mProductStrategyPreferredDevices.end()) {
+ ALOGV("%s no preferred device for strategy %u", __func__, strategy);
+ return NAME_NOT_FOUND;
+ }
+
+ devices = devIt->second;
+ } break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as the DEVICE_ROLE_NONE is never set
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
}
- device = devIt->second;
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ mCapturePresetDevicesRole[audioSource][role] = devices;
+ // When the devices are set as preferred devices, remove them from the disabled devices.
+ doRemoveDevicesRoleForCapturePreset(
+ audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/);
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support setting devices role as disabled for capture preset.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it is no need to set device role as none
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ mCapturePresetDevicesRole[audioSource][role] = excludeDeviceTypeAddrsFrom(
+ mCapturePresetDevicesRole[audioSource][role], devices);
+ for (const auto& device : devices) {
+ mCapturePresetDevicesRole[audioSource][role].push_back(device);
+ }
+ // When the devices are set as preferred devices, remove them from the disabled devices.
+ doRemoveDevicesRoleForCapturePreset(
+ audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/);
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support setting devices role as disabled for capture preset.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it is no need to set device role as none
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices) {
+ return doRemoveDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices, bool forceMatched)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ case DEVICE_ROLE_DISABLED: {
+ if (mCapturePresetDevicesRole.count(audioSource) == 0 ||
+ mCapturePresetDevicesRole[audioSource].count(role) == 0) {
+ return NAME_NOT_FOUND;
+ }
+ AudioDeviceTypeAddrVector remainingDevices = excludeDeviceTypeAddrsFrom(
+ mCapturePresetDevicesRole[audioSource][role], devices);
+ if (forceMatched && remainingDevices.size() !=
+ mCapturePresetDevicesRole[audioSource][role].size() - devices.size()) {
+ // There are some devices from `devicesToRemove` that are not shown in the cached record
+ return BAD_VALUE;
+ }
+ mCapturePresetDevicesRole[audioSource][role] = remainingDevices;
+ if (mCapturePresetDevicesRole[audioSource][role].empty()) {
+ // Remove the role when device list is empty
+ mCapturePresetDevicesRole[audioSource].erase(role);
+ }
+ } break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it makes no sense to remove devices with
+ // role as DEVICE_ROLE_NONE
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ if (mCapturePresetDevicesRole.count(audioSource) == 0 ||
+ mCapturePresetDevicesRole[audioSource].erase(role) == 0) {
+ // no preferred device for the given audio source
+ return NAME_NOT_FOUND;
+ }
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support remove devices role as disabled for strategy.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it makes no sense to remove devices with
+ // role as DEVICE_ROLE_NONE for a strategy
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices) const
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ return BAD_VALUE;
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ case DEVICE_ROLE_DISABLED: {
+ if (mCapturePresetDevicesRole.count(audioSource) == 0) {
+ return NAME_NOT_FOUND;
+ }
+ auto devIt = mCapturePresetDevicesRole.at(audioSource).find(role);
+ if (devIt == mCapturePresetDevicesRole.at(audioSource).end()) {
+ ALOGV("%s no devices role(%d) for capture preset %u", __func__, role, audioSource);
+ return NAME_NOT_FOUND;
+ }
+
+ devices = devIt->second;
+ } break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as the DEVICE_ROLE_NONE is never set
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
return NO_ERROR;
}
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index 151c7bb..060568a 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -321,10 +321,11 @@
void ProductStrategyPreferredRoutingMap::dump(android::String8* dst, int spaces) const {
dst->appendFormat("\n%*sPreferred devices per product strategy dump:", spaces, "");
for (const auto& iter : *this) {
- dst->appendFormat("\n%*sStrategy %u dev:%08x addr:%s",
+ dst->appendFormat("\n%*sStrategy %u %s",
spaces + 2, "",
(uint32_t) iter.first,
- iter.second.mType, iter.second.mAddress.c_str());
+ dumpAudioDeviceTypeAddrVector(iter.second, true /*includeSensitiveInfo*/)
+ .c_str());
}
dst->appendFormat("\n");
}
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index dfb20b5..f64608d 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -34,6 +34,8 @@
using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>;
using StrategyVector = std::vector<product_strategy_t>;
using VolumeGroupVector = std::vector<volume_group_t>;
+using CapturePresetDevicesRoleMap =
+ std::map<audio_source_t, std::map<device_role_t, AudioDeviceTypeAddrVector>>;
/**
* This interface is dedicated to the policy manager that a Policy Engine shall implement.
@@ -293,36 +295,113 @@
virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const = 0;
/**
- * @brief setPreferredDeviceForStrategy sets the default device to be used for a
- * strategy when available
+ * @brief setDevicesRoleForStrategy sets devices role for a strategy when available. To remove
+ * devices role, removeDevicesRoleForStrategy must be called. When devices role is set
+ * successfully, previously set devices for the same role and strategy will be removed.
* @param strategy the audio strategy whose routing will be affected
- * @param device the audio device to route to when available
- * @return BAD_VALUE if the strategy is invalid,
- * or NO_ERROR if the preferred device was set
+ * @param role the role of the devices for the strategy. All device roles are defined at
+ * system/media/audio/include/system/audio_policy.h. DEVICE_ROLE_NONE is invalid
+ * for setting.
+ * @param devices the audio devices to be set
+ * @return BAD_VALUE if the strategy or role is invalid,
+ * or NO_ERROR if the role of the devices for strategy was set
*/
- virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device) = 0;
+ virtual status_t setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
/**
- * @brief removePreferredDeviceForStrategy removes the preferred device previously set
+ * @brief removeDevicesRoleForStrategy removes the role of device(s) previously set
* for the given strategy
* @param strategy the audio strategy whose routing will be affected
- * @return BAD_VALUE if the strategy is invalid,
- * or NO_ERROR if the preferred device was removed
+ * @param role the role of the devices for strategy
+ * @return BAD_VALUE if the strategy or role is invalid,
+ * or NO_ERROR if the devices for this role was removed
*/
- virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0;
+ virtual status_t removeDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role) = 0;
/**
- * @brief getPreferredDeviceForStrategy queries which device is set as the
- * preferred device for the given strategy
+ * @brief getDevicesForRoleAndStrategy queries which devices have the specified role for the
+ * specified strategy
* @param strategy the strategy to query
- * @param device returns configured as the preferred device if one was set
- * @return BAD_VALUE if the strategy is invalid,
- * or NAME_NOT_FOUND if no preferred device was set
- * or NO_ERROR if the device parameter was initialized to the preferred device
+ * @param role the role of the devices to query
+ * @param devices returns list of devices with matching role for the specified strategy.
+ * DEVICE_ROLE_NONE is invalid as input.
+ * @return BAD_VALUE if the strategy or role is invalid,
+ * or NAME_NOT_FOUND if no device for the role and strategy was set
+ * or NO_ERROR if the devices parameter contains a list of devices
*/
- virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device) const = 0;
+ virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
+ AudioDeviceTypeAddrVector &devices) const = 0;
+
+ /**
+ * @brief setDevicesRoleForCapturePreset sets devices role for a capture preset when available.
+ * To remove devices role, removeDevicesRoleForCapturePreset must be called. Calling
+ * clearDevicesRoleForCapturePreset will remove all devices as role. When devices role is set
+ * successfully, previously set devices for the same role and capture preset will be removed.
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset. All device roles are defined at
+ * system/media/audio/include/system/audio_policy.h. DEVICE_ROLE_NONE is invalid
+ * for setting.
+ * @param devices the audio devices to be set
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NO_ERROR if the role of the devices for capture preset was set
+ */
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ /**
+ * @brief addDevicesRoleForCapturePreset adds devices role for a capture preset when available.
+ * To remove devices role, removeDevicesRoleForCapturePreset must be called. Calling
+ * clearDevicesRoleForCapturePreset will remove all devices as role.
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset. All device roles are defined at
+ * system/media/audio/include/system/audio_policy.h. DEVICE_ROLE_NONE is invalid
+ * for setting.
+ * @param devices the audio devices to be added
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NO_ERROR if the role of the devices for capture preset was added
+ */
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ /**
+ * @brief removeDevicesRoleForCapturePreset removes the role of device(s) previously set
+ * for the given capture preset
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset
+ * @param devices the devices to be removed
+ * @return BAD_VALUE if 1) the capture preset is invalid, 2) role is invalid or 3) the list of
+ * devices to be removed are not all present as role for a capture preset
+ * or NO_ERROR if the devices for this role was removed
+ */
+ virtual status_t removeDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices) = 0;
+
+ /**
+ * @brief clearDevicesRoleForCapturePreset removes the role of all device(s) previously set
+ * for the given capture preset
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NO_ERROR if the devices for this role was removed
+ */
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role);
+
+ /**
+ * @brief getDevicesForRoleAndCapturePreset queries which devices have the specified role for
+ * the specified capture preset
+ * @param audioSource the capture preset to query
+ * @param role the role of the devices to query
+ * @param devices returns list of devices with matching role for the specified capture preset.
+ * DEVICE_ROLE_NONE is invalid as input.
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NAME_NOT_FOUND if no device for the role and capture preset was set
+ * or NO_ERROR if the devices parameter contains a list of devices
+ */
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices) const = 0;
virtual void dump(String8 *dst) const = 0;
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 0ec169a..19937ed 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -184,16 +184,7 @@
break;
case STRATEGY_DTMF:
- if (!isInCall()) {
- // when off call, DTMF strategy follows the same rules as MEDIA strategy
- devices = getDevicesForStrategyInt(
- STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs);
- break;
- }
- // when in call, DTMF and PHONE strategies follow the same rules
- FALLTHROUGH_INTENDED;
-
- case STRATEGY_PHONE:
+ case STRATEGY_PHONE: {
// Force use of only devices on primary output if:
// - in call AND
// - cannot route from voice call RX OR
@@ -216,84 +207,24 @@
availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID));
if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
- String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
- ((availPrimaryInputDevices.getDevice(
- txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
- (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
+ String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
+ ((availPrimaryInputDevices.getDevice(
+ txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
+ (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
availableOutputDevices = availPrimaryOutputDevices;
}
}
- // for phone strategy, we first consider the forced use and then the available devices by
- // order of priority
- switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
- case AUDIO_POLICY_FORCE_BT_SCO:
- if (!isInCall() || strategy != STRATEGY_DTMF) {
- devices = availableOutputDevices.getDevicesFromType(
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
- if (!devices.isEmpty()) break;
- }
- devices = availableOutputDevices.getFirstDevicesFromTypes({
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO});
- if (!devices.isEmpty()) break;
- // if SCO device is requested but no SCO device is available, fall back to default case
- FALLTHROUGH_INTENDED;
-
- default: // FORCE_NONE
- devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
- if (!devices.isEmpty()) break;
-
- // TODO (b/161358428): remove when preferred device
- // for strategy phone will be used instead of AUDIO_POLICY_FORCE_FOR_COMMUNICATION
- devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_BLE_HEADSET);
- if (!devices.isEmpty()) break;
-
- // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
- if (!isInCall() &&
- (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
- devices = availableOutputDevices.getFirstDevicesFromTypes({
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES});
- if (!devices.isEmpty()) break;
- }
- devices = availableOutputDevices.getFirstDevicesFromTypes({
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADSET,
- AUDIO_DEVICE_OUT_LINE, AUDIO_DEVICE_OUT_USB_HEADSET,
- AUDIO_DEVICE_OUT_USB_DEVICE});
- if (!devices.isEmpty()) break;
- if (!isInCall()) {
- devices = availableOutputDevices.getFirstDevicesFromTypes({
- AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
- AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET});
- if (!devices.isEmpty()) break;
- }
- devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_EARPIECE);
- break;
-
- case AUDIO_POLICY_FORCE_SPEAKER:
- // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
- // A2DP speaker when forcing to speaker output
- if (!isInCall()) {
- devices = availableOutputDevices.getDevicesFromType(
- AUDIO_DEVICE_OUT_BLE_SPEAKER);
- if (!devices.isEmpty()) break;
-
- if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
- devices = availableOutputDevices.getDevicesFromType(
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
- if (!devices.isEmpty()) break;
- }
- }
- if (!isInCall()) {
- devices = availableOutputDevices.getFirstDevicesFromTypes({
- AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_DEVICE,
- AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_AUX_DIGITAL,
- AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET});
- if (!devices.isEmpty()) break;
- }
- devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
- break;
- }
- break;
+ devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
+ if (!devices.isEmpty()) break;
+ devices = availableOutputDevices.getFirstDevicesFromTypes({
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
+ AUDIO_DEVICE_OUT_WIRED_HEADSET,
+ AUDIO_DEVICE_OUT_LINE,
+ AUDIO_DEVICE_OUT_USB_HEADSET,
+ AUDIO_DEVICE_OUT_USB_DEVICE});
+ if (!devices.isEmpty()) break;
+ devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_EARPIECE);
+ } break;
case STRATEGY_SONIFICATION:
@@ -336,7 +267,8 @@
}
}
// Use both Bluetooth SCO and phone default output when ringing in normal mode
- if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
+ if (audio_is_bluetooth_out_sco_device(getPreferredDeviceTypeForLegacyStrategy(
+ availableOutputDevices, STRATEGY_PHONE))) {
if (strategy == STRATEGY_SONIFICATION) {
devices.replaceDevicesByType(
AUDIO_DEVICE_OUT_SPEAKER,
@@ -506,13 +438,16 @@
}
}
+ audio_devices_t commDeviceType =
+ getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE);
+
switch (inputSource) {
case AUDIO_SOURCE_DEFAULT:
case AUDIO_SOURCE_MIC:
device = availableDevices.getDevice(
AUDIO_DEVICE_IN_BLUETOOTH_A2DP, String8(""), AUDIO_FORMAT_DEFAULT);
if (device != nullptr) break;
- if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) {
+ if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
device = availableDevices.getDevice(
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
if (device != nullptr) break;
@@ -533,30 +468,29 @@
availableDevices = availablePrimaryDevices;
}
- switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
- case AUDIO_POLICY_FORCE_BT_SCO:
+ if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
// if SCO device is requested but no SCO device is available, fall back to default case
device = availableDevices.getDevice(
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
if (device != nullptr) {
break;
}
- FALLTHROUGH_INTENDED;
-
- default: // FORCE_NONE
- // TODO (b/161358428): remove AUDIO_DEVICE_IN_BLE_HEADSET from the list
- // when preferred device for strategy phone will be used instead of
- // AUDIO_POLICY_FORCE_FOR_COMMUNICATION.
- device = availableDevices.getFirstExistingDevice({
- AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET,
- AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
- AUDIO_DEVICE_IN_BUILTIN_MIC});
+ }
+ switch (commDeviceType) {
+ case AUDIO_DEVICE_OUT_BLE_HEADSET:
+ device = availableDevices.getDevice(
+ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
break;
-
- case AUDIO_POLICY_FORCE_SPEAKER:
+ case AUDIO_DEVICE_OUT_SPEAKER:
device = availableDevices.getFirstExistingDevice({
AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC});
break;
+ default: // FORCE_NONE
+ device = availableDevices.getFirstExistingDevice({
+ AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
+ AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
+ break;
+
}
break;
@@ -569,7 +503,7 @@
LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
availableDevices = availablePrimaryDevices;
}
- if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) {
+ if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
device = availableDevices.getDevice(
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
if (device != nullptr) break;
@@ -619,6 +553,7 @@
ALOGE_IF(device == nullptr,
"getDeviceForInputSource() no default device defined");
}
+
ALOGV_IF(device != nullptr,
"getDeviceForInputSource()input source %d, device %08x",
inputSource, device->type());
@@ -636,31 +571,66 @@
}
}
-DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const {
- DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+product_strategy_t Engine::getProductStrategyFromLegacy(legacy_strategy legacyStrategy) const {
+ for (const auto& strategyMap : mLegacyStrategyMap) {
+ if (strategyMap.second == legacyStrategy) {
+ return strategyMap.first;
+ }
+ }
+ return PRODUCT_STRATEGY_NONE;
+}
- // check if this strategy has a preferred device that is available,
- // if yes, give priority to it
- AudioDeviceTypeAddr preferredStrategyDevice;
- const status_t status = getPreferredDeviceForStrategy(strategy, preferredStrategyDevice);
+audio_devices_t Engine::getPreferredDeviceTypeForLegacyStrategy(
+ const DeviceVector& availableOutputDevices, legacy_strategy legacyStrategy) const {
+ product_strategy_t strategy = getProductStrategyFromLegacy(legacyStrategy);
+ DeviceVector devices = getPreferredAvailableDevicesForProductStrategy(
+ availableOutputDevices, strategy);
+ if (devices.size() > 0) {
+ return devices[0]->type();
+ }
+ return AUDIO_DEVICE_NONE;
+}
+
+DeviceVector Engine::getPreferredAvailableDevicesForProductStrategy(
+ const DeviceVector& availableOutputDevices, product_strategy_t strategy) const {
+ DeviceVector preferredAvailableDevVec = {};
+ AudioDeviceTypeAddrVector preferredStrategyDevices;
+ const status_t status = getDevicesForRoleAndStrategy(
+ strategy, DEVICE_ROLE_PREFERRED, preferredStrategyDevices);
if (status == NO_ERROR) {
// there is a preferred device, is it available?
- sp<DeviceDescriptor> preferredAvailableDevDescr = availableOutputDevices.getDevice(
- preferredStrategyDevice.mType,
- String8(preferredStrategyDevice.mAddress.c_str()),
- AUDIO_FORMAT_DEFAULT);
- if (preferredAvailableDevDescr != nullptr) {
- ALOGVV("%s using pref device 0x%08x/%s for strategy %u",
- __func__, preferredStrategyDevice.mType,
- preferredStrategyDevice.mAddress.c_str(), strategy);
- return DeviceVector(preferredAvailableDevDescr);
+ preferredAvailableDevVec =
+ availableOutputDevices.getDevicesFromDeviceTypeAddrVec(preferredStrategyDevices);
+ if (preferredAvailableDevVec.size() == preferredAvailableDevVec.size()) {
+ ALOGVV("%s using pref device %s for strategy %u",
+ __func__, preferredAvailableDevVec.toString().c_str(), strategy);
+ return preferredAvailableDevVec;
}
}
+ return preferredAvailableDevVec;
+}
+
+DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const {
+ DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+ auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
+ mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
+
+ // When not in call, STRATEGY_PHONE and STRATEGY_DTMF follow STRATEGY_MEDIA
+ if (!isInCall() && (legacyStrategy == STRATEGY_PHONE || legacyStrategy == STRATEGY_DTMF)) {
+ legacyStrategy = STRATEGY_MEDIA;
+ strategy = getProductStrategyFromLegacy(STRATEGY_MEDIA);
+ }
+ // check if this strategy has a preferred device that is available,
+ // if yes, give priority to it.
+ DeviceVector preferredAvailableDevVec =
+ getPreferredAvailableDevicesForProductStrategy(availableOutputDevices, strategy);
+ if (!preferredAvailableDevVec.isEmpty()) {
+ return preferredAvailableDevVec;
+ }
DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs();
- auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
- mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
+
return getDevicesForStrategyInt(legacyStrategy,
availableOutputDevices,
availableInputDevices, outputs);
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index bb9e2df..6214fe7 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -83,6 +83,12 @@
sp<DeviceDescriptor> getDeviceForInputSource(audio_source_t inputSource) const;
+ product_strategy_t getProductStrategyFromLegacy(legacy_strategy legacyStrategy) const;
+ audio_devices_t getPreferredDeviceTypeForLegacyStrategy(
+ const DeviceVector& availableOutputDevices, legacy_strategy legacyStrategy) const;
+ DeviceVector getPreferredAvailableDevicesForProductStrategy(
+ const DeviceVector& availableOutputDevices, product_strategy_t strategy) const;
+
DeviceStrategyMap mDevicesForStrategies;
std::map<product_strategy_t, legacy_strategy> mLegacyStrategyMap;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a8fdedf..beaa979 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -790,16 +790,7 @@
}
updateCallAndOutputRouting(forceVolumeReeval, delayMs);
-
- for (const auto& activeDesc : mInputs.getActiveInputs()) {
- auto newDevice = getNewInputDevice(activeDesc);
- // Force new input selection if the new device can not be reached via current input
- if (activeDesc->mProfile->getSupportedDevices().contains(newDevice)) {
- setInputDevice(activeDesc->mIoHandle, newDevice);
- } else {
- closeInput(activeDesc->mIoHandle);
- }
- }
+ updateInputRouting();
}
void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
@@ -3096,16 +3087,16 @@
// Returns true if all devices types match the predicate and are supported by one HW module
bool AudioPolicyManager::areAllDevicesSupported(
- const Vector<AudioDeviceTypeAddr>& devices,
+ const AudioDeviceTypeAddrVector& devices,
std::function<bool(audio_devices_t)> predicate,
const char *context) {
for (size_t i = 0; i < devices.size(); i++) {
sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
- devices[i].mType, devices[i].mAddress.c_str(), String8(),
+ devices[i].mType, devices[i].getAddress(), String8(),
AUDIO_FORMAT_DEFAULT, false /*allowToCreate*/, true /*matchAddress*/);
if (devDesc == nullptr || (predicate != nullptr && !predicate(devices[i].mType))) {
- ALOGE("%s: device type %#x address %s not supported or not an output device",
- context, devices[i].mType, devices[i].mAddress.c_str());
+ ALOGE("%s: device type %#x address %s not supported or not match predicate",
+ context, devices[i].mType, devices[i].getAddress());
return false;
}
}
@@ -3113,7 +3104,7 @@
}
status_t AudioPolicyManager::setUidDeviceAffinities(uid_t uid,
- const Vector<AudioDeviceTypeAddr>& devices) {
+ const AudioDeviceTypeAddrVector& devices) {
ALOGV("%s() uid=%d num devices %zu", __FUNCTION__, uid, devices.size());
if (!areAllDevicesSupported(devices, audio_is_output_device, __func__)) {
return BAD_VALUE;
@@ -3145,25 +3136,35 @@
return res;
}
-status_t AudioPolicyManager::setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device) {
- ALOGV("%s() strategy=%d device=%08x addr=%s", __FUNCTION__,
- strategy, device.mType, device.mAddress.c_str());
- Vector<AudioDeviceTypeAddr> devices;
- devices.add(device);
+status_t AudioPolicyManager::setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) {
+ ALOGV("%s() strategy=%d role=%d %s", __func__, strategy, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
if (!areAllDevicesSupported(devices, audio_is_output_device, __func__)) {
return BAD_VALUE;
}
- status_t status = mEngine->setPreferredDeviceForStrategy(strategy, device);
+ status_t status = mEngine->setDevicesRoleForStrategy(strategy, role, devices);
if (status != NO_ERROR) {
- ALOGW("Engine could not set preferred device %08x %s for strategy %d",
- device.mType, device.mAddress.c_str(), strategy);
+ ALOGW("Engine could not set preferred devices %s for strategy %d role %d",
+ dumpAudioDeviceTypeAddrVector(devices).c_str(), strategy, role);
return status;
}
checkForDeviceAndOutputChanges();
- updateCallAndOutputRouting();
+
+ bool forceVolumeReeval = false;
+ // FIXME: workaround for truncated touch sounds
+ // to be removed when the problem is handled by system UI
+ uint32_t delayMs = 0;
+ if (strategy == mCommunnicationStrategy) {
+ forceVolumeReeval = true;
+ delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
+ updateInputRouting();
+ }
+ updateCallAndOutputRouting(forceVolumeReeval, delayMs);
return NO_ERROR;
}
@@ -3194,30 +3195,124 @@
}
}
-status_t AudioPolicyManager::removePreferredDeviceForStrategy(product_strategy_t strategy)
-{
- ALOGI("%s() strategy=%d", __FUNCTION__, strategy);
+void AudioPolicyManager::updateInputRouting() {
+ for (const auto& activeDesc : mInputs.getActiveInputs()) {
+ auto newDevice = getNewInputDevice(activeDesc);
+ // Force new input selection if the new device can not be reached via current input
+ if (activeDesc->mProfile->getSupportedDevices().contains(newDevice)) {
+ setInputDevice(activeDesc->mIoHandle, newDevice);
+ } else {
+ closeInput(activeDesc->mIoHandle);
+ }
+ }
+}
- status_t status = mEngine->removePreferredDeviceForStrategy(strategy);
+status_t AudioPolicyManager::removeDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role)
+{
+ ALOGI("%s() strategy=%d role=%d", __func__, strategy, role);
+
+ status_t status = mEngine->removeDevicesRoleForStrategy(strategy, role);
if (status != NO_ERROR) {
- ALOGW("Engine could not remove preferred device for strategy %d", strategy);
+ ALOGV("Engine could not remove preferred device for strategy %d status %d",
+ strategy, status);
return status;
}
checkForDeviceAndOutputChanges();
- updateCallAndOutputRouting();
+
+ bool forceVolumeReeval = false;
+ // FIXME: workaround for truncated touch sounds
+ // to be removed when the problem is handled by system UI
+ uint32_t delayMs = 0;
+ if (strategy == mCommunnicationStrategy) {
+ forceVolumeReeval = true;
+ delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
+ updateInputRouting();
+ }
+ updateCallAndOutputRouting(forceVolumeReeval, delayMs);
return NO_ERROR;
}
-status_t AudioPolicyManager::getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device) {
- return mEngine->getPreferredDeviceForStrategy(strategy, device);
+status_t AudioPolicyManager::getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices) {
+ return mEngine->getDevicesForRoleAndStrategy(strategy, role, devices);
+}
+
+status_t AudioPolicyManager::setDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices) {
+ ALOGV("%s() audioSource=%d role=%d %s", __func__, audioSource, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
+ if (!areAllDevicesSupported(devices, audio_call_is_input_device, __func__)) {
+ return BAD_VALUE;
+ }
+ status_t status = mEngine->setDevicesRoleForCapturePreset(audioSource, role, devices);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not set preferred devices %s for audio source %d role %d",
+ dumpAudioDeviceTypeAddrVector(devices).c_str(), audioSource, role);
+
+ return status;
+}
+
+status_t AudioPolicyManager::addDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices) {
+ ALOGV("%s() audioSource=%d role=%d %s", __func__, audioSource, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
+ if (!areAllDevicesSupported(devices, audio_call_is_input_device, __func__)) {
+ return BAD_VALUE;
+ }
+ status_t status = mEngine->addDevicesRoleForCapturePreset(audioSource, role, devices);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not add preferred devices %s for audio source %d role %d",
+ dumpAudioDeviceTypeAddrVector(devices).c_str(), audioSource, role);
+
+ updateInputRouting();
+ return status;
+}
+
+status_t AudioPolicyManager::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices)
+{
+ ALOGV("%s() audioSource=%d role=%d devices=%s", __func__, audioSource, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
+ if (!areAllDevicesSupported(devices, audio_call_is_input_device, __func__)) {
+ return BAD_VALUE;
+ }
+
+ status_t status = mEngine->removeDevicesRoleForCapturePreset(
+ audioSource, role, devices);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not remove devices role (%d) for capture preset %d", role, audioSource);
+
+ updateInputRouting();
+ return status;
+}
+
+status_t AudioPolicyManager::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) {
+ ALOGV("%s() audioSource=%d role=%d", __func__, audioSource, role);
+
+ status_t status = mEngine->clearDevicesRoleForCapturePreset(audioSource, role);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not clear devices role (%d) for capture preset %d", role, audioSource);
+
+ updateInputRouting();
+ return status;
+}
+
+status_t AudioPolicyManager::getDevicesForRoleAndCapturePreset(
+ audio_source_t audioSource, device_role_t role, AudioDeviceTypeAddrVector &devices) {
+ return mEngine->getDevicesForRoleAndCapturePreset(audioSource, role, devices);
}
status_t AudioPolicyManager::setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices) {
- ALOGI("%s() userId=%d num devices %zu", __FUNCTION__, userId, devices.size());\
+ const AudioDeviceTypeAddrVector& devices) {
+ ALOGI("%s() userId=%d num devices %zu", __func__, userId, devices.size());
if (!areAllDevicesSupported(devices, audio_is_output_device, __func__)) {
return BAD_VALUE;
}
@@ -3276,7 +3371,9 @@
}
dst->appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
dst->appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
+ dst->appendFormat(" Communnication Strategy: %d\n", mCommunnicationStrategy);
dst->appendFormat(" Config source: %s\n", mConfig.getSource().c_str()); // getConfig not const
+
mAvailableOutputDevices.dump(dst, String8("Available output"));
mAvailableInputDevices.dump(dst, String8("Available input"));
mHwModulesAll.dump(dst);
@@ -4572,6 +4669,9 @@
// Silence ALOGV statements
property_set("log.tag." LOG_TAG, "D");
+ mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
+ mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
+
updateDevicesAndOutputs();
return status;
}
@@ -5399,6 +5499,17 @@
}
}
+bool AudioPolicyManager::isScoRequestedForComm() const {
+ AudioDeviceTypeAddrVector devices;
+ mEngine->getDevicesForRoleAndStrategy(mCommunnicationStrategy, DEVICE_ROLE_PREFERRED, devices);
+ for (const auto &device : devices) {
+ if (audio_is_bluetooth_out_sco_device(device.mType)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void AudioPolicyManager::checkA2dpSuspend()
{
audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
@@ -5410,23 +5521,21 @@
bool isScoConnected =
(mAvailableInputDevices.types().count(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0 ||
!Intersection(mAvailableOutputDevices.types(), getAudioDeviceOutAllScoSet()).empty());
+ bool isScoRequested = isScoRequestedForComm();
// if suspended, restore A2DP output if:
// ((SCO device is NOT connected) ||
- // ((forced usage communication is NOT SCO) && (forced usage for record is NOT SCO) &&
+ // ((SCO is not requested) &&
// (phone state is NOT in call) && (phone state is NOT ringing)))
//
// if not suspended, suspend A2DP output if:
// (SCO device is connected) &&
- // ((forced usage for communication is SCO) || (forced usage for record is SCO) ||
+ // ((SCO is requested) ||
// ((phone state is in call) || (phone state is ringing)))
//
if (mA2dpSuspended) {
if (!isScoConnected ||
- ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) !=
- AUDIO_POLICY_FORCE_BT_SCO) &&
- (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) !=
- AUDIO_POLICY_FORCE_BT_SCO) &&
+ (!isScoRequested &&
(mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
(mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
@@ -5435,10 +5544,7 @@
}
} else {
if (isScoConnected &&
- ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ==
- AUDIO_POLICY_FORCE_BT_SCO) ||
- (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) ==
- AUDIO_POLICY_FORCE_BT_SCO) ||
+ (isScoRequested ||
(mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
(mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
@@ -6150,16 +6256,17 @@
bool isVoiceVolSrc = callVolSrc == volumeSource;
bool isBtScoVolSrc = btScoVolSrc == volumeSource;
- audio_policy_forced_cfg_t forceUseForComm =
- mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
+ bool isScoRequested = isScoRequestedForComm();
// do not change in call volume if bluetooth is connected and vice versa
// if sco and call follow same curves, bypass forceUseForComm
if ((callVolSrc != btScoVolSrc) &&
- ((isVoiceVolSrc && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
- (isBtScoVolSrc && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO))) {
- ALOGV("%s cannot set volume group %d volume with force use = %d for comm", __func__,
- volumeSource, forceUseForComm);
- return INVALID_OPERATION;
+ ((isVoiceVolSrc && isScoRequested) ||
+ (isBtScoVolSrc && !isScoRequested))) {
+ ALOGV("%s cannot set volume group %d volume when is%srequested for comm", __func__,
+ volumeSource, isScoRequested ? " " : "n ot ");
+ // Do not return an error here as AudioService will always set both voice call
+ // and bluetooth SCO volumes due to stream aliasing.
+ return NO_ERROR;
}
if (deviceTypes.empty()) {
deviceTypes = outputDesc->devices().types();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index b588f89..2a024c9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -263,17 +263,42 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes);
virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes);
virtual status_t setUidDeviceAffinities(uid_t uid,
- const Vector<AudioDeviceTypeAddr>& devices);
+ const AudioDeviceTypeAddrVector& devices);
virtual status_t removeUidDeviceAffinities(uid_t uid);
virtual status_t setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices);
+ const AudioDeviceTypeAddrVector& devices);
virtual status_t removeUserIdDeviceAffinities(int userId);
- virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device);
- virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy);
- virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device);
+ virtual status_t setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t removeDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role);
+
+
+ virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices);
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role);
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices);
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
@@ -532,6 +557,11 @@
void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0);
/**
+ * @brief updates routing for all inputs.
+ */
+ void updateInputRouting();
+
+ /**
* @brief checkOutputForAttributes checks and if necessary changes outputs used for the
* given audio attributes.
* must be called every time a condition that affects the output choice for a given
@@ -787,6 +817,10 @@
std::unordered_set<audio_format_t> mManualSurroundFormats;
std::unordered_map<uid_t, audio_flags_mask_t> mAllowedCapturePolicies;
+
+ // Cached product strategy ID corresponding to legacy strategy STRATEGY_PHONE
+ product_strategy_t mCommunnicationStrategy;
+
private:
void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
@@ -938,10 +972,11 @@
sp<AudioPatch> *patchDescPtr);
bool areAllDevicesSupported(
- const Vector<AudioDeviceTypeAddr>& devices,
+ const AudioDeviceTypeAddrVector& devices,
std::function<bool(audio_devices_t)> predicate,
const char* context);
+ bool isScoRequestedForComm() const;
};
};
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 45d8730..dcd30f6 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1261,7 +1261,7 @@
}
status_t AudioPolicyService::setUidDeviceAffinities(uid_t uid,
- const Vector<AudioDeviceTypeAddr>& devices) {
+ const AudioDeviceTypeAddrVector& devices) {
Mutex::Autolock _l(mLock);
if(!modifyAudioRoutingAllowed()) {
return PERMISSION_DENIED;
@@ -1286,7 +1286,7 @@
}
status_t AudioPolicyService::setUserIdDeviceAffinities(int userId,
- const Vector<AudioDeviceTypeAddr>& devices) {
+ const AudioDeviceTypeAddrVector& devices) {
Mutex::Autolock _l(mLock);
if(!modifyAudioRoutingAllowed()) {
return PERMISSION_DENIED;
@@ -1498,33 +1498,36 @@
return mAudioPolicyManager->isCallScreenModeSupported();
}
-status_t AudioPolicyService::setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device)
+status_t AudioPolicyService::setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mAudioPolicyManager->setPreferredDeviceForStrategy(strategy, device);
+ return mAudioPolicyManager->setDevicesRoleForStrategy(strategy, role, devices);
}
-status_t AudioPolicyService::removePreferredDeviceForStrategy(product_strategy_t strategy)
+status_t AudioPolicyService::removeDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mAudioPolicyManager->removePreferredDeviceForStrategy(strategy);
+ return mAudioPolicyManager->removeDevicesRoleForStrategy(strategy, role);
}
-status_t AudioPolicyService::getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device)
+status_t AudioPolicyService::getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mAudioPolicyManager->getPreferredDeviceForStrategy(strategy, device);
+ return mAudioPolicyManager->getDevicesForRoleAndStrategy(strategy, role, devices);
}
status_t AudioPolicyService::registerSoundTriggerCaptureStateListener(
@@ -1535,4 +1538,55 @@
return NO_ERROR;
}
+status_t AudioPolicyService::setDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->setDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioPolicyService::addDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->addDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioPolicyService::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->removeDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioPolicyService::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->clearDevicesRoleForCapturePreset(audioSource, role);
+}
+
+status_t AudioPolicyService::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 869a963..0b218c2 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -226,19 +226,41 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
- virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+ virtual status_t setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices);
virtual status_t removeUidDeviceAffinities(uid_t uid);
- virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy,
- const AudioDeviceTypeAddr &device);
+ virtual status_t setDevicesRoleForStrategy(product_strategy_t strategy,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
- virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy);
+ virtual status_t removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role);
+ virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices);
- virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy,
- AudioDeviceTypeAddr &device);
- virtual status_t setUserIdDeviceAffinities(int userId, const Vector<AudioDeviceTypeAddr>& devices);
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices);
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role);
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t setUserIdDeviceAffinities(int userId,
+ const AudioDeviceTypeAddrVector& devices);
virtual status_t removeUserIdDeviceAffinities(int userId);
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index efdb241..ca03e1f 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -18,7 +18,10 @@
"libxml2",
],
- static_libs: ["libaudiopolicycomponents"],
+ static_libs: [
+ "libaudiopolicycomponents",
+ "libgmock"
+ ],
header_libs: [
"libaudiopolicycommon",
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 0bd5442..ca2164b 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -20,6 +20,7 @@
#include <unistd.h>
#include <gtest/gtest.h>
+#include <gmock/gmock.h>
#define LOG_TAG "APM_Test"
#include <Serializer.h>
@@ -36,6 +37,7 @@
#include "AudioPolicyTestManager.h"
using namespace android;
+using testing::UnorderedElementsAre;
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
@@ -1193,3 +1195,109 @@
EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
}
+
+using DevicesRoleForCapturePresetParam = std::tuple<audio_source_t, device_role_t>;
+
+class AudioPolicyManagerDevicesRoleForCapturePresetTest
+ : public AudioPolicyManagerTestWithConfigurationFile,
+ public testing::WithParamInterface<DevicesRoleForCapturePresetParam> {
+protected:
+ // The `inputDevice` and `inputDevice2` indicate the audio devices type to be used for setting
+ // device role. They must be declared in the test_audio_policy_configuration.xml
+ AudioDeviceTypeAddr inputDevice = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
+ AudioDeviceTypeAddr inputDevice2 = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_HDMI, "");
+};
+
+TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCapturePreset) {
+ const audio_source_t audioSource = std::get<0>(GetParam());
+ const device_role_t role = std::get<1>(GetParam());
+
+ // Test invalid device when setting
+ const AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
+ const AudioDeviceTypeAddrVector outputDevices = {outputDevice};
+ ASSERT_EQ(BAD_VALUE,
+ mManager->setDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+ ASSERT_EQ(BAD_VALUE,
+ mManager->addDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+ AudioDeviceTypeAddrVector devices;
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ ASSERT_TRUE(devices.empty());
+ ASSERT_EQ(BAD_VALUE,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+
+ // Without setting, call get/remove/clear must fail
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, devices));
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->clearDevicesRoleForCapturePreset(audioSource, role));
+
+ // Test set/get devices role
+ const AudioDeviceTypeAddrVector inputDevices = {inputDevice};
+ ASSERT_EQ(NO_ERROR,
+ mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice));
+
+ // Test setting will change the previously set devices
+ const AudioDeviceTypeAddrVector inputDevices2 = {inputDevice2};
+ ASSERT_EQ(NO_ERROR,
+ mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices2));
+ devices.clear();
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
+
+ // Test add devices
+ ASSERT_EQ(NO_ERROR,
+ mManager->addDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ devices.clear();
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice, inputDevice2));
+
+ // Test remove devices
+ ASSERT_EQ(NO_ERROR,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ devices.clear();
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
+
+ // Test remove devices that are not set as the device role
+ ASSERT_EQ(BAD_VALUE,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+
+ // Test clear devices
+ ASSERT_EQ(NO_ERROR,
+ mManager->clearDevicesRoleForCapturePreset(audioSource, role));
+ devices.clear();
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ DevicesRoleForCapturePresetOperation,
+ AudioPolicyManagerDevicesRoleForCapturePresetTest,
+ testing::Values(
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_MIC, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_UPLINK,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_DOWNLINK,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_CALL, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_CAMCORDER, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_RECOGNITION,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_COMMUNICATION,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_REMOTE_SUBMIX,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_UNPROCESSED, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_PERFORMANCE,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_ECHO_REFERENCE,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_FM_TUNER, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_HOTWORD, DEVICE_ROLE_PREFERRED})
+ )
+ );
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 8b1e2c0..0e45204 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_library_shared {
+cc_library {
name: "libaaudioservice",