Merge "Generate the toString method for SoundDoseRecord"
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 1e1a49d..7d68c5b 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -36,6 +36,7 @@
"DrmUtils.cpp",
"DrmHalListener.cpp",
"DrmStatus.cpp",
+ "DrmMetricsLogger.cpp",
],
local_include_dirs: [
diff --git a/drm/libmediadrm/DrmMetricsLogger.cpp b/drm/libmediadrm/DrmMetricsLogger.cpp
new file mode 100644
index 0000000..bcdfadf
--- /dev/null
+++ b/drm/libmediadrm/DrmMetricsLogger.cpp
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "DrmMetricsLogger"
+
+#include <media/MediaMetrics.h>
+#include <mediadrm/DrmHal.h>
+#include <mediadrm/DrmMetricsLogger.h>
+#include <mediadrm/DrmUtils.h>
+
+namespace android {
+
+namespace {
+
+std::vector<uint8_t> toStdVec(Vector<uint8_t> const& sessionId) {
+ auto sessionKey = sessionId.array();
+ std::vector<uint8_t> vec(sessionKey, sessionKey + sessionId.size());
+ return vec;
+}
+} // namespace
+
+DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
+ : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonceMsb(0), mObjNonceLsb(0), mFrontend(frontend) {}
+
+DrmMetricsLogger::~DrmMetricsLogger() {}
+
+DrmStatus DrmMetricsLogger::initCheck() const {
+ DrmStatus status = mImpl->initCheck();
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* result) {
+ DrmStatus status = mImpl->isCryptoSchemeSupported(uuid, mimeType, securityLevel, result);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
+ std::memcpy(mUuid, uuid, sizeof(mUuid));
+ if (checkGetRandom(&mObjNonceMsb, __func__) == OK &&
+ checkGetRandom(&mObjNonceLsb, __func__) == OK) {
+ DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
+ if (status == OK) {
+ reportMediaDrmCreated();
+ } else {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+ }
+ return ERROR_DRM_RESOURCE_BUSY;
+}
+
+DrmStatus DrmMetricsLogger::destroyPlugin() {
+ DrmStatus status = mImpl->destroyPlugin();
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
+ Vector<uint8_t>& sessionId) {
+ SessionContext ctx{};
+ if (checkGetRandom(&ctx.mNonceMsb, __func__) == OK &&
+ checkGetRandom(&ctx.mNonceLsb, __func__) == OK) {
+ DrmStatus status = mImpl->openSession(securityLevel, sessionId);
+ if (status == OK) {
+ std::vector<uint8_t> sessionKey = toStdVec(sessionId);
+ ctx.mTargetSecurityLevel = securityLevel;
+ if (getSecurityLevel(sessionId, &ctx.mActualSecurityLevel) != OK) {
+ ctx.mActualSecurityLevel = DrmPlugin::kSecurityLevelUnknown;
+ }
+ {
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ mSessionMap.insert({sessionKey, ctx});
+ }
+ reportMediaDrmSessionOpened(sessionKey);
+ } else {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+ }
+ return ERROR_DRM_RESOURCE_BUSY;
+}
+
+DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
+ std::vector<uint8_t> sid = toStdVec(sessionId);
+ {
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ mSessionMap.erase(sid);
+ }
+ DrmStatus status = mImpl->closeSession(sessionId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, sid);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType) {
+ DrmStatus status =
+ mImpl->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters,
+ request, defaultUrl, keyRequestType);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId) {
+ DrmStatus status = mImpl->provideKeyResponse(sessionId, response, keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeKeys(Vector<uint8_t> const& keySetId) {
+ DrmStatus status = mImpl->removeKeys(keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId) {
+ DrmStatus status = mImpl->restoreKeys(sessionId, keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const {
+ DrmStatus status = mImpl->queryKeyStatus(sessionId, infoMap);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getProvisionRequest(String8 const& certType,
+ String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl) {
+ DrmStatus status = mImpl->getProvisionRequest(certType, certAuthority, request, defaultUrl);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey) {
+ DrmStatus status = mImpl->provideProvisionResponse(response, certificate, wrappedKey);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStops(List<Vector<uint8_t>>& secureStops) {
+ DrmStatus status = mImpl->getSecureStops(secureStops);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStopIds(List<Vector<uint8_t>>& secureStopIds) {
+ DrmStatus status = mImpl->getSecureStopIds(secureStopIds);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecureStop(Vector<uint8_t> const& ssid,
+ Vector<uint8_t>& secureStop) {
+ DrmStatus status = mImpl->getSecureStop(ssid, secureStop);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::releaseSecureStops(Vector<uint8_t> const& ssRelease) {
+ DrmStatus status = mImpl->releaseSecureStops(ssRelease);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeSecureStop(Vector<uint8_t> const& ssid) {
+ DrmStatus status = mImpl->removeSecureStop(ssid);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeAllSecureStops() {
+ DrmStatus status = mImpl->removeAllSecureStops();
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+ DrmPlugin::HdcpLevel* maxLevel) const {
+ DrmStatus status = mImpl->getHdcpLevels(connectedLevel, maxLevel);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getNumberOfSessions(uint32_t* currentSessions,
+ uint32_t* maxSessions) const {
+ DrmStatus status = mImpl->getNumberOfSessions(currentSessions, maxSessions);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const {
+ DrmStatus status = mImpl->getSecurityLevel(sessionId, level);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const {
+ DrmStatus status = mImpl->getOfflineLicenseKeySetIds(keySetIds);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::removeOfflineLicense(Vector<uint8_t> const& keySetId) {
+ DrmStatus status = mImpl->removeOfflineLicense(keySetId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getOfflineLicenseState(
+ Vector<uint8_t> const& keySetId, DrmPlugin::OfflineLicenseState* licenseState) const {
+ DrmStatus status = mImpl->getOfflineLicenseState(keySetId, licenseState);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getPropertyString(String8 const& name, String8& value) const {
+ DrmStatus status = mImpl->getPropertyString(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getPropertyByteArray(String8 const& name,
+ Vector<uint8_t>& value) const {
+ DrmStatus status = mImpl->getPropertyByteArray(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setPropertyString(String8 const& name, String8 const& value) const {
+ DrmStatus status = mImpl->setPropertyString(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setPropertyByteArray(String8 const& name,
+ Vector<uint8_t> const& value) const {
+ DrmStatus status = mImpl->setPropertyByteArray(name, value);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getMetrics(const sp<IDrmMetricsConsumer>& consumer) {
+ DrmStatus status = mImpl->getMetrics(consumer);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm) {
+ DrmStatus status = mImpl->setCipherAlgorithm(sessionId, algorithm);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setMacAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm) {
+ DrmStatus status = mImpl->setMacAlgorithm(sessionId, algorithm);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
+ DrmStatus status = mImpl->encrypt(sessionId, keyId, input, iv, output);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output) {
+ DrmStatus status = mImpl->decrypt(sessionId, keyId, input, iv, output);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature) {
+ DrmStatus status = mImpl->sign(sessionId, keyId, message, signature);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match) {
+ DrmStatus status = mImpl->verify(sessionId, keyId, message, signature, match);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message,
+ Vector<uint8_t> const& wrappedKey, Vector<uint8_t>& signature) {
+ DrmStatus status = mImpl->signRSA(sessionId, algorithm, message, wrappedKey, signature);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setListener(const sp<IDrmClient>& listener) {
+ DrmStatus status = mImpl->setListener(listener);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime, bool* required) const {
+ DrmStatus status = mImpl->requiresSecureDecoder(mime, required);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const {
+ DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::setPlaybackId(Vector<uint8_t> const& sessionId,
+ const char* playbackId) {
+ DrmStatus status = mImpl->setPlaybackId(sessionId, playbackId);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__, toStdVec(sessionId));
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+ DrmStatus status = mImpl->getLogMessages(logs);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
+ DrmStatus status = mImpl->getSupportedSchemes(schemes);
+ if (status != OK) {
+ reportMediaDrmErrored(status, __func__);
+ }
+ return status;
+}
+
+void DrmMetricsLogger::reportMediaDrmCreated() const {
+ mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
+ mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
+ mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt32(handle, "frontend", mFrontend);
+ mediametrics_selfRecord(handle);
+ mediametrics_delete(handle);
+}
+
+void DrmMetricsLogger::reportMediaDrmSessionOpened(std::vector<uint8_t> sessionId) const {
+ mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
+ mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
+ mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ auto it = mSessionMap.find(sessionId);
+ if (it != mSessionMap.end()) {
+ mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
+ mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
+ mediametrics_setInt64(handle, "target_seucrity_level", it->second.mTargetSecurityLevel);
+ mediametrics_setInt64(handle, "actual_seucrity_level", it->second.mActualSecurityLevel);
+ }
+ mediametrics_setInt32(handle, "frontend", mFrontend);
+ mediametrics_selfRecord(handle);
+ mediametrics_delete(handle);
+}
+
+void DrmMetricsLogger::reportMediaDrmErrored(DrmStatus error_code, const char* api,
+ std::vector<uint8_t> sessionId) const {
+ mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
+ mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
+ mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
+ if (!sessionId.empty()) {
+ const std::lock_guard<std::mutex> lock(mSessionMapMutex);
+ auto it = mSessionMap.find(sessionId);
+ if (it != mSessionMap.end()) {
+ mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
+ mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
+ }
+ }
+ mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
+ mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
+ mediametrics_setInt32(handle, "error_code", error_code);
+ mediametrics_setCString(handle, "api", api);
+ mediametrics_setInt32(handle, "frontend", mFrontend);
+ mediametrics_selfRecord(handle);
+ mediametrics_delete(handle);
+}
+
+DrmStatus DrmMetricsLogger::checkGetRandom(int64_t* nonce, const char* api) {
+ ssize_t bytes = getrandom(nonce, sizeof(int64_t), GRND_NONBLOCK);
+ if (bytes < sizeof(int64_t)) {
+ ALOGE("getrandom failed: %d", errno);
+ reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
+ return ERROR_DRM_RESOURCE_BUSY;
+ }
+ return OK;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index cb103f7..a99b1d1 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -59,11 +59,11 @@
namespace {
-template <typename Hal>
-Hal* MakeObject(status_t* pstatus) {
+template <typename Hal, typename... Ts>
+Hal* MakeObject(status_t* pstatus, Ts... args) {
status_t err = OK;
status_t& status = pstatus ? *pstatus : err;
- auto obj = new Hal();
+ auto obj = new Hal(args...);
status = obj->initCheck();
if (status != OK && status != NO_INIT) {
return NULL;
@@ -192,8 +192,8 @@
return factories;
}
-sp<IDrm> MakeDrm(status_t* pstatus) {
- return MakeObject<DrmHal>(pstatus);
+sp<IDrm> MakeDrm(IDrmFrontend frontend, status_t* pstatus) {
+ return MakeObject<DrmMetricsLogger>(pstatus, frontend);
}
sp<ICrypto> MakeCrypto(status_t* pstatus) {
diff --git a/drm/libmediadrm/include/mediadrm/DrmHalHidl.h b/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
index 45764a1..73a9e1d 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHalHidl.h
@@ -70,7 +70,7 @@
DrmPlugin::SecurityLevel level, bool* isSupported);
virtual DrmStatus createPlugin(const uint8_t uuid[16],
- const String8 &appPackageName);
+ const String8 &appPackageName);
virtual DrmStatus destroyPlugin();
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
new file mode 100644
index 0000000..638fb35
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsLogger.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include <mediadrm/DrmStatus.h>
+#include <mediadrm/IDrm.h>
+#include <sys/random.h>
+#include <map>
+#include <mutex>
+
+#ifndef DRM_METRICS_LOGGER_H
+#define DRM_METRICS_LOGGER_H
+
+namespace android {
+
+struct SessionContext {
+ int64_t mNonceMsb;
+ int64_t mNonceLsb;
+ int64_t mTargetSecurityLevel;
+ DrmPlugin::SecurityLevel mActualSecurityLevel;
+};
+
+class DrmMetricsLogger : public IDrm {
+ public:
+ DrmMetricsLogger(IDrmFrontend);
+
+ virtual ~DrmMetricsLogger();
+
+ virtual DrmStatus initCheck() const;
+
+ virtual DrmStatus isCryptoSchemeSupported(const uint8_t uuid[16], const String8& mimeType,
+ DrmPlugin::SecurityLevel securityLevel, bool* result);
+
+ virtual DrmStatus createPlugin(const uint8_t uuid[16], const String8& appPackageName);
+
+ virtual DrmStatus destroyPlugin();
+
+ virtual DrmStatus openSession(DrmPlugin::SecurityLevel securityLevel,
+ Vector<uint8_t>& sessionId);
+
+ virtual DrmStatus closeSession(Vector<uint8_t> const& sessionId);
+
+ virtual DrmStatus getKeyRequest(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& initData, String8 const& mimeType,
+ DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const& optionalParameters,
+ Vector<uint8_t>& request, String8& defaultUrl,
+ DrmPlugin::KeyRequestType* keyRequestType);
+
+ virtual DrmStatus provideKeyResponse(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& response,
+ Vector<uint8_t>& keySetId);
+
+ virtual DrmStatus removeKeys(Vector<uint8_t> const& keySetId);
+
+ virtual DrmStatus restoreKeys(Vector<uint8_t> const& sessionId,
+ Vector<uint8_t> const& keySetId);
+
+ virtual DrmStatus queryKeyStatus(Vector<uint8_t> const& sessionId,
+ KeyedVector<String8, String8>& infoMap) const;
+
+ virtual DrmStatus getProvisionRequest(String8 const& certType, String8 const& certAuthority,
+ Vector<uint8_t>& request, String8& defaultUrl);
+
+ virtual DrmStatus provideProvisionResponse(Vector<uint8_t> const& response,
+ Vector<uint8_t>& certificate,
+ Vector<uint8_t>& wrappedKey);
+
+ virtual DrmStatus getSecureStops(List<Vector<uint8_t>>& secureStops);
+ virtual DrmStatus getSecureStopIds(List<Vector<uint8_t>>& secureStopIds);
+ virtual DrmStatus getSecureStop(Vector<uint8_t> const& ssid, Vector<uint8_t>& secureStop);
+
+ virtual DrmStatus releaseSecureStops(Vector<uint8_t> const& ssRelease);
+ virtual DrmStatus removeSecureStop(Vector<uint8_t> const& ssid);
+ virtual DrmStatus removeAllSecureStops();
+
+ virtual DrmStatus getHdcpLevels(DrmPlugin::HdcpLevel* connectedLevel,
+ DrmPlugin::HdcpLevel* maxLevel) const;
+ virtual DrmStatus getNumberOfSessions(uint32_t* currentSessions, uint32_t* maxSessions) const;
+ virtual DrmStatus getSecurityLevel(Vector<uint8_t> const& sessionId,
+ DrmPlugin::SecurityLevel* level) const;
+
+ virtual DrmStatus getOfflineLicenseKeySetIds(List<Vector<uint8_t>>& keySetIds) const;
+ virtual DrmStatus removeOfflineLicense(Vector<uint8_t> const& keySetId);
+ virtual DrmStatus getOfflineLicenseState(Vector<uint8_t> const& keySetId,
+ DrmPlugin::OfflineLicenseState* licenseState) const;
+
+ virtual DrmStatus getPropertyString(String8 const& name, String8& value) const;
+ virtual DrmStatus getPropertyByteArray(String8 const& name, Vector<uint8_t>& value) const;
+ virtual DrmStatus setPropertyString(String8 const& name, String8 const& value) const;
+ virtual DrmStatus setPropertyByteArray(String8 const& name, Vector<uint8_t> const& value) const;
+
+ virtual DrmStatus getMetrics(const sp<IDrmMetricsConsumer>& consumer);
+
+ virtual DrmStatus setCipherAlgorithm(Vector<uint8_t> const& sessionId,
+ String8 const& algorithm);
+
+ virtual DrmStatus setMacAlgorithm(Vector<uint8_t> const& sessionId, String8 const& algorithm);
+
+ virtual DrmStatus encrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output);
+
+ virtual DrmStatus decrypt(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& input, Vector<uint8_t> const& iv,
+ Vector<uint8_t>& output);
+
+ virtual DrmStatus sign(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t>& signature);
+
+ virtual DrmStatus verify(Vector<uint8_t> const& sessionId, Vector<uint8_t> const& keyId,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& signature,
+ bool& match);
+
+ virtual DrmStatus signRSA(Vector<uint8_t> const& sessionId, String8 const& algorithm,
+ Vector<uint8_t> const& message, Vector<uint8_t> const& wrappedKey,
+ Vector<uint8_t>& signature);
+
+ virtual DrmStatus setListener(const sp<IDrmClient>& listener);
+
+ virtual DrmStatus requiresSecureDecoder(const char* mime, bool* required) const;
+
+ virtual DrmStatus requiresSecureDecoder(const char* mime,
+ DrmPlugin::SecurityLevel securityLevel,
+ bool* required) const;
+
+ virtual DrmStatus setPlaybackId(Vector<uint8_t> const& sessionId, const char* playbackId);
+
+ virtual DrmStatus getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const;
+
+ virtual DrmStatus getSupportedSchemes(std::vector<uint8_t>& schemes) const;
+
+ void reportMediaDrmCreated() const;
+
+ void reportMediaDrmSessionOpened(std::vector<uint8_t> sessionId) const;
+
+ void reportMediaDrmErrored(DrmStatus error_code, const char* api,
+ std::vector<uint8_t> sessionId = std::vector<uint8_t>()) const;
+
+ DrmStatus checkGetRandom(int64_t* nonce, const char* api);
+
+ private:
+ sp<IDrm> mImpl;
+ int64_t mUuid[2] = {};
+ int64_t mObjNonceMsb, mObjNonceLsb;
+ std::map<std::vector<uint8_t>, SessionContext> mSessionMap;
+ mutable std::mutex mSessionMapMutex;
+ IDrmFrontend mFrontend;
+ DISALLOW_EVIL_CONSTRUCTORS(DrmMetricsLogger);
+};
+
+} // namespace android
+
+#endif // DRM_METRICS_LOGGER_H
\ No newline at end of file
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index 3dc7485..f37d1d1 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -33,6 +33,13 @@
} // namespace drm
} // namespace hardware
+enum IDrmFrontend : int32_t {
+ IDRM_UNKNOWN = 0,
+ IDRM_JNI = 1,
+ IDRM_NDK = 2,
+ IDRM_NUPLAYER = 3,
+};
+
namespace drm = ::android::hardware::drm;
struct AString;
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 0044bac..ce8536c 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -22,6 +22,7 @@
#include <android/hardware/drm/1.4/IDrmPlugin.h>
#include <android/hardware/drm/1.4/types.h>
#include <media/stagefright/MediaErrors.h>
+#include <mediadrm/DrmMetricsLogger.h>
#include <mediadrm/DrmStatus.h>
#include <utils/Errors.h> // for status_t
#include <utils/Log.h>
@@ -119,7 +120,7 @@
bool UseDrmService();
-sp<IDrm> MakeDrm(status_t *pstatus = nullptr);
+sp<IDrm> MakeDrm(IDrmFrontend frontend = IDRM_JNI, status_t* pstatus = nullptr);
sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
diff --git a/include/media/MicrophoneInfo.h b/include/media/MicrophoneInfo.h
index a5045b9..6d6c594 100644
--- a/include/media/MicrophoneInfo.h
+++ b/include/media/MicrophoneInfo.h
@@ -70,6 +70,9 @@
}
virtual status_t writeToParcelable(MicrophoneInfoData* parcelable) const {
+#if defined(BACKEND_NDK)
+ using ::aidl::android::convertReinterpret;
+#endif
parcelable->deviceId = mDeviceId;
parcelable->portId = mPortId;
parcelable->type = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(mType));
@@ -98,6 +101,9 @@
}
virtual status_t readFromParcelable(const MicrophoneInfoData& parcelable) {
+#if defined(BACKEND_NDK)
+ using ::aidl::android::convertReinterpret;
+#endif
mDeviceId = parcelable.deviceId;
mPortId = parcelable.portId;
mType = VALUE_OR_RETURN_STATUS(convertReinterpret<uint32_t>(parcelable.type));
@@ -208,6 +214,10 @@
int32_t mDirectionality;
};
+#if defined(BACKEND_NDK)
+using ::aidl::ConversionResult;
+#endif
+
// Conversion routines, according to AidlConversion.h conventions.
inline ConversionResult<MicrophoneInfo>
aidl2legacy_MicrophoneInfo(const media::MicrophoneInfoData& aidl) {
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index d151817..8cbe3ea 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -245,12 +245,14 @@
"latest_android_media_audio_common_types_ndk_shared",
],
srcs: [
+ "DeviceHalAidl.cpp",
"DevicesFactoryHalEntry.cpp",
"DevicesFactoryHalAidl.cpp",
"EffectBufferHalAidl.cpp",
"EffectHalAidl.cpp",
"EffectsFactoryHalAidl.cpp",
"EffectsFactoryHalEntry.cpp",
+ "StreamHalAidl.cpp",
],
static_libs: [
"android.hardware.common-V2-ndk",
@@ -271,4 +273,4 @@
"-Wthread-safety",
"-DBACKEND_NDK",
],
-}
\ No newline at end of file
+}
diff --git a/media/libaudiohal/impl/ConversionHelperAidl.h b/media/libaudiohal/impl/ConversionHelperAidl.h
new file mode 100644
index 0000000..097ccfd
--- /dev/null
+++ b/media/libaudiohal/impl/ConversionHelperAidl.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <string>
+#include <string_view>
+
+namespace android {
+
+class ConversionHelperAidl {
+ protected:
+ ConversionHelperAidl(std::string_view className) : mClassName(className) {}
+
+ const std::string& getClassName() const {
+ return mClassName;
+ }
+
+ const std::string mClassName;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index d85d960..02e8fa7 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -16,94 +16,149 @@
#define LOG_TAG "DeviceHalAidl"
-#include "DeviceHalAidl.h"
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
-status_t DeviceHalAidl::getSupportedDevices(uint32_t* devices) {
- ALOGE("%s not implemented yet devices %p", __func__, devices);
- return OK;
+#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using ::aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
+ // Obsolete.
+ return INVALID_OPERATION;
}
status_t DeviceHalAidl::initCheck() {
- ALOGE("%s not implemented yet", __func__);
+ if (mModule == nullptr) return NO_INIT;
+ // HAL modules are already initialized by the time they are published to the SM.
return OK;
}
status_t DeviceHalAidl::setVoiceVolume(float volume) {
+ TIME_CHECK();
mVoiceVolume = volume;
ALOGE("%s not implemented yet %f", __func__, volume);
return OK;
}
status_t DeviceHalAidl::setMasterVolume(float volume) {
+ TIME_CHECK();
mMasterVolume = volume;
ALOGE("%s not implemented yet %f", __func__, volume);
return OK;
}
status_t DeviceHalAidl::getMasterVolume(float *volume) {
+ TIME_CHECK();
*volume = mMasterVolume;
ALOGE("%s not implemented yet %f", __func__, *volume);
return OK;
}
-status_t DeviceHalAidl::setMode(audio_mode_t mode) {
- ALOGE("%s not implemented yet %u", __func__, mode);
+status_t DeviceHalAidl::setMode(audio_mode_t mode __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
status_t DeviceHalAidl::setMicMute(bool state) {
+ TIME_CHECK();
mMicMute = state;
ALOGE("%s not implemented yet %d", __func__, state);
return OK;
}
+
status_t DeviceHalAidl::getMicMute(bool *state) {
+ TIME_CHECK();
*state = mMicMute;
ALOGE("%s not implemented yet %d", __func__, *state);
return OK;
}
+
status_t DeviceHalAidl::setMasterMute(bool state) {
+ TIME_CHECK();
mMasterMute = state;
ALOGE("%s not implemented yet %d", __func__, state);
return OK;
}
+
status_t DeviceHalAidl::getMasterMute(bool *state) {
+ TIME_CHECK();
*state = mMasterMute;
ALOGE("%s not implemented yet %d", __func__, *state);
return OK;
}
-status_t DeviceHalAidl::setParameters(const String8& kvPairs) {
- ALOGE("%s not implemented yet %s", __func__, kvPairs.c_str());
+status_t DeviceHalAidl::setParameters(const String8& kvPairs __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::getParameters(const String8& keys, String8 *values) {
- ALOGE("%s not implemented yet %s %s", __func__, keys.c_str(), values->c_str());
+status_t DeviceHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+ TIME_CHECK();
+ values->clear();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
- ALOGE("%s not implemented yet %p %zu", __func__, config, *size);
+status_t DeviceHalAidl::getInputBufferSize(
+ const struct audio_config* config __unused, size_t* size __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::openOutputStream(audio_io_handle_t handle, audio_devices_t devices,
- audio_output_flags_t flags, struct audio_config* config,
- const char* address,
- sp<StreamOutHalInterface>* outStream) {
- ALOGE("%s not implemented yet %d %u %u %p %s %p", __func__, handle, devices, flags, config,
- address, outStream);
+status_t DeviceHalAidl::openOutputStream(
+ audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+ audio_output_flags_t flags __unused, struct audio_config* config,
+ const char* address __unused,
+ sp<StreamOutHalInterface>* outStream) {
+ if (!outStream || !config) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ config->sample_rate = 48000;
+ config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ StreamDescriptor descriptor;
+ descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+ audio_channel_count_from_out_mask(config->channel_mask);
+ descriptor.bufferSizeFrames = 600;
+ *outStream = sp<StreamOutHalAidl>::make(descriptor, nullptr);
return OK;
}
-status_t DeviceHalAidl::openInputStream(audio_io_handle_t handle, audio_devices_t devices,
- struct audio_config* config, audio_input_flags_t flags,
- const char* address, audio_source_t source,
- audio_devices_t outputDevice,
- const char* outputDeviceAddress,
- sp<StreamInHalInterface>* inStream) {
- ALOGE("%s not implemented yet %d %u %u %u %p %s %s %p %d", __func__, handle, devices,
- outputDevice, flags, config, address, outputDeviceAddress, inStream, source);
+status_t DeviceHalAidl::openInputStream(
+ audio_io_handle_t handle __unused, audio_devices_t devices __unused,
+ struct audio_config* config, audio_input_flags_t flags __unused,
+ const char* address __unused, audio_source_t source __unused,
+ audio_devices_t outputDevice __unused,
+ const char* outputDeviceAddress __unused,
+ sp<StreamInHalInterface>* inStream) {
+ if (!inStream || !config) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ config->sample_rate = 48000;
+ config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
+ StreamDescriptor descriptor;
+ descriptor.frameSizeBytes = audio_bytes_per_sample(config->format) *
+ audio_channel_count_from_out_mask(config->channel_mask);
+ descriptor.bufferSizeFrames = 600;
+ *inStream = sp<StreamInHalAidl>::make(descriptor, nullptr);
return OK;
}
@@ -112,66 +167,94 @@
return OK;
}
-status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources,
- const struct audio_port_config* sources,
- unsigned int num_sinks,
- const struct audio_port_config* sinks,
- audio_patch_handle_t* patch) {
- ALOGE("%s not implemented yet %d %p %d %p %p", __func__, num_sources, sources, num_sinks,
- sinks, patch);
+status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources __unused,
+ const struct audio_port_config* sources __unused,
+ unsigned int num_sinks __unused,
+ const struct audio_port_config* sinks __unused,
+ audio_patch_handle_t* patch __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
- ALOGE("%s not implemented yet patch %d", __func__, patch);
+status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
- ALOGE("%s not implemented yet config %p", __func__, config);
+status_t DeviceHalAidl::getAudioPort(struct audio_port* port __unused) {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::getAudioPort(struct audio_port_v7 *port __unused) {
+ TIME_CHECK();
+ ALOGE("%s not implemented yet", __func__);
+ return INVALID_OPERATION;
+}
+
+status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
status_t DeviceHalAidl::getMicrophones(
- std::vector<audio_microphone_characteristic_t>* microphones) {
- ALOGE("%s not implemented yet microphones %p", __func__, microphones);
+ std::vector<audio_microphone_characteristic_t>* microphones __unused) {
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) {
+status_t DeviceHalAidl::addDeviceEffect(audio_port_handle_t device __unused,
+ sp<EffectHalInterface> effect) {
if (!effect) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet device %d", __func__, device);
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
-status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device,
+status_t DeviceHalAidl::removeDeviceEffect(audio_port_handle_t device __unused,
sp<EffectHalInterface> effect) {
if (!effect) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet device %d", __func__, device);
+ TIME_CHECK();
+ if (!mModule) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
return OK;
}
status_t DeviceHalAidl::getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType __unused,
std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos __unused) {
+ TIME_CHECK();
ALOGE("%s not implemented yet", __func__);
return OK;
}
int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+ TIME_CHECK();
ALOGE("%s not implemented yet", __func__);
return OK;
}
int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+ TIME_CHECK();
ALOGE("%s not implemented yet", __func__);
return OK;
}
error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+ TIME_CHECK();
ALOGE("%s not implemented yet", __func__);
return base::unexpected(INVALID_OPERATION);
}
@@ -181,7 +264,10 @@
return OK;
};
-int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) override {
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
+ TIME_CHECK();
ALOGE("%s not implemented yet", __func__);
return INVALID_OPERATION;
}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 5e8a8dd..91d48cc 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -16,14 +16,15 @@
#pragma once
+#include <aidl/android/hardware/audio/core/BpModule.h>
#include <media/audiohal/DeviceHalInterface.h>
#include <media/audiohal/EffectHalInterface.h>
-#include <aidl/android/hardware/audio/core/BpModule.h>
+#include "ConversionHelperAidl.h"
namespace android {
-class DeviceHalAidl : public DeviceHalInterface {
+class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl {
public:
// Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
status_t getSupportedDevices(uint32_t *devices) override;
@@ -86,6 +87,12 @@
// Releases an audio patch.
status_t releaseAudioPatch(audio_patch_handle_t patch) override;
+ // Fills the list of supported attributes for a given audio port.
+ status_t getAudioPort(struct audio_port* port) override;
+
+ // Fills the list of supported attributes for a given audio port.
+ status_t getAudioPort(struct audio_port_v7 *port) override;
+
// Set audio port configuration.
status_t setAudioPortConfig(const struct audio_port_config* config) override;
@@ -111,8 +118,10 @@
int32_t supportsBluetoothVariableLatency(bool* supports __unused) override;
private:
- friend class DevicesFactoryHalAidl;
- const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mCore;
+ friend class sp<DeviceHalAidl>;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
+ // FIXME: Remove these after implementing calls into the HAL.
float mMasterVolume = 0.0f;
float mVoiceVolume = 0.0f;
bool mMasterMute = false;
@@ -120,11 +129,10 @@
// Can not be constructed directly by clients.
explicit DeviceHalAidl(
- const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& core)
- : mCore(core) {}
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module)
+ : ConversionHelperAidl("DeviceHalAidl"), mModule(module) {}
- // The destructor automatically closes the device.
- ~DeviceHalAidl();
+ ~DeviceHalAidl() override = default;
};
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index be063ab..12acebd 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -46,9 +46,6 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
-#define TIME_CHECK() auto timeCheck = \
- mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
: CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
}
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
index b9ca164..ee29f09 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.cpp
@@ -35,27 +35,28 @@
ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
}
-void DevicesFactoryHalAidl::onFirstRef() {
- ALOGE("%s not implemented yet", __func__);
-}
-
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
status_t DevicesFactoryHalAidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (name == nullptr || device == nullptr) {
return BAD_VALUE;
}
- ALOGE("%s not implemented yet %s", __func__, name);
- return INVALID_OPERATION;
- // TODO: only support primary now ("default" means "primary")
- if (strcmp(name, "primary") != 0) {
- auto serviceName = std::string() + IModule::descriptor + "/default";
- auto service = IModule::fromBinder(
+ std::shared_ptr<IModule> service;
+ // FIXME: Normally we will list available HAL modules and connect to them,
+ // however currently we still get the list of module names from the config.
+ // Since the example service does not have all modules, the SM will wait
+ // for the missing ones forever.
+ if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0) {
+ if (strcmp(name, "primary") == 0) name = "default";
+ auto serviceName = std::string(IModule::descriptor) + "/" + name;
+ service = IModule::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
- ALOGW("%s fromBinder %s %s", __func__, IModule::descriptor, service ? "succ" : "fail");
- *device = new DeviceHalAidl(service);
+ ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
}
+ // If the service is a nullptr, the device will not be really functional,
+ // but will not crash either.
+ *device = sp<DeviceHalAidl>::make(service);
return OK;
}
@@ -68,21 +69,25 @@
}
status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
- if (callback == nullptr) {
- return BAD_VALUE;
+ // Dynamic registration of module instances is not supported. The functionality
+ // in the audio server which is related to this callback can be removed together
+ // with HIDL support.
+ ALOG_ASSERT(callback != nullptr);
+ if (callback != nullptr) {
+ callback->onNewDevicesAvailable();
}
- ALOGE("%s not implemented yet", __func__);
- return INVALID_OPERATION;
+ return NO_ERROR;
}
AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
int32_t versionNumber = 0;
- if (mIConfig) {
- if (!mIConfig->getInterfaceVersion(&versionNumber).isOk()) {
- ALOGE("%s getInterfaceVersion failed", __func__);
- } else {
- ALOGI("%s getInterfaceVersion %d", __func__, versionNumber);
+ if (mIConfig != 0) {
+ if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
+ !status.isOk()) {
+ ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
}
+ } else {
+ ALOGW("%s no IConfig instance", __func__);
}
// AIDL does not have minor version, fill 0 for all versions
return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
diff --git a/media/libaudiohal/impl/DevicesFactoryHalAidl.h b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
index 71138a0..cb627bc 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalAidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalAidl.h
@@ -27,7 +27,6 @@
public:
explicit DevicesFactoryHalAidl(
std::shared_ptr<::aidl::android::hardware::audio::core::IConfig> iConfig);
- void onFirstRef() override;
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index 3956a6c..ed952a3 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -46,9 +46,6 @@
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
-#define TIME_CHECK() auto timeCheck = \
- mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
: EffectConversionHelperHidl("EffectHalHidl"),
mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
new file mode 100644
index 0000000..7338952
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define LOG_TAG "StreamHalAidl"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
+#include <mediautils/TimeCheck.h>
+#include <utils/Log.h>
+
+#include "DeviceHalAidl.h"
+#include "StreamHalAidl.h"
+
+using ::aidl::android::hardware::audio::core::IStreamCommon;
+using ::aidl::android::hardware::audio::core::IStreamIn;
+using ::aidl::android::hardware::audio::core::IStreamOut;
+using ::aidl::android::hardware::audio::core::StreamDescriptor;
+
+namespace android {
+
+StreamHalAidl::StreamHalAidl(
+ std::string_view className, bool isInput, const StreamDescriptor& descriptor,
+ const std::shared_ptr<IStreamCommon>& stream)
+ : ConversionHelperAidl(className),
+ mIsInput(isInput),
+ mFrameSizeBytes(descriptor.frameSizeBytes),
+ mBufferSizeFrames(descriptor.bufferSizeFrames),
+ mCommandMQ(new CommandMQ(descriptor.command)),
+ mReplyMQ(new ReplyMQ(descriptor.reply)),
+ mDataMQ(maybeCreateDataMQ(descriptor)),
+ mStream(stream) {
+ // Instrument audio signal power logging.
+ // Note: This assumes channel mask, format, and sample rate do not change after creation.
+ if (audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+ /* mStreamPowerLog.isUserDebugOrEngBuild() && */
+ StreamHalAidl::getAudioProperties(&config) == NO_ERROR) {
+ mStreamPowerLog.init(config.sample_rate, config.channel_mask, config.format);
+ }
+}
+
+StreamHalAidl::~StreamHalAidl() {
+ if (mStream != nullptr) {
+ ndk::ScopedAStatus status = mStream->close();
+ ALOGE_IF(!status.isOk(), "%s: status %s", __func__, status.getDescription().c_str());
+ }
+}
+
+status_t StreamHalAidl::getBufferSize(size_t *size) {
+ if (size == nullptr) {
+ return BAD_VALUE;
+ }
+ if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0) {
+ return NO_INIT;
+ }
+ *size = mFrameSizeBytes * mBufferSizeFrames;
+ return OK;
+}
+
+status_t StreamHalAidl::getAudioProperties(audio_config_base_t *configBase) {
+ if (configBase == nullptr) {
+ return BAD_VALUE;
+ }
+ TIME_CHECK();
+ *configBase = AUDIO_CONFIG_BASE_INITIALIZER;
+ configBase->sample_rate = 48000;
+ configBase->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ configBase->channel_mask = mIsInput ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_OUT_STEREO;
+ // if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::setParameters(const String8& kvPairs __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::getParameters(const String8& keys __unused, String8 *values) {
+ TIME_CHECK();
+ values->clear();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::getFrameSize(size_t *size) {
+ if (size == nullptr) {
+ return BAD_VALUE;
+ }
+ if (mFrameSizeBytes == 0) {
+ return NO_INIT;
+ }
+ *size = mFrameSizeBytes;
+ return OK;
+}
+
+status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::standby() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::dump(int fd __unused, const Vector<String16>& args __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::start() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::stop() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::createMmapBuffer(int32_t minSizeFrames __unused,
+ struct audio_mmap_buffer_info *info __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::getMmapPosition(struct audio_mmap_position *position __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::setHalThreadPriority(int priority __unused) {
+ mHalThreadPriority = priority;
+ return OK;
+}
+
+status_t StreamHalAidl::getHalPid(pid_t *pid __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+bool StreamHalAidl::requestHalThreadPriority(pid_t threadPid __unused, pid_t threadId __unused) {
+ if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
+ return true;
+ }
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
+ std::optional<audio_source_t> source __unused,
+ audio_devices_t type __unused) {
+ TIME_CHECK();
+ LOG_ALWAYS_FATAL_IF(port.type != AUDIO_PORT_TYPE_DEVICE, "port type must be device");
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamHalAidl::legacyReleaseAudioPatch() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+namespace {
+
+/* Notes on callback ownership.
+
+This is how Binder ownership model looks like. The server implementation
+is owned by Binder framework (via sp<>). Proxies are owned by clients.
+When the last proxy disappears, Binder framework releases the server impl.
+
+Thus, it is not needed to keep any references to StreamCallback (this is
+the server impl) -- it will live as long as HAL server holds a strong ref to
+IStreamCallback proxy.
+
+The callback only keeps a weak reference to the stream. The stream is owned
+by AudioFlinger.
+
+*/
+
+class StreamCallback : public ::aidl::android::hardware::audio::core::BnStreamCallback {
+ ndk::ScopedAStatus onTransferReady() override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onError() override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onDrainReady() override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+} // namespace
+
+StreamOutHalAidl::StreamOutHalAidl(
+ const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
+ : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, descriptor,
+ nullptr /* FIXME: Retrieve IStreamCommon */),
+ mStream(stream) {}
+
+status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
+ TIME_CHECK();
+ *latency = 0;
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::setVolume(float left __unused, float right __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::write(
+ const void *buffer __unused, size_t bytes __unused, size_t *written __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ *written = 0;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::supportsPauseAndResume(
+ bool *supportsPause __unused, bool *supportsResume __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::pause() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::resume() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::supportsDrain(bool *supportsDrain __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::drain(bool earlyNotify __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::flush() {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getPresentationPosition(
+ uint64_t *frames __unused, struct timespec *timestamp __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::updateSourceMetadata(
+ const StreamOutHalInterface::SourceMetadata& sourceMetadata __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::getPlaybackRateParameters(
+ audio_playback_rate_t* playbackRate __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setPlaybackRateParameters(
+ const audio_playback_rate_t& playbackRate __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamOutHalAidl::setEventCallback(
+ const sp<StreamOutHalInterfaceEventCallback>& callback __unused) {
+ return INVALID_OPERATION;
+}
+
+namespace {
+
+struct StreamOutEventCallback {
+ StreamOutEventCallback(const wp<StreamOutHalAidl>& stream) : mStream(stream) {}
+ private:
+ wp<StreamOutHalAidl> mStream;
+};
+
+} // namespace
+
+status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
+ return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::getRecommendedLatencyModes(
+ std::vector<audio_latency_mode_t> *modes __unused) {
+ return INVALID_OPERATION;
+};
+
+status_t StreamOutHalAidl::setLatencyModeCallback(
+ const sp<StreamOutHalInterfaceLatencyModeCallback>& callback __unused) {
+ return INVALID_OPERATION;
+};
+
+void StreamOutHalAidl::onWriteReady() {
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+ if (callback == 0) return;
+ ALOGV("asyncCallback onWriteReady");
+ callback->onWriteReady();
+}
+
+void StreamOutHalAidl::onDrainReady() {
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+ if (callback == 0) return;
+ ALOGV("asyncCallback onDrainReady");
+ callback->onDrainReady();
+}
+
+void StreamOutHalAidl::onError() {
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
+ if (callback == 0) return;
+ ALOGV("asyncCallback onError");
+ callback->onError();
+}
+
+void StreamOutHalAidl::onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs __unused) {
+ sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.load().promote();
+ if (callback == nullptr) return;
+ ALOGV("asyncCodecFormatCallback %s", __func__);
+ callback->onCodecFormatChanged(metadataBs);
+}
+
+void StreamOutHalAidl::onRecommendedLatencyModeChanged(
+ const std::vector<audio_latency_mode_t>& modes __unused) {
+ sp<StreamOutHalInterfaceLatencyModeCallback> callback = mLatencyModeCallback.load().promote();
+ if (callback == nullptr) return;
+ callback->onRecommendedLatencyModeChanged(modes);
+}
+
+status_t StreamOutHalAidl::exit() {
+ // FIXME this is using hard-coded strings but in the future, this functionality will be
+ // converted to use audio HAL extensions required to support tunneling
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+StreamInHalAidl::StreamInHalAidl(
+ const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
+ : StreamHalAidl("StreamInHalAidl", true /*isInput*/, descriptor,
+ nullptr /* FIXME: Retrieve IStreamCommon */),
+ mStream(stream) {}
+
+status_t StreamInHalAidl::setGain(float gain __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamInHalAidl::read(
+ void *buffer __unused, size_t bytes __unused, size_t *read __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ // FIXME: Don't forget to update mPowerLog
+ return OK;
+}
+
+status_t StreamInHalAidl::getInputFramesLost(uint32_t *framesLost __unused) {
+ TIME_CHECK();
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamInHalAidl::getCapturePosition(int64_t *frames __unused, int64_t *time __unused) {
+ // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
+ if (!mStream) return NO_INIT;
+ ALOGE("%s not implemented yet", __func__);
+ return OK;
+}
+
+status_t StreamInHalAidl::getActiveMicrophones(
+ std::vector<media::MicrophoneInfo> *microphones __unused) {
+ if (mStream == 0) return NO_INIT;
+ return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::updateSinkMetadata(
+ const StreamInHalInterface::SinkMetadata& sinkMetadata __unused) {
+ return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneDirection(
+ audio_microphone_direction_t direction __unused) {
+ if (mStream == 0) return NO_INIT;
+ return INVALID_OPERATION;
+}
+
+status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+ if (mStream == 0) return NO_INIT;
+ return INVALID_OPERATION;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
new file mode 100644
index 0000000..86f48f3
--- /dev/null
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string_view>
+
+#include <aidl/android/hardware/audio/core/BpStreamCommon.h>
+#include <aidl/android/hardware/audio/core/BpStreamIn.h>
+#include <aidl/android/hardware/audio/core/BpStreamOut.h>
+#include <fmq/AidlMessageQueue.h>
+#include <media/audiohal/EffectHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
+#include <mediautils/Synchronization.h>
+
+#include "ConversionHelperAidl.h"
+#include "StreamPowerLog.h"
+
+namespace android {
+
+class DeviceHalAidl;
+
+class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl {
+ public:
+ // Return size of input/output buffer in bytes for this stream - eg. 4800.
+ status_t getBufferSize(size_t *size) override;
+
+ // Return the base configuration of the stream:
+ // - channel mask;
+ // - format - e.g. AUDIO_FORMAT_PCM_16_BIT;
+ // - sampling rate in Hz - eg. 44100.
+ status_t getAudioProperties(audio_config_base_t *configBase) override;
+
+ // Set audio stream parameters.
+ status_t setParameters(const String8& kvPairs) override;
+
+ // Get audio stream parameters.
+ status_t getParameters(const String8& keys, String8 *values) override;
+
+ // Return the frame size (number of bytes per sample) of a stream.
+ status_t getFrameSize(size_t *size) override;
+
+ // Add or remove the effect on the stream.
+ status_t addEffect(sp<EffectHalInterface> effect) override;
+ status_t removeEffect(sp<EffectHalInterface> effect) override;
+
+ // Put the audio hardware input/output into standby mode.
+ status_t standby() override;
+
+ status_t dump(int fd, const Vector<String16>& args) override;
+
+ // Start a stream operating in mmap mode.
+ status_t start() override;
+
+ // Stop a stream operating in mmap mode.
+ status_t stop() override;
+
+ // Retrieve information on the data buffer in mmap mode.
+ status_t createMmapBuffer(int32_t minSizeFrames,
+ struct audio_mmap_buffer_info *info) override;
+
+ // Get current read/write position in the mmap buffer
+ status_t getMmapPosition(struct audio_mmap_position *position) override;
+
+ // Set the priority of the thread that interacts with the HAL
+ // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+ status_t setHalThreadPriority(int priority) override;
+
+ status_t legacyCreateAudioPatch(const struct audio_port_config& port,
+ std::optional<audio_source_t> source,
+ audio_devices_t type) override;
+
+ status_t legacyReleaseAudioPatch() override;
+
+ protected:
+ typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Command,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> CommandMQ;
+ typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Reply,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> ReplyMQ;
+ typedef AidlMessageQueue<int8_t,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
+
+ // Subclasses can not be constructed directly by clients.
+ StreamHalAidl(std::string_view className,
+ bool isInput,
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream);
+
+ ~StreamHalAidl() override;
+
+ status_t getHalPid(pid_t *pid);
+
+ bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
+
+ const bool mIsInput;
+ const size_t mFrameSizeBytes;
+ const size_t mBufferSizeFrames;
+ const std::unique_ptr<CommandMQ> mCommandMQ;
+ const std::unique_ptr<ReplyMQ> mReplyMQ;
+ const std::unique_ptr<DataMQ> mDataMQ;
+ // mStreamPowerLog is used for audio signal power logging.
+ StreamPowerLog mStreamPowerLog;
+
+ private:
+ static std::unique_ptr<DataMQ> maybeCreateDataMQ(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
+ using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
+ if (descriptor.audio.getTag() == Tag::fmq) {
+ return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>());
+ }
+ return nullptr;
+ }
+
+ const int HAL_THREAD_PRIORITY_DEFAULT = -1;
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
+ int mHalThreadPriority = HAL_THREAD_PRIORITY_DEFAULT;
+};
+
+class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
+ public:
+ // Return the audio hardware driver estimated latency in milliseconds.
+ status_t getLatency(uint32_t *latency) override;
+
+ // Use this method in situations where audio mixing is done in the hardware.
+ status_t setVolume(float left, float right) override;
+
+ // Selects the audio presentation (if available).
+ status_t selectPresentation(int presentationId, int programId) override;
+
+ // Write audio buffer to driver.
+ status_t write(const void *buffer, size_t bytes, size_t *written) override;
+
+ // Return the number of audio frames written by the audio dsp to DAC since
+ // the output has exited standby.
+ status_t getRenderPosition(uint32_t *dspFrames) override;
+
+ // Get the local time at which the next write to the audio driver will be presented.
+ status_t getNextWriteTimestamp(int64_t *timestamp) override;
+
+ // Set the callback for notifying completion of non-blocking write and drain.
+ status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
+
+ // Returns whether pause and resume operations are supported.
+ status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) override;
+
+ // Notifies to the audio driver to resume playback following a pause.
+ status_t pause() override;
+
+ // Notifies to the audio driver to resume playback following a pause.
+ status_t resume() override;
+
+ // Returns whether drain operation is supported.
+ status_t supportsDrain(bool *supportsDrain) override;
+
+ // Requests notification when data buffered by the driver/hardware has been played.
+ status_t drain(bool earlyNotify) override;
+
+ // Notifies to the audio driver to flush the queued data.
+ status_t flush() override;
+
+ // Return a recent count of the number of audio frames presented to an external observer.
+ status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;
+
+ // Called when the metadata of the stream's source has been changed.
+ status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
+ // Returns the Dual Mono mode presentation setting.
+ status_t getDualMonoMode(audio_dual_mono_mode_t* mode) override;
+
+ // Sets the Dual Mono mode presentation on the output device.
+ status_t setDualMonoMode(audio_dual_mono_mode_t mode) override;
+
+ // Returns the Audio Description Mix level in dB.
+ status_t getAudioDescriptionMixLevel(float* leveldB) override;
+
+ // Sets the Audio Description Mix level in dB.
+ status_t setAudioDescriptionMixLevel(float leveldB) override;
+
+ // Retrieves current playback rate parameters.
+ status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) override;
+
+ // Sets the playback rate parameters that control playback behavior.
+ status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) override;
+
+ status_t setEventCallback(const sp<StreamOutHalInterfaceEventCallback>& callback) override;
+
+ status_t setLatencyMode(audio_latency_mode_t mode) override;
+ status_t getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) override;
+ status_t setLatencyModeCallback(
+ const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) override;
+
+ void onRecommendedLatencyModeChanged(const std::vector<audio_latency_mode_t>& modes);
+
+ status_t exit() override;
+
+ void onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs);
+
+ // Methods used by StreamOutCallback ().
+ // FIXME: Consider the required visibility.
+ void onWriteReady();
+ void onDrainReady();
+ void onError();
+
+ private:
+ friend class sp<StreamOutHalAidl>;
+
+ mediautils::atomic_wp<StreamOutHalInterfaceCallback> mCallback;
+ mediautils::atomic_wp<StreamOutHalInterfaceEventCallback> mEventCallback;
+ mediautils::atomic_wp<StreamOutHalInterfaceLatencyModeCallback> mLatencyModeCallback;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut> mStream;
+
+ // Can not be constructed directly by clients.
+ StreamOutHalAidl(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream);
+
+ ~StreamOutHalAidl() override = default;
+};
+
+class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
+ public:
+ // Set the input gain for the audio driver.
+ status_t setGain(float gain) override;
+
+ // Read audio buffer in from driver.
+ status_t read(void *buffer, size_t bytes, size_t *read) override;
+
+ // Return the amount of input frames lost in the audio driver.
+ status_t getInputFramesLost(uint32_t *framesLost) override;
+
+ // Return a recent count of the number of audio frames received and
+ // the clock time associated with that frame count.
+ status_t getCapturePosition(int64_t *frames, int64_t *time) override;
+
+ // Get active microphones
+ status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) override;
+
+ // Set microphone direction (for processing)
+ status_t setPreferredMicrophoneDirection(
+ audio_microphone_direction_t direction) override;
+
+ // Set microphone zoom (for processing)
+ status_t setPreferredMicrophoneFieldDimension(float zoom) override;
+
+ // Called when the metadata of the stream's sink has been changed.
+ status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
+ private:
+ friend class sp<StreamInHalAidl>;
+
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn> mStream;
+
+ // Can not be constructed directly by clients.
+ StreamInHalAidl(
+ const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
+ const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream);
+
+ ~StreamInHalAidl() override = default;
+};
+
+} // namespace android
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 76f9a60..2c289e1 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -46,9 +46,6 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
-#define TIME_CHECK() auto TimeCheck = \
- mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
-
StreamHalHidl::StreamHalHidl(std::string_view className, IStream *stream)
: CoreConversionHelperHidl(className),
mStream(stream),
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 2c8219e..094b415 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -106,16 +106,10 @@
virtual status_t releaseAudioPatch(audio_patch_handle_t patch) = 0;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port* port) {
- ALOGE("%s override me port %p", __func__, port);
- return OK;
- }
+ virtual status_t getAudioPort(struct audio_port* port) = 0;
// Fills the list of supported attributes for a given audio port.
- virtual status_t getAudioPort(struct audio_port_v7 *port) {
- ALOGE("%s override me port %p", __func__, port);
- return OK;
- }
+ virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
// Set audio port configuration.
virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
diff --git a/media/libeffects/downmix/aidl/DownmixContext.cpp b/media/libeffects/downmix/aidl/DownmixContext.cpp
index 6869689..43bfeed 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.cpp
+++ b/media/libeffects/downmix/aidl/DownmixContext.cpp
@@ -21,6 +21,7 @@
#include "DownmixContext.h"
using aidl::android::hardware::audio::effect::IEffect;
+using ::aidl::android::media::audio::common::AudioChannelLayout;
using ::android::hardware::audio::common::getChannelCount;
namespace aidl::android::hardware::audio::effect {
diff --git a/media/libeffects/downmix/aidl/DownmixContext.h b/media/libeffects/downmix/aidl/DownmixContext.h
index 8a244ac..9a9f2da 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.h
+++ b/media/libeffects/downmix/aidl/DownmixContext.h
@@ -22,9 +22,6 @@
namespace aidl::android::hardware::audio::effect {
-using media::audio::common::AudioChannelLayout;
-using media::audio::common::AudioDeviceDescription;
-
enum DownmixState {
DOWNMIX_STATE_UNINITIALIZED,
DOWNMIX_STATE_INITIALIZED,
@@ -45,34 +42,25 @@
}
Downmix::Type getDmType() const { return mType; }
- RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override {
- // FIXME change volume
- mVolumeStereo = volumeStereo;
- return RetCode::SUCCESS;
- }
- Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
-
- RetCode setOutputDevice(const AudioDeviceDescription& device) override {
+ RetCode setOutputDevice(
+ const std::vector<::aidl::android::media::audio::common::AudioDeviceDescription>&
+ device) override {
// FIXME change type if playing on headset vs speaker
mOutputDevice = device;
return RetCode::SUCCESS;
}
- AudioDeviceDescription getOutputDevice() { return mOutputDevice; }
IEffect::Status lvmProcess(float* in, float* out, int samples);
private:
DownmixState mState;
Downmix::Type mType;
- AudioChannelLayout mChMask;
+ ::aidl::android::media::audio::common::AudioChannelLayout mChMask;
::android::audio_utils::channels::ChannelMix mChannelMix;
// Common Params
- AudioDeviceDescription mOutputDevice;
- Parameter::VolumeStereo mVolumeStereo;
-
void init_params(const Parameter::Common& common);
- bool isChannelMaskValid(AudioChannelLayout channelMask);
+ bool isChannelMaskValid(::aidl::android::media::audio::common::AudioChannelLayout channelMask);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index 3aee721..c601c38 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -287,32 +287,42 @@
}
bool BundleContext::isDeviceSupportedBassBoost(
- const aidl::android::media::audio::common::AudioDeviceDescription& device) {
- return (device == AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER, ""} ||
- device == AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
- AudioDeviceDescription::CONNECTION_BT_SCO} ||
- device == AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
- AudioDeviceDescription::CONNECTION_BT_A2DP});
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+ for (const auto& device : devices) {
+ if (device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER, ""} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
+ AudioDeviceDescription::CONNECTION_BT_SCO} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
+ AudioDeviceDescription::CONNECTION_BT_A2DP}) {
+ return false;
+ }
+ }
+ return true;
}
bool BundleContext::isDeviceSupportedVirtualizer(
- const aidl::android::media::audio::common::AudioDeviceDescription& device) {
- return (device == AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_ANALOG} ||
- device == AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
- AudioDeviceDescription::CONNECTION_ANALOG} ||
- device == AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
- AudioDeviceDescription::CONNECTION_BT_A2DP} ||
- device == AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
- AudioDeviceDescription::CONNECTION_USB});
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+ for (const auto& device : devices) {
+ if (device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
+ AudioDeviceDescription::CONNECTION_ANALOG} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
+ AudioDeviceDescription::CONNECTION_ANALOG} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
+ AudioDeviceDescription::CONNECTION_BT_A2DP} &&
+ device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
+ AudioDeviceDescription::CONNECTION_USB}) {
+ return false;
+ }
+ }
+ return true;
}
RetCode BundleContext::setOutputDevice(
- const aidl::android::media::audio::common::AudioDeviceDescription& device) {
- mOutputDevice = device;
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
+ mOutputDevice = devices;
switch (mType) {
case lvm::BundleEffectType::BASS_BOOST:
- if (isDeviceSupportedBassBoost(device)) {
+ if (!isDeviceSupportedBassBoost(devices)) {
// If a device doesn't support bass boost, the effect must be temporarily disabled.
// The effect must still report its original state as this can only be changed by
// the start/stop commands.
@@ -330,7 +340,7 @@
}
break;
case lvm::BundleEffectType::VIRTUALIZER:
- if (isDeviceSupportedVirtualizer(device)) {
+ if (!isDeviceSupportedVirtualizer(devices)) {
if (mEnabled) {
disableOperatingMode();
}
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index be723f7..1f328fc 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -57,11 +57,14 @@
return mChMask;
}
bool isDeviceSupportedBassBoost(
- const aidl::android::media::audio::common::AudioDeviceDescription& device);
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+ devices);
bool isDeviceSupportedVirtualizer(
- const aidl::android::media::audio::common::AudioDeviceDescription& device);
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+ devices);
RetCode setOutputDevice(
- const aidl::android::media::audio::common::AudioDeviceDescription& device) override;
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices)
+ override;
RetCode setEqualizerPreset(const std::size_t presetIdx);
int getEqualizerPreset() const { return mCurPresetIdx; }
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index aef9295..bc19379 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -128,4 +128,36 @@
visibility: [
"//hardware/interfaces/audio/aidl/default",
],
-}
\ No newline at end of file
+}
+
+cc_library_shared {
+ name: "libreverbaidl",
+ srcs: [
+ "Reverb/aidl/ReverbContext.cpp",
+ "Reverb/aidl/EffectReverb.cpp",
+ ":effectCommonFile",
+ ],
+ static_libs: ["libreverb"],
+ defaults: [
+ "aidlaudioservice_defaults",
+ "latest_android_hardware_audio_effect_ndk_shared",
+ "latest_android_media_audio_common_types_ndk_shared",
+ ],
+ local_include_dirs: ["Reverb/aidl"],
+ header_libs: [
+ "libaudioeffects",
+ "libhardware_headers",
+ ],
+ shared_libs: [
+ "libbase",
+ "libaudioutils",
+ "libcutils",
+ "liblog",
+ ],
+ cflags: [
+ "-Wthread-safety",
+ ],
+ visibility: [
+ "//hardware/interfaces/audio/aidl/default",
+ ],
+}
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
new file mode 100644
index 0000000..51825ca
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define LOG_TAG "EffectReverb"
+#include <Utils.h>
+#include <algorithm>
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <audio_effects/effect_bassboost.h>
+#include <audio_effects/effect_equalizer.h>
+#include <audio_effects/effect_virtualizer.h>
+
+#include "EffectReverb.h"
+#include <limits.h>
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EffectReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kAuxEnvReverbImplUUID;
+using aidl::android::hardware::audio::effect::kAuxPresetReverbImplUUID;
+using aidl::android::hardware::audio::effect::kInsertEnvReverbImplUUID;
+using aidl::android::hardware::audio::effect::kInsertPresetReverbImplUUID;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+bool isReverbUuidSupported(const AudioUuid* uuid) {
+ return (*uuid == kAuxEnvReverbImplUUID || *uuid == kInsertEnvReverbImplUUID ||
+ *uuid == kAuxPresetReverbImplUUID || *uuid == kInsertPresetReverbImplUUID);
+}
+
+extern "C" binder_exception_t createEffect(const AudioUuid* uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (uuid == nullptr || !isReverbUuidSupported(uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<EffectReverb>(*uuid);
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || !isReverbUuidSupported(in_impl_uuid)) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (*in_impl_uuid == kAuxEnvReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kAuxEnvReverbDesc;
+ } else if (*in_impl_uuid == kInsertEnvReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kInsertEnvReverbDesc;
+ } else if (*in_impl_uuid == kAuxPresetReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kAuxPresetReverbDesc;
+ } else if (*in_impl_uuid == kInsertPresetReverbImplUUID) {
+ *_aidl_return = aidl::android::hardware::audio::effect::lvm::kInsertPresetReverbDesc;
+ }
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectReverb::EffectReverb(const AudioUuid& uuid) {
+ LOG(DEBUG) << __func__ << uuid.toString();
+ if (uuid == kAuxEnvReverbImplUUID) {
+ mType = lvm::ReverbEffectType::AUX_ENV;
+ mDescriptor = &lvm::kAuxEnvReverbDesc;
+ mEffectName = &lvm::kAuxEnvReverbEffectName;
+ } else if (uuid == kInsertEnvReverbImplUUID) {
+ mType = lvm::ReverbEffectType::INSERT_ENV;
+ mDescriptor = &lvm::kInsertEnvReverbDesc;
+ mEffectName = &lvm::kInsertEnvReverbEffectName;
+ } else if (uuid == kAuxPresetReverbImplUUID) {
+ mType = lvm::ReverbEffectType::AUX_PRESET;
+ mDescriptor = &lvm::kAuxPresetReverbDesc;
+ mEffectName = &lvm::kAuxPresetReverbEffectName;
+ } else if (uuid == kInsertPresetReverbImplUUID) {
+ mType = lvm::ReverbEffectType::INSERT_PRESET;
+ mDescriptor = &lvm::kInsertPresetReverbDesc;
+ mEffectName = &lvm::kInsertPresetReverbEffectName;
+ } else {
+ LOG(ERROR) << __func__ << uuid.toString() << " not supported!";
+ }
+}
+
+EffectReverb::~EffectReverb() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus EffectReverb::getDescriptor(Descriptor* _aidl_return) {
+ RETURN_IF(!_aidl_return, EX_ILLEGAL_ARGUMENT, "Parameter:nullptr");
+ LOG(DEBUG) << _aidl_return->toString();
+ *_aidl_return = *mDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterSpecific(const Parameter::Specific& specific) {
+ LOG(DEBUG) << __func__ << " specific " << specific.toString();
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto tag = specific.getTag();
+ switch (tag) {
+ case Parameter::Specific::presetReverb:
+ return setParameterPresetReverb(specific);
+ case Parameter::Specific::environmentalReverb:
+ return setParameterEnvironmentalReverb(specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "specificParamNotSupported");
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterPresetReverb(const Parameter::Specific& specific) {
+ auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+ auto tag = prParam.getTag();
+
+ switch (tag) {
+ case PresetReverb::preset: {
+ RETURN_IF(mContext->setPresetReverbPreset(prParam.get<PresetReverb::preset>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setPresetFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "PresetReverbTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::setParameterEnvironmentalReverb(
+ const Parameter::Specific& specific) {
+ auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+ auto tag = erParam.getTag();
+
+ switch (tag) {
+ case EnvironmentalReverb::roomLevelMb: {
+ RETURN_IF(mContext->setEnvironmentalReverbRoomLevel(
+ erParam.get<EnvironmentalReverb::roomLevelMb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::roomHfLevelMb: {
+ RETURN_IF(
+ mContext->setEnvironmentalReverbRoomHfLevel(
+ erParam.get<EnvironmentalReverb::roomHfLevelMb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::decayTimeMs: {
+ RETURN_IF(mContext->setEnvironmentalReverbDecayTime(
+ erParam.get<EnvironmentalReverb::decayTimeMs>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::decayHfRatioPm: {
+ RETURN_IF(
+ mContext->setEnvironmentalReverbDecayHfRatio(
+ erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::levelMb: {
+ RETURN_IF(mContext->setEnvironmentalReverbLevel(
+ erParam.get<EnvironmentalReverb::levelMb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::delayMs: {
+ RETURN_IF(mContext->setEnvironmentalReverbDelay(
+ erParam.get<EnvironmentalReverb::delayMs>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDelayFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::diffusionPm: {
+ RETURN_IF(mContext->setEnvironmentalReverbDiffusion(
+ erParam.get<EnvironmentalReverb::diffusionPm>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::densityPm: {
+ RETURN_IF(mContext->setEnvironmentalReverbDensity(
+ erParam.get<EnvironmentalReverb::densityPm>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDensityFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::bypass: {
+ RETURN_IF(mContext->setEnvironmentalReverbBypass(
+ erParam.get<EnvironmentalReverb::bypass>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setBypassFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
+ auto tag = id.getTag();
+
+ switch (tag) {
+ case Parameter::Id::presetReverbTag:
+ return getParameterPresetReverb(id.get<Parameter::Id::presetReverbTag>(), specific);
+ case Parameter::Id::environmentalReverbTag:
+ return getParameterEnvironmentalReverb(id.get<Parameter::Id::environmentalReverbTag>(),
+ specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "wrongIdTag");
+ }
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterPresetReverb(const PresetReverb::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != PresetReverb::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "PresetReverbTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ PresetReverb prParam;
+ auto tag = id.get<PresetReverb::Id::commonTag>();
+ switch (tag) {
+ case PresetReverb::preset: {
+ prParam.set<PresetReverb::preset>(mContext->getPresetReverbPreset());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "PresetReverbTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::presetReverb>(prParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectReverb::getParameterEnvironmentalReverb(const EnvironmentalReverb::Id& id,
+ Parameter::Specific* specific) {
+ RETURN_IF(id.getTag() != EnvironmentalReverb::Id::commonTag, EX_ILLEGAL_ARGUMENT,
+ "EnvironmentalReverbTagNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ EnvironmentalReverb erParam;
+
+ auto tag = id.get<EnvironmentalReverb::Id::commonTag>();
+ switch (tag) {
+ case EnvironmentalReverb::roomLevelMb: {
+ erParam.set<EnvironmentalReverb::roomLevelMb>(
+ mContext->getEnvironmentalReverbRoomLevel());
+ break;
+ }
+ case EnvironmentalReverb::roomHfLevelMb: {
+ erParam.set<EnvironmentalReverb::roomHfLevelMb>(
+ mContext->getEnvironmentalReverbRoomHfLevel());
+ break;
+ }
+ case EnvironmentalReverb::decayTimeMs: {
+ erParam.set<EnvironmentalReverb::decayTimeMs>(
+ mContext->getEnvironmentalReverbDecayTime());
+ break;
+ }
+ case EnvironmentalReverb::decayHfRatioPm: {
+ erParam.set<EnvironmentalReverb::decayHfRatioPm>(
+ mContext->getEnvironmentalReverbDecayHfRatio());
+ break;
+ }
+ case EnvironmentalReverb::levelMb: {
+ erParam.set<EnvironmentalReverb::levelMb>(mContext->getEnvironmentalReverbLevel());
+ break;
+ }
+ case EnvironmentalReverb::delayMs: {
+ erParam.set<EnvironmentalReverb::delayMs>(mContext->getEnvironmentalReverbDelay());
+ break;
+ }
+ case EnvironmentalReverb::diffusionPm: {
+ erParam.set<EnvironmentalReverb::diffusionPm>(
+ mContext->getEnvironmentalReverbDiffusion());
+ break;
+ }
+ case EnvironmentalReverb::densityPm: {
+ erParam.set<EnvironmentalReverb::densityPm>(mContext->getEnvironmentalReverbDensity());
+ break;
+ }
+ case EnvironmentalReverb::bypass: {
+ erParam.set<EnvironmentalReverb::bypass>(mContext->getEnvironmentalReverbBypass());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::environmentalReverb>(erParam);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EffectReverb::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ mContext = std::make_shared<ReverbContext>(1 /* statusFmqDepth */, common, mType);
+ }
+
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> EffectReverb::getContext() {
+ return mContext;
+}
+
+RetCode EffectReverb::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+ndk::ScopedAStatus EffectReverb::commandImpl(CommandId command) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ switch (command) {
+ case CommandId::START:
+ mContext->enable();
+ break;
+ case CommandId::STOP:
+ mContext->disable();
+ break;
+ case CommandId::RESET:
+ mContext->disable();
+ mContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EffectReverb::effectProcessImpl(float* in, float* out, int sampleToProcess) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!mContext, status, "nullContext");
+ return mContext->lvmProcess(in, out, sampleToProcess);
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
new file mode 100644
index 0000000..d7d2bbd
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/EffectReverb.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+
+#include "effect-impl/EffectImpl.h"
+#include "ReverbContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectReverb final : public EffectImpl {
+ public:
+ explicit EffectReverb(const AudioUuid& uuid);
+ ~EffectReverb() override;
+
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ std::shared_ptr<EffectContext> getContext() override;
+ RetCode releaseContext() override;
+
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+ ndk::ScopedAStatus commandImpl(CommandId command) override;
+
+ std::string getEffectName() override { return *mEffectName; }
+
+ private:
+ std::shared_ptr<ReverbContext> mContext;
+ const Descriptor* mDescriptor;
+ const std::string* mEffectName;
+ lvm::ReverbEffectType mType;
+
+ IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
+
+ ndk::ScopedAStatus setParameterPresetReverb(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Id& id,
+ Parameter::Specific* specific);
+
+ ndk::ScopedAStatus setParameterEnvironmentalReverb(const Parameter::Specific& specific);
+ ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Id& id,
+ Parameter::Specific* specific);
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
new file mode 100644
index 0000000..d35c22b
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.cpp
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#include <cstddef>
+#define LOG_TAG "ReverbContext"
+#include <Utils.h>
+
+#include "ReverbContext.h"
+#include "VectorArithmetic.h"
+#include "math.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+
+#define GOTO_IF_LVREV_ERROR(status, tag, log) \
+ do { \
+ LVREV_ReturnStatus_en temp = (status); \
+ if (temp != LVREV_SUCCESS) { \
+ LOG(ERROR) << __func__ << " return status: " << temp << " " << (log); \
+ goto tag; \
+ } \
+ } while (0)
+
+RetCode ReverbContext::init() {
+ if (isPreset()) {
+ // force reloading preset at first call to process()
+ mPreset = PresetReverb::Presets::NONE;
+ mNextPreset = PresetReverb::Presets::NONE;
+ }
+
+ mVolume.left = kUnitVolume;
+ mVolume.right = kUnitVolume;
+ mPrevVolume.left = kUnitVolume;
+ mPrevVolume.right = kUnitVolume;
+ volumeMode = VOLUME_FLAT;
+
+ mSamplesToExitCount = kDefaultDecayTime * mCommon.input.base.sampleRate / 1000;
+
+ /* Saved strength is used to return the exact strength that was used in the set to the get
+ * because we map the original strength range of 0:1000 to 1:15, and this will avoid
+ * quantisation like effect when returning
+ */
+ mRoomLevel = lvm::kMinLevel;
+ mRoomHfLevel = 0;
+ mEnabled = LVM_FALSE;
+ mDecayTime = kDefaultDecayTime;
+ mDecayHfRatio = kDefaultDamping * 20;
+ mDensity = kDefaultRoomSize * 10;
+ mDiffusion = kDefaultDensity * 10;
+ mLevel = lvm::kMinLevel;
+
+ // allocate lvm reverb instance
+ LVREV_ReturnStatus_en status = LVREV_SUCCESS;
+ {
+ std::lock_guard lg(mMutex);
+ LVREV_InstanceParams_st params = {
+ .MaxBlockSize = lvm::kMaxCallSize,
+ // Max format, could be mono during process
+ .SourceFormat = LVM_STEREO,
+ .NumDelays = LVREV_DELAYLINES_4,
+ };
+ /* Init sets the instance handle */
+ status = LVREV_GetInstanceHandle(&mInstance, ¶ms);
+ GOTO_IF_LVREV_ERROR(status, deinit, "LVREV_GetInstanceHandleFailed");
+
+ // set control
+ LVREV_ControlParams_st controlParams;
+ initControlParameter(controlParams);
+ status = LVREV_SetControlParameters(mInstance, &controlParams);
+ GOTO_IF_LVREV_ERROR(status, deinit, "LVREV_SetControlParametersFailed");
+ }
+
+ return RetCode::SUCCESS;
+
+deinit:
+ deInit();
+ return RetCode::ERROR_EFFECT_LIB_ERROR;
+}
+
+void ReverbContext::deInit() {
+ std::lock_guard lg(mMutex);
+ if (mInstance) {
+ LVREV_FreeInstance(mInstance);
+ mInstance = nullptr;
+ }
+}
+
+RetCode ReverbContext::enable() {
+ if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+ mEnabled = true;
+ mSamplesToExitCount = (mDecayTime * mCommon.input.base.sampleRate) / 1000;
+ // force no volume ramp for first buffer processed after enabling the effect
+ volumeMode = VOLUME_FLAT;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::disable() {
+ if (!mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
+ mEnabled = false;
+ return RetCode::SUCCESS;
+}
+
+bool ReverbContext::isAuxiliary() {
+ return (mType == lvm::ReverbEffectType::AUX_ENV || mType == lvm::ReverbEffectType::AUX_PRESET);
+}
+
+bool ReverbContext::isPreset() {
+ return (mType == lvm::ReverbEffectType::AUX_PRESET ||
+ mType == lvm::ReverbEffectType::INSERT_PRESET);
+}
+
+RetCode ReverbContext::setVolumeStereo(const Parameter::VolumeStereo& volume) {
+ if (volumeMode == VOLUME_OFF) {
+ // force no volume ramp for first buffer processed after getting volume control
+ volumeMode = VOLUME_FLAT;
+ }
+ mVolumeStereo = volume;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setPresetReverbPreset(const PresetReverb::Presets& preset) {
+ mNextPreset = preset;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbRoomLevel(int roomLevel) {
+ if (roomLevel < lvm::kEnvReverbCap.minRoomLevelMb ||
+ roomLevel > lvm::kEnvReverbCap.maxRoomLevelMb) {
+ LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ // Sum of room and reverb level controls
+ // needs to subtract max levels for both room level and reverb level
+ int combinedLevel = (roomLevel + mLevel) - lvm::kMaxReverbLevel;
+ params.Level = convertLevel(combinedLevel);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mRoomLevel = roomLevel;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbRoomHfLevel(int roomHfLevel) {
+ if (roomHfLevel < lvm::kEnvReverbCap.minRoomHfLevelMb ||
+ roomHfLevel > lvm::kEnvReverbCap.maxRoomHfLevelMb) {
+ LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.LPF = convertHfLevel(roomHfLevel);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mRoomHfLevel = roomHfLevel;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDecayTime(int decayTime) {
+ if (decayTime < 0 || decayTime > lvm::kEnvReverbCap.maxDecayTimeMs) {
+ LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ int time = decayTime;
+ if (time > lvm::kMaxT60) {
+ time = lvm::kMaxT60;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.T60 = (LVM_UINT16)time;
+ mSamplesToExitCount = (params.T60 * mCommon.input.base.sampleRate) / 1000;
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDecayTime = time;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDecayHfRatio(int decayHfRatio) {
+ if (decayHfRatio < lvm::kEnvReverbCap.minDecayHfRatioPm ||
+ decayHfRatio > lvm::kEnvReverbCap.maxDecayHfRatioPm) {
+ LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.Damping = (LVM_INT16)(decayHfRatio / 20);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDecayHfRatio = decayHfRatio;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbLevel(int level) {
+ if (level < lvm::kEnvReverbCap.minLevelMb || level > lvm::kEnvReverbCap.maxLevelMb) {
+ LOG(ERROR) << __func__ << " invalid level: " << level;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ // Sum of room and reverb level controls
+ // needs to subtract max levels for both room level and level
+ int combinedLevel = (level + mRoomLevel) - lvm::kMaxReverbLevel;
+ params.Level = convertLevel(combinedLevel);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mLevel = level;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDelay(int delay) {
+ if (delay < 0 || delay > lvm::kEnvReverbCap.maxDelayMs) {
+ LOG(ERROR) << __func__ << " invalid delay: " << delay;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ mDelay = delay;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDiffusion(int diffusion) {
+ if (diffusion < 0 || diffusion > lvm::kEnvReverbCap.maxDiffusionPm) {
+ LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.Density = (LVM_INT16)(diffusion / 10);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDiffusion = diffusion;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbDensity(int density) {
+ if (density < 0 || density > lvm::kEnvReverbCap.maxDensityPm) {
+ LOG(ERROR) << __func__ << " invalid density: " << density;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+
+ // Update Control Parameter
+ LVREV_ControlParams_st params;
+ {
+ std::lock_guard lg(mMutex);
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_GetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
+
+ params.RoomSize = (LVM_INT16)(((density * 99) / 1000) + 1);
+
+ RETURN_VALUE_IF(LVREV_SUCCESS != LVREV_SetControlParameters(mInstance, ¶ms),
+ RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
+ }
+ mDensity = density;
+ return RetCode::SUCCESS;
+}
+
+RetCode ReverbContext::setEnvironmentalReverbBypass(bool bypass) {
+ mBypass = bypass;
+ return RetCode::SUCCESS;
+}
+
+void ReverbContext::loadPreset() {
+ // TODO: add delay when early reflections are implemented
+ mPreset = mNextPreset;
+
+ if (mPreset != PresetReverb::Presets::NONE) {
+ const t_reverb_settings preset = mReverbPresets[mPreset];
+ setEnvironmentalReverbRoomLevel(preset.roomLevel);
+ setEnvironmentalReverbRoomHfLevel(preset.roomHFLevel);
+ setEnvironmentalReverbDecayTime(preset.decayTime);
+ setEnvironmentalReverbDecayHfRatio(preset.decayHFRatio);
+ setEnvironmentalReverbLevel(preset.reverbLevel);
+ // reverbDelay
+ setEnvironmentalReverbDiffusion(preset.diffusion);
+ setEnvironmentalReverbDensity(preset.density);
+ }
+}
+
+void ReverbContext::initControlParameter(LVREV_ControlParams_st& params) {
+ /* Set the initial process parameters */
+ /* General parameters */
+ params.OperatingMode = LVM_MODE_ON;
+ params.SampleRate = LVM_FS_44100;
+ params.SourceFormat = (::android::hardware::audio::common::getChannelCount(
+ mCommon.input.base.channelMask) == 1
+ ? LVM_MONO
+ : LVM_STEREO);
+
+ if (!isAuxiliary() && params.SourceFormat == LVM_MONO) {
+ params.SourceFormat = LVM_STEREO;
+ }
+
+ /* Reverb parameters */
+ params.Level = kDefaultLevel;
+ params.LPF = kDefaultLPF;
+ params.HPF = kDefaultHPF;
+ params.T60 = kDefaultDecayTime;
+ params.Density = kDefaultDensity;
+ params.Damping = kDefaultDamping;
+ params.RoomSize = kDefaultRoomSize;
+}
+
+/*
+ * Convert level from OpenSL ES format to LVM format
+ *
+ * @param level : level to be applied
+ */
+
+int ReverbContext::convertLevel(int level) {
+ for (int i = 0; i < kLevelMapping.size(); i++) {
+ if (level <= kLevelMapping[i]) {
+ return i;
+ }
+ }
+ return kDefaultLevel;
+}
+
+/*
+ * Convert level HF from OpenSL ES format to LVM format
+ *
+ * @param hfLevel : level to be applied
+ */
+
+int16_t ReverbContext::convertHfLevel(int hfLevel) {
+ for (auto lpfPair : kLPFMapping) {
+ if (hfLevel <= lpfPair.roomHf) {
+ return lpfPair.lpf;
+ }
+ }
+ return kDefaultLPF;
+}
+
+IEffect::Status ReverbContext::lvmProcess(float* in, float* out, int samples) {
+ IEffect::Status status = {EX_NULL_POINTER, 0, 0};
+ RETURN_VALUE_IF(!in, status, "nullInput");
+ RETURN_VALUE_IF(!out, status, "nullOutput");
+ status = {EX_ILLEGAL_STATE, 0, 0};
+ int64_t inputFrameCount = getCommon().input.frameCount;
+ int64_t outputFrameCount = getCommon().output.frameCount;
+ RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
+ RETURN_VALUE_IF(0 == getInputFrameSize(), status, "zeroFrameSize");
+
+ LOG(DEBUG) << __func__ << " start processing";
+ std::lock_guard lg(mMutex);
+
+ int channels =
+ ::android::hardware::audio::common::getChannelCount(mCommon.input.base.channelMask);
+ int outChannels =
+ ::android::hardware::audio::common::getChannelCount(mCommon.output.base.channelMask);
+ int frameCount = mCommon.input.frameCount;
+
+ // Reverb only effects the stereo channels in multichannel source.
+ if (channels < 1 || channels > LVM_MAX_CHANNELS) {
+ LOG(ERROR) << __func__ << " process invalid PCM channels " << channels;
+ return status;
+ }
+
+ std::vector<float> inFrames(samples);
+ std::vector<float> outFrames(frameCount * FCC_2);
+
+ if (isPreset() && mNextPreset != mPreset) {
+ loadPreset();
+ }
+
+ if (isAuxiliary()) {
+ inFrames.assign(in, in + samples);
+ } else {
+ // mono input is duplicated
+ if (channels >= FCC_2) {
+ for (int i = 0; i < frameCount; i++) {
+ inFrames[FCC_2 * i] = in[channels * i] * kSendLevel;
+ inFrames[FCC_2 * i + 1] = in[channels * i + 1] * kSendLevel;
+ }
+ } else {
+ for (int i = 0; i < frameCount; i++) {
+ inFrames[FCC_2 * i] = inFrames[FCC_2 * i + 1] = in[i] * kSendLevel;
+ }
+ }
+ }
+
+ if (isPreset() && mPreset == PresetReverb::Presets::NONE) {
+ std::fill(outFrames.begin(), outFrames.end(), 0); // always stereo here
+ } else {
+ if (!mEnabled && mSamplesToExitCount > 0) {
+ std::fill(outFrames.begin(), outFrames.end(), 0);
+ LOG(VERBOSE) << "Zeroing " << channels << " samples per frame at the end of call ";
+ }
+
+ /* Process the samples, producing a stereo output */
+ LVREV_ReturnStatus_en lvrevStatus =
+ LVREV_Process(mInstance, /* Instance handle */
+ inFrames.data(), /* Input buffer */
+ outFrames.data(), /* Output buffer */
+ frameCount); /* Number of samples to read */
+ if (lvrevStatus != LVREV_SUCCESS) {
+ LOG(ERROR) << __func__ << lvrevStatus;
+ return {EX_UNSUPPORTED_OPERATION, 0, 0};
+ }
+ }
+ // Convert to 16 bits
+ if (isAuxiliary()) {
+ // nothing to do here
+ } else {
+ if (channels >= FCC_2) {
+ for (int i = 0; i < frameCount; i++) {
+ // Mix with dry input
+ outFrames[FCC_2 * i] += in[channels * i];
+ outFrames[FCC_2 * i + 1] += in[channels * i + 1];
+ }
+ } else {
+ for (int i = 0; i < frameCount; i++) {
+ // Mix with dry input
+ outFrames[FCC_2 * i] += in[i];
+ outFrames[FCC_2 * i + 1] += in[i];
+ }
+ }
+
+ // apply volume with ramp if needed
+ if (mVolume != mPrevVolume && volumeMode == VOLUME_RAMP) {
+ float vl = mPrevVolume.left;
+ float incl = (mVolume.left - vl) / frameCount;
+ float vr = mPrevVolume.right;
+ float incr = (mVolume.right - vr) / frameCount;
+
+ for (int i = 0; i < frameCount; i++) {
+ outFrames[FCC_2 * i] *= vl;
+ outFrames[FCC_2 * i + 1] *= vr;
+
+ vl += incl;
+ vr += incr;
+ }
+ mPrevVolume = mVolume;
+ } else if (volumeMode != VOLUME_OFF) {
+ if (mVolume.left != kUnitVolume || mVolume.right != kUnitVolume) {
+ for (int i = 0; i < frameCount; i++) {
+ outFrames[FCC_2 * i] *= mVolume.left;
+ outFrames[FCC_2 * i + 1] *= mVolume.right;
+ }
+ }
+ mPrevVolume = mVolume;
+ volumeMode = VOLUME_RAMP;
+ }
+ }
+
+ bool accumulate = false;
+ if (outChannels > 2) {
+ // Accumulate if required
+ if (accumulate) {
+ for (int i = 0; i < frameCount; i++) {
+ out[outChannels * i] += outFrames[FCC_2 * i];
+ out[outChannels * i + 1] += outFrames[FCC_2 * i + 1];
+ }
+ } else {
+ for (int i = 0; i < frameCount; i++) {
+ out[outChannels * i] = outFrames[FCC_2 * i];
+ out[outChannels * i + 1] = outFrames[FCC_2 * i + 1];
+ }
+ }
+ if (!isAuxiliary()) {
+ for (int i = 0; i < frameCount; i++) {
+ // channels and outChannels are expected to be same.
+ for (int j = FCC_2; j < outChannels; j++) {
+ out[outChannels * i + j] = in[outChannels * i + j];
+ }
+ }
+ }
+ } else {
+ if (accumulate) {
+ if (outChannels == FCC_1) {
+ for (int i = 0; i < frameCount; i++) {
+ out[i] += ((outFrames[i * FCC_2] + outFrames[i * FCC_2 + 1]) * 0.5f);
+ }
+ } else {
+ for (int i = 0; i < frameCount * FCC_2; i++) {
+ out[i] += outFrames[i];
+ }
+ }
+ } else {
+ if (outChannels == FCC_1) {
+ From2iToMono_Float(outFrames.data(), out, frameCount);
+ } else {
+ for (int i = 0; i < frameCount * FCC_2; i++) {
+ out[i] = outFrames[i];
+ }
+ }
+ }
+ }
+
+ LOG(DEBUG) << __func__ << " done processing";
+
+ if (!mEnabled && mSamplesToExitCount > 0) {
+ // signed - unsigned will trigger integer overflow if result becomes negative.
+ mSamplesToExitCount -= samples;
+ }
+
+ return {STATUS_OK, samples, outChannels * frameCount};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
new file mode 100644
index 0000000..af49a25
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbContext.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <unordered_map>
+
+#include "ReverbTypes.h"
+#include "effect-impl/EffectContext.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+enum VolumeMode {
+ VOLUME_OFF,
+ VOLUME_FLAT,
+ VOLUME_RAMP,
+};
+
+struct LPFPair {
+ int roomHf;
+ int lpf;
+};
+
+class ReverbContext final : public EffectContext {
+ public:
+ ReverbContext(int statusDepth, const Parameter::Common& common,
+ const lvm::ReverbEffectType& type)
+ : EffectContext(statusDepth, common), mType(type) {
+ LOG(DEBUG) << __func__ << type;
+ init();
+ }
+ ~ReverbContext() override {
+ LOG(DEBUG) << __func__;
+ deInit();
+ }
+
+ RetCode init();
+ void deInit();
+
+ RetCode enable();
+ RetCode disable();
+
+ bool isAuxiliary();
+ bool isPreset();
+
+ RetCode setPresetReverbPreset(const PresetReverb::Presets& preset);
+ PresetReverb::Presets getPresetReverbPreset() const { return mNextPreset; }
+
+ RetCode setEnvironmentalReverbRoomLevel(int roomLevel);
+ int getEnvironmentalReverbRoomLevel() const { return mRoomLevel; }
+ RetCode setEnvironmentalReverbRoomHfLevel(int roomHfLevel);
+ int getEnvironmentalReverbRoomHfLevel() const { return mRoomHfLevel; }
+ RetCode setEnvironmentalReverbDecayTime(int decayTime);
+ int getEnvironmentalReverbDecayTime() const { return mDecayTime; }
+ RetCode setEnvironmentalReverbDecayHfRatio(int decayHfRatio);
+ int getEnvironmentalReverbDecayHfRatio() const { return mDecayHfRatio; }
+ RetCode setEnvironmentalReverbLevel(int level);
+ int getEnvironmentalReverbLevel() const { return mLevel; }
+ RetCode setEnvironmentalReverbDelay(int delay);
+ int getEnvironmentalReverbDelay() const { return mDelay; }
+ RetCode setEnvironmentalReverbDiffusion(int diffusion);
+ int getEnvironmentalReverbDiffusion() const { return mDiffusion; }
+ RetCode setEnvironmentalReverbDensity(int density);
+ int getEnvironmentalReverbDensity() const { return mDensity; }
+ RetCode setEnvironmentalReverbBypass(bool bypass);
+ bool getEnvironmentalReverbBypass() const { return mBypass; }
+
+ RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) override;
+ Parameter::VolumeStereo getVolumeStereo() override { return mVolumeStereo; }
+
+ IEffect::Status lvmProcess(float* in, float* out, int samples);
+
+ private:
+ static constexpr inline float kUnitVolume = 1;
+ static constexpr inline float kSendLevel = 0.75f;
+ static constexpr inline int kDefaultLevel = 0;
+ static constexpr inline int kDefaultLPF = 23999; /* Default low pass filter, in Hz */
+ static constexpr inline int kDefaultHPF = 50; /* Default high pass filter, in Hz */
+ static constexpr inline int kDefaultDecayTime = 1490; /* Default Decay time, in ms */
+ static constexpr inline int kDefaultDensity = 100; /* Default Echo density */
+ static constexpr inline int kDefaultDamping = 21;
+ static constexpr inline int kDefaultRoomSize = 100;
+
+ static inline const std::vector<LPFPair> kLPFMapping = {
+ // Limit range to 50 for LVREV parameter range
+ {-10000, 50}, {-5000, 50}, {-4000, 50}, {-3000, 158}, {-2000, 502}, {-1000, 1666},
+ {-900, 1897}, {-800, 2169}, {-700, 2496}, {-600, 2895}, {-500, 3400}, {-400, 4066},
+ {-300, 5011}, {-200, 6537}, {-100, 9826}, {-99, 9881}, {-98, 9937}, {-97, 9994},
+ {-96, 10052}, {-95, 10111}, {-94, 10171}, {-93, 10231}, {-92, 10293}, {-91, 10356},
+ {-90, 10419}, {-89, 10484}, {-88, 10549}, {-87, 10616}, {-86, 10684}, {-85, 10753},
+ {-84, 10823}, {-83, 10895}, {-82, 10968}, {-81, 11042}, {-80, 11117}, {-79, 11194},
+ {-78, 11272}, {-77, 11352}, {-76, 11433}, {-75, 11516}, {-74, 11600}, {-73, 11686},
+ {-72, 11774}, {-71, 11864}, {-70, 11955}, {-69, 12049}, {-68, 12144}, {-67, 12242},
+ {-66, 12341}, {-65, 12443}, {-64, 12548}, {-63, 12654}, {-62, 12763}, {-61, 12875},
+ {-60, 12990}, {-59, 13107}, {-58, 13227}, {-57, 13351}, {-56, 13477}, {-55, 13607},
+ {-54, 13741}, {-53, 13878}, {-52, 14019}, {-51, 14164}, {-50, 14313}, {-49, 14467},
+ {-48, 14626}, {-47, 14789}, {-46, 14958}, {-45, 15132}, {-44, 15312}, {-43, 15498},
+ {-42, 15691}, {-41, 15890}, {-40, 16097}, {-39, 16311}, {-38, 16534}, {-37, 16766},
+ {-36, 17007}, {-35, 17259}, {-34, 17521}, {-33, 17795}, {-32, 18081}, {-31, 18381},
+ {-30, 18696}, {-29, 19027}, {-28, 19375}, {-27, 19742}, {-26, 20129}, {-25, 20540},
+ {-24, 20976}, {-23, 21439}, {-22, 21934}, {-21, 22463}, {-20, 23031}, {-19, 23643},
+ {-18, 23999}};
+
+ static inline const std::vector<int> kLevelMapping = {
+ -12000, -4000, -3398, -3046, -2796, -2603, -2444, -2310, -2194, -2092, -2000, -1918,
+ -1842, -1773, -1708, -1648, -1592, -1540, -1490, -1443, -1398, -1356, -1316, -1277,
+ -1240, -1205, -1171, -1138, -1106, -1076, -1046, -1018, -990, -963, -938, -912,
+ -888, -864, -841, -818, -796, -775, -754, -734, -714, -694, -675, -656,
+ -638, -620, -603, -585, -568, -552, -536, -520, -504, -489, -474, -459,
+ -444, -430, -416, -402, -388, -375, -361, -348, -335, -323, -310, -298,
+ -286, -274, -262, -250, -239, -228, -216, -205, -194, -184, -173, -162,
+ -152, -142, -132, -121, -112, -102, -92, -82, -73, -64, -54, -45,
+ -36, -27, -18, -9, 0};
+
+ static inline std::unordered_map<PresetReverb::Presets, t_reverb_settings> mReverbPresets = {
+ {PresetReverb::Presets::NONE, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {PresetReverb::Presets::SMALLROOM,
+ {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000}},
+ {PresetReverb::Presets::MEDIUMROOM,
+ {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000}},
+ {PresetReverb::Presets::LARGEROOM,
+ {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000}},
+ {PresetReverb::Presets::MEDIUMHALL,
+ {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000}},
+ {PresetReverb::Presets::LARGEHALL,
+ {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000}},
+ {PresetReverb::Presets::PLATE, {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750}}};
+
+ std::mutex mMutex;
+ const lvm::ReverbEffectType mType;
+ bool mEnabled = false;
+ LVREV_Handle_t mInstance GUARDED_BY(mMutex);
+
+ int mRoomLevel;
+ int mRoomHfLevel;
+ int mDecayTime;
+ int mDecayHfRatio;
+ int mLevel;
+ int mDelay;
+ int mDiffusion;
+ int mDensity;
+ bool mBypass;
+
+ PresetReverb::Presets mPreset;
+ PresetReverb::Presets mNextPreset;
+
+ int mSamplesToExitCount;
+
+ Parameter::VolumeStereo mVolume;
+ Parameter::VolumeStereo mPrevVolume;
+ VolumeMode volumeMode;
+
+ void initControlParameter(LVREV_ControlParams_st& params);
+ int16_t convertHfLevel(int hfLevel);
+ int convertLevel(int level);
+ void loadPreset();
+};
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
new file mode 100644
index 0000000..e37602c
--- /dev/null
+++ b/media/libeffects/lvm/wrapper/Reverb/aidl/ReverbTypes.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <android/binder_enums.h>
+#include <audio_effects/effect_environmentalreverb.h>
+#include <audio_effects/effect_presetreverb.h>
+#include "effect-impl/EffectUUID.h"
+// from Reverb/lib
+#include "LVREV.h"
+
+namespace aidl::android::hardware::audio::effect {
+namespace lvm {
+
+constexpr inline int kMaxCallSize = 256;
+constexpr inline int kMinLevel = -6000;
+constexpr inline int kMaxT60 = 7000; /* Maximum decay time */
+constexpr inline int kMaxReverbLevel = 2000;
+constexpr inline int kMaxFrameSize = 2560;
+constexpr inline int kCpuLoadARM9E = 470; // Expressed in 0.1 MIPS
+constexpr inline int kMemUsage = (71 + (kMaxFrameSize >> 7)); // Expressed in kB
+
+static const EnvironmentalReverb::Capability kEnvReverbCap = {.minRoomLevelMb = lvm::kMinLevel,
+ .maxRoomLevelMb = 0,
+ .minRoomHfLevelMb = -4000,
+ .maxRoomHfLevelMb = 0,
+ .maxDecayTimeMs = lvm::kMaxT60,
+ .minDecayHfRatioPm = 100,
+ .maxDecayHfRatioPm = 2000,
+ .minLevelMb = lvm::kMinLevel,
+ .maxLevelMb = 0,
+ .maxDelayMs = 65,
+ .maxDiffusionPm = 1000,
+ .maxDensityPm = 1000};
+
+// NXP SW auxiliary environmental reverb
+static const std::string kAuxEnvReverbEffectName = "Auxiliary Environmental Reverb";
+static const Descriptor kAuxEnvReverbDesc = {
+ .common = {.id = {.type = kEnvReverbTypeUUID,
+ .uuid = kAuxEnvReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::AUXILIARY},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kAuxEnvReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::environmentalReverb>(kEnvReverbCap)};
+
+// NXP SW insert environmental reverb
+static const std::string kInsertEnvReverbEffectName = "Insert Environmental Reverb";
+static const Descriptor kInsertEnvReverbDesc = {
+ .common = {.id = {.type = kEnvReverbTypeUUID,
+ .uuid = kInsertEnvReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kInsertEnvReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::environmentalReverb>(kEnvReverbCap)};
+
+static const std::vector<PresetReverb::Presets> kSupportedPresets{
+ ndk::enum_range<PresetReverb::Presets>().begin(),
+ ndk::enum_range<PresetReverb::Presets>().end()};
+static const PresetReverb::Capability kPresetReverbCap = {.supportedPresets = kSupportedPresets};
+
+// NXP SW auxiliary preset reverb
+static const std::string kAuxPresetReverbEffectName = "Auxiliary Preset Reverb";
+static const Descriptor kAuxPresetReverbDesc = {
+ .common = {.id = {.type = kPresetReverbTypeUUID,
+ .uuid = kAuxPresetReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::AUXILIARY},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kAuxPresetReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+
+// NXP SW insert preset reverb
+static const std::string kInsertPresetReverbEffectName = "Insert Preset Reverb";
+static const Descriptor kInsertPresetReverbDesc = {
+ .common = {.id = {.type = kPresetReverbTypeUUID,
+ .uuid = kInsertPresetReverbImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .cpuLoad = kCpuLoadARM9E,
+ .memoryUsage = kMemUsage,
+ .name = kInsertPresetReverbEffectName,
+ .implementor = "NXP Software Ltd."},
+ .capability = Capability::make<Capability::presetReverb>(kPresetReverbCap)};
+
+enum class ReverbEffectType {
+ AUX_ENV,
+ INSERT_ENV,
+ AUX_PRESET,
+ INSERT_PRESET,
+};
+
+inline std::ostream& operator<<(std::ostream& out, const ReverbEffectType& type) {
+ switch (type) {
+ case ReverbEffectType::AUX_ENV:
+ return out << kAuxEnvReverbEffectName;
+ case ReverbEffectType::INSERT_ENV:
+ return out << kInsertEnvReverbEffectName;
+ case ReverbEffectType::AUX_PRESET:
+ return out << kAuxPresetReverbEffectName;
+ case ReverbEffectType::INSERT_PRESET:
+ return out << kInsertPresetReverbEffectName;
+ }
+ return out << "EnumReverbEffectTypeError";
+}
+
+inline std::ostream& operator<<(std::ostream& out, const LVREV_ReturnStatus_en& status) {
+ switch (status) {
+ case LVREV_SUCCESS:
+ return out << "LVREV_SUCCESS";
+ case LVREV_NULLADDRESS:
+ return out << "LVREV_NULLADDRESS";
+ case LVREV_OUTOFRANGE:
+ return out << "LVREV_OUTOFRANGE";
+ case LVREV_INVALIDNUMSAMPLES:
+ return out << "LVREV_INVALIDNUMSAMPLES";
+ case LVREV_RETURNSTATUS_DUMMY:
+ return out << "LVREV_RETURNSTATUS_DUMMY";
+ }
+ return out << "EnumLvrevRetStatusError";
+}
+
+} // namespace lvm
+} // namespace aidl::android::hardware::audio::effect
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
index 5e29b3f..a964d4f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
@@ -22,14 +22,13 @@
#include <mediadrm/DrmUtils.h>
#include <utils/Log.h>
-
namespace android {
// static helpers - internal
sp<IDrm> NuPlayerDrm::CreateDrm(status_t *pstatus)
{
- return DrmUtils::MakeDrm(pstatus);
+ return DrmUtils::MakeDrm(IDRM_NUPLAYER, pstatus);
}
sp<ICrypto> NuPlayerDrm::createCrypto(status_t *pstatus)
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index f4674de..5005365 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -253,7 +253,7 @@
}
static sp<IDrm> CreateDrm() {
- return DrmUtils::MakeDrm();
+ return DrmUtils::MakeDrm(IDRM_NDK);
}
diff --git a/media/ndk/include/media/NdkMediaDrm.h b/media/ndk/include/media/NdkMediaDrm.h
index 4eca3d7..8044140 100644
--- a/media/ndk/include/media/NdkMediaDrm.h
+++ b/media/ndk/include/media/NdkMediaDrm.h
@@ -261,8 +261,8 @@
/**
* Open a new session with the MediaDrm object. A session ID is returned.
*
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed.
- * Returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use.
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if provisioning is needed.
+ * Returns AMEDIA_DRM_RESOURCE_BUSY if required resources are in use.
*
* Available since API level 21.
*/
@@ -327,7 +327,7 @@
* 2. keyRequestSize will be set to the size of the request
* If this does not return AMEDIA_OK, value of these parameters should not be used.
*
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if reprovisioning is needed, due to a
* problem with the device certificate.
*
* Available since API level 21.
@@ -390,7 +390,7 @@
* 4. keyRequestType will be set to the key request type. Passing in NULL means
* you don't need it to be reported.
*
- * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns AMEDIA_DRM_NOT_PROVISIONED if reprovisioning is needed, due to a
* problem with the device certificate.
*
* Available since API level 33.
@@ -457,7 +457,7 @@
* On entry, numPairs should be set by the caller to the maximum number of pairs
* that can be returned (the size of the array). On exit, numPairs will be set
* to the number of entries written to the array. If the number of {key, value} pairs
- * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
+ * to be returned is greater than *numPairs, AMEDIA_DRM_SHORT_BUFFER will be returned
* and numPairs will be set to the number of pairs available.
*
* Available since API level 21.
@@ -495,7 +495,7 @@
* DRM engine plugin.
* responseSize is the length of the provisioning response in bytes.
*
- * Returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
+ * Returns AMEDIA_DRM_DEVICE_REVOKED if the response indicates that the
* server rejected the request
*
* Available since API level 21.
@@ -522,7 +522,7 @@
* numSecureStops is set by the caller to the maximum number of secure stops to
* return. On exit, *numSecureStops will be set to the number actually returned.
* If *numSecureStops is too small for the number of secure stops available,
- * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
+ * AMEDIA_DRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
* number required.
*
* Available since API level 21.
@@ -657,7 +657,7 @@
* Generate a signature using the specified macAlgorithm over the message data
* referenced by message of size messageSize and store the signature in the
* buffer referenced signature of max size *signatureSize. If the buffer is not
- * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
+ * large enough to hold the signature, AMEDIA_DRM_SHORT_BUFFER is returned and
* *signatureSize is set to the buffer size required. The key to use is identified
* by the 16 byte keyId. The key must have been loaded into the session using
* provideKeyResponse.
@@ -670,7 +670,7 @@
/*
* Perform a signature verification using the specified macAlgorithm over the message
- * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
+ * data referenced by the message parameter of size messageSize. Returns AMEDIA_OK
* if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
* use is identified by the 16 byte keyId. The key must have been loaded into the
* session using provideKeyResponse.
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 0cf5bd9..a5378e6 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -312,7 +312,7 @@
}
// Automatically create a TimeCheck class for a class and method.
-// This is used for Audio HIDL support.
+// This is used for Audio HAL support.
mediautils::TimeCheck makeTimeCheckStatsForClassMethod(
std::string_view className, std::string_view methodName) {
std::shared_ptr<MethodStatistics<std::string>> statistics =
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index f9ea50c..f1d572f 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -147,4 +147,9 @@
TimeCheck makeTimeCheckStatsForClassMethod(
std::string_view className, std::string_view methodName);
+// A handy statement-like macro to put at the beginning of almost every method
+// which calls into HAL. Note that it requires the class to implement 'getClassName'.
+#define TIME_CHECK() auto timeCheck = \
+ mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
+
} // namespace android::mediautils
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index caa1750..c54be55 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2073,6 +2073,7 @@
}
client->setImageDumpMask(mImageDumpMask);
+ client->setStreamUseCaseOverrides(mStreamUseCaseOverrides);
} // lock is destroyed, allow further connect calls
// Important: release the mutex here so the client can call back into the service from its
@@ -4451,6 +4452,13 @@
String8 activeClientString = mActiveClientManager.toString();
dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
+ if (mStreamUseCaseOverrides.size() > 0) {
+ dprintf(fd, "Active stream use case overrides:");
+ for (int64_t useCaseOverride : mStreamUseCaseOverrides) {
+ dprintf(fd, " %" PRId64, useCaseOverride);
+ }
+ dprintf(fd, "\n");
+ }
dumpEventLog(fd);
@@ -4954,6 +4962,11 @@
return handleGetImageDumpMask(out);
} else if (args.size() >= 2 && args[0] == String16("set-camera-mute")) {
return handleSetCameraMute(args);
+ } else if (args.size() >= 2 && args[0] == String16("set-stream-use-case-override")) {
+ return handleSetStreamUseCaseOverrides(args);
+ } else if (args.size() >= 1 && args[0] == String16("clear-stream-use-case-override")) {
+ handleClearStreamUseCaseOverrides();
+ return OK;
} else if (args.size() >= 2 && args[0] == String16("watch")) {
return handleWatchCommand(args, in, out);
} else if (args.size() >= 2 && args[0] == String16("set-watchdog")) {
@@ -5160,6 +5173,43 @@
return OK;
}
+status_t CameraService::handleSetStreamUseCaseOverrides(const Vector<String16>& args) {
+ std::vector<int64_t> useCasesOverride;
+ for (size_t i = 1; i < args.size(); i++) {
+ int64_t useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ String8 arg8 = String8(args[i]);
+ if (arg8 == "DEFAULT") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ } else if (arg8 == "PREVIEW") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW;
+ } else if (arg8 == "STILL_CAPTURE") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE;
+ } else if (arg8 == "VIDEO_RECORD") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD;
+ } else if (arg8 == "PREVIEW_VIDEO_STILL") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL;
+ } else if (arg8 == "VIDEO_CALL") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
+ } else if (arg8 == "CROPPED_RAW") {
+ useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW;
+ } else {
+ ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg8.c_str());
+ return BAD_VALUE;
+ }
+ useCasesOverride.push_back(useCase);
+ }
+
+ Mutex::Autolock lock(mServiceLock);
+ mStreamUseCaseOverrides = std::move(useCasesOverride);
+
+ return OK;
+}
+
+void CameraService::handleClearStreamUseCaseOverrides() {
+ Mutex::Autolock lock(mServiceLock);
+ mStreamUseCaseOverrides.clear();
+}
+
status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) {
if (args.size() >= 3 && args[1] == String16("start")) {
return startWatchingTags(args, outFd);
@@ -5517,6 +5567,15 @@
" Valid values 0=OFF, 1=ON for JPEG\n"
" get-image-dump-mask returns the current image-dump-mask value\n"
" set-camera-mute <0/1> enable or disable camera muting\n"
+ " set-stream-use-case-override <usecase1> <usecase2> ... override stream use cases\n"
+ " Use cases applied in descending resolutions. So usecase1 is assigned to the\n"
+ " largest resolution, usecase2 is assigned to the 2nd largest resolution, and so\n"
+ " on. In case the number of usecases is smaller than the number of streams, the\n"
+ " last use case is assigned to all the remaining streams. In case of multiple\n"
+ " streams with the same resolution, the tie-breaker is (JPEG, RAW, YUV, and PRIV)\n"
+ " Valid values are (case sensitive): DEFAULT, PREVIEW, STILL_CAPTURE, VIDEO_RECORD,\n"
+ " PREVIEW_VIDEO_STILL, VIDEO_CALL, CROPPED_RAW\n"
+ " clear-stream-use-case-override clear the stream use case override\n"
" watch <start|stop|dump|print|clear> manages tag monitoring in connected clients\n"
" help print this message\n");
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 4f92f15..c5671505 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -355,6 +355,13 @@
// Set Camera service watchdog
virtual status_t setCameraServiceWatchdog(bool enabled) = 0;
+ // Set stream use case overrides
+ virtual void setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides) = 0;
+
+ // Clear stream use case overrides
+ virtual void clearStreamUseCaseOverrides() = 0;
+
// The injection camera session to replace the internal camera
// session.
virtual status_t injectCamera(const String8& injectedCamId,
@@ -1257,6 +1264,12 @@
// Set the camera mute state
status_t handleSetCameraMute(const Vector<String16>& args);
+ // Set the stream use case overrides
+ status_t handleSetStreamUseCaseOverrides(const Vector<String16>& args);
+
+ // Clear the stream use case overrides
+ void handleClearStreamUseCaseOverrides();
+
// Handle 'watch' command as passed through 'cmd'
status_t handleWatchCommand(const Vector<String16> &args, int inFd, int outFd);
@@ -1355,6 +1368,9 @@
// Camera Service watchdog flag
bool mCameraServiceWatchdogEnabled = true;
+ // Current stream use case overrides
+ std::vector<int64_t> mStreamUseCaseOverrides;
+
/**
* A listener class that implements the IBinder::DeathRecipient interface
* for use to call back the error state injected by the external camera, and
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index d447fe0..d20638c 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -2380,6 +2380,15 @@
return mDevice->setCameraMute(enabled);
}
+void Camera2Client::setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides) {
+ mDevice->setStreamUseCaseOverrides(useCaseOverrides);
+}
+
+void Camera2Client::clearStreamUseCaseOverrides() {
+ mDevice->clearStreamUseCaseOverrides();
+}
+
status_t Camera2Client::waitUntilCurrentRequestIdLocked() {
int32_t activeRequestId = mStreamingProcessor->getActiveRequestId();
if (activeRequestId != 0) {
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index c5324db..f035fea 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -93,6 +93,10 @@
virtual status_t setCameraServiceWatchdog(bool enabled);
+ virtual void setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides);
+ virtual void clearStreamUseCaseOverrides();
+
/**
* Interface used by CameraService
*/
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 281d971..e59b110 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1781,6 +1781,15 @@
return mDevice->setCameraMute(enabled);
}
+void CameraDeviceClient::setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides) {
+ mDevice->setStreamUseCaseOverrides(useCaseOverrides);
+}
+
+void CameraDeviceClient::clearStreamUseCaseOverrides() {
+ mDevice->clearStreamUseCaseOverrides();
+}
+
binder::Status CameraDeviceClient::switchToOffline(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const std::vector<int>& offlineOutputIds,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 0c87872..36c627a 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -214,6 +214,9 @@
virtual status_t setCameraServiceWatchdog(bool enabled);
+ virtual void setStreamUseCaseOverrides(const std::vector<int64_t>& useCaseOverrides);
+ virtual void clearStreamUseCaseOverrides() override;
+
/**
* Device listener interface
*/
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index ea90987..c260cfe 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -94,6 +94,13 @@
return INVALID_OPERATION;
}
+void CameraOfflineSessionClient::setStreamUseCaseOverrides(
+ const std::vector<int64_t>& /*useCaseOverrides*/) {
+}
+
+void CameraOfflineSessionClient::clearStreamUseCaseOverrides() {
+}
+
status_t CameraOfflineSessionClient::dump(int fd, const Vector<String16>& args) {
return BasicClient::dump(fd, args);
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 89b27f8..906d454 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -89,6 +89,11 @@
status_t setCameraServiceWatchdog(bool enabled) override;
+ void setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides) override;
+
+ void clearStreamUseCaseOverrides() override;
+
// permissions management
status_t startCameraOps() override;
status_t finishCameraOps() override;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 6c30606..065d0d1 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -480,6 +480,15 @@
void setImageDumpMask(int mask) { mImageDumpMask = mask; }
/**
+ * Set stream use case overrides
+ */
+ void setStreamUseCaseOverrides(const std::vector<int64_t>& useCaseOverrides) {
+ mStreamUseCaseOverrides = useCaseOverrides;
+ }
+
+ void clearStreamUseCaseOverrides() {}
+
+ /**
* The injection camera session to replace the internal camera
* session.
*/
@@ -493,6 +502,7 @@
protected:
bool mImageDumpMask = 0;
+ std::vector<int64_t> mStreamUseCaseOverrides;
};
}; // namespace android
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 927dc47..c0b5add 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -2246,7 +2246,7 @@
}
CameraMetadata info2;
res = device->getCameraCharacteristics(true /*overrideForPerfClass*/, &info2,
- /*overrideToPortrait*/true);
+ /*overrideToPortrait*/false);
if (res == INVALID_OPERATION) {
dprintf(fd, " API2 not directly supported\n");
} else if (res != OK) {
@@ -2597,8 +2597,8 @@
if (overrideToPortrait) {
const auto &lensFacingEntry = characteristics->find(ANDROID_LENS_FACING);
const auto &sensorOrientationEntry = characteristics->find(ANDROID_SENSOR_ORIENTATION);
+ uint8_t lensFacing = lensFacingEntry.data.u8[0];
if (lensFacingEntry.count > 0 && sensorOrientationEntry.count > 0) {
- uint8_t lensFacing = lensFacingEntry.data.u8[0];
int32_t sensorOrientation = sensorOrientationEntry.data.i32[0];
int32_t newSensorOrientation = sensorOrientation;
@@ -2619,6 +2619,8 @@
}
if (characteristics->exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
+ ALOGV("%s: Erasing ANDROID_INFO_DEVICE_STATE_ORIENTATIONS for lens facing %d",
+ __FUNCTION__, lensFacing);
characteristics->erase(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 28a150c..26c9794 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2364,6 +2364,9 @@
tryRemoveFakeStreamLocked();
}
+ // Override stream use case based on "adb shell command"
+ overrideStreamUseCaseLocked();
+
// Start configuring the streams
ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
@@ -4161,6 +4164,19 @@
return OK;
}
+void Camera3Device::setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides) {
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+ mStreamUseCaseOverrides = useCaseOverrides;
+}
+
+void Camera3Device::clearStreamUseCaseOverrides() {
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+ mStreamUseCaseOverrides.clear();
+}
+
void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError) {
if (mNextRequests.empty()) {
return;
@@ -5315,4 +5331,56 @@
return mInjectionMethods->stopInjection();
}
+void Camera3Device::overrideStreamUseCaseLocked() {
+ if (mStreamUseCaseOverrides.size() == 0) {
+ return;
+ }
+
+ // Start from an array of indexes in mStreamUseCaseOverrides, and sort them
+ // based first on size, and second on formats of [JPEG, RAW, YUV, PRIV].
+ // Refer to CameraService::printHelp for details.
+ std::vector<int> outputStreamsIndices(mOutputStreams.size());
+ for (size_t i = 0; i < outputStreamsIndices.size(); i++) {
+ outputStreamsIndices[i] = i;
+ }
+
+ std::sort(outputStreamsIndices.begin(), outputStreamsIndices.end(),
+ [&](int a, int b) -> bool {
+
+ auto formatScore = [](int format) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_BLOB:
+ return 4;
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_RAW10:
+ case HAL_PIXEL_FORMAT_RAW12:
+ return 3;
+ case HAL_PIXEL_FORMAT_YCBCR_420_888:
+ return 2;
+ case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+ return 1;
+ default:
+ return 0;
+ }
+ };
+
+ int sizeA = mOutputStreams[a]->getWidth() * mOutputStreams[a]->getHeight();
+ int sizeB = mOutputStreams[a]->getWidth() * mOutputStreams[a]->getHeight();
+ int formatAScore = formatScore(mOutputStreams[a]->getFormat());
+ int formatBScore = formatScore(mOutputStreams[b]->getFormat());
+ if (sizeA > sizeB ||
+ (sizeA == sizeB && formatAScore >= formatBScore)) {
+ return true;
+ } else {
+ return false;
+ }
+ });
+
+ size_t overlapSize = std::min(mStreamUseCaseOverrides.size(), mOutputStreams.size());
+ for (size_t i = 0; i < mOutputStreams.size(); i++) {
+ mOutputStreams[outputStreamsIndices[i]]->setStreamUseCase(
+ mStreamUseCaseOverrides[std::min(i, overlapSize-1)]);
+ }
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 990f556..8752312 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -303,6 +303,13 @@
*/
status_t setCameraServiceWatchdog(bool enabled);
+ // Set stream use case overrides
+ void setStreamUseCaseOverrides(
+ const std::vector<int64_t>& useCaseOverrides);
+
+ // Clear stream use case overrides
+ void clearStreamUseCaseOverrides();
+
// Get the status trackeer for the camera device
wp<camera3::StatusTracker> getStatusTracker() { return mStatusTracker; }
@@ -1494,6 +1501,8 @@
sp<Camera3DeviceInjectionMethods> mInjectionMethods;
+ void overrideStreamUseCaseLocked();
+
}; // class Camera3Device
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.h b/services/camera/libcameraservice/device3/Camera3FakeStream.h
index a93d1da..1e9f478 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.h
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.h
@@ -101,6 +101,8 @@
virtual status_t setBatchSize(size_t batchSize) override;
virtual void onMinDurationChanged(nsecs_t /*duration*/, bool /*fixedFps*/) {}
+
+ virtual void setStreamUseCase(int64_t /*streamUseCase*/) {}
protected:
/**
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 4d6ab3d..2227232 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -1386,6 +1386,11 @@
mFixedFps = fixedFps;
}
+void Camera3OutputStream::setStreamUseCase(int64_t streamUseCase) {
+ Mutex::Autolock l(mLock);
+ camera_stream::use_case = streamUseCase;
+}
+
void Camera3OutputStream::returnPrefetchedBuffersLocked() {
std::vector<Surface::BatchBuffer> batchedBuffers;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index a2f16d4..9a08485 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -259,6 +259,11 @@
virtual void onMinDurationChanged(nsecs_t duration, bool fixedFps) override;
/**
+ * Modify stream use case
+ */
+ virtual void setStreamUseCase(int64_t streamUseCase) override;
+
+ /**
* Apply ZSL related consumer usage quirk.
*/
static void applyZSLUsageQuirk(int format, uint64_t *consumerUsage /*inout*/);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index dbc6fe1..4baa7e8 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -117,6 +117,11 @@
* AE_TARGET_FPS_RANGE in the capture request.
*/
virtual void onMinDurationChanged(nsecs_t duration, bool fixedFps) = 0;
+
+ /**
+ * Modify the stream use case for this output.
+ */
+ virtual void setStreamUseCase(int64_t streamUseCase) = 0;
};
// Helper class to organize a synchronized mapping of stream IDs to stream instances
diff --git a/services/oboeservice/AAudioClientTracker.cpp b/services/oboeservice/AAudioClientTracker.cpp
index 054a896..c0dac11 100644
--- a/services/oboeservice/AAudioClientTracker.cpp
+++ b/services/oboeservice/AAudioClientTracker.cpp
@@ -73,13 +73,13 @@
return AAUDIO_ERROR_NULL;
}
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
if (mNotificationClients.count(pid) == 0) {
- sp<IBinder> binder = IInterface::asBinder(client);
- sp<NotificationClient> notificationClient = new NotificationClient(pid, binder);
+ const sp<IBinder> binder = IInterface::asBinder(client);
+ const sp<NotificationClient> notificationClient = new NotificationClient(pid, binder);
mNotificationClients[pid] = notificationClient;
- status_t status = binder->linkToDeath(notificationClient);
+ const status_t status = binder->linkToDeath(notificationClient);
ALOGW_IF(status != NO_ERROR, "registerClient() linkToDeath = %d\n", status);
return AAudioConvert_androidToAAudioResult(status);
} else {
@@ -90,12 +90,12 @@
void AAudioClientTracker::unregisterClient(pid_t pid) {
ALOGV("unregisterClient(), calling pid = %d, getpid() = %d\n", pid, getpid());
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
mNotificationClients.erase(pid);
}
int32_t AAudioClientTracker::getStreamCount(pid_t pid) {
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
auto it = mNotificationClients.find(pid);
if (it != mNotificationClients.end()) {
return it->second->getStreamCount();
@@ -105,18 +105,19 @@
}
aaudio_result_t
-AAudioClientTracker::registerClientStream(pid_t pid, sp<AAudioServiceStreamBase> serviceStream) {
+AAudioClientTracker::registerClientStream(
+ pid_t pid, const sp<AAudioServiceStreamBase>& serviceStream) {
ALOGV("registerClientStream(%d,)\n", pid);
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
return getNotificationClient_l(pid)->registerClientStream(serviceStream);
}
// Find the tracker for this process and remove it.
aaudio_result_t
AAudioClientTracker::unregisterClientStream(pid_t pid,
- sp<AAudioServiceStreamBase> serviceStream) {
+ const sp<AAudioServiceStreamBase>& serviceStream) {
ALOGV("unregisterClientStream(%d,)\n", pid);
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
auto it = mNotificationClients.find(pid);
if (it != mNotificationClients.end()) {
ALOGV("unregisterClientStream(%d,) found NotificationClient\n", pid);
@@ -129,12 +130,12 @@
void AAudioClientTracker::setExclusiveEnabled(pid_t pid, bool enabled) {
ALOGD("%s(%d, %d)\n", __func__, pid, enabled);
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
getNotificationClient_l(pid)->setExclusiveEnabled(enabled);
}
bool AAudioClientTracker::isExclusiveEnabled(pid_t pid) {
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
return getNotificationClient_l(pid)->isExclusiveEnabled();
}
@@ -158,24 +159,21 @@
: mProcessId(pid), mBinder(binder) {
}
-AAudioClientTracker::NotificationClient::~NotificationClient() {
-}
-
int32_t AAudioClientTracker::NotificationClient::getStreamCount() {
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
return mStreams.size();
}
aaudio_result_t AAudioClientTracker::NotificationClient::registerClientStream(
- sp<AAudioServiceStreamBase> serviceStream) {
- std::lock_guard<std::mutex> lock(mLock);
+ const sp<AAudioServiceStreamBase>& serviceStream) {
+ const std::lock_guard<std::mutex> lock(mLock);
mStreams.insert(serviceStream);
return AAUDIO_OK;
}
aaudio_result_t AAudioClientTracker::NotificationClient::unregisterClientStream(
- sp<AAudioServiceStreamBase> serviceStream) {
- std::lock_guard<std::mutex> lock(mLock);
+ const sp<AAudioServiceStreamBase>& serviceStream) {
+ const std::lock_guard<std::mutex> lock(mLock);
mStreams.erase(serviceStream);
return AAUDIO_OK;
}
@@ -189,20 +187,20 @@
std::set<sp<AAudioServiceStreamBase>> streamsToClose;
{
- std::lock_guard<std::mutex> lock(mLock);
+ const std::lock_guard<std::mutex> lock(mLock);
for (const auto& serviceStream : mStreams) {
streamsToClose.insert(serviceStream);
}
}
for (const auto& serviceStream : streamsToClose) {
- aaudio_handle_t handle = serviceStream->getHandle();
+ const aaudio_handle_t handle = serviceStream->getHandle();
ALOGW("binderDied() close abandoned stream 0x%08X\n", handle);
aaudioService->asAAudioServiceInterface().closeStream(handle);
}
// mStreams should be empty now
}
- sp<NotificationClient> keep(this);
+ const sp<NotificationClient> keep(this);
AAudioClientTracker::getInstance().unregisterClient(mProcessId);
}
diff --git a/services/oboeservice/AAudioClientTracker.h b/services/oboeservice/AAudioClientTracker.h
index 2b38621..cd3b75a 100644
--- a/services/oboeservice/AAudioClientTracker.h
+++ b/services/oboeservice/AAudioClientTracker.h
@@ -54,10 +54,10 @@
int32_t getStreamCount(pid_t pid);
aaudio_result_t registerClientStream(pid_t pid,
- android::sp<AAudioServiceStreamBase> serviceStream);
+ const android::sp<AAudioServiceStreamBase>& serviceStream);
- aaudio_result_t unregisterClientStream(pid_t pid,
- android::sp<AAudioServiceStreamBase> serviceStream);
+ aaudio_result_t unregisterClientStream(
+ pid_t pid, const android::sp<AAudioServiceStreamBase>& serviceStream);
/**
* Specify whether a process is allowed to create an EXCLUSIVE MMAP stream.
@@ -84,15 +84,17 @@
class NotificationClient : public IBinder::DeathRecipient {
public:
NotificationClient(pid_t pid, const android::sp<IBinder>& binder);
- virtual ~NotificationClient();
+ ~NotificationClient() override = default;
int32_t getStreamCount();
std::string dump() const;
- aaudio_result_t registerClientStream(android::sp<AAudioServiceStreamBase> serviceStream);
+ aaudio_result_t registerClientStream(
+ const android::sp<AAudioServiceStreamBase>& serviceStream);
- aaudio_result_t unregisterClientStream(android::sp<AAudioServiceStreamBase> serviceStream);
+ aaudio_result_t unregisterClientStream(
+ const android::sp<AAudioServiceStreamBase>& serviceStream);
void setExclusiveEnabled(bool enabled) {
mExclusiveEnabled = enabled;
@@ -103,7 +105,7 @@
}
// IBinder::DeathRecipient
- virtual void binderDied(const android::wp<IBinder>& who);
+ void binderDied(const android::wp<IBinder>& who) override;
private:
mutable std::mutex mLock;
diff --git a/services/oboeservice/AAudioCommandQueue.cpp b/services/oboeservice/AAudioCommandQueue.cpp
index 9bd18b3..be80b12 100644
--- a/services/oboeservice/AAudioCommandQueue.cpp
+++ b/services/oboeservice/AAudioCommandQueue.cpp
@@ -25,7 +25,7 @@
namespace aaudio {
-aaudio_result_t AAudioCommandQueue::sendCommand(std::shared_ptr<AAudioCommand> command) {
+aaudio_result_t AAudioCommandQueue::sendCommand(const std::shared_ptr<AAudioCommand>& command) {
{
std::scoped_lock<std::mutex> _l(mLock);
if (!mRunning) {
diff --git a/services/oboeservice/AAudioCommandQueue.h b/services/oboeservice/AAudioCommandQueue.h
index 64442a3..ad62d8a 100644
--- a/services/oboeservice/AAudioCommandQueue.h
+++ b/services/oboeservice/AAudioCommandQueue.h
@@ -26,7 +26,7 @@
namespace aaudio {
-typedef int32_t aaudio_command_opcode;
+using aaudio_command_opcode = int32_t;
class AAudioCommandParam {
public:
@@ -39,7 +39,7 @@
explicit AAudioCommand(
aaudio_command_opcode opCode, std::shared_ptr<AAudioCommandParam> param = nullptr,
bool waitForReply = false, int64_t timeoutNanos = 0)
- : operationCode(opCode), parameter(param), isWaitingForReply(waitForReply),
+ : operationCode(opCode), parameter(std::move(param)), isWaitingForReply(waitForReply),
timeoutNanoseconds(timeoutNanos) { }
virtual ~AAudioCommand() = default;
@@ -66,7 +66,7 @@
* @return the result of sending the command or the result of executing the command if command
* need to wait for a reply. If timeout happens, AAUDIO_ERROR_TIMEOUT will be returned.
*/
- aaudio_result_t sendCommand(std::shared_ptr<AAudioCommand> command);
+ aaudio_result_t sendCommand(const std::shared_ptr<AAudioCommand>& command);
/**
* Wait for next available command OR until the timeout is expired.
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 20e4cc5..b5ee2f2 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -162,7 +162,7 @@
const aaudio::AAudioStreamRequest &request,
sp<AAudioServiceEndpoint> &endpointToSteal) {
- std::lock_guard<std::mutex> lock(mExclusiveLock);
+ const std::lock_guard<std::mutex> lock(mExclusiveLock);
const AAudioStreamConfiguration &configuration = request.getConstantConfiguration();
@@ -183,19 +183,20 @@
// and START calls. This will help preserve app compatibility.
// An app can avoid having this happen by closing their streams when
// the app is paused.
- pid_t pid = VALUE_OR_FATAL(
+ const pid_t pid = VALUE_OR_FATAL(
aidl2legacy_int32_t_pid_t(request.getAttributionSource().pid));
AAudioClientTracker::getInstance().setExclusiveEnabled(pid, false);
endpointToSteal = endpoint; // return it to caller
}
return nullptr;
} else {
- sp<AAudioServiceEndpointMMAP> endpointMMap = new AAudioServiceEndpointMMAP(aaudioService);
+ const sp<AAudioServiceEndpointMMAP> endpointMMap =
+ new AAudioServiceEndpointMMAP(aaudioService);
ALOGV("%s(), no match so try to open MMAP %p for dev %d",
__func__, endpointMMap.get(), configuration.getDeviceId());
endpoint = endpointMMap;
- aaudio_result_t result = endpoint->open(request);
+ const aaudio_result_t result = endpoint->open(request);
if (result != AAUDIO_OK) {
endpoint.clear();
} else {
@@ -217,10 +218,10 @@
AAudioService &aaudioService,
const aaudio::AAudioStreamRequest &request) {
- std::lock_guard<std::mutex> lock(mSharedLock);
+ const std::lock_guard<std::mutex> lock(mSharedLock);
const AAudioStreamConfiguration &configuration = request.getConstantConfiguration();
- aaudio_direction_t direction = configuration.getDirection();
+ const aaudio_direction_t direction = configuration.getDirection();
// Try to find an existing endpoint.
sp<AAudioServiceEndpointShared> endpoint = findSharedEndpoint_l(configuration);
@@ -228,7 +229,7 @@
// If we can't find an existing one then open a new one.
if (endpoint.get() == nullptr) {
// we must call openStream with audioserver identity
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ const int64_t token = IPCThreadState::self()->clearCallingIdentity();
switch (direction) {
case AAUDIO_DIRECTION_INPUT:
endpoint = new AAudioServiceEndpointCapture(aaudioService);
@@ -241,7 +242,7 @@
}
if (endpoint.get() != nullptr) {
- aaudio_result_t result = endpoint->open(request);
+ const aaudio_result_t result = endpoint->open(request);
if (result != AAUDIO_OK) {
endpoint.clear();
} else {
@@ -261,7 +262,7 @@
return endpoint;
}
-void AAudioEndpointManager::closeEndpoint(sp<AAudioServiceEndpoint>serviceEndpoint) {
+void AAudioEndpointManager::closeEndpoint(const sp<AAudioServiceEndpoint>& serviceEndpoint) {
if (serviceEndpoint->getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
return closeExclusiveEndpoint(serviceEndpoint);
} else {
@@ -269,14 +270,15 @@
}
}
-void AAudioEndpointManager::closeExclusiveEndpoint(sp<AAudioServiceEndpoint> serviceEndpoint) {
+void AAudioEndpointManager::closeExclusiveEndpoint(
+ const sp<AAudioServiceEndpoint>& serviceEndpoint) {
if (serviceEndpoint.get() == nullptr) {
return;
}
// Decrement the reference count under this lock.
- std::lock_guard<std::mutex> lock(mExclusiveLock);
- int32_t newRefCount = serviceEndpoint->getOpenCount() - 1;
+ const std::lock_guard<std::mutex> lock(mExclusiveLock);
+ const int32_t newRefCount = serviceEndpoint->getOpenCount() - 1;
serviceEndpoint->setOpenCount(newRefCount);
// If no longer in use then actually close it.
@@ -292,14 +294,14 @@
}
}
-void AAudioEndpointManager::closeSharedEndpoint(sp<AAudioServiceEndpoint> serviceEndpoint) {
+void AAudioEndpointManager::closeSharedEndpoint(const sp<AAudioServiceEndpoint>& serviceEndpoint) {
if (serviceEndpoint.get() == nullptr) {
return;
}
// Decrement the reference count under this lock.
- std::lock_guard<std::mutex> lock(mSharedLock);
- int32_t newRefCount = serviceEndpoint->getOpenCount() - 1;
+ const std::lock_guard<std::mutex> lock(mSharedLock);
+ const int32_t newRefCount = serviceEndpoint->getOpenCount() - 1;
serviceEndpoint->setOpenCount(newRefCount);
// If no longer in use then actually close it.
diff --git a/services/oboeservice/AAudioEndpointManager.h b/services/oboeservice/AAudioEndpointManager.h
index b07bcef..1d38d26 100644
--- a/services/oboeservice/AAudioEndpointManager.h
+++ b/services/oboeservice/AAudioEndpointManager.h
@@ -61,7 +61,7 @@
android::sp<AAudioServiceEndpoint> openEndpoint(android::AAudioService &audioService,
const aaudio::AAudioStreamRequest &request);
- void closeEndpoint(android::sp<AAudioServiceEndpoint> serviceEndpoint);
+ void closeEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint);
private:
android::sp<AAudioServiceEndpoint> openExclusiveEndpoint(android::AAudioService &aaudioService,
@@ -79,8 +79,8 @@
const AAudioStreamConfiguration& configuration)
REQUIRES(mSharedLock);
- void closeExclusiveEndpoint(android::sp<AAudioServiceEndpoint> serviceEndpoint);
- void closeSharedEndpoint(android::sp<AAudioServiceEndpoint> serviceEndpoint);
+ void closeExclusiveEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint);
+ void closeSharedEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint);
// Use separate locks because opening a Shared endpoint requires opening an Exclusive one.
// That could cause a recursive lock.
diff --git a/services/oboeservice/AAudioMixer.cpp b/services/oboeservice/AAudioMixer.cpp
index ad4b830..6890985 100644
--- a/services/oboeservice/AAudioMixer.cpp
+++ b/services/oboeservice/AAudioMixer.cpp
@@ -45,7 +45,8 @@
memset(mOutputBuffer.get(), 0, mBufferSizeInBytes);
}
-int32_t AAudioMixer::mix(int streamIndex, std::shared_ptr<FifoBuffer> fifo, bool allowUnderflow) {
+int32_t AAudioMixer::mix(
+ int streamIndex, const std::shared_ptr<FifoBuffer>& fifo, bool allowUnderflow) {
WrappingBuffer wrappingBuffer;
float *destination = mOutputBuffer.get();
diff --git a/services/oboeservice/AAudioMixer.h b/services/oboeservice/AAudioMixer.h
index 1a120f2..d773178 100644
--- a/services/oboeservice/AAudioMixer.h
+++ b/services/oboeservice/AAudioMixer.h
@@ -24,7 +24,7 @@
class AAudioMixer {
public:
- AAudioMixer() {}
+ AAudioMixer() = default;
void allocate(int32_t samplesPerFrame, int32_t framesPerBurst);
@@ -37,7 +37,9 @@
* @param allowUnderflow if true then allow mixer to advance read index past the write index
* @return frames read from this stream
*/
- int32_t mix(int streamIndex, std::shared_ptr<android::FifoBuffer> fifo, bool allowUnderflow);
+ int32_t mix(int streamIndex,
+ const std::shared_ptr<android::FifoBuffer>& fifo,
+ bool allowUnderflow);
float *getOutputBuffer();
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 2679b2e..e9c0884 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -62,7 +62,7 @@
AAudioClientTracker::getInstance().setAAudioService(this);
}
-status_t AAudioService::dump(int fd, const Vector<String16>& args) {
+status_t AAudioService::dump(int fd, const Vector<String16>& /*args*/) {
std::string result;
if (!dumpAllowed()) {
@@ -83,7 +83,7 @@
}
Status AAudioService::registerClient(const sp<IAAudioClient> &client) {
- pid_t pid = IPCThreadState::self()->getCallingPid();
+ const pid_t pid = IPCThreadState::self()->getCallingPid();
AAudioClientTracker::getInstance().registerClient(pid, client);
return Status::ok();
}
@@ -106,24 +106,24 @@
// 4) Thread A can then get the lock and also open a shared stream.
// Without the lock. Thread A might sneak in and reallocate an exclusive stream
// before B can open the shared stream.
- std::unique_lock<std::recursive_mutex> lock(mOpenLock);
+ const std::unique_lock<std::recursive_mutex> lock(mOpenLock);
aaudio_result_t result = AAUDIO_OK;
sp<AAudioServiceStreamBase> serviceStream;
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
- bool sharingModeMatchRequired = request.isSharingModeMatchRequired();
- aaudio_sharing_mode_t sharingMode = configurationInput.getSharingMode();
+ const bool sharingModeMatchRequired = request.isSharingModeMatchRequired();
+ const aaudio_sharing_mode_t sharingMode = configurationInput.getSharingMode();
// Enforce limit on client processes.
AttributionSourceState attributionSource = request.getAttributionSource();
- pid_t pid = IPCThreadState::self()->getCallingPid();
+ const pid_t pid = IPCThreadState::self()->getCallingPid();
attributionSource.pid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(
legacy2aidl_pid_t_int32_t(pid));
attributionSource.uid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(
legacy2aidl_uid_t_int32_t(IPCThreadState::self()->getCallingUid()));
attributionSource.token = sp<BBinder>::make();
if (attributionSource.pid != mAudioClient.attributionSource.pid) {
- int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid);
+ const int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid);
if (count >= MAX_STREAMS_PER_PROCESS) {
ALOGE("openStream(): exceeded max streams per process %d >= %d",
count, MAX_STREAMS_PER_PROCESS);
@@ -168,7 +168,7 @@
serviceStream.clear();
AIDL_RETURN(result);
} else {
- aaudio_handle_t handle = mStreamTracker.addStreamForHandle(serviceStream.get());
+ const aaudio_handle_t handle = mStreamTracker.addStreamForHandle(serviceStream.get());
serviceStream->setHandle(handle);
AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream);
paramsOut.copyFrom(*serviceStream);
@@ -185,7 +185,7 @@
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
// Check permission and ownership first.
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGE("closeStream(0x%0x), illegal stream handle", streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
@@ -197,13 +197,13 @@
int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
}
AudioEndpointParcelable endpointParcelable;
- aaudio_result_t result = serviceStream->getDescription(endpointParcelable);
+ const aaudio_result_t result = serviceStream->getDescription(endpointParcelable);
if (result == AAUDIO_OK) {
*endpoint = std::move(endpointParcelable).parcelable();
}
@@ -213,7 +213,7 @@
Status AAudioService::startStream(int32_t streamHandle, int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
@@ -224,7 +224,7 @@
Status AAudioService::pauseStream(int32_t streamHandle, int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
@@ -235,7 +235,7 @@
Status AAudioService::stopStream(int32_t streamHandle, int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
@@ -246,7 +246,7 @@
Status AAudioService::flushStream(int32_t streamHandle, int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
@@ -254,16 +254,16 @@
AIDL_RETURN(serviceStream->flush());
}
-Status AAudioService::registerAudioThread(int32_t streamHandle, int32_t clientThreadId, int64_t periodNanoseconds,
- int32_t *_aidl_return) {
+Status AAudioService::registerAudioThread(int32_t streamHandle, int32_t clientThreadId,
+ int64_t /*periodNanoseconds*/, int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
}
- int32_t priority = isCallerInService()
+ const int32_t priority = isCallerInService()
? kRealTimeAudioPriorityService : kRealTimeAudioPriorityClient;
AIDL_RETURN(serviceStream->registerAudioThread(clientThreadId, priority));
}
@@ -272,7 +272,7 @@
int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
@@ -283,13 +283,13 @@
Status AAudioService::exitStandby(int32_t streamHandle, Endpoint* endpoint, int32_t *_aidl_return) {
static_assert(std::is_same_v<aaudio_result_t, std::decay_t<typeof(*_aidl_return)>>);
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGE("getStreamDescription(), illegal stream handle = 0x%0x", streamHandle);
AIDL_RETURN(AAUDIO_ERROR_INVALID_HANDLE);
}
AudioEndpointParcelable endpointParcelable;
- aaudio_result_t result = serviceStream->exitStandby(&endpointParcelable);
+ const aaudio_result_t result = serviceStream->exitStandby(&endpointParcelable);
if (result == AAUDIO_OK) {
*endpoint = std::move(endpointParcelable).parcelable();
}
@@ -297,16 +297,18 @@
}
bool AAudioService::isCallerInService() {
- pid_t clientPid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mAudioClient.attributionSource.pid));
- uid_t clientUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mAudioClient.attributionSource.uid));
+ const pid_t clientPid = VALUE_OR_FATAL(
+ aidl2legacy_int32_t_pid_t(mAudioClient.attributionSource.pid));
+ const uid_t clientUid = VALUE_OR_FATAL(
+ aidl2legacy_int32_t_uid_t(mAudioClient.attributionSource.uid));
return clientPid == IPCThreadState::self()->getCallingPid() &&
clientUid == IPCThreadState::self()->getCallingUid();
}
-aaudio_result_t AAudioService::closeStream(sp<AAudioServiceStreamBase> serviceStream) {
+aaudio_result_t AAudioService::closeStream(const sp<AAudioServiceStreamBase>& serviceStream) {
// This is protected by a lock in AAudioClientTracker.
// It is safe to unregister the same stream twice.
- pid_t pid = serviceStream->getOwnerProcessId();
+ const pid_t pid = serviceStream->getOwnerProcessId();
AAudioClientTracker::getInstance().unregisterClientStream(pid, serviceStream);
// This is protected by a lock in mStreamTracker.
// It is safe to remove the same stream twice.
@@ -325,10 +327,10 @@
const uid_t ownerUserId = serviceStream->getOwnerUserId();
const uid_t clientUid = VALUE_OR_FATAL(
aidl2legacy_int32_t_uid_t(mAudioClient.attributionSource.uid));
- bool callerOwnsIt = callingUserId == ownerUserId;
- bool serverCalling = callingUserId == clientUid;
- bool serverOwnsIt = ownerUserId == clientUid;
- bool allowed = callerOwnsIt || serverCalling || serverOwnsIt;
+ const bool callerOwnsIt = callingUserId == ownerUserId;
+ const bool serverCalling = callingUserId == clientUid;
+ const bool serverOwnsIt = ownerUserId == clientUid;
+ const bool allowed = callerOwnsIt || serverCalling || serverOwnsIt;
if (!allowed) {
ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d",
callingUserId, streamHandle, ownerUserId);
@@ -342,7 +344,7 @@
const android::AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) {
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
return AAUDIO_ERROR_INVALID_HANDLE;
@@ -352,7 +354,7 @@
aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle,
audio_port_handle_t portHandle) {
- sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
+ const sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGW("%s(), invalid streamHandle = 0x%0x", __func__, streamHandle);
return AAUDIO_ERROR_INVALID_HANDLE;
@@ -364,14 +366,14 @@
// So we do not have to check permissions.
aaudio_result_t AAudioService::disconnectStreamByPortHandle(audio_port_handle_t portHandle) {
ALOGD("%s(%d) called", __func__, portHandle);
- sp<AAudioServiceStreamBase> serviceStream =
+ const sp<AAudioServiceStreamBase> serviceStream =
mStreamTracker.findStreamByPortHandle(portHandle);
if (serviceStream.get() == nullptr) {
ALOGE("%s(), could not find stream with portHandle = %d", __func__, portHandle);
return AAUDIO_ERROR_INVALID_HANDLE;
}
// This is protected by a lock and will just return if already stopped.
- aaudio_result_t result = serviceStream->stop();
+ const aaudio_result_t result = serviceStream->stop();
serviceStream->disconnect();
return result;
}
diff --git a/services/oboeservice/AAudioService.h b/services/oboeservice/AAudioService.h
index 0a111fb..df66f1b 100644
--- a/services/oboeservice/AAudioService.h
+++ b/services/oboeservice/AAudioService.h
@@ -45,7 +45,7 @@
public:
AAudioService();
- virtual ~AAudioService() = default;
+ ~AAudioService() override = default;
aaudio::AAudioServiceInterface& asAAudioServiceInterface() {
return mAdapter;
@@ -53,7 +53,7 @@
static const char* getServiceName() { return AAUDIO_SERVICE_NAME; }
- virtual status_t dump(int fd, const Vector<String16>& args) override;
+ status_t dump(int fd, const Vector<String16>& args) override;
binder::Status registerClient(const ::android::sp<::aaudio::IAAudioClient>& client) override;
@@ -103,7 +103,7 @@
* This is only called from within the Service.
* It bypasses the permission checks in closeStream(handle).
*/
- aaudio_result_t closeStream(sp<aaudio::AAudioServiceStreamBase> serviceStream);
+ aaudio_result_t closeStream(const sp<aaudio::AAudioServiceStreamBase>& serviceStream);
private:
class Adapter : public aaudio::AAudioBinderAdapter {
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index fd546f6..2b94dbf 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -88,7 +88,7 @@
// @return true if stream found
bool AAudioServiceEndpoint::isStreamRegistered(audio_port_handle_t portHandle) {
- std::lock_guard<std::mutex> lock(mLockStreams);
+ const std::lock_guard<std::mutex> lock(mLockStreams);
for (const auto& stream : mRegisteredStreams) {
if (stream->getPortHandle() == portHandle) {
return true;
@@ -101,7 +101,7 @@
AAudioServiceEndpoint::disconnectRegisteredStreams() {
std::vector<android::sp<AAudioServiceStreamBase>> streamsDisconnected;
{
- std::lock_guard<std::mutex> lock(mLockStreams);
+ const std::lock_guard<std::mutex> lock(mLockStreams);
mRegisteredStreams.swap(streamsDisconnected);
}
mConnected.store(false);
@@ -122,7 +122,7 @@
void AAudioServiceEndpoint::releaseRegisteredStreams() {
// List of streams to be closed after we disconnect everything.
- std::vector<android::sp<AAudioServiceStreamBase>> streamsToClose
+ const std::vector<android::sp<AAudioServiceStreamBase>> streamsToClose
= disconnectRegisteredStreams();
// Close outside the lock to avoid recursive locks.
@@ -133,14 +133,14 @@
}
}
-aaudio_result_t AAudioServiceEndpoint::registerStream(sp<AAudioServiceStreamBase>stream) {
- std::lock_guard<std::mutex> lock(mLockStreams);
+aaudio_result_t AAudioServiceEndpoint::registerStream(const sp<AAudioServiceStreamBase>& stream) {
+ const std::lock_guard<std::mutex> lock(mLockStreams);
mRegisteredStreams.push_back(stream);
return AAUDIO_OK;
}
-aaudio_result_t AAudioServiceEndpoint::unregisterStream(sp<AAudioServiceStreamBase>stream) {
- std::lock_guard<std::mutex> lock(mLockStreams);
+aaudio_result_t AAudioServiceEndpoint::unregisterStream(const sp<AAudioServiceStreamBase>& stream) {
+ const std::lock_guard<std::mutex> lock(mLockStreams);
mRegisteredStreams.erase(std::remove(
mRegisteredStreams.begin(), mRegisteredStreams.end(), stream),
mRegisteredStreams.end());
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 92004c5..dff571b 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -43,7 +43,7 @@
, public AAudioStreamParameters {
public:
- virtual ~AAudioServiceEndpoint();
+ ~AAudioServiceEndpoint() override;
virtual std::string dump() const;
@@ -55,9 +55,9 @@
*/
virtual void close() = 0;
- aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
+ aaudio_result_t registerStream(const android::sp<AAudioServiceStreamBase>& stream);
- aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
+ aaudio_result_t unregisterStream(const android::sp<AAudioServiceStreamBase>& stream);
virtual aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream,
audio_port_handle_t *clientHandle) = 0;
@@ -65,14 +65,14 @@
virtual aaudio_result_t stopStream(android::sp<AAudioServiceStreamBase> stream,
audio_port_handle_t clientHandle) = 0;
- virtual aaudio_result_t startClient(const android::AudioClient& client,
- const audio_attributes_t *attr,
- audio_port_handle_t *clientHandle) {
+ virtual aaudio_result_t startClient(const android::AudioClient& /*client*/,
+ const audio_attributes_t* /*attr*/,
+ audio_port_handle_t* /*clientHandle*/) {
ALOGD("AAudioServiceEndpoint::startClient(...) AAUDIO_ERROR_UNAVAILABLE");
return AAUDIO_ERROR_UNAVAILABLE;
}
- virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle) {
+ virtual aaudio_result_t stopClient(audio_port_handle_t /*clientHandle*/) {
ALOGD("AAudioServiceEndpoint::stopClient(...) AAUDIO_ERROR_UNAVAILABLE");
return AAUDIO_ERROR_UNAVAILABLE;
}
@@ -82,7 +82,7 @@
return AAUDIO_ERROR_UNAVAILABLE;
}
- virtual aaudio_result_t exitStandby(AudioEndpointParcelable* parcelable) {
+ virtual aaudio_result_t exitStandby(AudioEndpointParcelable* /*parcelable*/) {
ALOGD("AAudioServiceEndpoint::exitStandby() AAUDIO_ERROR_UNAVAILABLE");
return AAUDIO_ERROR_UNAVAILABLE;
}
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 95bd4bb..ba8070b 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -90,5 +90,5 @@
}
ALOGD("callbackLoop() exiting");
- return NULL; // TODO review
+ return nullptr; // TODO review
}
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.h b/services/oboeservice/AAudioServiceEndpointCapture.h
index 2ca43cf..b77100d 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.h
+++ b/services/oboeservice/AAudioServiceEndpointCapture.h
@@ -30,7 +30,7 @@
class AAudioServiceEndpointCapture : public AAudioServiceEndpointShared {
public:
explicit AAudioServiceEndpointCapture(android::AAudioService &audioService);
- virtual ~AAudioServiceEndpointCapture() = default;
+ ~AAudioServiceEndpointCapture() override = default;
aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override;
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 3d237b3..d4cdb0b 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -37,7 +37,7 @@
#include "AAudioServiceEndpointPlay.h"
#include "AAudioServiceEndpointMMAP.h"
-#define AAUDIO_BUFFER_CAPACITY_MIN 4 * 512
+#define AAUDIO_BUFFER_CAPACITY_MIN (4 * 512)
#define AAUDIO_SAMPLE_RATE_DEFAULT 48000
// This is an estimate of the time difference between the HW and the MMAP time.
@@ -85,7 +85,7 @@
return it != NEXT_FORMAT_TO_TRY.end() ? it->second : AUDIO_FORMAT_DEFAULT;
}
-}
+} // namespace
aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamRequest &request) {
aaudio_result_t result = AAUDIO_OK;
@@ -111,7 +111,7 @@
audio_format_t nextFormatToTry = AUDIO_FORMAT_DEFAULT;
result = openWithFormat(audioFormat, &nextFormatToTry);
- if (result == AAUDIO_OK || result != AAUDIO_ERROR_UNAVAILABLE) {
+ if (result != AAUDIO_ERROR_UNAVAILABLE) {
// Return if it is successful or there is an error that is not
// AAUDIO_ERROR_UNAVAILABLE happens.
ALOGI("Opened format=%#x with result=%d", audioFormat, result);
@@ -165,12 +165,12 @@
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
}
- MmapStreamInterface::stream_direction_t streamDirection =
+ const MmapStreamInterface::stream_direction_t streamDirection =
(direction == AAUDIO_DIRECTION_OUTPUT)
? MmapStreamInterface::DIRECTION_OUTPUT
: MmapStreamInterface::DIRECTION_INPUT;
- aaudio_session_id_t requestedSessionId = getSessionId();
+ const aaudio_session_id_t requestedSessionId = getSessionId();
audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
// Open HAL stream. Set mMmapStream
@@ -178,15 +178,15 @@
"sample_rate=%u, channel_mask=%#x, device=%d",
__func__, config.format, config.sample_rate,
config.channel_mask, deviceId);
- status_t status = MmapStreamInterface::openMmapStream(streamDirection,
- &attributes,
- &config,
- mMmapClient,
- &deviceId,
- &sessionId,
- this, // callback
- mMmapStream,
- &mPortHandle);
+ const status_t status = MmapStreamInterface::openMmapStream(streamDirection,
+ &attributes,
+ &config,
+ mMmapClient,
+ &deviceId,
+ &sessionId,
+ this, // callback
+ mMmapStream,
+ &mPortHandle);
ALOGD("%s() mMapClient.attributionSource = %s => portHandle = %d\n",
__func__, mMmapClient.attributionSource.toString().c_str(), mPortHandle);
if (status != OK) {
@@ -209,7 +209,7 @@
ALOGW("%s() - openMmapStream() failed to set sessionId", __func__);
}
- aaudio_session_id_t actualSessionId =
+ const aaudio_session_id_t actualSessionId =
(requestedSessionId == AAUDIO_SESSION_ID_NONE)
? AAUDIO_SESSION_ID_NONE
: (aaudio_session_id_t) sessionId;
@@ -278,7 +278,7 @@
if (stream != nullptr) {
attr = getAudioAttributesFrom(stream.get());
}
- aaudio_result_t result = startClient(
+ const aaudio_result_t result = startClient(
mMmapClient, stream == nullptr ? nullptr : &attr, &tempHandle);
// When AudioFlinger is passed a valid port handle then it should not change it.
LOG_ALWAYS_FATAL_IF(tempHandle != mPortHandle,
@@ -288,8 +288,8 @@
return result;
}
-aaudio_result_t AAudioServiceEndpointMMAP::stopStream(sp<AAudioServiceStreamBase> stream,
- audio_port_handle_t clientHandle __unused) {
+aaudio_result_t AAudioServiceEndpointMMAP::stopStream(sp<AAudioServiceStreamBase> /*stream*/,
+ audio_port_handle_t /*clientHandle*/) {
mFramesTransferred.reset32();
// Round 64-bit counter up to a multiple of the buffer capacity.
@@ -306,23 +306,21 @@
aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) {
- if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
- status_t status = mMmapStream->start(client, attr, clientHandle);
- return AAudioConvert_androidToAAudioResult(status);
+ return mMmapStream == nullptr
+ ? AAUDIO_ERROR_NULL
+ : AAudioConvert_androidToAAudioResult(mMmapStream->start(client, attr, clientHandle));
}
aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t clientHandle) {
- if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
- aaudio_result_t result = AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
- return result;
+ return mMmapStream == nullptr
+ ? AAUDIO_ERROR_NULL
+ : AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
}
aaudio_result_t AAudioServiceEndpointMMAP::standby() {
- if (mMmapStream == nullptr) {
- return AAUDIO_ERROR_NULL;
- }
- aaudio_result_t result = AAudioConvert_androidToAAudioResult(mMmapStream->standby());
- return result;
+ return mMmapStream == nullptr
+ ? AAUDIO_ERROR_NULL
+ : AAudioConvert_androidToAAudioResult(mMmapStream->standby());
}
aaudio_result_t AAudioServiceEndpointMMAP::exitStandby(AudioEndpointParcelable* parcelable) {
@@ -330,11 +328,12 @@
return AAUDIO_ERROR_NULL;
}
mAudioDataFileDescriptor.reset();
- aaudio_result_t result = createMmapBuffer(&mAudioDataFileDescriptor);
+ const aaudio_result_t result = createMmapBuffer(&mAudioDataFileDescriptor);
if (result == AAUDIO_OK) {
- int32_t bytesPerFrame = calculateBytesPerFrame();
- int32_t capacityInBytes = getBufferCapacity() * bytesPerFrame;
- int fdIndex = parcelable->addFileDescriptor(mAudioDataFileDescriptor, capacityInBytes);
+ const int32_t bytesPerFrame = calculateBytesPerFrame();
+ const int32_t capacityInBytes = getBufferCapacity() * bytesPerFrame;
+ const int fdIndex = parcelable->addFileDescriptor(
+ mAudioDataFileDescriptor, capacityInBytes);
parcelable->mDownDataQueueParcelable.setupMemory(fdIndex, 0, capacityInBytes);
parcelable->mDownDataQueueParcelable.setBytesPerFrame(bytesPerFrame);
parcelable->mDownDataQueueParcelable.setFramesPerBurst(mFramesPerBurst);
@@ -350,10 +349,10 @@
if (mMmapStream == nullptr) {
return AAUDIO_ERROR_NULL;
}
- status_t status = mMmapStream->getMmapPosition(&position);
+ const status_t status = mMmapStream->getMmapPosition(&position);
ALOGV("%s() status= %d, pos = %d, nanos = %lld\n",
__func__, status, position.position_frames, (long long) position.time_nanoseconds);
- aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
+ const aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
if (result == AAUDIO_ERROR_UNAVAILABLE) {
ALOGW("%s(): getMmapPosition() has no position data available", __func__);
} else if (result != AAUDIO_OK) {
@@ -367,8 +366,8 @@
return result;
}
-aaudio_result_t AAudioServiceEndpointMMAP::getTimestamp(int64_t *positionFrames,
- int64_t *timeNanos) {
+aaudio_result_t AAudioServiceEndpointMMAP::getTimestamp(int64_t* /*positionFrames*/,
+ int64_t* /*timeNanos*/) {
return 0; // TODO
}
@@ -381,7 +380,7 @@
} else {
// Must be a SHARED stream?
ALOGD("%s(%d) disconnect a specific stream", __func__, portHandle);
- aaudio_result_t result = mAAudioService.disconnectStreamByPortHandle(portHandle);
+ const aaudio_result_t result = mAAudioService.disconnectStreamByPortHandle(portHandle);
ALOGD("%s(%d) disconnectStreamByPortHandle returned %d", __func__, portHandle, result);
}
};
@@ -389,7 +388,7 @@
// This is called by AudioFlinger when it wants to destroy a stream.
void AAudioServiceEndpointMMAP::onTearDown(audio_port_handle_t portHandle) {
ALOGD("%s(portHandle = %d) called", __func__, portHandle);
- android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
+ const android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
std::thread asyncTask([holdEndpoint, portHandle]() {
holdEndpoint->handleTearDownAsync(portHandle);
});
@@ -398,18 +397,18 @@
void AAudioServiceEndpointMMAP::onVolumeChanged(float volume) {
ALOGD("%s() volume = %f", __func__, volume);
- std::lock_guard<std::mutex> lock(mLockStreams);
+ const std::lock_guard<std::mutex> lock(mLockStreams);
for(const auto& stream : mRegisteredStreams) {
stream->onVolumeChanged(volume);
}
};
void AAudioServiceEndpointMMAP::onRoutingChanged(audio_port_handle_t portHandle) {
- const int32_t deviceId = static_cast<int32_t>(portHandle);
+ const auto deviceId = static_cast<int32_t>(portHandle);
ALOGD("%s() called with dev %d, old = %d", __func__, deviceId, getDeviceId());
if (getDeviceId() != deviceId) {
if (getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
- android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
+ const android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
std::thread asyncTask([holdEndpoint, deviceId]() {
ALOGD("onRoutingChanged() asyncTask launched");
holdEndpoint->disconnectRegisteredStreams();
@@ -429,9 +428,9 @@
AudioEndpointParcelable* parcelable)
{
// Gather information on the data queue based on HAL info.
- int32_t bytesPerFrame = calculateBytesPerFrame();
- int32_t capacityInBytes = getBufferCapacity() * bytesPerFrame;
- int fdIndex = parcelable->addFileDescriptor(mAudioDataFileDescriptor, capacityInBytes);
+ const int32_t bytesPerFrame = calculateBytesPerFrame();
+ const int32_t capacityInBytes = getBufferCapacity() * bytesPerFrame;
+ const int fdIndex = parcelable->addFileDescriptor(mAudioDataFileDescriptor, capacityInBytes);
parcelable->mDownDataQueueParcelable.setupMemory(fdIndex, 0, capacityInBytes);
parcelable->mDownDataQueueParcelable.setBytesPerFrame(bytesPerFrame);
parcelable->mDownDataQueueParcelable.setFramesPerBurst(mFramesPerBurst);
@@ -447,7 +446,7 @@
}
uint64_t tempPositionFrames;
int64_t tempTimeNanos;
- status_t status = mMmapStream->getExternalPosition(&tempPositionFrames, &tempTimeNanos);
+ const status_t status = mMmapStream->getExternalPosition(&tempPositionFrames, &tempTimeNanos);
if (status != OK) {
// getExternalPosition reports error. The HAL may not support the API. Cache the result
// so that the call will not go to the HAL next time.
@@ -527,8 +526,8 @@
if (minSizeFrames <= 0) { // zero will get rejected
minSizeFrames = AAUDIO_BUFFER_CAPACITY_MIN;
}
- status_t status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo);
- bool isBufferShareable = mMmapBufferinfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE;
+ const status_t status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo);
+ const bool isBufferShareable = mMmapBufferinfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE;
if (status != OK) {
ALOGE("%s() - createMmapBuffer() failed with status %d %s",
__func__, status, strerror(-status));
@@ -545,7 +544,7 @@
setBufferCapacity(mMmapBufferinfo.buffer_size_frames);
if (!isBufferShareable) {
// Exclusive mode can only be used by the service because the FD cannot be shared.
- int32_t audioServiceUid =
+ const int32_t audioServiceUid =
VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
if ((mMmapClient.attributionSource.uid != audioServiceUid) &&
getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 73e0f61..4f77393 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -44,7 +44,7 @@
public:
explicit AAudioServiceEndpointMMAP(android::AAudioService &audioService);
- virtual ~AAudioServiceEndpointMMAP() = default;
+ ~AAudioServiceEndpointMMAP() override = default;
std::string dump() const override;
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index 2a5939f..637405d 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -158,5 +158,5 @@
ALOGD("%s() exiting, enabled = %d, state = %d, result = %d <<<<<<<<<<<<< MIXER",
__func__, mCallbackEnabled.load(), getStreamInternal()->getState(), result);
- return NULL; // TODO review
+ return nullptr; // TODO review
}
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 02202d8..1dd0c3a 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -103,8 +103,7 @@
// Prevent the stream from being deleted while being used.
// This is just for extra safety. It is probably not needed because
// this callback should be joined before the stream is closed.
- AAudioServiceEndpointShared *endpointPtr =
- static_cast<AAudioServiceEndpointShared *>(arg);
+ auto endpointPtr = static_cast<AAudioServiceEndpointShared *>(arg);
android::sp<AAudioServiceEndpointShared> endpoint(endpointPtr);
// Balance the incStrong() in startSharingThread_l().
endpoint->decStrong(nullptr);
@@ -140,7 +139,7 @@
aaudio_result_t aaudio::AAudioServiceEndpointShared::stopSharingThread() {
mCallbackEnabled.store(false);
- return getStreamInternal()->joinThread(NULL);
+ return getStreamInternal()->joinThread(nullptr);
}
aaudio_result_t AAudioServiceEndpointShared::startStream(
@@ -180,8 +179,8 @@
return result;
}
-aaudio_result_t AAudioServiceEndpointShared::stopStream(sp<AAudioServiceStreamBase> sharedStream,
- audio_port_handle_t clientHandle) {
+aaudio_result_t AAudioServiceEndpointShared::stopStream(
+ sp<AAudioServiceStreamBase> /*sharedStream*/, audio_port_handle_t clientHandle) {
// Ignore result.
(void) getStreamInternal()->stopClient(clientHandle);
diff --git a/services/oboeservice/AAudioServiceEndpointShared.h b/services/oboeservice/AAudioServiceEndpointShared.h
index 3e760c4..0efb227 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.h
+++ b/services/oboeservice/AAudioServiceEndpointShared.h
@@ -39,7 +39,7 @@
public:
explicit AAudioServiceEndpointShared(AudioStreamInternal *streamInternal);
- virtual ~AAudioServiceEndpointShared() = default;
+ ~AAudioServiceEndpointShared() override = default;
std::string dump() const override;
@@ -79,6 +79,6 @@
std::atomic<int> mRunningStreamCount{0};
};
-}
+} // namespace aaudio
#endif //AAUDIO_SERVICE_ENDPOINT_SHARED_H
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 35d712c..8e1e497 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -83,9 +83,8 @@
}
std::string AAudioServiceStreamBase::dumpHeader() {
- return std::string(
- " T Handle UId Port Run State Format Burst Chan Mask Capacity"
- " HwFormat HwChan HwRate");
+ return {" T Handle UId Port Run State Format Burst Chan Mask Capacity"
+ " HwFormat HwChan HwRate"};
}
std::string AAudioServiceStreamBase::dump() const {
@@ -477,8 +476,7 @@
disconnect_l();
break;
case REGISTER_AUDIO_THREAD: {
- RegisterAudioThreadParam *param =
- (RegisterAudioThreadParam *) command->parameter.get();
+ auto param = (RegisterAudioThreadParam *) command->parameter.get();
command->result =
param == nullptr ? AAUDIO_ERROR_ILLEGAL_ARGUMENT
: registerAudioThread_l(param->mOwnerPid,
@@ -487,21 +485,20 @@
}
break;
case UNREGISTER_AUDIO_THREAD: {
- UnregisterAudioThreadParam *param =
- (UnregisterAudioThreadParam *) command->parameter.get();
+ auto param = (UnregisterAudioThreadParam *) command->parameter.get();
command->result =
param == nullptr ? AAUDIO_ERROR_ILLEGAL_ARGUMENT
: unregisterAudioThread_l(param->mClientThreadId);
}
break;
case GET_DESCRIPTION: {
- GetDescriptionParam *param = (GetDescriptionParam *) command->parameter.get();
+ auto param = (GetDescriptionParam *) command->parameter.get();
command->result = param == nullptr ? AAUDIO_ERROR_ILLEGAL_ARGUMENT
: getDescription_l(param->mParcelable);
}
break;
case EXIT_STANDBY: {
- ExitStandbyParam *param = (ExitStandbyParam *) command->parameter.get();
+ auto param = (ExitStandbyParam *) command->parameter.get();
command->result = param == nullptr ? AAUDIO_ERROR_ILLEGAL_ARGUMENT
: exitStandby_l(param->mParcelable);
standbyTime = AudioClock::getNanoseconds() + IDLE_TIMEOUT_NANOS;
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index b5f8b90..0f51503 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -62,7 +62,7 @@
public:
explicit AAudioServiceStreamBase(android::AAudioService &aAudioService);
- virtual ~AAudioServiceStreamBase();
+ ~AAudioServiceStreamBase() override;
enum {
ILLEGAL_THREAD_ID = 0
@@ -254,7 +254,7 @@
RegisterAudioThreadParam(pid_t ownerPid, pid_t clientThreadId, int priority)
: AAudioCommandParam(), mOwnerPid(ownerPid),
mClientThreadId(clientThreadId), mPriority(priority) { }
- ~RegisterAudioThreadParam() = default;
+ ~RegisterAudioThreadParam() override = default;
pid_t mOwnerPid;
pid_t mClientThreadId;
@@ -265,9 +265,9 @@
class UnregisterAudioThreadParam : public AAudioCommandParam {
public:
- UnregisterAudioThreadParam(pid_t clientThreadId)
+ explicit UnregisterAudioThreadParam(pid_t clientThreadId)
: AAudioCommandParam(), mClientThreadId(clientThreadId) { }
- ~UnregisterAudioThreadParam() = default;
+ ~UnregisterAudioThreadParam() override = default;
pid_t mClientThreadId;
};
@@ -275,9 +275,9 @@
class GetDescriptionParam : public AAudioCommandParam {
public:
- GetDescriptionParam(AudioEndpointParcelable* parcelable)
+ explicit GetDescriptionParam(AudioEndpointParcelable* parcelable)
: AAudioCommandParam(), mParcelable(parcelable) { }
- ~GetDescriptionParam() = default;
+ ~GetDescriptionParam() override = default;
AudioEndpointParcelable* mParcelable;
};
@@ -324,9 +324,9 @@
}
class ExitStandbyParam : public AAudioCommandParam {
public:
- ExitStandbyParam(AudioEndpointParcelable* parcelable)
+ explicit ExitStandbyParam(AudioEndpointParcelable* parcelable)
: AAudioCommandParam(), mParcelable(parcelable) { }
- ~ExitStandbyParam() = default;
+ ~ExitStandbyParam() override = default;
AudioEndpointParcelable* mParcelable;
};
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index cd8c91e..8b8c5e6 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -47,7 +47,7 @@
public:
AAudioServiceStreamMMAP(android::AAudioService &aAudioService,
bool inService);
- virtual ~AAudioServiceStreamMMAP() = default;
+ ~AAudioServiceStreamMMAP() override = default;
aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override;
diff --git a/services/oboeservice/AAudioServiceStreamShared.h b/services/oboeservice/AAudioServiceStreamShared.h
index 78f9787..0b2513a 100644
--- a/services/oboeservice/AAudioServiceStreamShared.h
+++ b/services/oboeservice/AAudioServiceStreamShared.h
@@ -44,7 +44,7 @@
public:
explicit AAudioServiceStreamShared(android::AAudioService &aAudioService);
- virtual ~AAudioServiceStreamShared() = default;
+ ~AAudioServiceStreamShared() override = default;
static std::string dumpHeader();
diff --git a/services/oboeservice/AAudioStreamTracker.cpp b/services/oboeservice/AAudioStreamTracker.cpp
index 9bbbc73..c86a7a2 100644
--- a/services/oboeservice/AAudioStreamTracker.cpp
+++ b/services/oboeservice/AAudioStreamTracker.cpp
@@ -78,7 +78,8 @@
return handle;
}
-aaudio_handle_t AAudioStreamTracker::addStreamForHandle(sp<AAudioServiceStreamBase> serviceStream) {
+aaudio_handle_t AAudioStreamTracker::addStreamForHandle(
+ const sp<AAudioServiceStreamBase>& serviceStream) {
std::lock_guard<std::mutex> lock(mHandleLock);
aaudio_handle_t handle = mPreviousHandle;
// Assign a unique handle.
diff --git a/services/oboeservice/AAudioStreamTracker.h b/services/oboeservice/AAudioStreamTracker.h
index 43870fc..99f4b6c 100644
--- a/services/oboeservice/AAudioStreamTracker.h
+++ b/services/oboeservice/AAudioStreamTracker.h
@@ -64,7 +64,7 @@
* @param serviceStream
* @return handle for identifying the stream
*/
- aaudio_handle_t addStreamForHandle(android::sp<AAudioServiceStreamBase> serviceStream);
+ aaudio_handle_t addStreamForHandle(const android::sp<AAudioServiceStreamBase>& serviceStream);
/**
* @return string that can be added to dumpsys
diff --git a/services/oboeservice/AAudioThread.h b/services/oboeservice/AAudioThread.h
index b2774e0..91ad715 100644
--- a/services/oboeservice/AAudioThread.h
+++ b/services/oboeservice/AAudioThread.h
@@ -29,7 +29,7 @@
*/
class Runnable {
public:
- Runnable() {};
+ Runnable() = default;
virtual ~Runnable() = default;
virtual void run() = 0;
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 5076239..56c0dc9 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -21,6 +21,64 @@
default_applicable_licenses: ["frameworks_av_license"],
}
+tidy_errors = [
+ // https://clang.llvm.org/extra/clang-tidy/checks/list.html
+ // For many categories, the checks are too many to specify individually.
+ // Feel free to disable as needed - as warnings are generally ignored,
+ // we treat warnings as errors.
+ "android-*",
+ "bugprone-*",
+ "cert-*",
+ "clang-analyzer-security*",
+ "google-*",
+ "misc-*",
+ //"modernize-*", // explicitly list the modernize as they can be subjective.
+ "modernize-avoid-bind",
+ //"modernize-avoid-c-arrays", // std::array<> can be verbose
+ "modernize-concat-nested-namespaces",
+ //"modernize-deprecated-headers", // C headers still ok even if there is C++ equivalent.
+ "modernize-deprecated-ios-base-aliases",
+ "modernize-loop-convert",
+ "modernize-make-shared",
+ "modernize-make-unique",
+ "modernize-pass-by-value",
+ "modernize-raw-string-literal",
+ "modernize-redundant-void-arg",
+ "modernize-replace-auto-ptr",
+ "modernize-replace-random-shuffle",
+ "modernize-return-braced-init-list",
+ "modernize-shrink-to-fit",
+ "modernize-unary-static-assert",
+ "modernize-use-auto",
+ "modernize-use-bool-literals",
+ "modernize-use-default-member-init",
+ "modernize-use-emplace",
+ "modernize-use-equals-default",
+ "modernize-use-equals-delete",
+ // "modernize-use-nodiscard", // Maybe add this in the future
+ "modernize-use-noexcept",
+ "modernize-use-nullptr",
+ "modernize-use-override",
+ // "modernize-use-trailing-return-type", // not necessarily more readable
+ "modernize-use-transparent-functors",
+ "modernize-use-uncaught-exceptions",
+ "modernize-use-using",
+ "performance-*",
+
+ // Remove some pedantic stylistic requirements.
+ "-android-cloexec-dup", // found in AAudioServiceEndpointMMAP.cpp
+ "-bugprone-narrowing-conversions", // found in several interface from size_t to int32_t
+
+ "-google-readability-casting", // C++ casts not always necessary and may be verbose
+ "-google-readability-todo", // do not require TODO(info)
+ "-google-build-using-namespace", // Reenable and fix later.
+ "-google-global-names-in-headers", // found in several files
+
+ "-misc-non-private-member-variables-in-classes", // found in aidl generated files
+
+]
+
+
cc_library {
name: "libaaudioservice",
@@ -89,4 +147,11 @@
"frameworks/av/media/libnbaio/include_mono",
"frameworks/av/media/libnbaio/include",
],
+
+ tidy: true,
+ tidy_checks: tidy_errors,
+ tidy_checks_as_errors: tidy_errors,
+ tidy_flags: [
+ "-format-style=file",
+ ]
}
diff --git a/services/oboeservice/SharedMemoryProxy.cpp b/services/oboeservice/SharedMemoryProxy.cpp
index 78d4884..549a36e 100644
--- a/services/oboeservice/SharedMemoryProxy.cpp
+++ b/services/oboeservice/SharedMemoryProxy.cpp
@@ -58,7 +58,7 @@
}
// Get original memory address.
- mOriginalSharedMemory = (uint8_t *) mmap(0, mSharedMemorySizeInBytes,
+ mOriginalSharedMemory = (uint8_t *) mmap(nullptr, mSharedMemorySizeInBytes,
PROT_READ|PROT_WRITE,
MAP_SHARED,
mOriginalFileDescriptor, 0);
diff --git a/services/oboeservice/SharedMemoryProxy.h b/services/oboeservice/SharedMemoryProxy.h
index 89eeb4b..81a0753 100644
--- a/services/oboeservice/SharedMemoryProxy.h
+++ b/services/oboeservice/SharedMemoryProxy.h
@@ -30,7 +30,7 @@
*/
class SharedMemoryProxy {
public:
- SharedMemoryProxy() {}
+ SharedMemoryProxy() = default;
~SharedMemoryProxy();
diff --git a/services/oboeservice/SharedRingBuffer.cpp b/services/oboeservice/SharedRingBuffer.cpp
index fd2a454..eebff51 100644
--- a/services/oboeservice/SharedRingBuffer.cpp
+++ b/services/oboeservice/SharedRingBuffer.cpp
@@ -62,7 +62,7 @@
// Map the fd to memory addresses. Use a temporary pointer to keep the mmap result and update
// it to `mSharedMemory` only when mmap operate successfully.
- uint8_t* tmpPtr = (uint8_t *) mmap(0, mSharedMemorySizeInBytes,
+ auto tmpPtr = (uint8_t *) mmap(nullptr, mSharedMemorySizeInBytes,
PROT_READ|PROT_WRITE,
MAP_SHARED,
mFileDescriptor.get(), 0);
@@ -74,10 +74,8 @@
mSharedMemory = tmpPtr;
// Get addresses for our counters and data from the shared memory.
- fifo_counter_t *readCounterAddress =
- (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_READ_OFFSET];
- fifo_counter_t *writeCounterAddress =
- (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_WRITE_OFFSET];
+ auto readCounterAddress = (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_READ_OFFSET];
+ auto writeCounterAddress = (fifo_counter_t *) &mSharedMemory[SHARED_RINGBUFFER_WRITE_OFFSET];
uint8_t *dataAddress = &mSharedMemory[SHARED_RINGBUFFER_DATA_OFFSET];
mFifoBuffer = std::make_shared<FifoBufferIndirect>(bytesPerFrame, capacityInFrames,
diff --git a/services/oboeservice/SharedRingBuffer.h b/services/oboeservice/SharedRingBuffer.h
index cff1261..463bf11 100644
--- a/services/oboeservice/SharedRingBuffer.h
+++ b/services/oboeservice/SharedRingBuffer.h
@@ -39,7 +39,7 @@
*/
class SharedRingBuffer {
public:
- SharedRingBuffer() {}
+ SharedRingBuffer() = default;
virtual ~SharedRingBuffer();
diff --git a/services/oboeservice/TimestampScheduler.h b/services/oboeservice/TimestampScheduler.h
index baa5c41..6b5f4b1 100644
--- a/services/oboeservice/TimestampScheduler.h
+++ b/services/oboeservice/TimestampScheduler.h
@@ -31,7 +31,7 @@
class TimestampScheduler
{
public:
- TimestampScheduler() {};
+ TimestampScheduler() = default;
virtual ~TimestampScheduler() = default;
/**