Merge "Add uid to audioflinger track dumps" into main
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e9b757b..34ff367 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -30,8 +30,10 @@
# Only turn on clang-format check for the following subfolders.
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+ camera/
media/libaudioclient/tests/
media/libaudiohal/tests/
media/libmediatranscoding/
services/camera/virtualcamera/
services/mediatranscoding/
+ services/camera/libcameraservice/
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index ec36335..db33dd7 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -164,3 +164,10 @@
description: "Enable stream reconfiguration for unchanged streams"
bug: "341740105"
}
+
+flag {
+ namespace: "camera_platform"
+ name: "use_context_attribution_source"
+ description: "Use the context-provided AttributionSource when checking for client permissions"
+ bug: "190657833"
+}
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 6d29ef5..53c4489 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -170,97 +170,78 @@
}
sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
- if (mCameraService.get() == nullptr) {
- if (CameraUtils::isCameraServiceDisabled()) {
- return mCameraService;
- }
+ if (mCameraService.get() != nullptr) {
+ return mCameraService;
+ }
+ if (CameraUtils::isCameraServiceDisabled()) {
+ return mCameraService;
+ }
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder;
- binder = sm->checkService(String16(kCameraServiceName));
- if (binder == nullptr) {
- ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder;
+ binder = sm->checkService(String16(kCameraServiceName));
+ if (binder == nullptr) {
+ ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
+ return nullptr;
+ }
+ sp<hardware::ICameraService> cameraService = interface_cast<hardware::ICameraService>(binder);
+ if (mDeathNotifier == nullptr) {
+ mDeathNotifier = new DeathNotifier(this);
+ binder->linkToDeath(mDeathNotifier);
+ }
+
+ // Setup looper thread to perform availability callbacks
+ if (mCbLooper == nullptr) {
+ mCbLooper = new ALooper;
+ mCbLooper->setName("C2N-mgr-looper");
+ status_t err = mCbLooper->start(
+ /*runOnCallingThread*/false,
+ /*canCallJava*/ true,
+ PRIORITY_DEFAULT);
+ if (err != OK) {
+ ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
+ __FUNCTION__, strerror(-err), err);
+ mCbLooper.clear();
return nullptr;
}
- if (mDeathNotifier == nullptr) {
- mDeathNotifier = new DeathNotifier(this);
+ if (mHandler == nullptr) {
+ mHandler = new CallbackHandler(this);
}
- binder->linkToDeath(mDeathNotifier);
- mCameraService = interface_cast<hardware::ICameraService>(binder);
+ mCbLooper->registerHandler(mHandler);
+ }
- // Setup looper thread to perfrom availiability callbacks
- if (mCbLooper == nullptr) {
- mCbLooper = new ALooper;
- mCbLooper->setName("C2N-mgr-looper");
- status_t err = mCbLooper->start(
- /*runOnCallingThread*/false,
- /*canCallJava*/ true,
- PRIORITY_DEFAULT);
- if (err != OK) {
- ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
- __FUNCTION__, strerror(-err), err);
- mCbLooper.clear();
- return nullptr;
- }
- if (mHandler == nullptr) {
- mHandler = new CallbackHandler(this);
- }
- mCbLooper->registerHandler(mHandler);
+ // register ICameraServiceListener
+ std::vector<hardware::CameraStatus> cameraStatuses{};
+ if (mCameraServiceListener == nullptr) {
+ mCameraServiceListener = new CameraServiceListener(this);
+ cameraService->addListener(mCameraServiceListener, &cameraStatuses);
+ }
+
+ for (auto& c : cameraStatuses) {
+ onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
+
+ for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
+ onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
+ c.deviceId, c.cameraId, unavailablePhysicalId);
}
+ }
+ // setup vendor tags
+ if (!setupVendorTags(cameraService)) {
+ ALOGE("%s: Vendor tag descriptor cache couldn't be set up", __FUNCTION__);
+ return nullptr;
+ }
- // register ICameraServiceListener
- if (mCameraServiceListener == nullptr) {
- mCameraServiceListener = new CameraServiceListener(this);
- }
- std::vector<hardware::CameraStatus> cameraStatuses{};
- mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
- for (auto& c : cameraStatuses) {
- onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
+ mCameraService = cameraService;
+ ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
+ return mCameraService;
+}
- for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
- onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
- c.deviceId, c.cameraId, unavailablePhysicalId);
- }
- }
-
- // setup vendor tags
- sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
- binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
-
- if (ret.isOk()) {
- if (0 < desc->getTagCount()) {
- status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
- if (err != OK) {
- ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
- __FUNCTION__, strerror(-err), err);
- }
- } else {
- sp<VendorTagDescriptorCache> cache =
- new VendorTagDescriptorCache();
- binder::Status res =
- mCameraService->getCameraVendorTagCache(
- /*out*/cache.get());
- if (res.serviceSpecificErrorCode() ==
- hardware::ICameraService::ERROR_DISCONNECTED) {
- // No camera module available, not an error on devices with no cameras
- VendorTagDescriptorCache::clearGlobalVendorTagCache();
- } else if (res.isOk()) {
- status_t err =
- VendorTagDescriptorCache::setAsGlobalVendorTagCache(
- cache);
- if (err != OK) {
- ALOGE("%s: Failed to set vendor tag cache,"
- "received error %s (%d)", __FUNCTION__,
- strerror(-err), err);
- }
- } else {
- VendorTagDescriptorCache::clearGlobalVendorTagCache();
- ALOGE("%s: Failed to setup vendor tag cache: %s",
- __FUNCTION__, res.toString8().c_str());
- }
- }
- } else if (ret.serviceSpecificErrorCode() ==
- hardware::ICameraService::ERROR_DEPRECATED_HAL) {
+bool CameraManagerGlobal::setupVendorTags(sp<hardware::ICameraService> &cameraService) {
+ sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
+ binder::Status ret = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
+ if (!ret.isOk()) {
+ if (ret.serviceSpecificErrorCode() ==
+ hardware::ICameraService::ERROR_DEPRECATED_HAL) {
ALOGW("%s: Camera HAL too old; does not support vendor tags",
__FUNCTION__);
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
@@ -268,9 +249,45 @@
ALOGE("%s: Failed to get vendor tag descriptors: %s",
__FUNCTION__, ret.toString8().c_str());
}
+ return false;
}
- ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
- return mCameraService;
+
+ if (0 < desc->getTagCount()) {
+ status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+ if (err != OK) {
+ ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
+ __FUNCTION__, strerror(-err), err);
+ return false;
+ }
+ } else {
+ sp<VendorTagDescriptorCache> cache =
+ new VendorTagDescriptorCache();
+ binder::Status res =
+ cameraService->getCameraVendorTagCache(
+ /*out*/cache.get());
+ if (res.serviceSpecificErrorCode() ==
+ hardware::ICameraService::ERROR_DISCONNECTED) {
+ // No camera module available, not an error on devices with no cameras
+ VendorTagDescriptorCache::clearGlobalVendorTagCache();
+ } else if (res.isOk()) {
+ status_t err =
+ VendorTagDescriptorCache::setAsGlobalVendorTagCache(
+ cache);
+ if (err != OK) {
+ ALOGE("%s: Failed to set vendor tag cache,"
+ "received error %s (%d)", __FUNCTION__,
+ strerror(-err), err);
+ return false;
+ }
+ } else {
+ VendorTagDescriptorCache::clearGlobalVendorTagCache();
+ ALOGE("%s: Failed to setup vendor tag cache: %s",
+ __FUNCTION__, res.toString8().c_str());
+ return false;
+ }
+ }
+
+ return true;
}
void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
@@ -290,6 +307,8 @@
key.cameraId);
}
cm->mCameraService.clear();
+ cm->mCameraServiceListener.clear();
+ cm->mDeathNotifier.clear();
// TODO: consider adding re-connect call here?
}
}
@@ -398,6 +417,9 @@
bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
bool camera2Support = false;
auto cs = getCameraServiceLocked();
+ if (cs == nullptr) {
+ return false;
+ }
binder::Status serviceRet =
cs->supportsCameraApi(cameraId,
hardware::ICameraService::API_VERSION_2, &camera2Support);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index f4124ef..cb7a4ff 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -105,6 +105,8 @@
template <class T>
void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
+ bool setupVendorTags(sp<hardware::ICameraService> &cameraService);
+
class DeathNotifier : public IBinder::DeathRecipient {
public:
explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 1817490..7fb2d05 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -480,10 +480,21 @@
* camera device auto-exposure routine for the overridden
* fields for a given capture will be available in its
* CaptureResult.</p>
+ * <p>When ACAMERA_CONTROL_AE_MODE is AE_MODE_ON and if the device
+ * supports manual flash strength control, i.e.,
+ * if ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and
+ * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL are greater than 1, then
+ * the auto-exposure (AE) precapture metering sequence should be
+ * triggered to avoid the image being incorrectly exposed at
+ * different ACAMERA_FLASH_STRENGTH_LEVEL.</p>
*
+ * @see ACAMERA_CONTROL_AE_MODE
* @see ACAMERA_CONTROL_MODE
* @see ACAMERA_FLASH_INFO_AVAILABLE
* @see ACAMERA_FLASH_MODE
+ * @see ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL
+ * @see ACAMERA_FLASH_STRENGTH_LEVEL
+ * @see ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL
* @see ACAMERA_SENSOR_EXPOSURE_TIME
* @see ACAMERA_SENSOR_FRAME_DURATION
* @see ACAMERA_SENSOR_SENSITIVITY
@@ -8233,7 +8244,17 @@
* ACAMERA_SENSOR_FRAME_DURATION are ignored. The
* application has control over the various
* ACAMERA_FLASH_* fields.</p>
+ * <p>If the device supports manual flash strength control, i.e.,
+ * if ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and
+ * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL are greater than 1, then
+ * the auto-exposure (AE) precapture metering sequence should be
+ * triggered for the configured flash mode and strength to avoid
+ * the image being incorrectly exposed at different
+ * ACAMERA_FLASH_STRENGTH_LEVEL.</p>
*
+ * @see ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL
+ * @see ACAMERA_FLASH_STRENGTH_LEVEL
+ * @see ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL
* @see ACAMERA_SENSOR_EXPOSURE_TIME
* @see ACAMERA_SENSOR_FRAME_DURATION
* @see ACAMERA_SENSOR_SENSITIVITY
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index cdba8ff..5b69f5c 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -194,11 +194,11 @@
return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
}
-bool CameraManagerGlobal::setupVendorTags() {
+bool CameraManagerGlobal::setupVendorTags(std::shared_ptr<ICameraService> &cameraService) {
sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
Status status = Status::NO_ERROR;
std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
- ScopedAStatus remoteRet = mCameraService->getCameraVendorTagSections(&providerIdsAndVts);
+ ScopedAStatus remoteRet = cameraService->getCameraVendorTagSections(&providerIdsAndVts);
if (!remoteRet.isOk()) {
if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
@@ -261,15 +261,12 @@
ALOGE("%s: Could not get ICameraService instance.", __FUNCTION__);
return nullptr;
}
-
if (mDeathRecipient.get() == nullptr) {
mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
AIBinder_DeathRecipient_new(CameraManagerGlobal::binderDeathCallback));
+ AIBinder_linkToDeath(cameraService->asBinder().get(),
+ mDeathRecipient.get(), /*cookie=*/ this);
}
- AIBinder_linkToDeath(cameraService->asBinder().get(),
- mDeathRecipient.get(), /*cookie=*/ this);
-
- mCameraService = cameraService;
// Setup looper thread to perform availability callbacks
if (mCbLooper == nullptr) {
@@ -291,33 +288,25 @@
mCbLooper->registerHandler(mHandler);
}
+ std::vector<CameraStatusAndId> cameraStatuses;
// register ICameraServiceListener
if (mCameraServiceListener == nullptr) {
mCameraServiceListener = ndk::SharedRefBase::make<CameraServiceListener>(weak_from_this());
- }
-
- std::vector<CameraStatusAndId> cameraStatuses;
- Status status = Status::NO_ERROR;
- ScopedAStatus remoteRet = mCameraService->addListener(mCameraServiceListener,
- &cameraStatuses);
-
- if (!remoteRet.isOk()) {
- if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
- Status errStatus = static_cast<Status>(remoteRet.getServiceSpecificError());
- ALOGE("%s: Failed to add listener to camera service: %s", __FUNCTION__,
- toString(errStatus).c_str());
- } else {
- ALOGE("%s: Transaction failed when adding listener to camera service: %d",
- __FUNCTION__, remoteRet.getExceptionCode());
+ ScopedAStatus remoteRet = cameraService->addListener(mCameraServiceListener,
+ &cameraStatuses);
+ if (!remoteRet.isOk()) {
+ if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+ Status errStatus = static_cast<Status>(remoteRet.getServiceSpecificError());
+ ALOGE("%s: Failed to add listener to camera service: %s", __FUNCTION__,
+ toString(errStatus).c_str());
+ } else {
+ ALOGE("%s: Transaction failed when adding listener to camera service: %d",
+ __FUNCTION__, remoteRet.getExceptionCode());
+ }
+ return nullptr;
}
}
- // Setup vendor tags
- if (!setupVendorTags()) {
- ALOGE("Unable to set up vendor tags");
- return nullptr;
- }
-
for (auto& csi: cameraStatuses){
onStatusChangedLocked(csi.deviceStatus, csi.cameraId);
@@ -326,6 +315,13 @@
csi.cameraId, unavailablePhysicalId);
}
}
+
+ // Setup vendor tags
+ if (!setupVendorTags(cameraService)) {
+ ALOGE("Unable to set up vendor tags");
+ return nullptr;
+ }
+ mCameraService = cameraService;
return mCameraService;
}
@@ -346,6 +342,8 @@
instance->onStatusChangedLocked(deviceStatus, cameraId);
}
instance->mCameraService.reset();
+ instance->mDeathRecipient.release();
+ instance->mCameraServiceListener.reset();
// TODO: consider adding re-connect call here?
}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 2d8eefa..5688e76 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -188,7 +188,7 @@
const std::string &physicalCameraId);
void onStatusChangedLocked(const CameraDeviceStatus &status, const std::string &cameraId,
const std::string &physicalCameraId);
- bool setupVendorTags();
+ bool setupVendorTags(std::shared_ptr<ICameraService> &cameraService);
// Utils for status
static bool validStatus(CameraDeviceStatus status);
diff --git a/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h b/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
index f046785..97a8cc4 100644
--- a/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
+++ b/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
@@ -35,7 +35,8 @@
class DrmRemotelyProvisionedComponent : public BnRemotelyProvisionedComponent {
public:
DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm, std::string drmVendor,
- std::string drmDesc, std::vector<uint8_t> bcc);
+ std::string drmDesc, std::vector<uint8_t> bcc,
+ std::vector<uint8_t> bcc_signature);
ScopedAStatus getHardwareInfo(RpcHardwareInfo* info) override;
ScopedAStatus generateEcdsaP256KeyPair(bool testMode, MacedPublicKey* macedPublicKey,
@@ -60,6 +61,7 @@
std::string mDrmVendor;
std::string mDrmDesc;
std::vector<uint8_t> mBcc;
+ std::vector<uint8_t> mBccSignature;
};
} // namespace android::mediadrm
diff --git a/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp b/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
index 440be79..65054b0 100644
--- a/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
+++ b/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
@@ -28,11 +28,13 @@
DrmRemotelyProvisionedComponent::DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm,
std::string drmVendor,
std::string drmDesc,
- std::vector<uint8_t> bcc)
+ std::vector<uint8_t> bcc,
+ std::vector<uint8_t> bcc_signature)
: mDrm(std::move(drm)),
mDrmVendor(std::move(drmVendor)),
mDrmDesc(std::move(drmDesc)),
- mBcc(std::move(bcc)) {}
+ mBcc(std::move(bcc)),
+ mBccSignature(std::move(bcc_signature)) {}
ScopedAStatus DrmRemotelyProvisionedComponent::getHardwareInfo(RpcHardwareInfo* info) {
info->versionNumber = 3;
@@ -107,7 +109,7 @@
for (auto i : keyToProp) {
auto key = i.first;
auto prop = i.second;
- const auto& val= deviceInfoMap.get(key);
+ const auto& val = deviceInfoMap.get(key);
if (val == nullptr || val->asTstr()->value().empty()) {
std::string propValue = android::base::GetProperty(prop, "");
if (propValue.empty()) {
@@ -161,12 +163,16 @@
}
// assemble AuthenticatedRequest (definition in IRemotelyProvisionedComponent.aidl)
- *out = cppbor::Array()
- .add(1 /* version */)
- .add(cppbor::Map() /* UdsCerts */)
- .add(cppbor::EncodedItem(mBcc))
- .add(cppbor::EncodedItem(std::move(deviceSignedCsrPayload)))
- .encode();
+ cppbor::Array request_array = cppbor::Array().add(1 /* version */);
+ if (!mBccSignature.empty()) {
+ request_array.add(cppbor::EncodedItem(mBccSignature) /* UdsCerts */);
+ } else {
+ request_array.add(cppbor::Map() /* empty UdsCerts */);
+ }
+ request_array.add(cppbor::EncodedItem(mBcc))
+ .add(cppbor::EncodedItem(std::move(deviceSignedCsrPayload)));
+ *out = request_array.encode();
+
return ScopedAStatus::ok();
}
} // namespace android::mediadrm
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp b/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
index 515d157..750b51e 100644
--- a/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
+++ b/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
@@ -87,13 +87,21 @@
status.getDescription().c_str());
return;
}
-
+ std::vector<uint8_t> bcc_signature;
+ status =
+ mDrm->getPropertyByteArray("bootCertificateChainSignature", &bcc_signature);
+ if (!status.isOk()) {
+ ALOGW("mDrm->getPropertyByteArray(\"bootCertificateChainSignature\") failed."
+ "Detail: [%s].",
+ status.getDescription().c_str());
+ // bcc signature is optional, no need to return when it is unavailable.
+ }
std::string compName(instance);
auto comps = static_cast<
std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>*>(
context);
(*comps)[compName] = ::ndk::SharedRefBase::make<DrmRemotelyProvisionedComponent>(
- mDrm, drmVendor, drmDesc, bcc);
+ mDrm, drmVendor, drmDesc, bcc, bcc_signature);
});
return comps;
}
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 1a637ac..695cad6 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -45,6 +45,32 @@
"file_patterns": ["(?i)drm|crypto"]
}
],
+ "postsubmit": [
+ {
+ "name": "MctsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.EncodeDecodeTest"
+ }
+ ]
+ },
+ {
+ "name": "MctsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.DecodeEditEncodeTest"
+ }
+ ]
+ },
+ {
+ "name": "MctsMediaCodecTestCases",
+ "options": [
+ {
+ "include-filter": "android.media.codec.cts.ExtractDecodeEditEncodeMuxTest"
+ }
+ ]
+ }
+ ],
// Postsubmit tests for TV devices
"tv-postsubmit": [
{
diff --git a/media/aconfig/codec_fwk.aconfig b/media/aconfig/codec_fwk.aconfig
index 2bf53f9..ed1522b 100644
--- a/media/aconfig/codec_fwk.aconfig
+++ b/media/aconfig/codec_fwk.aconfig
@@ -13,6 +13,16 @@
}
flag {
+ name: "codec_buffer_state_cleanup"
+ namespace: "codec_fwk"
+ description: "Bugfix flag for more buffer state cleanup in MediaCodec"
+ bug: "343502509"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "dataspace_v0_partial"
namespace: "codec_fwk"
description: "Bugfix flag for using V0 dataspace in some cases"
diff --git a/media/audio/aconfig/audio_framework.aconfig b/media/audio/aconfig/audio_framework.aconfig
index b8555df..411996e 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -47,6 +47,14 @@
bug: "316414750"
}
+flag {
+ name: "dolby_ac4_level4_encoding_api"
+ namespace: "media_audio"
+ description: "Feature flag for Dolby AC-4 level 4 AudioFormat encoding."
+ is_fixed_read_only: true
+ bug: "266537650"
+}
+
# TODO remove
flag {
name: "foreground_audio_control"
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 890a1c7..90996a3 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -741,6 +741,8 @@
{// Note: not in the IANA registry.
AUDIO_FORMAT_APTX_HD, make_AudioFormatDescription("audio/vnd.qcom.aptx.hd")},
{AUDIO_FORMAT_AC4, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AC4)},
+ {AUDIO_FORMAT_AC4_L4, make_AudioFormatDescription(
+ std::string(::android::MEDIA_MIMETYPE_AUDIO_AC4) + ";version=02.01.04")},
{// Note: not in the IANA registry.
AUDIO_FORMAT_LDAC, make_AudioFormatDescription("audio/vnd.sony.ldac")},
{AUDIO_FORMAT_MAT,
@@ -1055,14 +1057,6 @@
return OK;
}
-namespace {
- // Use '01' for LSB bits 0 and 1 as Bluetooth MAC addresses are never multicast
- // and universaly administered
- constexpr std::array<uint8_t, 4> BTANON_PREFIX {0xFD, 0xFF, 0xFF, 0xFF};
- // Keep sync with ServiceUtilities.cpp mustAnonymizeBluetoothAddress
- constexpr const char * BTANON_PREFIX_STR = "XX:XX:XX:XX:";
-}
-
::android::status_t aidl2legacy_AudioDevice_audio_device(
const AudioDevice& aidl,
audio_devices_t* legacyType, std::string* legacyAddress) {
@@ -1077,16 +1071,8 @@
case Tag::mac: {
const std::vector<uint8_t>& mac = aidl.address.get<AudioDeviceAddress::mac>();
if (mac.size() != 6) return BAD_VALUE;
- if (std::equal(BTANON_PREFIX.begin(), BTANON_PREFIX.end(), mac.begin())) {
- // special case for anonymized mac address:
- // change anonymized bytes back from FD:FF:FF:FF: to XX:XX:XX:XX:
- snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN,
- "%s%02X:%02X", BTANON_PREFIX_STR, mac[4], mac[5]);
- } else {
- snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN,
- "%02X:%02X:%02X:%02X:%02X:%02X",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- }
+ snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
} break;
case Tag::ipv4: {
const std::vector<uint8_t>& ipv4 = aidl.address.get<AudioDeviceAddress::ipv4>();
@@ -1148,20 +1134,8 @@
switch (suggestDeviceAddressTag(aidl.type)) {
case Tag::mac: {
std::vector<uint8_t> mac(6);
- int status;
- // special case for anonymized mac address:
- // change anonymized bytes so that they can be scanned as HEX bytes
- if (legacyAddress.starts_with(BTANON_PREFIX_STR)) {
- std::copy(BTANON_PREFIX.begin(), BTANON_PREFIX.end(), mac.begin());
- LOG_ALWAYS_FATAL_IF(legacyAddress.length() <= strlen(BTANON_PREFIX_STR));
- status = sscanf(legacyAddress.c_str() + strlen(BTANON_PREFIX_STR),
- "%hhX:%hhX",
- &mac[4], &mac[5]);
- status += 4;
- } else {
- status = sscanf(legacyAddress.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
- &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
- }
+ int status = sscanf(legacyAddress.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
if (status != mac.size()) {
ALOGE("%s: malformed MAC address: \"%s\"", __func__, legacyAddress.c_str());
return unexpected(BAD_VALUE);
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
index 149c6ee..aed5e68 100644
--- a/media/codec2/components/mp3/C2SoftMp3Dec.cpp
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -114,7 +114,9 @@
c2_status_t C2SoftMP3::onStop() {
// Make sure that the next buffer output does not still
// depend on fragments from the last one decoded.
- pvmp3_InitDecoder(mConfig, mDecoderBuf);
+ if (mDecoderBuf) {
+ pvmp3_InitDecoder(mConfig, mDecoderBuf);
+ }
mSignalledError = false;
mIsFirst = true;
mSignalledOutputEos = false;
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h b/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
index de0f566..bb4c596 100644
--- a/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
+++ b/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
@@ -52,6 +52,13 @@
using ::aidl::android::hardware::media::bufferpool2::IClientManager;
struct ComponentStore : public BnComponentStore {
+ /**
+ * Constructor for ComponentStore.
+ *
+ * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+ * Be careful about the order of SetPreferredCodec2ComponentStore() and
+ * ComponentStore() in the code.
+ */
ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
virtual ~ComponentStore();
diff --git a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
index 847c90c..028238b 100644
--- a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
@@ -55,6 +55,13 @@
using ::android::sp;
struct ComponentStore : public IComponentStore {
+ /**
+ * Constructor for ComponentStore.
+ *
+ * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+ * Be careful about the order of SetPreferredCodec2ComponentStore() and
+ * ComponentStore() in the code.
+ */
ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
virtual ~ComponentStore();
diff --git a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
index 9028149..b023115 100644
--- a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
@@ -56,6 +56,13 @@
using ::android::sp;
struct ComponentStore : public IComponentStore {
+ /**
+ * Constructor for ComponentStore.
+ *
+ * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+ * Be careful about the order of SetPreferredCodec2ComponentStore() and
+ * ComponentStore() in the code.
+ */
ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
virtual ~ComponentStore();
diff --git a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
index 4fd260b..a7e043b 100644
--- a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
@@ -56,6 +56,13 @@
using ::android::sp;
struct ComponentStore : public IComponentStore {
+ /**
+ * Constructor for ComponentStore.
+ *
+ * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+ * Be careful about the order of SetPreferredCodec2ComponentStore() and
+ * ComponentStore() in the code.
+ */
ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
virtual ~ComponentStore();
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index 68dba34..29b876c 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -47,12 +47,7 @@
"name": "audioeffect_analysis"
},
{
- "name": "CtsVirtualDevicesTestCases",
- "options" : [
- {
- "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
- }
- ]
+ "name": "CtsVirtualDevicesAudioTestCases"
}
]
}
diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 2076045..7f55e48 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -483,27 +483,8 @@
AudioDeviceAddress::make<AudioDeviceAddress::Tag::alsa>(
std::vector<int32_t>{1, 2}))));
-TEST(AnonymizedBluetoothAddressRoundTripTest, Legacy2Aidl2Legacy) {
- const std::vector<uint8_t> sAnonymizedAidlAddress {0xFD, 0xFF, 0xFF, 0xFF, 0xAB, 0xCD};
- const std::string sAnonymizedLegacyAddress = std::string("XX:XX:XX:XX:AB:CD");
- auto device = legacy2aidl_audio_device_AudioDevice(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
- sAnonymizedLegacyAddress);
- ASSERT_TRUE(device.ok());
- ASSERT_EQ(AudioDeviceAddress::Tag::mac, device.value().address.getTag());
- ASSERT_EQ(sAnonymizedAidlAddress, device.value().address.get<AudioDeviceAddress::mac>());
-
- audio_devices_t legacyType;
- std::string legacyAddress;
- status_t status =
- aidl2legacy_AudioDevice_audio_device(device.value(), &legacyType, &legacyAddress);
- ASSERT_EQ(OK, status);
- EXPECT_EQ(legacyType, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP);
- EXPECT_EQ(sAnonymizedLegacyAddress, legacyAddress);
-}
-
class AudioFormatDescriptionRoundTripTest : public testing::TestWithParam<AudioFormatDescription> {
};
-
TEST_P(AudioFormatDescriptionRoundTripTest, Aidl2Legacy2Aidl) {
const auto initial = GetParam();
auto conv = aidl2legacy_AudioFormatDescription_audio_format_t(initial);
diff --git a/media/libaudioclient/tests/audiorouting_tests.cpp b/media/libaudioclient/tests/audiorouting_tests.cpp
index 8151d39..a3ab9d2 100644
--- a/media/libaudioclient/tests/audiorouting_tests.cpp
+++ b/media/libaudioclient/tests/audiorouting_tests.cpp
@@ -86,7 +86,18 @@
}
}
-TEST(AudioTrackTest, DefaultRoutingTest) {
+class AudioTrackTest
+ : public ::testing::TestWithParam<int> {
+
+public:
+ AudioTrackTest()
+ : mSampleRate(GetParam()){};
+
+ const uint32_t mSampleRate;
+
+};
+
+TEST_P(AudioTrackTest, DefaultRoutingTest) {
audio_port_v7 port;
if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
@@ -95,7 +106,8 @@
// create record instance
sp<AudioCapture> capture = sp<AudioCapture>::make(
- AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
+ AUDIO_SOURCE_REMOTE_SUBMIX, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_IN_STEREO);
ASSERT_NE(nullptr, capture);
ASSERT_EQ(OK, capture->create()) << "record creation failed";
sp<OnAudioDeviceUpdateNotifier> cbCapture = sp<OnAudioDeviceUpdateNotifier>::make();
@@ -103,7 +115,7 @@
// create playback instance
sp<AudioPlayback> playback = sp<AudioPlayback>::make(
- 48000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ mSampleRate, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE);
ASSERT_NE(nullptr, playback);
ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
@@ -133,6 +145,12 @@
playback->stop();
}
+INSTANTIATE_TEST_SUITE_P(
+ AudioTrackParameterizedTest,
+ AudioTrackTest,
+ ::testing::Values(44100, 48000)
+);
+
class AudioRoutingTest : public ::testing::Test {
public:
void SetUp() override {
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
index f352849..0cdf0f2 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.cpp
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -368,16 +368,21 @@
const AudioConfig& config, const std::optional<AudioIoFlags>& flags, int32_t ioHandle,
AudioSource source, const std::set<int32_t>& destinationPortIds,
AudioPortConfig* portConfig, bool* created) {
- // These flags get removed one by one in this order when retrying port finding.
- static const std::vector<AudioInputFlags> kOptionalInputFlags{
- AudioInputFlags::FAST, AudioInputFlags::RAW, AudioInputFlags::VOIP_TX };
if (auto portConfigIt = findPortConfig(config, flags, ioHandle);
portConfigIt == mPortConfigs.end() && flags.has_value()) {
- auto optionalInputFlagsIt = kOptionalInputFlags.begin();
+ // These input flags get removed one by one in this order when retrying port finding.
+ std::vector<AudioInputFlags> optionalInputFlags {
+ AudioInputFlags::FAST, AudioInputFlags::RAW, AudioInputFlags::VOIP_TX };
+ // For remote submix input, retry with direct input flag removed as the remote submix
+ // input is not expected to manipulate the contents of the audio stream.
+ if (mRemoteSubmixIn.has_value()) {
+ optionalInputFlags.push_back(AudioInputFlags::DIRECT);
+ }
+ auto optionalInputFlagsIt = optionalInputFlags.begin();
AudioIoFlags matchFlags = flags.value();
auto portsIt = findPort(config, matchFlags, destinationPortIds);
while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::input
- && optionalInputFlagsIt != kOptionalInputFlags.end()) {
+ && optionalInputFlagsIt != optionalInputFlags.end()) {
if (!isBitPositionFlagSet(
matchFlags.get<AudioIoFlags::Tag::input>(), *optionalInputFlagsIt)) {
++optionalInputFlagsIt;
@@ -392,6 +397,36 @@
config.toString().c_str(), flags.value().toString().c_str(),
matchFlags.toString().c_str());
}
+ // These output flags get removed one by one in this order when retrying port finding.
+ std::vector<AudioOutputFlags> optionalOutputFlags { };
+ // For remote submix output, retry with these output flags removed one by one:
+ // 1. DIRECT: remote submix outputs are expected not to manipulate the contents of the
+ // audio stream.
+ // 2. IEC958_NONAUDIO: remote submix outputs are not connected to ALSA and do not require
+ // non audio signalling.
+ if (mRemoteSubmixOut.has_value()) {
+ optionalOutputFlags.push_back(AudioOutputFlags::DIRECT);
+ optionalOutputFlags.push_back(AudioOutputFlags::IEC958_NONAUDIO);
+ }
+ auto optionalOutputFlagsIt = optionalOutputFlags.begin();
+ matchFlags = flags.value();
+ while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::output
+ && optionalOutputFlagsIt != optionalOutputFlags.end()) {
+ if (!isBitPositionFlagSet(
+ matchFlags.get<AudioIoFlags::Tag::output>(),*optionalOutputFlagsIt)) {
+ ++optionalOutputFlagsIt;
+ continue;
+ }
+ matchFlags.set<AudioIoFlags::Tag::output>(matchFlags.get<AudioIoFlags::Tag::output>() &
+ ~makeBitPositionFlagMask(*optionalOutputFlagsIt++));
+ portsIt = findPort(config, matchFlags, destinationPortIds);
+ AUGMENT_LOG(I,
+ "mix port for config %s, flags %s was not found"
+ "retried with flags %s",
+ config.toString().c_str(), flags.value().toString().c_str(),
+ matchFlags.toString().c_str());
+ }
+
if (portsIt == mPorts.end()) {
AUGMENT_LOG(E, "mix port for config %s, flags %s is not found",
config.toString().c_str(), matchFlags.toString().c_str());
@@ -792,7 +827,8 @@
status_t status = prepareToOpenStreamHelper(ioHandle, devicePortConfig.portId,
devicePortConfig.id, flags, source, initialConfig, cleanups, config,
mixPortConfig, patch);
- if (status != OK) {
+ if (status != OK && !(mRemoteSubmixOut.has_value() &&
+ initialConfig.base.format.type != AudioFormatType::PCM)) {
// If using the client-provided config did not work out for establishing a mix port config
// or patching, try with the device port config. Note that in general device port config and
// mix port config are not required to be the same, however they must match if the HAL
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index d5e3cf7..53d4311 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -90,6 +90,12 @@
}
}
+RetCode BundleContext::setCommon(const Parameter::Common& common) {
+ RetCode ret = EffectContext::setCommon(common);
+ RETURN_VALUE_IF(ret != RetCode::SUCCESS, ret, " setCommonFailed");
+ return init();
+}
+
RetCode BundleContext::enable() {
if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
// Bass boost or Virtualizer can be temporarily disabled if playing over device speaker due to
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index e5ab40d..d5de5bd 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -35,6 +35,8 @@
void deInit();
lvm::BundleEffectType getBundleType() const { return mType; }
+ RetCode setCommon(const Parameter::Common& common) override;
+
RetCode enable() override;
RetCode enableOperatingMode();
RetCode disable() override;
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index 116ed9a..d76ed25 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -122,6 +122,10 @@
static sp<IMediaPlayerService> sService;
Mutex mLock;
+ // Static lock was added to the client in order to consume at most
+ // one service thread from image extraction requests of the same
+ // client process(See also b/21277449).
+ static Mutex sLock;
sp<IMediaMetadataRetriever> mRetriever;
};
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 40fd022..9196f9f 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -35,6 +35,8 @@
sp<IMediaPlayerService> MediaMetadataRetriever::sService;
sp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier;
+Mutex MediaMetadataRetriever::sLock;
+
const sp<IMediaPlayerService> MediaMetadataRetriever::getService()
{
Mutex::Autolock lock(sServiceLock);
@@ -143,6 +145,7 @@
ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d) colorFormat(%d) metaOnly(%d)",
timeUs, option, colorFormat, metaOnly);
Mutex::Autolock _l(mLock);
+ Mutex::Autolock _gLock(sLock);
if (mRetriever == 0) {
ALOGE("retriever is not initialized");
return NULL;
@@ -155,6 +158,7 @@
ALOGV("getImageAtIndex: index(%d) colorFormat(%d) metaOnly(%d) thumbnail(%d)",
index, colorFormat, metaOnly, thumbnail);
Mutex::Autolock _l(mLock);
+ Mutex::Autolock _gLock(sLock);
if (mRetriever == 0) {
ALOGE("retriever is not initialized");
return NULL;
@@ -167,6 +171,7 @@
ALOGV("getImageRectAtIndex: index(%d) colorFormat(%d) rect {%d, %d, %d, %d}",
index, colorFormat, left, top, right, bottom);
Mutex::Autolock _l(mLock);
+ Mutex::Autolock _gLock(sLock);
if (mRetriever == 0) {
ALOGE("retriever is not initialized");
return NULL;
@@ -180,6 +185,7 @@
ALOGV("getFrameAtIndex: index(%d), colorFormat(%d) metaOnly(%d)",
index, colorFormat, metaOnly);
Mutex::Autolock _l(mLock);
+ Mutex::Autolock _gLock(sLock);
if (mRetriever == 0) {
ALOGE("retriever is not initialized");
return NULL;
diff --git a/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp b/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp
index cc60933..f0db018 100644
--- a/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp
+++ b/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp
@@ -50,7 +50,7 @@
// We write a length greater than the following session id array. Should be discarded.
data.writeUint32(2);
- data.writeUnpadded(kMockByteArray, 1);
+ data.write(kMockByteArray, 1);
status_t result = IMediaPlayer::asBinder(iMediaPlayer_)
->transact(PREPARE_DRM, data, &reply);
diff --git a/media/libmediametrics/MediaMetricsItem.cpp b/media/libmediametrics/MediaMetricsItem.cpp
index ecb248d..2c58461 100644
--- a/media/libmediametrics/MediaMetricsItem.cpp
+++ b/media/libmediametrics/MediaMetricsItem.cpp
@@ -334,21 +334,21 @@
// This is checked only once in the lifetime of the process.
const uid_t uid = getuid();
- switch (uid) {
- case AID_RADIO: // telephony subsystem, RIL
+ const uid_t appid = multiuser_get_app_id(uid);
+
+ if (appid == AID_RADIO) {
+ // telephony subsystem, RIL
return false;
- default:
+ }
+
+ if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
// Some isolated processes can access the audio system; see
// AudioSystem::setAudioFlingerBinder (currently only the HotwordDetectionService). Instead
// of also allowing access to the MediaMetrics service, it's simpler to just disable it for
// now.
// TODO(b/190151205): Either allow the HotwordDetectionService to access MediaMetrics or
// make this disabling specific to that process.
- uid_t appid = multiuser_get_app_id(uid);
- if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
- return false;
- }
- break;
+ return false;
}
int enabled = property_get_int32(Item::EnabledProperty, -1);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 8b50359..9abe037 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2018,6 +2018,7 @@
int32_t flags;
CHECK(buffer->meta()->findInt32("flags", &flags));
if (flags & BUFFER_FLAG_DECODE_ONLY) {
+ ALOGV("discardDecodeOnlyOutputBuffer: mPortBuffers[out][%zu] NOT owned by client", index);
info->mOwnedByClient = false;
info->mData.clear();
mBufferChannel->discardBuffer(buffer);
@@ -4497,9 +4498,16 @@
{
/* size_t index = */updateBuffers(kPortIndexInput, msg);
- if (mState == FLUSHING
- || mState == STOPPING
- || mState == RELEASING) {
+ bool inStateToReturnBuffers =
+ mState == FLUSHING || mState == STOPPING || mState == RELEASING;
+ if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+ // Late callbacks from the codec could arrive here
+ // after the codec is already stopped or released.
+ inStateToReturnBuffers = mState == FLUSHING ||
+ mState == STOPPING || mState == INITIALIZED ||
+ mState == RELEASING || mState == UNINITIALIZED;
+ }
+ if (inStateToReturnBuffers) {
returnBuffersToCodecOnPort(kPortIndexInput);
break;
}
@@ -4578,9 +4586,16 @@
/* size_t index = */updateBuffers(kPortIndexOutput, msg);
- if (mState == FLUSHING
- || mState == STOPPING
- || mState == RELEASING) {
+ bool inStateToReturnBuffers =
+ mState == FLUSHING || mState == STOPPING || mState == RELEASING;
+ if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+ // Late callbacks from the codec could arrive here
+ // after the codec is already stopped or released.
+ inStateToReturnBuffers = mState == FLUSHING ||
+ mState == STOPPING || mState == INITIALIZED ||
+ mState == RELEASING || mState == UNINITIALIZED;
+ }
+ if (inStateToReturnBuffers) {
returnBuffersToCodecOnPort(kPortIndexOutput);
break;
}
@@ -5946,7 +5961,7 @@
}
updateHdrMetrics(false /* isConfig */);
- }
+}
void MediaCodec::extractCSD(const sp<AMessage> &format) {
mCSD.clear();
@@ -6025,7 +6040,6 @@
return -EINVAL;
}
if (codecInputData->data() == NULL) {
- ALOGV("Input buffer %zu is not properly allocated", bufferIndex);
mErrorLog.log(LOG_TAG, base::StringPrintf(
"Fatal error: input buffer %zu is not properly allocated", bufferIndex));
return -EINVAL;
@@ -6071,6 +6085,10 @@
mInputFormat.clear();
mOutputFormat.clear();
+ if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+ mCSD.clear();
+ mLeftover.clear();
+ }
mFlags &= ~kFlagOutputFormatChanged;
mFlags &= ~kFlagOutputBuffersChanged;
mFlags &= ~kFlagStickyError;
@@ -6129,6 +6147,8 @@
ALOGD("port %d buffer %zu still owned by client when codec is reclaimed",
portIndex, i);
} else {
+ ALOGV("returnBuffersToCodecOnPort: mPortBuffers[%s][%zu] NOT owned by client",
+ portIndex == kPortIndexInput ? "in" : "out", i);
info->mOwnedByClient = false;
info->mData.clear();
}
@@ -6481,6 +6501,7 @@
// synchronization boundary for getBufferAndFormat
Mutex::Autolock al(mBufferLock);
+ ALOGV("onQueueInputBuffer: mPortBuffers[in][%zu] NOT owned by client", index);
info->mOwnedByClient = false;
info->mData.clear();
@@ -6497,6 +6518,7 @@
sp<AMessage> msg = mLeftover.front();
mLeftover.pop_front();
msg->setSize("index", index);
+ ALOGV("handleLeftover(%zu)", index);
return onQueueInputBuffer(msg);
}
@@ -6565,6 +6587,7 @@
sp<MediaCodecBuffer> buffer;
{
Mutex::Autolock al(mBufferLock);
+ ALOGV("onReleaseOutputBuffer: mPortBuffers[out][%zu] NOT owned by client", index);
info->mOwnedByClient = false;
buffer = info->mData;
info->mData.clear();
@@ -6677,6 +6700,8 @@
{
Mutex::Autolock al(mBufferLock);
+ ALOGV("dequeuePortBuffer: mPortBuffers[%s][%zu] checking if not owned by client",
+ portIndex == kPortIndexInput ? "in" : "out", index);
CHECK(!info->mOwnedByClient);
info->mOwnedByClient = true;
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index b7efbce..354fab0 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -85,13 +85,37 @@
// writerTest fails about 5 out of 66
// { "name": "writerTest" },
{
- "name": "BatteryChecker_test"
+ "name": "BatteryChecker_test"
},
{
"name": "ExtractorFactoryTest"
},
{
"name": "HEVCUtilsUnitTest"
+ },
+ {
+ "name": "MctsMediaDecoderTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ }
+ ]
+ },
+ {
+ "name": "MctsMediaEncoderTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ }
+ ]
+ },
+ {
+ "name": "MctsMediaCodecTestCases",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ }
+ ]
}
]
}
diff --git a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
index 8817621..64fdfb9 100644
--- a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
+++ b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
@@ -115,7 +115,6 @@
Returns:
L_sum = 32-bit sum of L_var1 and L_var2 (Word32)
*/
- __attribute__((no_sanitize("integer")))
static inline Word32 L_add(Word32 L_var1, Word32 L_var2, Flag *pOverflow)
{
Word32 L_sum;
@@ -454,7 +453,8 @@
{
Word32 result;
- result = L_var3 + L_var1 * L_var2;
+ __builtin_mul_overflow(L_var1, L_var2, &result);
+ __builtin_add_overflow(L_var3, result, &result);
return result;
}
@@ -463,7 +463,8 @@
{
Word32 result;
- result = L_var3 - L_var1 * L_var2;
+ __builtin_mul_overflow(L_var1, L_var2, &result);
+ __builtin_sub_overflow(L_var3, result, &result);
return result;
}
diff --git a/media/module/codecs/amrnb/common/src/az_lsp.cpp b/media/module/codecs/amrnb/common/src/az_lsp.cpp
index f3098f5..a19ddbf 100644
--- a/media/module/codecs/amrnb/common/src/az_lsp.cpp
+++ b/media/module/codecs/amrnb/common/src/az_lsp.cpp
@@ -237,9 +237,6 @@
------------------------------------------------------------------------------
*/
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
static Word16 Chebps(Word16 x,
Word16 f[], /* (n) */
Word16 n,
diff --git a/media/module/codecs/amrnb/common/src/l_abs.cpp b/media/module/codecs/amrnb/common/src/l_abs.cpp
index 7e0ae99..b13a40a 100644
--- a/media/module/codecs/amrnb/common/src/l_abs.cpp
+++ b/media/module/codecs/amrnb/common/src/l_abs.cpp
@@ -186,8 +186,12 @@
; Function body here
----------------------------------------------------------------------------*/
- Word32 y = L_var1 - (L_var1 < 0);
- y = y ^(y >> 31);
- return (y);
+ if (L_var1 >= 0) return L_var1;
+ if (L_var1 != 0x80000000) return -L_var1;
+ // abs(0x80000000) can not be represented in Word32.
+ // we choose to return the closest value we can -- 0x7fffffff
+ // This is acceptable because it keeps the result within the valid 32-bit signed integer range,
+ // consistent with other overflow handling in the code. such as amrnb/enc/src/l_negate.cpp.
+ return 0x7FFFFFFF;
}
diff --git a/media/module/codecs/amrnb/common/src/lsp_az.cpp b/media/module/codecs/amrnb/common/src/lsp_az.cpp
index 495359f..bb8a34d 100644
--- a/media/module/codecs/amrnb/common/src/lsp_az.cpp
+++ b/media/module/codecs/amrnb/common/src/lsp_az.cpp
@@ -281,8 +281,8 @@
t0 += ((Word32)lo * *lsp) >> 15;
*(f) += *(f - 2); /* *f += f[-2] */
- *(f--) -= t0 << 2; /* *f -= t0 */
-
+ __builtin_sub_overflow(*(f), (t0 << 2), f); /* *f -= t0 */
+ f--;
}
*f -= (Word32)(*lsp++) << 10;
diff --git a/media/module/codecs/amrnb/common/src/norm_l.cpp b/media/module/codecs/amrnb/common/src/norm_l.cpp
index d8d1259..b24ebda 100644
--- a/media/module/codecs/amrnb/common/src/norm_l.cpp
+++ b/media/module/codecs/amrnb/common/src/norm_l.cpp
@@ -211,8 +211,7 @@
if (L_var1)
{
- Word32 y = L_var1 - (L_var1 < 0);
- L_var1 = y ^(y >> 31);
+ L_var1 = L_abs(L_var1);
while (!(0x40000000L & L_var1))
diff --git a/media/module/codecs/amrnb/common/src/residu.cpp b/media/module/codecs/amrnb/common/src/residu.cpp
index 2ad132f..9b077e2 100644
--- a/media/module/codecs/amrnb/common/src/residu.cpp
+++ b/media/module/codecs/amrnb/common/src/residu.cpp
@@ -227,22 +227,35 @@
p_input3 = p_input_ptr--;
p_input4 = p_input_ptr--;
+ Word32 tmp;
for (j = M >> 1; j != 0; j--)
{
- s1 += ((Word32) * (p_coef) * *(p_input1++));
- s2 += ((Word32) * (p_coef) * *(p_input2++));
- s3 += ((Word32) * (p_coef) * *(p_input3++));
- s4 += ((Word32) * (p_coef--) * *(p_input4++));
- s1 += ((Word32) * (p_coef) * *(p_input1++));
- s2 += ((Word32) * (p_coef) * *(p_input2++));
- s3 += ((Word32) * (p_coef) * *(p_input3++));
- s4 += ((Word32) * (p_coef--) * *(p_input4++));
+ __builtin_mul_overflow(*p_coef, *(p_input1++), &tmp);
+ __builtin_add_overflow(s1, tmp, &s1);
+ __builtin_mul_overflow(*p_coef, *(p_input2++), &tmp);
+ __builtin_add_overflow(s2, tmp, &s2);
+ __builtin_mul_overflow(*p_coef, *(p_input3++), &tmp);
+ __builtin_add_overflow(s3, tmp, &s3);
+ __builtin_mul_overflow(*(p_coef--), *(p_input4++), &tmp);
+ __builtin_add_overflow(s4, tmp, &s4);
+ __builtin_mul_overflow(*p_coef, *(p_input1++), &tmp);
+ __builtin_add_overflow(s1, tmp, &s1);
+ __builtin_mul_overflow(*p_coef, *(p_input2++), &tmp);
+ __builtin_add_overflow(s2, tmp, &s2);
+ __builtin_mul_overflow(*p_coef, *(p_input3++), &tmp);
+ __builtin_add_overflow(s3, tmp, &s3);
+ __builtin_mul_overflow(*(p_coef--), *(p_input4++), &tmp);
+ __builtin_add_overflow(s4, tmp, &s4);
}
- s1 += (((Word32) * (p_coef)) * *(p_input1));
- s2 += (((Word32) * (p_coef)) * *(p_input2));
- s3 += (((Word32) * (p_coef)) * *(p_input3));
- s4 += (((Word32) * (p_coef)) * *(p_input4));
+ __builtin_mul_overflow(*p_coef, *(p_input1), &tmp);
+ __builtin_add_overflow(s1, tmp, &s1);
+ __builtin_mul_overflow(*p_coef, *(p_input2), &tmp);
+ __builtin_add_overflow(s2, tmp, &s2);
+ __builtin_mul_overflow(*p_coef, *(p_input3), &tmp);
+ __builtin_add_overflow(s3, tmp, &s3);
+ __builtin_mul_overflow(*p_coef, *(p_input4), &tmp);
+ __builtin_add_overflow(s4, tmp, &s4);
*(p_residual_ptr--) = (Word16)(s1 >> 12);
*(p_residual_ptr--) = (Word16)(s2 >> 12);
diff --git a/media/module/codecs/amrnb/common/src/sub.cpp b/media/module/codecs/amrnb/common/src/sub.cpp
index b956912..d936128 100644
--- a/media/module/codecs/amrnb/common/src/sub.cpp
+++ b/media/module/codecs/amrnb/common/src/sub.cpp
@@ -187,9 +187,6 @@
; FUNCTION CODE
----------------------------------------------------------------------------*/
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
Word16 sub(Word16 var1, Word16 var2, Flag *pOverflow)
{
diff --git a/media/module/codecs/amrnb/common/src/syn_filt.cpp b/media/module/codecs/amrnb/common/src/syn_filt.cpp
index 36c1d84..82770f1 100644
--- a/media/module/codecs/amrnb/common/src/syn_filt.cpp
+++ b/media/module/codecs/amrnb/common/src/syn_filt.cpp
@@ -245,9 +245,6 @@
------------------------------------------------------------------------------
*/
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
void Syn_filt(
Word16 a[], /* (i) : a[M+1] prediction coefficients (M=10) */
Word16 x[], /* (i) : input signal */
diff --git a/media/module/codecs/amrnb/enc/src/autocorr.cpp b/media/module/codecs/amrnb/enc/src/autocorr.cpp
index c71811d..a078f5a 100644
--- a/media/module/codecs/amrnb/enc/src/autocorr.cpp
+++ b/media/module/codecs/amrnb/enc/src/autocorr.cpp
@@ -312,6 +312,7 @@
Word16 y[L_WINDOW];
Word32 sum;
+ Word32 mul;
Word16 overfl_shft;
@@ -343,7 +344,8 @@
temp = (amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15;
*(p_y++) = temp;
- sum += ((Word32)temp * temp) << 1;
+ __builtin_mul_overflow(temp, temp, &mul);
+ __builtin_add_overflow(sum, mul << 1, &sum);
if (sum < 0)
{
/*
@@ -395,10 +397,12 @@
{
temp = *p_y >> 2;
*(p_y++) = temp;
- sum += ((Word32)temp * temp) << 1;
+ __builtin_mul_overflow(temp, temp, &mul);
+ __builtin_add_overflow(sum, mul << 1, &sum);
temp = *p_y >> 2;
*(p_y++) = temp;
- sum += ((Word32)temp * temp) << 1;
+ __builtin_mul_overflow(temp, temp, &mul);
+ __builtin_add_overflow(sum, mul << 1, &sum);
}
if (sum > 0)
{
diff --git a/media/module/codecs/amrnb/enc/src/c2_9pf.cpp b/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
index b211032..56b4fb8 100644
--- a/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
@@ -610,6 +610,7 @@
Word32 alp1;
Word16 i;
Word32 L_temp;
+ Word32 mul;
Word16 *p_codvec = &codvec[0];
OSCL_UNUSED_ARG(pOverflow);
@@ -693,7 +694,8 @@
L_temp = ((Word32) alp * sq1) << 1;
/* s = L_msu(L_temp, sq, alp_16, pOverflow); */
- s = L_temp - (((Word32) sq * alp_16) << 1);
+ __builtin_mul_overflow(sq, alp_16, &mul);
+ __builtin_sub_overflow(L_temp, (mul << 1), &s);
if (s > 0)
{
diff --git a/media/module/codecs/amrnb/enc/src/c3_14pf.cpp b/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
index 58ab2fa..bb4fe36 100644
--- a/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
@@ -403,6 +403,7 @@
Word16 *p_codvec = &codvec[0];
Word32 s;
+ Word32 mul;
Word32 alp0;
Word32 alp1;
@@ -487,7 +488,8 @@
s = ((Word32) alp * sq1) << 1;
/* s = L_msu(s, sq, alp_16, pOverflow); */
- s -= (((Word32) sq * alp_16) << 1);
+ __builtin_mul_overflow(sq, alp_16, &mul);
+ __builtin_sub_overflow(s, (mul << 1), &s);
if (s > 0)
{
diff --git a/media/module/codecs/amrnb/enc/src/c4_17pf.cpp b/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
index d52b43b..062ee5a 100644
--- a/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
@@ -416,6 +416,7 @@
Word16 *p_codvec = &codvec[0];
Word32 s;
+ Word32 mul;
Word32 alp0;
Word32 alp1;
@@ -497,7 +498,8 @@
s = ((Word32) alp * sq1) << 1;
/* s = L_msu(s, sq, alp_16, pOverflow); */
- s -= (((Word32) sq * alp_16) << 1);
+ __builtin_mul_overflow(sq, alp_16, &mul);
+ __builtin_sub_overflow(s, (mul << 1), &s);
if (s > 0)
{
@@ -610,7 +612,8 @@
s = ((Word32) alp * sq1) << 1;
/* s = L_msu(s, sq, alp_16, pOverflow); */
- s -= (((Word32) sq * alp_16) << 1);
+ __builtin_mul_overflow(sq, alp_16, &mul);
+ __builtin_sub_overflow(s, (mul << 1), &s);
if (s > 0)
{
@@ -630,7 +633,8 @@
s = ((Word32) alpk * sq) << 1;
/* s = L_msu(s, psk, alp, pOverflow); */
- s -= (((Word32) psk * alp) << 1);
+ __builtin_mul_overflow(psk, alp, &mul);
+ __builtin_sub_overflow(s, (mul << 1), &s);
if (s > 0)
{
diff --git a/media/module/codecs/amrnb/enc/src/cor_h_x.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
index c25c026..398c71f 100644
--- a/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
+++ b/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
@@ -254,6 +254,7 @@
Word16 k;
Word32 s;
+ Word32 mul;
Word32 y32[L_CODE];
Word32 max;
Word32 tot;
@@ -275,15 +276,19 @@
for (j = (L_CODE - i - 1) >> 1; j != 0; j--)
{
- s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
- s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
+ __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+ __builtin_add_overflow(s, mul << 1, &s);
+ __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+ __builtin_add_overflow(s, mul << 1, &s);
}
- s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
+ __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+ __builtin_add_overflow(s, mul << 1, &s);
if (!((L_CODE - i) & 1)) /* if even number of iterations */
{
- s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
+ __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+ __builtin_add_overflow(s, mul << 1, &s);
}
y32[i] = s;
@@ -299,7 +304,7 @@
}
}
- tot += (max >> 1);
+ __builtin_add_overflow(tot, (max >> 1), &tot);
}
@@ -310,10 +315,13 @@
for (i = L_CODE >> 1; i != 0; i--)
{
+ Word32 result;
s = L_shl(*(p_y32++), j, pOverflow);
- *(p_ptr++) = (s + 0x00008000) >> 16;
+ __builtin_add_overflow(s, 0x00008000, &result);
+ *(p_ptr++) = result >> 16;
s = L_shl(*(p_y32++), j, pOverflow);
- *(p_ptr++) = (s + 0x00008000) >> 16;
+ __builtin_add_overflow(s, 0x00008000, &result);
+ *(p_ptr++) = result >> 16;
}
return;
diff --git a/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
index e32eb4a..80ebb73 100644
--- a/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
+++ b/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
@@ -268,7 +268,7 @@
max = s;
}
}
- tot = (tot + (max >> 1));
+ __builtin_add_overflow(tot, (max >> 1), &tot);
}
j = sub(norm_l(tot), sf, pOverflow);
diff --git a/media/module/codecs/amrnb/enc/src/dtx_enc.cpp b/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
index 2ccb777..0d56c9b 100644
--- a/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
+++ b/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
@@ -945,6 +945,7 @@
Word16 i;
Word32 L_frame_en;
+ Word32 mul;
Word32 L_temp;
Word16 log_en_e;
Word16 log_en_m;
@@ -967,7 +968,8 @@
for (i = L_FRAME; i != 0; i--)
{
- L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1;
+ __builtin_mul_overflow(*p_speech, *p_speech, &mul);
+ __builtin_add_overflow(L_frame_en, mul << 1, &L_frame_en);
p_speech++;
if (L_frame_en < 0)
{
diff --git a/media/module/codecs/amrnb/enc/src/levinson.cpp b/media/module/codecs/amrnb/enc/src/levinson.cpp
index 29cdac6..83dd81e 100644
--- a/media/module/codecs/amrnb/enc/src/levinson.cpp
+++ b/media/module/codecs/amrnb/enc/src/levinson.cpp
@@ -731,7 +731,7 @@
t0 = t0 << 5;
t1 = ((Word32) * (Rh + i) << 16) + ((Word32)(*(Rl + i)) << 1);
- t0 += t1;
+ __builtin_add_overflow(t0, t1, &t0);
/* K = -t0 / Alpha */
diff --git a/media/module/codecs/amrnb/enc/src/pitch_fr.cpp b/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
index 584f79b..ab0a221 100644
--- a/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
+++ b/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
@@ -326,6 +326,7 @@
Word16 norm_h;
Word16 norm_l;
Word32 s;
+ Word32 mul;
Word32 s2;
Word16 excf[L_SUBFR];
Word16 scaling;
@@ -353,10 +354,12 @@
{
temp = *(p_excf++);
*(p_s_excf++) = temp >> 2;
- s += (Word32) temp * temp;
+ __builtin_mul_overflow(temp, temp, &mul);
+ __builtin_add_overflow(s, mul, &s);
temp = *(p_excf++);
*(p_s_excf++) = temp >> 2;
- s += (Word32) temp * temp;
+ __builtin_mul_overflow(temp, temp, &mul);
+ __builtin_add_overflow(s, mul, &s);
}
@@ -387,20 +390,24 @@
while (j--)
{
- s += (Word32) * (p_x++) * *(p_s_excf);
- s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
+ __builtin_mul_overflow(*(p_x++), *p_s_excf, &mul);
+ __builtin_add_overflow(s, mul, &s);
+ __builtin_mul_overflow(*p_s_excf, *p_s_excf, &mul);
+ __builtin_add_overflow(s2, mul, &s2);
p_s_excf++;
- s += (Word32) * (p_x++) * *(p_s_excf);
- s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
+ __builtin_mul_overflow(*(p_x++), *p_s_excf, &mul);
+ __builtin_add_overflow(s, mul, &s);
+ __builtin_mul_overflow(*p_s_excf, *p_s_excf, &mul);
+ __builtin_add_overflow(s2, mul, &s2);
p_s_excf++;
}
s2 = s2 << 1;
s2 = Inv_sqrt(s2, pOverflow);
norm_h = (Word16)(s2 >> 16);
- norm_l = (Word16)((s2 >> 1) - (norm_h << 15));
+ __builtin_sub_overflow((s2 >> 1), (norm_h << 15), &norm_l);
corr_h = (Word16)(s >> 15);
- corr_l = (Word16)((s) - (corr_h << 15));
+ __builtin_sub_overflow(s, (corr_h << 15), &corr_l);
/* Normalize correlation = correlation * (1/sqrt(energy)) */
diff --git a/media/module/codecs/amrnb/enc/src/pitch_ol.cpp b/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
index c039bb0..0e4b74b 100644
--- a/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
+++ b/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
@@ -959,6 +959,7 @@
Word16 p_max3;
Word16 scal_flag = 0;
Word32 t0;
+ Word32 mul;
#ifdef VAD2
Word32 r01;
@@ -1002,7 +1003,8 @@
for (i = -pit_max; i < L_frame; i++)
{
- t0 += (((Word32) * (p_signal)) * *(p_signal)) << 1;
+ __builtin_mul_overflow(*p_signal, *p_signal, &mul);
+ __builtin_add_overflow(t0, mul << 1, &t0);
p_signal++;
if (t0 < 0)
{
diff --git a/media/module/codecs/amrnb/enc/src/pre_proc.cpp b/media/module/codecs/amrnb/enc/src/pre_proc.cpp
index 042920e..0e2be41 100644
--- a/media/module/codecs/amrnb/enc/src/pre_proc.cpp
+++ b/media/module/codecs/amrnb/enc/src/pre_proc.cpp
@@ -576,7 +576,7 @@
*(p_signal++) = (Word16)((L_tmp + 0x0000800L) >> 12);
st->y1_hi = (Word16)(L_tmp >> 12);
- st->y1_lo = (Word16)((L_tmp << 3) - ((Word32)(st->y1_hi) << 15));
+ __builtin_sub_overflow((Word16)(L_tmp << 3), (st->y1_hi) << 15, &st->y1_lo);
}
diff --git a/media/module/codecs/amrnb/enc/src/s10_8pf.cpp b/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
index 352b611..97d0318 100644
--- a/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
@@ -746,11 +746,13 @@
for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
{
- ps2 = ps1 + *(p_temp1++);
+ __builtin_add_overflow(ps1, *(p_temp1++), &ps2);
- alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
+ __builtin_add_overflow(alp1, *(p_temp2 + i5) << 12, &alp2);
- alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
+ Word32 result;
+ __builtin_add_overflow(alp2, *(p_temp1++) << 14, &result);
+ alp_16 = (Word16)(result >> 16);
sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
diff --git a/media/module/codecs/amrnb/enc/src/set_sign.cpp b/media/module/codecs/amrnb/enc/src/set_sign.cpp
index fa43f78..55658a4 100644
--- a/media/module/codecs/amrnb/enc/src/set_sign.cpp
+++ b/media/module/codecs/amrnb/enc/src/set_sign.cpp
@@ -505,6 +505,7 @@
Word16 en[L_CODE]; /* correlation vector */
Word32 s;
Word32 t;
+ Word32 mul;
Word32 L_temp;
Word16 *p_cn;
Word16 *p_dn;
@@ -525,7 +526,8 @@
val = *(p_cn++);
s = L_mac(s, val, val, pOverflow);
val = *(p_dn++);
- t += ((Word32) val * val) << 1;
+ __builtin_mul_overflow(val, val, &mul);
+ __builtin_add_overflow(t, mul << 1, &t);
}
s = Inv_sqrt(s, pOverflow);
k_cn = (Word16)((L_shl(s, 5, pOverflow)) >> 16);
diff --git a/media/module/codecs/amrnb/enc/src/spstproc.cpp b/media/module/codecs/amrnb/enc/src/spstproc.cpp
index b9574aa..5210a39 100644
--- a/media/module/codecs/amrnb/enc/src/spstproc.cpp
+++ b/media/module/codecs/amrnb/enc/src/spstproc.cpp
@@ -192,6 +192,7 @@
Word16 i;
Word16 j;
Word16 temp;
+ Word32 mul;
Word32 L_temp;
Word32 L_temp2;
Word16 tempShift;
@@ -262,8 +263,10 @@
*/
L_temp = ((Word32) * (p_exc++) * pitch_fac) << 1;
L_temp2 = ((Word32) * (p_exc--) * pitch_fac) << 1;
- L_temp += ((Word32) * (p_code++) * gain_code) << 1;
- L_temp2 += ((Word32) * (p_code++) * gain_code) << 1;
+ __builtin_mul_overflow(*(p_code++), gain_code, &mul);
+ __builtin_add_overflow(L_temp, mul << 1, &L_temp);
+ __builtin_mul_overflow(*(p_code++), gain_code, &mul);
+ __builtin_add_overflow(L_temp2, mul << 1, &L_temp2);
L_temp <<= tempShift;
L_temp2 <<= tempShift;
*(p_exc++) = (Word16)((L_temp + 0x08000L) >> 16);
diff --git a/media/module/codecs/amrwb/enc/src/az_isp.c b/media/module/codecs/amrwb/enc/src/az_isp.c
index d7074f0..22a5c25 100644
--- a/media/module/codecs/amrwb/enc/src/az_isp.c
+++ b/media/module/codecs/amrwb/enc/src/az_isp.c
@@ -248,10 +248,10 @@
b1_h = b0_h;
}
- t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
- t0 += (b2_h * (-32768))<<1; /* t0 = x*b1 - b2 */
- t0 -= (b2_l << 1);
- t0 += (f[n] << 12); /* t0 = x*b1 - b2 + f[i]/2 */
+ __builtin_add_overflow(((b1_h * x)<<1), (((b1_l * x)>>15)<<1), &t0);
+ __builtin_add_overflow(t0, (b2_h * (-32768))<<1, &t0); /* t0 = x*b1 - b2 */
+ __builtin_sub_overflow(t0, (b2_l << 1), &t0);
+ __builtin_add_overflow(t0, (f[n] << 12), &t0); /* t0 = x*b1 - b2 + f[i]/2 */
t0 = L_shl2(t0, 6); /* Q24 to Q30 with saturation */
diff --git a/media/module/codecs/amrwb/enc/src/syn_filt.c b/media/module/codecs/amrwb/enc/src/syn_filt.c
index 7eba12f..40398f5 100644
--- a/media/module/codecs/amrwb/enc/src/syn_filt.c
+++ b/media/module/codecs/amrwb/enc/src/syn_filt.c
@@ -109,38 +109,38 @@
p2 = &sig_lo[i - 1];
p3 = &sig_hi[i - 1];
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
- L_tmp -= vo_mult32((*p2--), (*p1));
- L_tmp1 -= vo_mult32((*p3--), (*p1++));
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+ __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+ __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
L_tmp = L_tmp >> 11;
L_tmp += vo_L_mult(exc[i], a0);
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 4e6492f..e13f8f7 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -18,7 +18,6 @@
#define LOG_TAG "ServiceUtilities"
#include <audio_utils/clock.h>
-#include <android-base/properties.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -29,11 +28,9 @@
#include <media/AidlConversionUtil.h>
#include <android/content/AttributionSourceState.h>
-#include <algorithm>
#include <iterator>
-#include <mutex>
+#include <algorithm>
#include <pwd.h>
-#include <thread>
/* When performing permission checks we do not use permission cache for
* runtime permissions (protection level dangerous) as they may change at
@@ -399,106 +396,6 @@
return NO_ERROR;
}
-// TODO(b/285588444), clean this up on main, but soak it for backporting purposes for now
-namespace {
-class BluetoothPermissionCache {
- static constexpr auto SYSPROP_NAME = "cache_key.system_server.package_info";
- const String16 BLUETOOTH_PERM {"android.permission.BLUETOOTH_CONNECT"};
- mutable std::mutex mLock;
- // Cached property conditionally defined, since only avail on bionic. On host, don't inval cache
-#if defined(__BIONIC__)
- // Unlocked, but only accessed from mListenerThread
- base::CachedProperty mCachedProperty;
-#endif
- // This thread is designed to never join/terminate, so no signal is fine
- const std::thread mListenerThread;
- GUARDED_BY(mLock)
- std::string mPropValue;
- GUARDED_BY(mLock)
- std::unordered_map<uid_t, bool> mCache;
- PermissionController mPc{};
-public:
- BluetoothPermissionCache()
-#if defined(__BIONIC__)
- : mCachedProperty{SYSPROP_NAME},
- mListenerThread([this]() mutable {
- while (true) {
- std::string newVal = mCachedProperty.WaitForChange() ?: "";
- std::lock_guard l{mLock};
- if (newVal != mPropValue) {
- ALOGV("Bluetooth permission update");
- mPropValue = newVal;
- mCache.clear();
- }
- }
- })
-#endif
- {}
-
- bool checkPermission(uid_t uid, pid_t pid) {
- std::lock_guard l{mLock};
- auto it = mCache.find(uid);
- if (it == mCache.end()) {
- it = mCache.insert({uid, mPc.checkPermission(BLUETOOTH_PERM, uid, pid)}).first;
- }
- return it->second;
- }
-};
-
-// Don't call this from locks, since it potentially calls up to system server!
-// Check for non-app UIDs above this method!
-bool checkBluetoothPermission(const AttributionSourceState& attr) {
- [[clang::no_destroy]] static BluetoothPermissionCache impl{};
- return impl.checkPermission(attr.uid, attr.pid);
-}
-} // anonymous
-
-/**
- * Determines if the MAC address in Bluetooth device descriptors returned by APIs of
- * a native audio service (audio flinger, audio policy) must be anonymized.
- * MAC addresses returned to system server or apps with BLUETOOTH_CONNECT permission
- * are not anonymized.
- *
- * @param attributionSource The attribution source of the calling app.
- * @param caller string identifying the caller for logging.
- * @return true if the MAC addresses must be anonymized, false otherwise.
- */
-bool mustAnonymizeBluetoothAddress(
- const AttributionSourceState& attributionSource, const String16&) {
- uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
- bool res;
- switch(multiuser_get_app_id(uid)) {
- case AID_ROOT:
- case AID_SYSTEM:
- case AID_RADIO:
- case AID_BLUETOOTH:
- case AID_MEDIA:
- case AID_AUDIOSERVER:
- // Don't anonymize for privileged clients
- res = false;
- break;
- default:
- res = !checkBluetoothPermission(attributionSource);
- break;
- }
- ALOGV("%s uid: %d, result: %d", __func__, uid, res);
- return res;
-}
-
-/**
- * Modifies the passed MAC address string in place for consumption by unprivileged clients.
- * the string is assumed to have a valid MAC address format.
- * the anonymization must be kept in sync with toAnonymizedAddress() in BluetoothUtils.java
- *
- * @param address input/output the char string contining the MAC address to anonymize.
- */
-void anonymizeBluetoothAddress(char *address) {
- if (address == nullptr || strlen(address) != strlen("AA:BB:CC:DD:EE:FF")) {
- return;
- }
- memcpy(address, "XX:XX:XX:XX", strlen("XX:XX:XX:XX"));
-}
-
sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() {
const sp<IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) {
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 461e190..2631469 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -114,10 +114,6 @@
bool bypassInterruptionPolicyAllowed(const AttributionSourceState& attributionSource);
bool callAudioInterceptionAllowed(const AttributionSourceState& attributionSource);
void purgePermissionCache();
-bool mustAnonymizeBluetoothAddress(
- const AttributionSourceState& attributionSource, const String16& caller);
-void anonymizeBluetoothAddress(char *address);
-
int32_t getOpForSource(audio_source_t source);
AttributionSourceState getCallingAttributionSource();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b9dbbad..0d5d61f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3055,7 +3055,7 @@
audio_config_base_t *mixerConfig,
audio_devices_t deviceType,
const String8& address,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
const audio_attributes_t attributes)
{
AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType);
@@ -3090,7 +3090,7 @@
mHardwareStatus = AUDIO_HW_IDLE;
if (status == NO_ERROR) {
- if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
+ if (*flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
const sp<IAfMmapPlaybackThread> thread = IAfMmapPlaybackThread::create(
this, *output, outHwDev, outputStream, mSystemReady);
mMmapThreads.add(*output, thread);
@@ -3099,22 +3099,22 @@
return thread;
} else {
sp<IAfPlaybackThread> thread;
- if (flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
+ if (*flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
thread = IAfPlaybackThread::createBitPerfectThread(
this, outputStream, *output, mSystemReady);
ALOGV("%s() created bit-perfect output: ID %d thread %p",
__func__, *output, thread.get());
- } else if (flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
+ } else if (*flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
thread = IAfPlaybackThread::createSpatializerThread(this, outputStream, *output,
mSystemReady, mixerConfig);
ALOGV("openOutput_l() created spatializer output: ID %d thread %p",
*output, thread.get());
- } else if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+ } else if (*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
thread = IAfPlaybackThread::createOffloadThread(this, outputStream, *output,
mSystemReady, halConfig->offload_info);
ALOGV("openOutput_l() created offload output: ID %d thread %p",
*output, thread.get());
- } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
+ } else if ((*flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !IAfThreadBase::isValidPcmSinkFormat(halConfig->format)
|| !IAfThreadBase::isValidPcmSinkChannelMask(halConfig->channel_mask)) {
thread = IAfPlaybackThread::createDirectOutputThread(this, outputStream, *output,
@@ -3178,7 +3178,7 @@
audio_utils::lock_guard _l(mutex());
const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
- &mixerConfig, deviceType, address, flags, attributes);
+ &mixerConfig, deviceType, address, &flags, attributes);
if (thread != 0) {
uint32_t latencyMs = 0;
if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2bc18ee..ace74ee 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -337,7 +337,7 @@
audio_config_base_t* mixerConfig,
audio_devices_t deviceType,
const String8& address,
- audio_output_flags_t flags,
+ audio_output_flags_t* flags,
audio_attributes_t attributes) final REQUIRES(mutex());
const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
getAudioHwDevs_l() const final REQUIRES(mutex(), hardwareMutex()) {
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
index 37dce3a..15b6ddf 100644
--- a/services/audioflinger/IAfPatchPanel.h
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -82,7 +82,7 @@
audio_config_base_t* mixerConfig,
audio_devices_t deviceType,
const String8& address,
- audio_output_flags_t flags,
+ audio_output_flags_t* flags,
audio_attributes_t attributes) REQUIRES(mutex()) = 0;
virtual audio_utils::mutex& mutex() const
RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 02d4fc2..d0b96de 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -268,7 +268,7 @@
&mixerConfig,
outputDevice,
outputDeviceAddress,
- flags,
+ &flags,
attributes);
ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
if (thread == 0) {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index eedf560..cca09d1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3254,9 +3254,9 @@
// Calculate size of normal sink buffer relative to the HAL output buffer size
double multiplier = 1.0;
- // Note: mType == SPATIALIZER does not support FastMixer.
- if (mType == MIXER && (kUseFastMixer == FastMixer_Static ||
- kUseFastMixer == FastMixer_Dynamic)) {
+ // Note: mType == SPATIALIZER does not support FastMixer and DEEP is by definition not "fast"
+ if ((mType == MIXER && !(mOutput->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) &&
+ (kUseFastMixer == FastMixer_Static || kUseFastMixer == FastMixer_Dynamic)) {
size_t minNormalFrameCount = (kMinNormalSinkBufferSizeMs * mSampleRate) / 1000;
size_t maxNormalFrameCount = (kMaxNormalSinkBufferSizeMs * mSampleRate) / 1000;
@@ -5191,7 +5191,16 @@
break;
case FastMixer_Static:
case FastMixer_Dynamic:
- initFastMixer = mFrameCount < mNormalFrameCount;
+ if (mType == MIXER && (output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
+ /* Do not init fast mixer on deep buffer, warn if buffers are confed too small */
+ initFastMixer = false;
+ ALOGW_IF(mFrameCount * 1000 / mSampleRate < kMinNormalSinkBufferSizeMs,
+ "HAL DEEP BUFFER Buffer (%zu ms) is smaller than set minimal buffer "
+ "(%u ms), seems like a configuration error",
+ mFrameCount * 1000 / mSampleRate, kMinNormalSinkBufferSizeMs);
+ } else {
+ initFastMixer = mFrameCount < mNormalFrameCount;
+ }
break;
}
ALOGW_IF(initFastMixer == false && mFrameCount < mNormalFrameCount,
@@ -5280,7 +5289,10 @@
mFastMixerNBLogWriter = afThreadCallback->newWriter_l(kFastMixerLogSize, "FastMixer");
state->mNBLogWriter = mFastMixerNBLogWriter.get();
sq->end();
- sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+ {
+ audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+ sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+ }
NBLog::thread_info_t info;
info.id = mId;
@@ -5339,8 +5351,11 @@
}
state->mCommand = FastMixerState::EXIT;
sq->end();
- sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
- mFastMixer->join();
+ {
+ audio_utils::mutex::scoped_join_wait_check queueWaitCheck(mFastMixer->getTid());
+ sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+ mFastMixer->join();
+ }
// Though the fast mixer thread has exited, it's state queue is still valid.
// We'll use that extract the final state which contains one remaining fast track
// corresponding to our sub-mix.
@@ -5420,7 +5435,10 @@
FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN);
#endif
sq->end();
- sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+ {
+ audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+ sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+ }
if (kUseFastMixer == FastMixer_Dynamic) {
mNormalSink = mPipeSink;
}
@@ -5453,7 +5471,10 @@
mFastMixerFutex = 0;
sq->end();
// BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now
- sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
+ {
+ audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+ sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
+ }
if (kUseFastMixer == FastMixer_Dynamic) {
mNormalSink = mOutputSink;
}
@@ -6349,7 +6370,10 @@
//
// This occurs with BT suspend when we idle the FastMixer with
// active tracks, which may be added or removed.
- sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block);
+ {
+ audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+ sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block);
+ }
}
#ifdef AUDIO_WATCHDOG
if (pauseAudioWatchdog && mAudioWatchdog != 0) {
@@ -7308,11 +7332,14 @@
{
PlaybackThread::flushHw_l();
mOutput->flush();
- mHwPaused = false;
mFlushPending = false;
mTimestampVerifier.discontinuity(discontinuityForStandbyOrFlush());
mTimestamp.clear();
mMonotonicFrameCounter.onFlush();
+ // We do not reset mHwPaused which is hidden from the Track client.
+ // Note: the client track in Tracks.cpp and AudioTrack.cpp
+ // has a FLUSHED state but the DirectOutputThread does not;
+ // those tracks will continue to show isStopped().
}
int64_t DirectOutputThread::computeWaitTimeNs_l() const {
@@ -8322,8 +8349,10 @@
afThreadCallback->newWriter_l(kFastCaptureLogSize, "FastCapture");
state->mNBLogWriter = mFastCaptureNBLogWriter.get();
sq->end();
- sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
-
+ {
+ audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastCapture->getTid());
+ sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
+ }
// start the fast capture
mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO);
pid_t tid = mFastCapture->getTid();
@@ -8357,8 +8386,11 @@
}
state->mCommand = FastCaptureState::EXIT;
sq->end();
- sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
- mFastCapture->join();
+ {
+ audio_utils::mutex::scoped_join_wait_check queueWaitCheck(mFastCapture->getTid());
+ sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
+ mFastCapture->join();
+ }
mFastCapture.clear();
}
mAfThreadCallback->unregisterWriter(mFastCaptureNBLogWriter);
@@ -8991,7 +9023,11 @@
mFastCaptureFutex = 0;
sq->end();
// BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now
- sq->push(FastCaptureStateQueue::BLOCK_UNTIL_ACKED);
+ {
+ audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastCapture->getTid());
+ sq->push(FastCaptureStateQueue::BLOCK_UNTIL_ACKED);
+ }
+
#if 0
if (kUseFastCapture == FastCapture_Dynamic) {
// FIXME
diff --git a/services/audioflinger/datapath/AudioHwDevice.cpp b/services/audioflinger/datapath/AudioHwDevice.cpp
index 5314e9e..c2e538c 100644
--- a/services/audioflinger/datapath/AudioHwDevice.cpp
+++ b/services/audioflinger/datapath/AudioHwDevice.cpp
@@ -41,19 +41,20 @@
AudioStreamOut **ppStreamOut,
audio_io_handle_t handle,
audio_devices_t deviceType,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
struct audio_config *config,
const char *address,
const std::vector<playback_track_metadata_v7_t>& sourceMetadata)
{
struct audio_config originalConfig = *config;
- auto outputStream = new AudioStreamOut(this, flags);
+ auto outputStream = new AudioStreamOut(this);
// Try to open the HAL first using the current format.
ALOGV("openOutputStream(), try sampleRate %d, format %#x, channelMask %#x", config->sample_rate,
config->format, config->channel_mask);
- status_t status = outputStream->open(handle, deviceType, config, address, sourceMetadata);
+ status_t status = outputStream->open(handle, deviceType, config, flags, address,
+ sourceMetadata);
if (status != NO_ERROR) {
delete outputStream;
@@ -67,19 +68,25 @@
// If the data is encoded then try again using wrapped PCM.
const bool wrapperNeeded = !audio_has_proportional_frames(originalConfig.format)
- && ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)
- && ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0);
+ && ((*flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)
+ && ((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0);
if (wrapperNeeded) {
if (SPDIFEncoder::isFormatSupported(originalConfig.format)) {
- outputStream = new SpdifStreamOut(this, flags, originalConfig.format);
- status = outputStream->open(handle, deviceType, &originalConfig, address,
+ outputStream = new SpdifStreamOut(this, originalConfig.format);
+ status = outputStream->open(handle, deviceType, &originalConfig, flags, address,
sourceMetadata);
if (status != NO_ERROR) {
ALOGE("ERROR - openOutputStream(), SPDIF open returned %d",
status);
delete outputStream;
outputStream = nullptr;
+ } else {
+ // on success, we need to assign the actual HAL stream config so that clients
+ // know and can later patch correctly.
+ config->format = originalConfig.format;
+ config->channel_mask = originalConfig.channel_mask;
+ config->sample_rate = originalConfig.sample_rate;
}
} else {
ALOGE("ERROR - openOutputStream(), SPDIFEncoder does not support format 0x%08x",
@@ -153,6 +160,12 @@
status);
delete inputStream;
inputStream = nullptr;
+ } else {
+ // on success, we need to assign the actual HAL stream config so that clients
+ // know and can later patch correctly.
+ config->format = originalConfig.format;
+ config->channel_mask = originalConfig.channel_mask;
+ config->sample_rate = originalConfig.sample_rate;
}
} else {
ALOGE("ERROR - openInputStream(), SPDIFDecoder does not support format 0x%08x",
diff --git a/services/audioflinger/datapath/AudioHwDevice.h b/services/audioflinger/datapath/AudioHwDevice.h
index e1a9018..6a35b91 100644
--- a/services/audioflinger/datapath/AudioHwDevice.h
+++ b/services/audioflinger/datapath/AudioHwDevice.h
@@ -85,7 +85,7 @@
AudioStreamOut **ppStreamOut,
audio_io_handle_t handle,
audio_devices_t deviceType,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
struct audio_config *config,
const char *address,
const std::vector<playback_track_metadata_v7_t>& sourceMetadata);
diff --git a/services/audioflinger/datapath/AudioStreamOut.cpp b/services/audioflinger/datapath/AudioStreamOut.cpp
index c65373e..7aadda3 100644
--- a/services/audioflinger/datapath/AudioStreamOut.cpp
+++ b/services/audioflinger/datapath/AudioStreamOut.cpp
@@ -30,9 +30,8 @@
namespace android {
// ----------------------------------------------------------------------------
-AudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags)
+AudioStreamOut::AudioStreamOut(AudioHwDevice *dev)
: audioHwDev(dev)
- , flags(flags)
{
}
@@ -93,14 +92,16 @@
audio_io_handle_t handle,
audio_devices_t deviceType,
struct audio_config *config,
+ audio_output_flags_t *flagsPtr,
const char *address,
const std::vector<playback_track_metadata_v7_t>& sourceMetadata)
{
sp<StreamOutHalInterface> outStream;
- const audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
- ? (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
- : flags;
+ audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
+ ? (audio_output_flags_t)(*flagsPtr | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
+ : *flagsPtr;
+ *flagsPtr = flags = customFlags;
int status = hwDev()->openOutputStream(
handle,
diff --git a/services/audioflinger/datapath/AudioStreamOut.h b/services/audioflinger/datapath/AudioStreamOut.h
index 2bf94a1..1857099 100644
--- a/services/audioflinger/datapath/AudioStreamOut.h
+++ b/services/audioflinger/datapath/AudioStreamOut.h
@@ -37,16 +37,17 @@
public:
AudioHwDevice * const audioHwDev;
sp<StreamOutHalInterface> stream;
- const audio_output_flags_t flags;
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
[[nodiscard]] sp<DeviceHalInterface> hwDev() const;
- AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags);
+ explicit AudioStreamOut(AudioHwDevice *dev);
virtual status_t open(
audio_io_handle_t handle,
audio_devices_t deviceType,
struct audio_config *config,
+ audio_output_flags_t *flagsPtr,
const char *address,
const std::vector<playback_track_metadata_v7_t>& sourceMetadata);
diff --git a/services/audioflinger/datapath/SpdifStreamIn.cpp b/services/audioflinger/datapath/SpdifStreamIn.cpp
index 98ce712..0090bc5 100644
--- a/services/audioflinger/datapath/SpdifStreamIn.cpp
+++ b/services/audioflinger/datapath/SpdifStreamIn.cpp
@@ -81,6 +81,11 @@
outputDevice,
outputDeviceAddress);
+ // reset config back to whatever is returned by HAL
+ config->sample_rate = customConfig.sample_rate;
+ config->format = customConfig.format;
+ config->channel_mask = customConfig.channel_mask;
+
ALOGI("SpdifStreamIn::open() status = %d", status);
#ifdef TEE_SINK
diff --git a/services/audioflinger/datapath/SpdifStreamOut.cpp b/services/audioflinger/datapath/SpdifStreamOut.cpp
index d3983b0..a565955 100644
--- a/services/audioflinger/datapath/SpdifStreamOut.cpp
+++ b/services/audioflinger/datapath/SpdifStreamOut.cpp
@@ -33,10 +33,8 @@
* PCM then we need to wrap the data in an SPDIF wrapper.
*/
SpdifStreamOut::SpdifStreamOut(AudioHwDevice *dev,
- audio_output_flags_t flags,
audio_format_t format)
- // Tell the HAL that the data will be compressed audio wrapped in a data burst.
- : AudioStreamOut(dev, (audio_output_flags_t) (flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO))
+ : AudioStreamOut(dev)
, mSpdifEncoder(this, format)
{
}
@@ -45,6 +43,7 @@
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
+ audio_output_flags_t *flags,
const char *address,
const std::vector<playback_track_metadata_v7_t>& sourceMetadata)
{
@@ -63,6 +62,8 @@
customConfig.format = AUDIO_FORMAT_PCM_16_BIT;
customConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ // Tell the HAL that the data will be compressed audio wrapped in a data burst.
+ *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO);
// Always print this because otherwise it could be very confusing if the
// HAL and AudioFlinger are using different formats.
@@ -76,9 +77,15 @@
handle,
devices,
&customConfig,
+ flags,
address,
sourceMetadata);
+ // reset config back to whatever is returned by HAL
+ config->sample_rate = customConfig.sample_rate;
+ config->format = customConfig.format;
+ config->channel_mask = customConfig.channel_mask;
+
ALOGI("SpdifStreamOut::open() status = %d", status);
#ifdef TEE_SINK
diff --git a/services/audioflinger/datapath/SpdifStreamOut.h b/services/audioflinger/datapath/SpdifStreamOut.h
index 1cd8f65..3241d6f 100644
--- a/services/audioflinger/datapath/SpdifStreamOut.h
+++ b/services/audioflinger/datapath/SpdifStreamOut.h
@@ -36,13 +36,13 @@
class SpdifStreamOut : public AudioStreamOut {
public:
- SpdifStreamOut(AudioHwDevice *dev, audio_output_flags_t flags,
- audio_format_t format);
+ SpdifStreamOut(AudioHwDevice *dev, audio_format_t format);
status_t open(
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
+ audio_output_flags_t *flags,
const char *address,
const std::vector<playback_track_metadata_v7_t>& sourceMetadata) override;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index e849bb4..edcb805 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -478,7 +478,7 @@
audio_config_base_t *mixerConfig,
const sp<DeviceDescriptorBase>& device,
uint32_t *latencyMs,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_attributes_t audioAttributes) = 0;
// creates a special output that is duplicated to the two outputs passed as arguments.
// The duplication is performed by a special mixer thread in the AudioFlinger.
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 3b7cae3..d499222 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -29,19 +29,21 @@
/**
* Legacy audio policy product strategies IDs. These strategies are supported by the default
* policy engine.
+ * IMPORTANT NOTE: the order of this enum is important as it determines the priority
+ * between active strategies for routing decisions: lower enum value => higher prioriy
*/
enum legacy_strategy {
STRATEGY_NONE = -1,
- STRATEGY_MEDIA,
STRATEGY_PHONE,
STRATEGY_SONIFICATION,
- STRATEGY_SONIFICATION_RESPECTFUL,
- STRATEGY_DTMF,
STRATEGY_ENFORCED_AUDIBLE,
- STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
STRATEGY_ACCESSIBILITY,
- STRATEGY_REROUTING,
+ STRATEGY_SONIFICATION_RESPECTFUL,
+ STRATEGY_MEDIA,
+ STRATEGY_DTMF,
STRATEGY_CALL_ASSISTANT,
+ STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+ STRATEGY_REROUTING,
STRATEGY_PATCH,
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 3c296e7..835fad2 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -412,7 +412,7 @@
const audio_config_base_t *mixerConfig,
const DeviceVector &devices,
audio_stream_type_t stream,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_io_handle_t *output,
audio_attributes_t attributes);
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index d206637..26bb94f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -137,6 +137,7 @@
class HwModuleCollection : public Vector<sp<HwModule> >
{
public:
+ sp<HwModule> getModuleFromHandle(audio_module_handle_t handle) const;
sp<HwModule> getModuleFromName(const char *name) const;
/**
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 848051c..2c41de4 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -656,7 +656,7 @@
const audio_config_base_t *mixerConfig,
const DeviceVector &devices,
audio_stream_type_t stream,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_io_handle_t *output,
audio_attributes_t attributes)
{
@@ -686,7 +686,7 @@
// create a default one
if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
lHalConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
- flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+ *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
lHalConfig.offload_info = AUDIO_INFO_INITIALIZER;
lHalConfig.offload_info.sample_rate = lHalConfig.sample_rate;
lHalConfig.offload_info.channel_mask = lHalConfig.channel_mask;
@@ -704,7 +704,7 @@
lMixerConfig = *mixerConfig;
}
- mFlags = (audio_output_flags_t)(mFlags | flags);
+ mFlags = (audio_output_flags_t)(mFlags | *flags);
// If no mixer config is specified for a spatializer output, default to 5.1 for proper
// configuration of the final downmixer or spatializer
@@ -722,8 +722,9 @@
&lMixerConfig,
device,
&mLatency,
- mFlags,
+ &mFlags,
attributes);
+ *flags = mFlags;
if (status == NO_ERROR) {
LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
index f5e135e..723887d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -342,7 +342,8 @@
AUDIO_FORMAT_AAC_XHE}},
{AUDIO_FORMAT_DOLBY_TRUEHD, {}},
{AUDIO_FORMAT_E_AC3_JOC, {}},
- {AUDIO_FORMAT_AC4, {}}};
+ {AUDIO_FORMAT_AC4, {}}, // L0-3
+ {AUDIO_FORMAT_AC4_L4, {}}};
}
bool AudioPolicyConfig::useDeepBufferForMedia() const {
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 6696b45..2d8231a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -283,6 +283,16 @@
dumpAudioRouteVector(mRoutes, dst, spaces);
}
+sp<HwModule> HwModuleCollection::getModuleFromHandle(audio_module_handle_t handle) const
+{
+ for (const auto& module : *this) {
+ if (module->getHandle() == handle) {
+ return module;
+ }
+ }
+ return nullptr;
+}
+
sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
{
for (const auto& module : *this) {
diff --git a/services/audiopolicy/config/surround_sound_configuration_5_0.xml b/services/audiopolicy/config/surround_sound_configuration_5_0.xml
index 590a181..6a268d8 100644
--- a/services/audiopolicy/config/surround_sound_configuration_5_0.xml
+++ b/services/audiopolicy/config/surround_sound_configuration_5_0.xml
@@ -27,5 +27,6 @@
<format name="AUDIO_FORMAT_DTS_HD" />
<format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
<format name="AUDIO_FORMAT_AC4" />
+ <format name="AUDIO_FORMAT_AC4_L4" />
</formats>
</surroundSound>
diff --git a/services/audiopolicy/config/surround_sound_configuration_aidl.xml b/services/audiopolicy/config/surround_sound_configuration_aidl.xml
index cf15711..51ccaa9 100644
--- a/services/audiopolicy/config/surround_sound_configuration_aidl.xml
+++ b/services/audiopolicy/config/surround_sound_configuration_aidl.xml
@@ -30,5 +30,6 @@
<format name="AUDIO_FORMAT_DTS_UHD_P2" />
<format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
<format name="AUDIO_FORMAT_AC4" />
+ <format name="AUDIO_FORMAT_AC4_L4" />
</formats>
</surroundSound>
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4da645b..c1c4a28 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1677,14 +1677,19 @@
releaseMsdOutputPatches(devices);
status_t status =
- outputDesc->open(config, nullptr /* mixerConfig */, devices, stream, flags, output,
+ outputDesc->open(config, nullptr /* mixerConfig */, devices, stream, &flags, output,
attributes);
- // only accept an output with the requested parameters
+ // only accept an output with the requested parameters, unless the format can be IEC61937
+ // encapsulated and opened by AudioFlinger as wrapped IEC61937.
+ const bool ignoreRequestedParametersCheck = audio_is_iec61937_compatible(config->format)
+ && (flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
+ && audio_has_proportional_frames(outputDesc->getFormat());
if (status != NO_ERROR ||
- (config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
- (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
- (config->channel_mask != 0 && config->channel_mask != outputDesc->getChannelMask())) {
+ (!ignoreRequestedParametersCheck &&
+ ((config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
+ (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
+ (config->channel_mask != 0 && config->channel_mask != outputDesc->getChannelMask())))) {
ALOGV("%s failed opening direct output: output %d sample rate %d %d,"
"format %d %d, channel mask %04x %04x", __func__, *output, config->sample_rate,
outputDesc->getSamplingRate(), config->format, outputDesc->getFormat(),
@@ -1704,11 +1709,11 @@
outputDesc->mDirectClientSession = session;
addOutput(*output, outputDesc);
- setOutputDevices(__func__, outputDesc,
- devices,
- true,
- 0,
- NULL);
+ // The version check is essentially to avoid making this call in the case of the HIDL HAL.
+ if (auto hwModule = mHwModules.getModuleFromHandle(mPrimaryModuleHandle); hwModule &&
+ hwModule->getHalVersionMajor() >= 3) {
+ setOutputDevices(__func__, outputDesc, devices, true, 0, NULL);
+ }
mPreviousOutputs = mOutputs;
ALOGV("%s returns new direct output %d", __func__, *output);
mpClientInterface->onAudioPortListUpdate();
@@ -4533,6 +4538,9 @@
"Engine could not set preferred devices %s for audio source %d role %d",
dumpAudioDeviceTypeAddrVector(devices).c_str(), audioSource, role);
+ if (status == NO_ERROR) {
+ updateInputRouting();
+ }
return status;
}
@@ -6154,7 +6162,8 @@
audio_devices_t deviceType = device->type();
// Enabling/disabling formats are applied to only HDMI devices. So, this function
// returns formats reported by HDMI devices.
- if (deviceType != AUDIO_DEVICE_OUT_HDMI) {
+ if (deviceType != AUDIO_DEVICE_OUT_HDMI &&
+ deviceType != AUDIO_DEVICE_OUT_HDMI_ARC && deviceType != AUDIO_DEVICE_OUT_HDMI_EARC) {
continue;
}
// Formats reported by sink devices
@@ -6223,13 +6232,13 @@
sp<SwAudioOutputDescriptor> outputDesc;
bool profileUpdated = false;
- DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
- AUDIO_DEVICE_OUT_HDMI);
+ DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromTypes(
+ {AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_HDMI_ARC, AUDIO_DEVICE_OUT_HDMI_EARC});
for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
// Simulate reconnection to update enabled surround sound formats.
String8 address = String8(hdmiOutputDevices[i]->address().c_str());
std::string name = hdmiOutputDevices[i]->getName();
- status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
+ status_t status = setDeviceConnectionStateInt(hdmiOutputDevices[i]->type(),
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.c_str(),
name.c_str(),
@@ -6237,7 +6246,7 @@
if (status != NO_ERROR) {
continue;
}
- status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
+ status = setDeviceConnectionStateInt(hdmiOutputDevices[i]->type(),
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.c_str(),
name.c_str(),
@@ -6775,11 +6784,12 @@
sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
mpClientInterface);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
DeviceVector(supportedDevice),
AUDIO_STREAM_DEFAULT,
- AUDIO_OUTPUT_FLAG_NONE, &output, attributes);
+ &flags, &output, attributes);
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for devices %s on hw module %s",
supportedDevice->toString().c_str(), hwModule->getName());
@@ -8149,9 +8159,21 @@
if (result.source == AUDIO_SOURCE_HOTWORD && !inputDesc->isSoundTrigger()) {
result.source = AUDIO_SOURCE_VOICE_RECOGNITION;
}
- return result; }).
+ return result; });
//only one input device for now
- addSource(device);
+ if (audio_is_remote_submix_device(device->type())) {
+ // remote submix HAL does not support audio conversion, need source device
+ // audio config to match the sink input descriptor audio config, otherwise AIDL
+ // HAL patching will fail
+ audio_port_config srcDevicePortConfig = {};
+ device->toAudioPortConfig(&srcDevicePortConfig, nullptr);
+ srcDevicePortConfig.sample_rate = inputDesc->getSamplingRate();
+ srcDevicePortConfig.channel_mask = inputDesc->getChannelMask();
+ srcDevicePortConfig.format = inputDesc->getFormat();
+ patchBuilder.addSource(srcDevicePortConfig);
+ } else {
+ patchBuilder.addSource(device);
+ }
status = installPatch(__func__, patchHandle, inputDesc.get(), patchBuilder.patch(), 0);
}
}
@@ -8518,9 +8540,11 @@
}
float volumeDb = computeVolume(curves, volumeSource, index, deviceTypes);
+ const VolumeSource dtmfVolSrc = toVolumeSource(AUDIO_STREAM_DTMF, false);
if (outputDesc->isFixedVolume(deviceTypes) ||
// Force VoIP volume to max for bluetooth SCO/BLE device except if muted
- (index != 0 && (isVoiceVolSrc || isBtScoVolSrc) &&
+ (index != 0 && (isVoiceVolSrc || isBtScoVolSrc
+ || (isInCall() && (dtmfVolSrc == volumeSource))) &&
(isSingleDeviceType(deviceTypes, audio_is_bluetooth_out_sco_device)
|| isSingleDeviceType(deviceTypes, audio_is_ble_out_device)))) {
volumeDb = 0.0f;
@@ -8882,6 +8906,8 @@
mReportedFormatsMap[devDesc] = formats;
if (devDesc->type() == AUDIO_DEVICE_OUT_HDMI ||
+ devDesc->type() == AUDIO_DEVICE_OUT_HDMI_ARC ||
+ devDesc->type() == AUDIO_DEVICE_OUT_HDMI_EARC ||
isDeviceOfModule(devDesc,AUDIO_HARDWARE_MODULE_ID_MSD)) {
modifySurroundFormats(devDesc, &formats);
size_t modifiedNumProfiles = 0;
@@ -9016,7 +9042,7 @@
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
status_t status = desc->open(halConfig, mixerConfig, devices,
- AUDIO_STREAM_DEFAULT, flags, &output, attributes);
+ AUDIO_STREAM_DEFAULT, &flags, &output, attributes);
if (status != NO_ERROR) {
ALOGE("%s failed to open output %d", __func__, status);
return nullptr;
@@ -9054,7 +9080,7 @@
config.offload_info.channel_mask = config.channel_mask;
config.offload_info.format = config.format;
- status = desc->open(&config, mixerConfig, devices, AUDIO_STREAM_DEFAULT, flags, &output,
+ status = desc->open(&config, mixerConfig, devices, AUDIO_STREAM_DEFAULT, &flags, &output,
attributes);
if (status != NO_ERROR) {
return nullptr;
@@ -9062,11 +9088,11 @@
}
addOutput(output, desc);
- setOutputDevices(__func__, desc,
- devices,
- true,
- 0,
- NULL);
+ // The version check is essentially to avoid making this call in the case of the HIDL HAL.
+ if (auto hwModule = mHwModules.getModuleFromHandle(mPrimaryModuleHandle); hwModule &&
+ hwModule->getHalVersionMajor() >= 3) {
+ setOutputDevices(__func__, desc, devices, true, 0, NULL);
+ }
sp<DeviceDescriptor> speaker = mAvailableOutputDevices.getDevice(
AUDIO_DEVICE_OUT_SPEAKER, String8(""), AUDIO_FORMAT_DEFAULT);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 9a5365c..363dfa7 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -56,7 +56,7 @@
audio_config_base_t *mixerConfig,
const sp<DeviceDescriptorBase>& device,
uint32_t *latencyMs,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_attributes_t attributes)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
@@ -74,7 +74,7 @@
request.mixerConfig = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_config_base_t_AudioConfigBase(*mixerConfig, false /*isInput*/));
request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_DeviceDescriptorBase(device));
- request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
+ request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_output_flags_t_int32_t_mask(*flags));
request.attributes = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_attributes_t_AudioAttributes(attributes));
@@ -89,7 +89,9 @@
.channel_mask = halConfig->channel_mask,
.format = halConfig->format,
};
- mAudioPolicyService->registerOutput(*output, config, flags);
+ *flags = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_int32_t_audio_output_flags_t_mask(response.flags));
+ mAudioPolicyService->registerOutput(*output, config, *flags);
}
return status;
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 60b155da..24ab6a1 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1687,19 +1687,6 @@
return Status::ok();
}
-template <typename Port>
-void anonymizePortBluetoothAddress(Port& port) {
- if (port.type != AUDIO_PORT_TYPE_DEVICE) {
- return;
- }
- if (!(audio_is_a2dp_device(port.ext.device.type)
- || audio_is_ble_device(port.ext.device.type)
- || audio_is_bluetooth_sco_device(port.ext.device.type)
- || audio_is_hearing_aid_out_device(port.ext.device.type))) {
- return;
- }
- anonymizeBluetoothAddress(port.ext.device.address);
-}
Status AudioPolicyService::listAudioPorts(media::AudioPortRole roleAidl,
media::AudioPortType typeAidl, Int* count,
@@ -1718,27 +1705,14 @@
std::unique_ptr<audio_port_v7[]> ports(new audio_port_v7[num_ports]);
unsigned int generation;
- const AttributionSourceState attributionSource = getCallingAttributionSource();
+ audio_utils::lock_guard _l(mMutex);
+ if (mAudioPolicyManager == NULL) {
+ return binderStatusFromStatusT(NO_INIT);
+ }
AutoCallerClear acc;
- {
- audio_utils::lock_guard _l(mMutex);
- if (mAudioPolicyManager == NULL) {
- return binderStatusFromStatusT(NO_INIT);
- }
- // AudioPolicyManager->listAudioPorts makes a deep copy of port structs into ports
- // so it is safe to access after releasing the mutex
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
- mAudioPolicyManager->listAudioPorts(
- role, type, &num_ports, ports.get(), &generation)));
- numPortsReq = std::min(numPortsReq, num_ports);
- }
-
- if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) {
- for (size_t i = 0; i < numPortsReq; ++i) {
- anonymizePortBluetoothAddress(ports[i]);
- }
- }
-
+ RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
+ mAudioPolicyManager->listAudioPorts(role, type, &num_ports, ports.get(), &generation)));
+ numPortsReq = std::min(numPortsReq, num_ports);
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
convertRange(ports.get(), ports.get() + numPortsReq, std::back_inserter(*portsAidl),
legacy2aidl_audio_port_v7_AudioPortFw)));
@@ -1761,24 +1735,12 @@
Status AudioPolicyService::getAudioPort(int portId,
media::AudioPortFw* _aidl_return) {
audio_port_v7 port{ .id = portId };
-
- const AttributionSourceState attributionSource = getCallingAttributionSource();
+ audio_utils::lock_guard _l(mMutex);
+ if (mAudioPolicyManager == NULL) {
+ return binderStatusFromStatusT(NO_INIT);
+ }
AutoCallerClear acc;
-
- {
- audio_utils::lock_guard _l(mMutex);
- if (mAudioPolicyManager == NULL) {
- return binderStatusFromStatusT(NO_INIT);
- }
- // AudioPolicyManager->getAudioPort makes a deep copy of the port struct into port
- // so it is safe to access after releasing the mutex
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
- }
-
- if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) {
- anonymizePortBluetoothAddress(port);
- }
-
+ RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPortFw(port));
return Status::ok();
}
@@ -1840,32 +1802,14 @@
std::unique_ptr<audio_patch[]> patches(new audio_patch[num_patches]);
unsigned int generation;
- const AttributionSourceState attributionSource = getCallingAttributionSource();
+ audio_utils::lock_guard _l(mMutex);
+ if (mAudioPolicyManager == NULL) {
+ return binderStatusFromStatusT(NO_INIT);
+ }
AutoCallerClear acc;
-
- {
- audio_utils::lock_guard _l(mMutex);
- if (mAudioPolicyManager == NULL) {
- return binderStatusFromStatusT(NO_INIT);
- }
- // AudioPolicyManager->listAudioPatches makes a deep copy of patches structs into patches
- // so it is safe to access after releasing the mutex
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
- mAudioPolicyManager->listAudioPatches(&num_patches, patches.get(), &generation)));
- numPatchesReq = std::min(numPatchesReq, num_patches);
- }
-
- if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) {
- for (size_t i = 0; i < numPatchesReq; ++i) {
- for (size_t j = 0; j < patches[i].num_sources; ++j) {
- anonymizePortBluetoothAddress(patches[i].sources[j]);
- }
- for (size_t j = 0; j < patches[i].num_sinks; ++j) {
- anonymizePortBluetoothAddress(patches[i].sinks[j]);
- }
- }
- }
-
+ RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
+ mAudioPolicyManager->listAudioPatches(&num_patches, patches.get(), &generation)));
+ numPatchesReq = std::min(numPatchesReq, num_patches);
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
convertRange(patches.get(), patches.get() + numPatchesReq,
std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatchFw)));
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index d74bc07..c47b5e9 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -823,7 +823,7 @@
audio_config_base_t *mixerConfig,
const sp<DeviceDescriptorBase>& device,
uint32_t *latencyMs,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_attributes_t attributes);
// creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
// a special mixer thread in the AudioFlinger.
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index a120649..79c25ab 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -42,7 +42,7 @@
audio_config_base_t *mixerConfig,
const sp<DeviceDescriptorBase>& /*device*/,
uint32_t * /*latencyMs*/,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_attributes_t /*attributes*/) override {
if (module >= mNextModuleHandle) {
ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
@@ -50,13 +50,13 @@
return BAD_VALUE;
}
*output = mNextIoHandle++;
- mOpenedOutputs[*output] = flags;
+ mOpenedOutputs[*output] = *flags;
ALOGD("%s: opened output %d: HAL(%s %s %d) Mixer(%s %s %d) %s", __func__, *output,
audio_channel_out_mask_to_string(halConfig->channel_mask),
audio_format_to_string(halConfig->format), halConfig->sample_rate,
audio_channel_out_mask_to_string(mixerConfig->channel_mask),
audio_format_to_string(mixerConfig->format), mixerConfig->sample_rate,
- android::toString(flags).c_str());
+ android::toString(*flags).c_str());
return NO_ERROR;
}
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 6f63721..9ddfd6c 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -37,7 +37,7 @@
audio_config_base_t* /*mixerConfig*/,
const sp<DeviceDescriptorBase>& /*device*/,
uint32_t* /*latencyMs*/,
- audio_output_flags_t /*flags*/,
+ audio_output_flags_t* /*flags*/,
audio_attributes_t /*attributes*/) override { return NO_INIT; }
audio_io_handle_t openDuplicateOutput(audio_io_handle_t /*output1*/,
audio_io_handle_t /*output2*/) override {
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 924a664..39f9b8a 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -500,6 +500,9 @@
void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
// TODO: Consider using Serializer to load part of the config from a string.
ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
+ mConfig->getHwModules().getModuleFromName(
+ AUDIO_HARDWARE_MODULE_ID_PRIMARY)->setHalVersion(3, 0);
+
mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
sp<AudioProfile> pcmOutputProfile = new AudioProfile(
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
@@ -531,7 +534,7 @@
addOutputProfile(spdifOutputProfile);
}
- sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
+ sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 3 /*halVersionMajor*/);
HwModuleCollection modules = mConfig->getHwModules();
modules.add(msdModule);
mConfig->setHwModules(modules);
@@ -2547,7 +2550,7 @@
audio_config_base_t * mixerConfig,
const sp<DeviceDescriptorBase>& device,
uint32_t * latencyMs,
- audio_output_flags_t flags,
+ audio_output_flags_t *flags,
audio_attributes_t attributes) override {
return mSimulateFailure ? BAD_VALUE :
AudioPolicyManagerTestClient::openOutput(
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 6a5d5e0..fa5eb6f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1725,20 +1725,6 @@
return Status::ok();
}
-Status CameraService::errorNotTrusted(int clientPid, int clientUid, const std::string& cameraId,
- const std::string& clientName, bool isPid) const {
- int callingPid = getCallingPid();
- int callingUid = getCallingUid();
- ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
- "(don't trust %s %d)", callingPid, callingUid, isPid ? "clientPid" : "clientUid",
- isPid ? clientPid : clientUid);
- return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
- "Untrusted caller (calling PID %d, UID %d) trying to "
- "forward camera access to camera %s for client %s (PID %d, UID %d)",
- getCallingPid(), getCallingUid(), cameraId.c_str(),
- clientName.c_str(), clientPid, clientUid);
-}
-
Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
const std::string& clientName, int clientUid, int clientPid) const {
int callingPid = getCallingPid();
@@ -2131,27 +2117,21 @@
std::string clientPackageNameMaybe = clientAttribution.packageName.value_or("");
bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
- std::string clientPackageName = resolvePackageName(clientAttribution.uid,
- clientPackageNameMaybe);
- logConnectionAttempt(clientAttribution.pid, clientPackageName, cameraIdStr, API_1);
- int clientUid = clientAttribution.uid;
- int clientPid = clientAttribution.pid;
-
- // Resolve the client identity. In the near future, we will no longer rely on USE_CALLING_*, and
- // need a way to guarantee the caller identity early.
-
- // Check if we can trust clientUid
- if (!resolveClientUid(clientUid)) {
- return errorNotTrusted(clientPid, clientUid, cameraIdStr, clientPackageName,
- /* isPid=*/ false);
+ AttributionSourceState resolvedClientAttribution(clientAttribution);
+ ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraIdStr);
+ if (!ret.isOk()) {
+ logRejected(cameraIdStr, getCallingPid(),
+ clientAttribution.packageName.value_or("<unknown>"),
+ toStdString(ret.toString8()));
+ return ret;
}
- // Check if we can trust clientUid
- if (!resolveClientPid(clientPid)) {
- return errorNotTrusted(clientPid, clientUid, cameraIdStr, clientPackageName,
- /* isPid= */ true);
- }
+ const int clientPid = resolvedClientAttribution.pid;
+ const int clientUid = resolvedClientAttribution.uid;
+ const std::string& clientPackageName = *resolvedClientAttribution.packageName;
+
+ logConnectionAttempt(clientPid, clientPackageName, cameraIdStr, API_1);
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
@@ -2161,8 +2141,9 @@
rotationOverride, forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*out*/client);
if (!ret.isOk()) {
- logRejected(cameraIdStr, getCallingPid(), clientAttribution.packageName.value_or(""),
- toStdString(ret.toString8()));
+ logRejected(cameraIdStr, getCallingPid(),
+ clientAttribution.packageName.value_or("<unknown>"),
+ toStdString(ret.toString8()));
return ret;
}
@@ -2268,31 +2249,30 @@
std::string cameraId = cameraIdOptional.value();
bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
- std::string clientPackageName = resolvePackageName(clientAttribution.uid,
- clientPackageNameMaybe);
- logConnectionAttempt(clientAttribution.pid, clientPackageName, cameraId, API_2);
- userid_t clientUserId = multiuser_get_user_id(clientAttribution.uid);
- if (clientAttribution.uid == USE_CALLING_UID) {
- clientUserId = multiuser_get_user_id(callingUid);
+ AttributionSourceState resolvedClientAttribution(clientAttribution);
+ if (!flags::use_context_attribution_source()) {
+ resolvedClientAttribution.pid = USE_CALLING_PID;
+ }
+ ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraId);
+ if (!ret.isOk()) {
+ logRejected(cameraId, getCallingPid(), clientAttribution.packageName.value_or(""),
+ toStdString(ret.toString8()));
+ return ret;
}
- // Resolve the client identity. In the near future, we will no longer rely on USE_CALLING_*, and
- // need a way to guarantee the caller identity early.
+ const int clientPid = resolvedClientAttribution.pid;
+ const int clientUid = resolvedClientAttribution.uid;
+ const std::string& clientPackageName = *resolvedClientAttribution.packageName;
+ userid_t clientUserId = multiuser_get_user_id(resolvedClientAttribution.uid);
- int clientUid = clientAttribution.uid;
- int clientPid = callingPid;
- // Check if we can trust clientUid
- if (!resolveClientUid(clientUid)) {
- return errorNotTrusted(clientPid, clientUid, cameraId, clientPackageName,
- /* isPid= */ false);
- }
+ logConnectionAttempt(clientPid, clientPackageName, cameraId, API_2);
if (oomScoreOffset < 0) {
- std::string msg =
- fmt::sprintf("Cannot increase the priority of a client %s pid %d for "
- "camera id %s", clientPackageName.c_str(), callingPid,
- cameraId.c_str());
+ std::string msg = fmt::sprintf(
+ "Cannot increase the priority of a client %s pid %d for "
+ "camera id %s",
+ clientPackageName.c_str(), clientPid, cameraId.c_str());
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -2307,25 +2287,24 @@
}
// enforce system camera permissions
- if (oomScoreOffset > 0
- && !hasPermissionsForSystemCamera(cameraId, callingPid,
- callingUid)
- && !isTrustedCallingUid(callingUid)) {
- std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for "
- "camera id %s without SYSTEM_CAMERA permissions",
- clientPackageName.c_str(), callingPid, cameraId.c_str());
+ if (oomScoreOffset > 0 && !hasPermissionsForSystemCamera(cameraId, clientPid, callingUid) &&
+ !isTrustedCallingUid(callingUid)) {
+ std::string msg = fmt::sprintf(
+ "Cannot change the priority of a client %s pid %d for "
+ "camera id %s without SYSTEM_CAMERA permissions",
+ clientPackageName.c_str(), clientPid, cameraId.c_str());
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
}
- ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb,
- cameraId, /*api1CameraId*/-1, clientPackageName, systemNativeClient,
- clientAttribution.attributionTag, clientUid, clientPid, API_2,
+ ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks, CameraDeviceClient>(
+ cameraCb, cameraId, /*api1CameraId*/ -1, clientPackageName, systemNativeClient,
+ resolvedClientAttribution.attributionTag, clientUid, clientPid, API_2,
/*shimUpdateOnly*/ false, oomScoreOffset, targetSdkVersion, rotationOverride,
- /*forceSlowJpegMode*/false, unresolvedCameraId, isNonSystemNdk, /*out*/client);
+ /*forceSlowJpegMode*/ false, unresolvedCameraId, isNonSystemNdk, /*out*/ client);
if (!ret.isOk()) {
- logRejected(cameraId, callingPid, clientPackageName, toStdString(ret.toString8()));
+ logRejected(cameraId, clientPid, clientPackageName, toStdString(ret.toString8()));
return ret;
}
@@ -2386,28 +2365,12 @@
}
void CameraService::logConnectionAttempt(int clientPid, const std::string& clientPackageName,
- const std::string& cameraId, apiLevel effectiveApiLevel) const {
- int packagePid = (clientPid == USE_CALLING_PID) ?
- getCallingPid() : clientPid;
+ const std::string& cameraId,
+ apiLevel effectiveApiLevel) const {
ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
- "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(),
- static_cast<int>(effectiveApiLevel));
-}
-
-std::string CameraService::resolvePackageName(int clientUid,
- const std::string& clientPackageNameMaybe) const {
- if (clientPackageNameMaybe.size() <= 0) {
- int packageUid = (clientUid == USE_CALLING_UID) ?
- getCallingUid() : clientUid;
- // NDK calls don't come with package names, but we need one for various cases.
- // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
- // do exist. For all authentication cases, all packages under the same UID get the
- // same permissions, so picking any associated package name is sufficient. For some
- // other cases, this may give inaccurate names for clients in logs.
- return getPackageNameFromUid(packageUid);
- } else {
- return clientPackageNameMaybe;
- }
+ "Camera API version %d",
+ clientPid, clientPackageName.c_str(), cameraId.c_str(),
+ static_cast<int>(effectiveApiLevel));
}
template<class CALLBACK, class CLIENT>
@@ -2419,11 +2382,6 @@
const std::string& originalCameraId, bool isNonSystemNdk, /*out*/sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
- int packageUid = (clientUid == USE_CALLING_UID) ?
- getCallingUid() : clientUid;
- int packagePid = (clientPid == USE_CALLING_PID) ?
- getCallingPid() : clientPid;
-
nsecs_t openTimeNs = systemTime();
sp<CLIENT> client = nullptr;
@@ -2643,7 +2601,7 @@
if (flags::camera_privacy_allowlist()) {
// Set camera muting behavior.
isCameraPrivacyEnabled = this->isCameraPrivacyEnabled(
- toString16(client->getPackageName()), cameraId, packagePid, packageUid);
+ toString16(client->getPackageName()), cameraId, clientPid, clientUid);
} else {
isCameraPrivacyEnabled =
mSensorPrivacyPolicy->isCameraPrivacyEnabled();
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 80bd783..5eb2536 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -934,12 +934,8 @@
binder::Status validateClientPermissionsLocked(const std::string& cameraId,
const std::string& clientName, int clientUid, int clientPid) const;
- // If clientPackageNameMaybe is empty, attempts to resolve the package name.
- std::string resolvePackageName(int clientUid, const std::string& clientPackageNameMaybe) const;
void logConnectionAttempt(int clientPid, const std::string& clientPackageName,
const std::string& cameraId, apiLevel effectiveApiLevel) const;
- binder::Status errorNotTrusted(int clientPid, int clientUid, const std::string& cameraId,
- const std::string& clientName, bool isPid) const;
bool isCameraPrivacyEnabled(const String16& packageName,const std::string& cameraId,
int clientPid, int ClientUid);
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 77c037a..7090545 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -14,32 +14,39 @@
* limitations under the License.
*/
-#include <inttypes.h>
-
#define LOG_TAG "Camera3StreamSplitter"
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <binder/ProcessState.h>
#include <camera/StringUtils.h>
#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferItem.h>
+#include <gui/BufferItemConsumer.h>
#include <gui/BufferQueue.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
-
+#include <system/window.h>
#include <ui/GraphicBuffer.h>
-
-#include <binder/ProcessState.h>
-
#include <utils/Trace.h>
#include <cutils/atomic.h>
+#include <inttypes.h>
+#include <algorithm>
+#include <cstdint>
+#include <memory>
#include "Camera3Stream.h"
+#include "Flags.h"
#include "Camera3StreamSplitter.h"
+// We're relying on a large number of yet-to-be-fully-launched flag dependencies
+// here. So instead of flagging each one, we flag the entire implementation to
+// improve legibility.
+#if USE_NEW_STREAM_SPLITTER
+
namespace android {
status_t Camera3StreamSplitter::connect(const std::unordered_map<size_t, sp<Surface>> &surfaces,
@@ -55,7 +62,7 @@
Mutex::Autolock lock(mMutex);
status_t res = OK;
- if (mOutputs.size() > 0 || mConsumer != nullptr) {
+ if (mOutputSurfaces.size() > 0 || mBufferItemConsumer != nullptr) {
SP_LOGE("%s: already connected", __FUNCTION__);
return BAD_VALUE;
}
@@ -82,43 +89,43 @@
}
}
-#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
- // Create BufferQueue for input
- BufferQueue::createBufferQueue(&mProducer, &mConsumer);
-#endif // !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-
// Allocate 1 extra buffer to handle the case where all buffers are detached
// from input, and attached to the outputs. In this case, the input queue's
// dequeueBuffer can still allocate 1 extra buffer before being blocked by
// the output's attachBuffer().
mMaxConsumerBuffers++;
+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
- mBufferItemConsumer = new BufferItemConsumer(consumerUsage, mMaxConsumerBuffers);
+ mBufferItemConsumer = sp<BufferItemConsumer>::make(consumerUsage, mMaxConsumerBuffers);
+ mSurface = mBufferItemConsumer->getSurface();
#else
- mBufferItemConsumer = new BufferItemConsumer(mConsumer, consumerUsage, mMaxConsumerBuffers);
+ // Create BufferQueue for input
+ sp<IGraphicBufferProducer> bqProducer;
+ sp<IGraphicBufferConsumer> bqConsumer;
+ BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
+
+ mBufferItemConsumer = new BufferItemConsumer(bqConsumer, consumerUsage, mMaxConsumerBuffers);
+ mSurface = new Surface(bqProducer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+
if (mBufferItemConsumer == nullptr) {
return NO_MEMORY;
}
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
- mProducer = mBufferItemConsumer->getSurface()->getIGraphicBufferProducer();
- mConsumer = mBufferItemConsumer->getIGraphicBufferConsumer();
-#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
- mConsumer->setConsumerName(toString8(mConsumerName));
+ mBufferItemConsumer->setName(toString8(mConsumerName));
- *consumer = new Surface(mProducer);
+ *consumer = mSurface;
if (*consumer == nullptr) {
return NO_MEMORY;
}
- res = mProducer->setAsyncMode(true);
+ res = mSurface->setAsyncMode(true);
if (res != OK) {
SP_LOGE("%s: Failed to enable input queue async mode: %s(%d)", __FUNCTION__,
strerror(-res), res);
return res;
}
- res = mConsumer->consumerConnect(this, /* controlledByApp */ false);
+ mBufferItemConsumer->setFrameAvailableListener(this);
mWidth = width;
mHeight = height;
@@ -139,25 +146,19 @@
ATRACE_CALL();
Mutex::Autolock lock(mMutex);
- for (auto& notifier : mNotifiers) {
- sp<IGraphicBufferProducer> producer = notifier.first;
- sp<OutputListener> listener = notifier.second;
- IInterface::asBinder(producer)->unlinkToDeath(listener);
- }
mNotifiers.clear();
- for (auto& output : mOutputs) {
+ for (auto& output : mOutputSurfaces) {
if (output.second != nullptr) {
output.second->disconnect(NATIVE_WINDOW_API_CAMERA);
}
}
- mOutputs.clear();
mOutputSurfaces.clear();
- mOutputSlots.clear();
+ mHeldBuffers.clear();
mConsumerBufferCount.clear();
- if (mConsumer.get() != nullptr) {
- mConsumer->consumerDisconnect();
+ if (mBufferItemConsumer != nullptr) {
+ mBufferItemConsumer->abandon();
}
if (mBuffers.size() > 0) {
@@ -189,7 +190,7 @@
}
if (mMaxConsumerBuffers > mAcquiredInputBuffers) {
- res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
+ res = mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
}
return res;
@@ -207,7 +208,7 @@
return BAD_VALUE;
}
- if (mOutputs[surfaceId] != nullptr) {
+ if (mOutputSurfaces[surfaceId] != nullptr) {
SP_LOGE("%s: surfaceId: %u already taken!", __FUNCTION__, (unsigned) surfaceId);
return BAD_VALUE;
}
@@ -226,11 +227,9 @@
return res;
}
- sp<IGraphicBufferProducer> gbp = outputQueue->getIGraphicBufferProducer();
// Connect to the buffer producer
- sp<OutputListener> listener(new OutputListener(this, gbp));
- IInterface::asBinder(gbp)->linkToDeath(listener);
- res = outputQueue->connect(NATIVE_WINDOW_API_CAMERA, listener);
+ sp<OutputListener> listener = sp<OutputListener>::make(this, outputQueue);
+ res = outputQueue->connect(NATIVE_WINDOW_API_CAMERA, listener, /* reportBufferRemoval */ false);
if (res != NO_ERROR) {
SP_LOGE("addOutput: failed to connect (%d)", res);
return res;
@@ -272,22 +271,21 @@
outputQueue->setDequeueTimeout(timeout);
}
- res = gbp->allowAllocation(false);
+ res = outputQueue->allowAllocation(false);
if (res != OK) {
SP_LOGE("%s: Failed to turn off allocation for outputQueue", __FUNCTION__);
return res;
}
// Add new entry into mOutputs
- mOutputs[surfaceId] = gbp;
mOutputSurfaces[surfaceId] = outputQueue;
mConsumerBufferCount[surfaceId] = maxConsumerBuffers;
if (mConsumerBufferCount[surfaceId] > mMaxHalBuffers) {
SP_LOGW("%s: Consumer buffer count %zu larger than max. Hal buffers: %zu", __FUNCTION__,
mConsumerBufferCount[surfaceId], mMaxHalBuffers);
}
- mNotifiers[gbp] = listener;
- mOutputSlots[gbp] = std::make_unique<OutputSlots>(totalBufferCount);
+ mNotifiers[outputQueue] = listener;
+ mHeldBuffers[outputQueue] = std::make_unique<HeldBuffers>(totalBufferCount);
mMaxConsumerBuffers += maxConsumerBuffers;
return NO_ERROR;
@@ -304,7 +302,7 @@
}
if (mAcquiredInputBuffers < mMaxConsumerBuffers) {
- res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
+ res = mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
if (res != OK) {
SP_LOGE("%s: setMaxAcquiredBufferCount failed %d", __FUNCTION__, res);
return res;
@@ -315,70 +313,54 @@
}
status_t Camera3StreamSplitter::removeOutputLocked(size_t surfaceId) {
- if (mOutputs[surfaceId] == nullptr) {
+ if (mOutputSurfaces[surfaceId] == nullptr) {
SP_LOGE("%s: output surface is not present!", __FUNCTION__);
return BAD_VALUE;
}
- sp<IGraphicBufferProducer> gbp = mOutputs[surfaceId];
+ sp<Surface> surface = mOutputSurfaces[surfaceId];
//Search and decrement the ref. count of any buffers that are
//still attached to the removed surface.
std::vector<uint64_t> pendingBufferIds;
- auto& outputSlots = *mOutputSlots[gbp];
- for (size_t i = 0; i < outputSlots.size(); i++) {
- if (outputSlots[i] != nullptr) {
- pendingBufferIds.push_back(outputSlots[i]->getId());
- auto rc = gbp->detachBuffer(i);
- if (rc != NO_ERROR) {
- //Buffers that fail to detach here will be scheduled for detach in the
- //input buffer queue and the rest of the registered outputs instead.
- //This will help ensure that camera stops accessing buffers that still
- //can get referenced by the disconnected output.
- mDetachedBuffers.emplace(outputSlots[i]->getId());
- }
+
+ // TODO: can we simplify this to just use the tracker?
+ for (const auto& buffer : (*mHeldBuffers[surface])) {
+ pendingBufferIds.push_back(buffer->getId());
+ auto rc = surface->detachBuffer(buffer);
+ if (rc != NO_ERROR) {
+ // Buffers that fail to detach here will be scheduled for detach in the
+ // input buffer queue and the rest of the registered outputs instead.
+ // This will help ensure that camera stops accessing buffers that still
+ // can get referenced by the disconnected output.
+ mDetachedBuffers.emplace(buffer->getId());
}
}
- mOutputs[surfaceId] = nullptr;
mOutputSurfaces[surfaceId] = nullptr;
- mOutputSlots[gbp] = nullptr;
+ mHeldBuffers[surface] = nullptr;
for (const auto &id : pendingBufferIds) {
decrementBufRefCountLocked(id, surfaceId);
}
- auto res = IInterface::asBinder(gbp)->unlinkToDeath(mNotifiers[gbp]);
- if (res != OK) {
- SP_LOGE("%s: Failed to unlink producer death listener: %d ", __FUNCTION__, res);
- return res;
- }
-
- res = gbp->disconnect(NATIVE_WINDOW_API_CAMERA);
+ status_t res = surface->disconnect(NATIVE_WINDOW_API_CAMERA);
if (res != OK) {
SP_LOGE("%s: Unable disconnect from producer interface: %d ", __FUNCTION__, res);
return res;
}
- mNotifiers[gbp] = nullptr;
+ mNotifiers[surface] = nullptr;
mMaxConsumerBuffers -= mConsumerBufferCount[surfaceId];
mConsumerBufferCount[surfaceId] = 0;
return res;
}
-status_t Camera3StreamSplitter::outputBufferLocked(const sp<IGraphicBufferProducer>& output,
+status_t Camera3StreamSplitter::outputBufferLocked(const sp<Surface>& output,
const BufferItem& bufferItem, size_t surfaceId) {
ATRACE_CALL();
status_t res;
- IGraphicBufferProducer::QueueBufferInput queueInput(
- bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp,
- bufferItem.mDataSpace, bufferItem.mCrop,
- static_cast<int32_t>(bufferItem.mScalingMode),
- bufferItem.mTransform, bufferItem.mFence);
-
- IGraphicBufferProducer::QueueBufferOutput queueOutput;
uint64_t bufferId = bufferItem.mGraphicBuffer->getId();
const BufferTracker& tracker = *(mBuffers[bufferId]);
- int slot = getSlotForOutputLocked(output, tracker.getBuffer());
if (mOutputSurfaces[surfaceId] != nullptr) {
sp<ANativeWindow> anw = mOutputSurfaces[surfaceId];
@@ -388,19 +370,26 @@
SP_LOGE("%s: Invalid surface id: %zu!", __FUNCTION__, surfaceId);
}
+ output->setBuffersTimestamp(bufferItem.mTimestamp);
+ output->setBuffersDataSpace(static_cast<ui::Dataspace>(bufferItem.mDataSpace));
+ output->setCrop(&bufferItem.mCrop);
+ output->setScalingMode(bufferItem.mScalingMode);
+ output->setBuffersTransform(bufferItem.mTransform);
+
// In case the output BufferQueue has its own lock, if we hold splitter lock while calling
// queueBuffer (which will try to acquire the output lock), the output could be holding its
// own lock calling releaseBuffer (which will try to acquire the splitter lock), running into
// circular lock situation.
mMutex.unlock();
- res = output->queueBuffer(slot, queueInput, &queueOutput);
+ SurfaceQueueBufferOutput queueBufferOutput;
+ res = output->queueBuffer(bufferItem.mGraphicBuffer, bufferItem.mFence, &queueBufferOutput);
mMutex.lock();
- SP_LOGV("%s: Queuing buffer to buffer queue %p slot %d returns %d",
- __FUNCTION__, output.get(), slot, res);
- //During buffer queue 'mMutex' is not held which makes the removal of
- //"output" possible. Check whether this is the case and return.
- if (mOutputSlots[output] == nullptr) {
+ SP_LOGV("%s: Queuing buffer to buffer queue %p bufferId %" PRIu64 " returns %d", __FUNCTION__,
+ output.get(), bufferId, res);
+ // During buffer queue 'mMutex' is not held which makes the removal of
+ // "output" possible. Check whether this is the case and return.
+ if (mOutputSurfaces[surfaceId] == nullptr) {
return res;
}
if (res != OK) {
@@ -418,7 +407,7 @@
// If the queued buffer replaces a pending buffer in the async
// queue, no onBufferReleased is called by the buffer queue.
// Proactively trigger the callback to avoid buffer loss.
- if (queueOutput.bufferReplaced) {
+ if (queueBufferOutput.bufferReplaced) {
onBufferReplacedLocked(output, surfaceId);
}
@@ -456,52 +445,32 @@
auto tracker = std::make_unique<BufferTracker>(gb, surface_ids);
for (auto& surface_id : surface_ids) {
- sp<IGraphicBufferProducer>& gbp = mOutputs[surface_id];
- if (gbp.get() == nullptr) {
+ sp<Surface>& surface = mOutputSurfaces[surface_id];
+ if (surface.get() == nullptr) {
//Output surface got likely removed by client.
continue;
}
- int slot = getSlotForOutputLocked(gbp, gb);
- if (slot != BufferItem::INVALID_BUFFER_SLOT) {
- //Buffer is already attached to this output surface.
- continue;
- }
+
//Temporarly Unlock the mutex when trying to attachBuffer to the output
//queue, because attachBuffer could block in case of a slow consumer. If
//we block while holding the lock, onFrameAvailable and onBufferReleased
//will block as well because they need to acquire the same lock.
mMutex.unlock();
- res = gbp->attachBuffer(&slot, gb);
+ res = surface->attachBuffer(anb);
mMutex.lock();
if (res != OK) {
- SP_LOGE("%s: Cannot attachBuffer from GraphicBufferProducer %p: %s (%d)",
- __FUNCTION__, gbp.get(), strerror(-res), res);
+ SP_LOGE("%s: Cannot attachBuffer from GraphicBufferProducer %p: %s (%d)", __FUNCTION__,
+ surface.get(), strerror(-res), res);
// TODO: might need to detach/cleanup the already attached buffers before return?
return res;
}
- if ((slot < 0) || (slot > BufferQueue::NUM_BUFFER_SLOTS)) {
- SP_LOGE("%s: Slot received %d either bigger than expected maximum %d or negative!",
- __FUNCTION__, slot, BufferQueue::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- }
//During buffer attach 'mMutex' is not held which makes the removal of
//"gbp" possible. Check whether this is the case and continue.
- if (mOutputSlots[gbp] == nullptr) {
+ if (mHeldBuffers[surface] == nullptr) {
continue;
}
- auto& outputSlots = *mOutputSlots[gbp];
- if (static_cast<size_t> (slot + 1) > outputSlots.size()) {
- outputSlots.resize(slot + 1);
- }
- if (outputSlots[slot] != nullptr) {
- // If the buffer is attached to a slot which already contains a buffer,
- // the previous buffer will be removed from the output queue. Decrement
- // the reference count accordingly.
- decrementBufRefCountLocked(outputSlots[slot]->getId(), surface_id);
- }
- SP_LOGV("%s: Attached buffer %p to slot %d on output %p.",__FUNCTION__, gb.get(),
- slot, gbp.get());
- outputSlots[slot] = gb;
+ mHeldBuffers[surface]->insert(gb);
+ SP_LOGV("%s: Attached buffer %p on output %p.", __FUNCTION__, gb.get(), surface.get());
}
mBuffers[bufferId] = std::move(tracker);
@@ -515,25 +484,14 @@
// Acquire and detach the buffer from the input
BufferItem bufferItem;
- status_t res = mConsumer->acquireBuffer(&bufferItem, /* presentWhen */ 0);
+ status_t res = mBufferItemConsumer->acquireBuffer(&bufferItem, /* presentWhen */ 0);
if (res != NO_ERROR) {
SP_LOGE("%s: Acquiring buffer from input failed (%d)", __FUNCTION__, res);
mOnFrameAvailableRes.store(res);
return;
}
- uint64_t bufferId;
- if (bufferItem.mGraphicBuffer != nullptr) {
- mInputSlots[bufferItem.mSlot] = bufferItem;
- } else if (bufferItem.mAcquireCalled) {
- bufferItem.mGraphicBuffer = mInputSlots[bufferItem.mSlot].mGraphicBuffer;
- mInputSlots[bufferItem.mSlot].mFrameNumber = bufferItem.mFrameNumber;
- } else {
- SP_LOGE("%s: Invalid input graphic buffer!", __FUNCTION__);
- mOnFrameAvailableRes.store(BAD_VALUE);
- return;
- }
- bufferId = bufferItem.mGraphicBuffer->getId();
+ uint64_t bufferId = bufferItem.mGraphicBuffer->getId();
if (mBuffers.find(bufferId) == mBuffers.end()) {
SP_LOGE("%s: Acquired buffer doesn't exist in attached buffer map",
@@ -556,13 +514,12 @@
SP_LOGV("%s: BufferTracker for buffer %" PRId64 ", number of requests %zu",
__FUNCTION__, bufferItem.mGraphicBuffer->getId(), tracker.requestedSurfaces().size());
for (const auto id : tracker.requestedSurfaces()) {
-
- if (mOutputs[id] == nullptr) {
+ if (mOutputSurfaces[id] == nullptr) {
//Output surface got likely removed by client.
continue;
}
- res = outputBufferLocked(mOutputs[id], bufferItem, id);
+ res = outputBufferLocked(mOutputSurfaces[id], bufferItem, id);
if (res != OK) {
SP_LOGE("%s: outputBufferLocked failed %d", __FUNCTION__, res);
mOnFrameAvailableRes.store(res);
@@ -601,26 +558,11 @@
mBuffers.erase(id);
uint64_t bufferId = tracker_ptr->getBuffer()->getId();
- int consumerSlot = -1;
- uint64_t frameNumber;
- auto inputSlot = mInputSlots.begin();
- for (; inputSlot != mInputSlots.end(); inputSlot++) {
- if (inputSlot->second.mGraphicBuffer->getId() == bufferId) {
- consumerSlot = inputSlot->second.mSlot;
- frameNumber = inputSlot->second.mFrameNumber;
- break;
- }
- }
- if (consumerSlot == -1) {
- SP_LOGE("%s: Buffer missing inside input slots!", __FUNCTION__);
- return;
- }
auto detachBuffer = mDetachedBuffers.find(bufferId);
bool detach = (detachBuffer != mDetachedBuffers.end());
if (detach) {
mDetachedBuffers.erase(detachBuffer);
- mInputSlots.erase(inputSlot);
}
// Temporarily unlock mutex to avoid circular lock:
// 1. This function holds splitter lock, calls releaseBuffer which triggers
@@ -629,15 +571,14 @@
// 2. Camera3SharedOutputStream::getBufferLocked calls
// attachBufferToOutputs, which holds the stream lock, and waits for the
// splitter lock.
- sp<IGraphicBufferConsumer> consumer(mConsumer);
mMutex.unlock();
int res = NO_ERROR;
- if (consumer != nullptr) {
+ if (mBufferItemConsumer != nullptr) {
if (detach) {
- res = consumer->detachBuffer(consumerSlot);
+ res = mBufferItemConsumer->detachBuffer(tracker_ptr->getBuffer());
} else {
- res = consumer->releaseBuffer(consumerSlot, frameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, tracker_ptr->getMergedFence());
+ res = mBufferItemConsumer->releaseBuffer(tracker_ptr->getBuffer(),
+ tracker_ptr->getMergedFence());
}
} else {
SP_LOGE("%s: consumer has become null!", __FUNCTION__);
@@ -659,23 +600,25 @@
}
}
-void Camera3StreamSplitter::onBufferReleasedByOutput(
- const sp<IGraphicBufferProducer>& from) {
+void Camera3StreamSplitter::onBufferReleasedByOutput(const sp<Surface>& from) {
ATRACE_CALL();
- sp<Fence> fence;
- int slot = BufferItem::INVALID_BUFFER_SLOT;
- auto res = from->dequeueBuffer(&slot, &fence, mWidth, mHeight, mFormat, mProducerUsage,
- nullptr, nullptr);
+ from->setBuffersDimensions(mWidth, mHeight);
+ from->setBuffersFormat(mFormat);
+ from->setUsage(mProducerUsage);
+
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ auto res = from->dequeueBuffer(&buffer, &fence);
Mutex::Autolock lock(mMutex);
- handleOutputDequeueStatusLocked(res, slot);
+ handleOutputDequeueStatusLocked(res, buffer);
if (res != OK) {
return;
}
size_t surfaceId = 0;
bool found = false;
- for (const auto& it : mOutputs) {
+ for (const auto& it : mOutputSurfaces) {
if (it.second == from) {
found = true;
surfaceId = it.first;
@@ -687,36 +630,29 @@
return;
}
- returnOutputBufferLocked(fence, from, surfaceId, slot);
+ returnOutputBufferLocked(fence, from, surfaceId, buffer);
}
-void Camera3StreamSplitter::onBufferReplacedLocked(
- const sp<IGraphicBufferProducer>& from, size_t surfaceId) {
+void Camera3StreamSplitter::onBufferReplacedLocked(const sp<Surface>& from, size_t surfaceId) {
ATRACE_CALL();
- sp<Fence> fence;
- int slot = BufferItem::INVALID_BUFFER_SLOT;
- auto res = from->dequeueBuffer(&slot, &fence, mWidth, mHeight, mFormat, mProducerUsage,
- nullptr, nullptr);
- handleOutputDequeueStatusLocked(res, slot);
+ from->setBuffersDimensions(mWidth, mHeight);
+ from->setBuffersFormat(mFormat);
+ from->setUsage(mProducerUsage);
+
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ auto res = from->dequeueBuffer(&buffer, &fence);
+ handleOutputDequeueStatusLocked(res, buffer);
if (res != OK) {
return;
}
- returnOutputBufferLocked(fence, from, surfaceId, slot);
+ returnOutputBufferLocked(fence, from, surfaceId, buffer);
}
void Camera3StreamSplitter::returnOutputBufferLocked(const sp<Fence>& fence,
- const sp<IGraphicBufferProducer>& from, size_t surfaceId, int slot) {
- sp<GraphicBuffer> buffer;
-
- if (mOutputSlots[from] == nullptr) {
- //Output surface got likely removed by client.
- return;
- }
-
- auto outputSlots = *mOutputSlots[from];
- buffer = outputSlots[slot];
+ const sp<Surface>& from, size_t surfaceId, const sp<GraphicBuffer>& buffer) {
BufferTracker& tracker = *(mBuffers[buffer->getId()]);
// Merge the release fence of the incoming buffer so that the fence we send
// back to the input includes all of the outputs' fences
@@ -727,9 +663,16 @@
auto detachBuffer = mDetachedBuffers.find(buffer->getId());
bool detach = (detachBuffer != mDetachedBuffers.end());
if (detach) {
- auto res = from->detachBuffer(slot);
+ auto res = from->detachBuffer(buffer);
if (res == NO_ERROR) {
- outputSlots[slot] = nullptr;
+ if (mHeldBuffers.contains(from)) {
+ mHeldBuffers[from]->erase(buffer);
+ } else {
+ uint64_t surfaceId = 0;
+ from->getUniqueId(&surfaceId);
+ SP_LOGW("%s: buffer %" PRIu64 " not found in held buffers of surface %" PRIu64,
+ __FUNCTION__, buffer->getId(), surfaceId);
+ }
} else {
SP_LOGE("%s: detach buffer from output failed (%d)", __FUNCTION__, res);
}
@@ -739,22 +682,17 @@
decrementBufRefCountLocked(buffer->getId(), surfaceId);
}
-void Camera3StreamSplitter::handleOutputDequeueStatusLocked(status_t res, int slot) {
+void Camera3StreamSplitter::handleOutputDequeueStatusLocked(status_t res,
+ const sp<GraphicBuffer>& buffer) {
if (res == NO_INIT) {
// If we just discovered that this output has been abandoned, note that,
// but we can't do anything else, since buffer is invalid
onAbandonedLocked();
- } else if (res == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
- SP_LOGE("%s: Producer needs to re-allocate buffer!", __FUNCTION__);
- SP_LOGE("%s: This should not happen with buffer allocation disabled!", __FUNCTION__);
- } else if (res == IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
- SP_LOGE("%s: All slot->buffer mapping should be released!", __FUNCTION__);
- SP_LOGE("%s: This should not happen with buffer allocation disabled!", __FUNCTION__);
} else if (res == NO_MEMORY) {
SP_LOGE("%s: No free buffers", __FUNCTION__);
} else if (res == WOULD_BLOCK) {
SP_LOGE("%s: Dequeue call will block", __FUNCTION__);
- } else if (res != OK || (slot == BufferItem::INVALID_BUFFER_SLOT)) {
+ } else if (res != OK || buffer == nullptr) {
SP_LOGE("%s: dequeue buffer from output failed (%d)", __FUNCTION__, res);
}
}
@@ -773,36 +711,20 @@
SP_LOGV("One of my outputs has abandoned me");
}
-int Camera3StreamSplitter::getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
- const sp<GraphicBuffer>& gb) {
- auto& outputSlots = *mOutputSlots[gbp];
-
- for (size_t i = 0; i < outputSlots.size(); i++) {
- if (outputSlots[i] == gb) {
- return (int)i;
- }
- }
-
- SP_LOGV("%s: Cannot find slot for gb %p on output %p", __FUNCTION__, gb.get(),
- gbp.get());
- return BufferItem::INVALID_BUFFER_SLOT;
-}
-
-Camera3StreamSplitter::OutputListener::OutputListener(
- wp<Camera3StreamSplitter> splitter,
- wp<IGraphicBufferProducer> output)
- : mSplitter(splitter), mOutput(output) {}
+Camera3StreamSplitter::OutputListener::OutputListener(wp<Camera3StreamSplitter> splitter,
+ wp<Surface> output)
+ : mSplitter(splitter), mOutput(output) {}
void Camera3StreamSplitter::OutputListener::onBufferReleased() {
ATRACE_CALL();
sp<Camera3StreamSplitter> splitter = mSplitter.promote();
- sp<IGraphicBufferProducer> output = mOutput.promote();
+ sp<Surface> output = mOutput.promote();
if (splitter != nullptr && output != nullptr) {
splitter->onBufferReleasedByOutput(output);
}
}
-void Camera3StreamSplitter::OutputListener::binderDied(const wp<IBinder>& /* who */) {
+void Camera3StreamSplitter::OutputListener::onRemoteDied() {
sp<Camera3StreamSplitter> splitter = mSplitter.promote();
if (splitter != nullptr) {
Mutex::Autolock lock(splitter->mMutex);
@@ -833,3 +755,5 @@
}
} // namespace android
+
+#endif // USE_NEW_STREAM_SPLITTER
\ No newline at end of file
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 43f12fb..0440e08 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -14,22 +14,25 @@
* limitations under the License.
*/
-#ifndef ANDROID_SERVERS_STREAMSPLITTER_H
-#define ANDROID_SERVERS_STREAMSPLITTER_H
+#pragma once
+#include <memory>
#include <unordered_set>
#include <camera/CameraMetadata.h>
-#include <gui/IConsumerListener.h>
-#include <gui/Surface.h>
#include <gui/BufferItemConsumer.h>
+#include <gui/Surface.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
+#include "Flags.h"
+
+#if USE_NEW_STREAM_SPLITTER // trying to do this for each change would be a huge hassle.
+
#define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
#define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
#define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
@@ -38,8 +41,6 @@
namespace android {
class GraphicBuffer;
-class IGraphicBufferConsumer;
-class IGraphicBufferProducer;
// Camera3StreamSplitter is an autonomous class that manages one input BufferQueue
// and multiple output BufferQueues. By using the buffer attach and detach logic
@@ -47,9 +48,8 @@
// BufferQueue, where each buffer queued to the input is available to be
// acquired by each of the outputs, and is able to be dequeued by the input
// again only once all of the outputs have released it.
-class Camera3StreamSplitter : public BnConsumerListener {
-public:
-
+class Camera3StreamSplitter : public BufferItemConsumer::FrameAvailableListener {
+ public:
// Constructor
Camera3StreamSplitter(bool useHalBufManager = false);
@@ -67,7 +67,7 @@
//
// A return value other than NO_ERROR means that an error has occurred and
// outputQueue has not been added to the splitter. BAD_VALUE is returned if
- // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations
+ // outputQueue is NULL. See Surface::connect for explanations
// of other error codes.
status_t addOutput(size_t surfaceId, const sp<Surface>& outputQueue);
@@ -97,7 +97,7 @@
void setHalBufferManager(bool enabled);
private:
- // From IConsumerListener
+ // From BufferItemConsumer::FrameAvailableListener
//
// During this callback, we store some tracking information, detach the
// buffer from the input, and attach it to each of the outputs. This call
@@ -106,23 +106,13 @@
// input.
void onFrameAvailable(const BufferItem& item) override;
- // From IConsumerListener
+ // From BufferItemConsumer::FrameAvailableListener
//
// Similar to onFrameAvailable, but buffer item is indeed replacing a buffer
// in the buffer queue. This can happen when buffer queue is in droppable
// mode.
void onFrameReplaced(const BufferItem& item) override;
- // From IConsumerListener
- // We don't care about released buffers because we detach each buffer as
- // soon as we acquire it. See the comment for onBufferReleased below for
- // some clarifying notes about the name.
- void onBuffersReleased() override {}
-
- // From IConsumerListener
- // We don't care about sideband streams, since we won't be splitting them
- void onSidebandStreamChanged() override {}
-
// This is the implementation of the onBufferReleased callback from
// IProducerListener. It gets called from an OutputListener (see below), and
// 'from' is which producer interface from which the callback was received.
@@ -132,10 +122,10 @@
// last output releasing the buffer, and if so, release it to the input.
// If we release the buffer to the input, we allow a blocked
// onFrameAvailable call to proceed.
- void onBufferReleasedByOutput(const sp<IGraphicBufferProducer>& from);
+ void onBufferReleasedByOutput(const sp<Surface>& from);
// Called by outputBufferLocked when a buffer in the async buffer queue got replaced.
- void onBufferReplacedLocked(const sp<IGraphicBufferProducer>& from, size_t surfaceId);
+ void onBufferReplacedLocked(const sp<Surface>& from, size_t surfaceId);
// When this is called, the splitter disconnects from (i.e., abandons) its
// input queue and signals any waiting onFrameAvailable calls to wake up.
@@ -149,35 +139,32 @@
void decrementBufRefCountLocked(uint64_t id, size_t surfaceId);
// Check for and handle any output surface dequeue errors.
- void handleOutputDequeueStatusLocked(status_t res, int slot);
+ void handleOutputDequeueStatusLocked(status_t res, const sp<GraphicBuffer>& buffer);
// Handles released output surface buffers.
- void returnOutputBufferLocked(const sp<Fence>& fence, const sp<IGraphicBufferProducer>& from,
- size_t surfaceId, int slot);
+ void returnOutputBufferLocked(const sp<Fence>& fence, const sp<Surface>& from, size_t surfaceId,
+ const sp<GraphicBuffer>& buffer);
// This is a thin wrapper class that lets us determine which BufferQueue
// the IProducerListener::onBufferReleased callback is associated with. We
// create one of these per output BufferQueue, and then pass the producer
// into onBufferReleasedByOutput above.
- class OutputListener : public SurfaceListener,
- public IBinder::DeathRecipient {
- public:
- OutputListener(wp<Camera3StreamSplitter> splitter,
- wp<IGraphicBufferProducer> output);
+ class OutputListener : public SurfaceListener {
+ public:
+ OutputListener(wp<Camera3StreamSplitter> splitter, wp<Surface> output);
virtual ~OutputListener() = default;
- // From IProducerListener
+ // From SurfaceListener
void onBufferReleased() override;
bool needsReleaseNotify() override { return true; };
- void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {};
+ void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>&) override {}
void onBufferDetached(int /*slot*/) override {}
- // From IBinder::DeathRecipient
- void binderDied(const wp<IBinder>& who) override;
+ void onRemoteDied() override;
private:
wp<Camera3StreamSplitter> mSplitter;
- wp<IGraphicBufferProducer> mOutput;
+ wp<Surface> mOutput;
};
class BufferTracker {
@@ -198,7 +185,6 @@
const std::vector<size_t> requestedSurfaces() const { return mRequestedSurfaces; }
private:
-
// Disallow copying
BufferTracker(const BufferTracker& other);
BufferTracker& operator=(const BufferTracker& other);
@@ -223,16 +209,12 @@
// Send a buffer to particular output, and increment the reference count
// of the buffer. If this output is abandoned, the buffer's reference count
// won't be incremented.
- status_t outputBufferLocked(const sp<IGraphicBufferProducer>& output,
- const BufferItem& bufferItem, size_t surfaceId);
+ status_t outputBufferLocked(const sp<Surface>& output, const BufferItem& bufferItem,
+ size_t surfaceId);
// Get unique name for the buffer queue consumer
std::string getUniqueConsumerName();
- // Helper function to get the BufferQueue slot where a particular buffer is attached to.
- int getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
- const sp<GraphicBuffer>& gb);
-
// Sum of max consumer buffers for all outputs
size_t mMaxConsumerBuffers = 0;
size_t mMaxHalBuffers = 0;
@@ -249,17 +231,9 @@
Mutex mMutex;
- sp<IGraphicBufferProducer> mProducer;
- sp<IGraphicBufferConsumer> mConsumer;
sp<BufferItemConsumer> mBufferItemConsumer;
sp<Surface> mSurface;
- //Map graphic buffer ids -> buffer items
- std::unordered_map<uint64_t, BufferItem> mInputSlots;
-
- //Map surface ids -> gbp outputs
- std::unordered_map<int, sp<IGraphicBufferProducer> > mOutputs;
-
//Map surface ids -> gbp outputs
std::unordered_map<int, sp<Surface>> mOutputSurfaces;
@@ -271,18 +245,22 @@
// buffer, but also contain merged release fences).
std::unordered_map<uint64_t, std::unique_ptr<BufferTracker> > mBuffers;
- struct GBPHash {
- std::size_t operator()(const sp<IGraphicBufferProducer>& producer) const {
- return std::hash<IGraphicBufferProducer *>{}(producer.get());
+ struct SurfaceHash {
+ std::size_t operator()(const sp<Surface>& producer) const {
+ return std::hash<Surface*>{}(producer.get());
}
};
- std::unordered_map<sp<IGraphicBufferProducer>, sp<OutputListener>,
- GBPHash> mNotifiers;
+ struct BufferHash {
+ std::size_t operator()(const sp<GraphicBuffer>& buffer) const {
+ return std::hash<GraphicBuffer*>{}(buffer.get());
+ }
+ };
- typedef std::vector<sp<GraphicBuffer>> OutputSlots;
- std::unordered_map<sp<IGraphicBufferProducer>, std::unique_ptr<OutputSlots>,
- GBPHash> mOutputSlots;
+ std::unordered_map<sp<Surface>, sp<OutputListener>, SurfaceHash> mNotifiers;
+
+ typedef std::unordered_set<sp<GraphicBuffer>, BufferHash> HeldBuffers;
+ std::unordered_map<sp<Surface>, std::unique_ptr<HeldBuffers>, SurfaceHash> mHeldBuffers;
//A set of buffers that could potentially stay in some of the outputs after removal
//and therefore should be detached from the input queue.
@@ -301,4 +279,4 @@
} // namespace android
-#endif
+#endif // USE_NEW_STREAM_SPLITTER
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
index 6c16317..37903e1 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "AttributionAndPermissionUtils"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+
#include "AttributionAndPermissionUtils.h"
#include <binder/AppOpsManager.h>
@@ -25,12 +28,12 @@
#include "CameraService.h"
#include <binder/IPCThreadState.h>
-#include <hwbinder/IPCThreadState.h>
#include <binderthreadstate/CallerUtils.h>
+#include <hwbinder/IPCThreadState.h>
namespace {
- static const std::string kPermissionServiceName = "permission";
-} // namespace anonymous
+static const std::string kPermissionServiceName = "permission";
+} // namespace
namespace android {
@@ -39,8 +42,7 @@
const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
const std::string AttributionAndPermissionUtils::sManageCameraPermission(
"android.permission.MANAGE_CAMERA");
-const std::string AttributionAndPermissionUtils::sCameraPermission(
- "android.permission.CAMERA");
+const std::string AttributionAndPermissionUtils::sCameraPermission("android.permission.CAMERA");
const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
"android.permission.SYSTEM_CAMERA");
const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
@@ -54,14 +56,14 @@
const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
"android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
-int AttributionAndPermissionUtils::getCallingUid() {
+int AttributionAndPermissionUtils::getCallingUid() const {
if (getCurrentServingCall() == BinderCallType::HWBINDER) {
return hardware::IPCThreadState::self()->getCallingUid();
}
return IPCThreadState::self()->getCallingUid();
}
-int AttributionAndPermissionUtils::getCallingPid() {
+int AttributionAndPermissionUtils::getCallingPid() const {
if (getCurrentServingCall() == BinderCallType::HWBINDER) {
return hardware::IPCThreadState::self()->getCallingPid();
}
@@ -84,67 +86,38 @@
return;
}
-// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
-bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
- int callingUid = getCallingUid();
-
- if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
- clientUid = callingUid;
- } else if (!isTrustedCallingUid(callingUid)) {
- return false;
+binder::Status AttributionAndPermissionUtils::resolveAttributionSource(
+ /*inout*/ AttributionSourceState& resolvedAttributionSource, const std::string& methodName,
+ const std::optional<std::string>& cameraIdMaybe) {
+ // Check if we can trust clientUid
+ if (!resolveClientUid(resolvedAttributionSource.uid)) {
+ return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
+ methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
+ /* isPid= */ false);
}
- return true;
-}
+ resolveAttributionPackage(resolvedAttributionSource);
-// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
-bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
- int callingUid = getCallingUid();
- int callingPid = getCallingPid();
-
- if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
- clientPid = callingPid;
- } else if (!isTrustedCallingUid(callingUid)) {
- return false;
+ if (!resolveClientPid(resolvedAttributionSource.pid)) {
+ return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
+ methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
+ /* isPid= */ true);
}
- return true;
+ return binder::Status::ok();
}
-bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(const std::string &cameraId,
- const AttributionSourceState &attributionSource) {
- if (isAutomotivePrivilegedClient(attributionSource.uid)) {
- // If cameraId is empty, then it means that this check is not used for the
- // purpose of accessing a specific camera, hence grant permission just
- // based on uid to the automotive privileged client.
- if (cameraId.empty())
- return true;
-
- auto cameraService = mCameraService.promote();
- if (cameraService == nullptr) {
- ALOGE("%s: CameraService unavailable.", __FUNCTION__);
- return false;
- }
-
- // If this call is used for accessing a specific camera then cam_id must be provided.
- // In that case, only pre-grants the permission for accessing the exterior system only
- // camera.
- return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
- }
-
- return false;
-}
-
-bool AttributionAndPermissionUtils::checkPermissionForPreflight(const std::string &cameraId,
- const std::string &permission, const AttributionSourceState &attributionSource,
- const std::string& message, int32_t attributedOpCode) {
+bool AttributionAndPermissionUtils::checkPermissionForPreflight(
+ const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode) {
if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
return true;
}
return mPermissionChecker->checkPermissionForPreflight(
- toString16(permission), attributionSource, toString16(message),
- attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+ toString16(permission), attributionSource, toString16(message),
+ attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
}
// Can camera service trust the caller based on the calling UID?
@@ -177,8 +150,7 @@
bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
// Returns false if this is not an automotive device type.
- if (!isAutomotiveDevice())
- return false;
+ if (!isAutomotiveDevice()) return false;
// Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
// privileged client uid used for safety critical use cases such as
@@ -213,8 +185,8 @@
return packageName;
}
-status_t AttributionAndPermissionUtils::getUidForPackage(const std::string &packageName,
- int userId, /*inout*/uid_t& uid, int err) {
+status_t AttributionAndPermissionUtils::getUidForPackage(const std::string& packageName, int userId,
+ /*inout*/ uid_t& uid, int err) {
PermissionController pc;
uid = pc.getPackageUid(toString16(packageName), 0);
if (uid <= 0) {
@@ -237,36 +209,128 @@
return (getCallingPid() == getpid());
}
-bool AttributionAndPermissionUtils::hasPermissionsForCamera(const std::string& cameraId,
- const AttributionSourceState& attributionSource) {
- return checkPermissionForPreflight(cameraId, sCameraPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
+bool AttributionAndPermissionUtils::hasPermissionsForCamera(
+ const std::string& cameraId, const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(cameraId, sCameraPermission, attributionSource,
+ std::string(), AppOpsManager::OP_NONE);
}
-bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(const std::string& cameraId,
- const AttributionSourceState& attributionSource, bool checkCameraPermissions) {
- bool systemCameraPermission = checkPermissionForPreflight(cameraId,
- sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
- return systemCameraPermission && (!checkCameraPermissions
- || hasPermissionsForCamera(cameraId, attributionSource));
+bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
+ const std::string& cameraId, const AttributionSourceState& attributionSource,
+ bool checkCameraPermissions) {
+ bool systemCameraPermission =
+ checkPermissionForPreflight(cameraId, sSystemCameraPermission, attributionSource,
+ std::string(), AppOpsManager::OP_NONE);
+ return systemCameraPermission &&
+ (!checkCameraPermissions || hasPermissionsForCamera(cameraId, attributionSource));
}
bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
const std::string& cameraId, const AttributionSourceState& attributionSource) {
return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
}
bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
const AttributionSourceState& attributionSource) {
return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
}
bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
const AttributionSourceState& attributionSource) {
return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
+ const std::string& cameraId, const AttributionSourceState& attributionSource) {
+ if (isAutomotivePrivilegedClient(attributionSource.uid)) {
+ // If cameraId is empty, then it means that this check is not used for the
+ // purpose of accessing a specific camera, hence grant permission just
+ // based on uid to the automotive privileged client.
+ if (cameraId.empty()) return true;
+
+ auto cameraService = mCameraService.promote();
+ if (cameraService == nullptr) {
+ ALOGE("%s: CameraService unavailable.", __FUNCTION__);
+ return false;
+ }
+
+ // If this call is used for accessing a specific camera then cam_id must be provided.
+ // In that case, only pre-grants the permission for accessing the exterior system only
+ // camera.
+ return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
+ }
+
+ return false;
+}
+
+void AttributionAndPermissionUtils::resolveAttributionPackage(
+ AttributionSourceState& resolvedAttributionSource) {
+ if (resolvedAttributionSource.packageName.has_value() &&
+ resolvedAttributionSource.packageName->size() > 0) {
+ return;
+ }
+
+ // NDK calls don't come with package names, but we need one for various cases.
+ // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
+ // do exist. For all authentication cases, all packages under the same UID get the
+ // same permissions, so picking any associated package name is sufficient. For some
+ // other cases, this may give inaccurate names for clients in logs.
+ resolvedAttributionSource.packageName = getPackageNameFromUid(resolvedAttributionSource.uid);
+}
+
+// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
+bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
+ int callingUid = getCallingUid();
+
+ bool validUid = true;
+ if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
+ clientUid = callingUid;
+ } else {
+ validUid = isTrustedCallingUid(callingUid);
+ if (flags::use_context_attribution_source()) {
+ validUid = validUid || (clientUid == callingUid);
+ }
+ }
+
+ return validUid;
+}
+
+// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
+bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
+ int callingUid = getCallingUid();
+ int callingPid = getCallingPid();
+
+ bool validPid = true;
+ if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
+ clientPid = callingPid;
+ } else {
+ validPid = isTrustedCallingUid(callingUid);
+ if (flags::use_context_attribution_source()) {
+ validPid = validPid || (clientPid == callingPid);
+ }
+ }
+
+ return validPid;
+}
+
+binder::Status AttributionAndPermissionUtils::errorNotTrusted(
+ int clientPid, int clientUid, const std::string& methodName,
+ const std::optional<std::string>& cameraIdMaybe, const std::string& clientName,
+ bool isPid) const {
+ int callingPid = getCallingPid();
+ int callingUid = getCallingUid();
+ ALOGE("CameraService::%s X (calling PID %d, calling UID %d) rejected "
+ "(don't trust %s %d)",
+ methodName.c_str(), callingPid, callingUid, isPid ? "clientPid" : "clientUid",
+ isPid ? clientPid : clientUid);
+ return STATUS_ERROR_FMT(hardware::ICameraService::ERROR_PERMISSION_DENIED,
+ "Untrusted caller (calling PID %d, UID %d) trying to "
+ "forward camera access to camera %s for client %s (PID %d, UID %d)",
+ getCallingPid(), getCallingUid(), cameraIdMaybe.value_or("N/A").c_str(),
+ clientName.c_str(), clientPid, clientUid);
}
const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
@@ -274,7 +338,7 @@
static thread_local sp<IPermissionController> sPermissionController = nullptr;
if (sPermissionController == nullptr ||
- !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
+ !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
if (binder == nullptr) {
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 8bfe6d8..22abccc 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -35,12 +35,10 @@
*/
class AttributionAndPermissionUtils {
public:
- AttributionAndPermissionUtils() { }
+ AttributionAndPermissionUtils() {}
virtual ~AttributionAndPermissionUtils() {}
- void setCameraService(wp<CameraService> cameraService) {
- mCameraService = cameraService;
- }
+ void setCameraService(wp<CameraService> cameraService) { mCameraService = cameraService; }
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid) {
AttributionSourceState attributionSource{};
@@ -50,20 +48,31 @@
}
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
- int32_t deviceId) {
+ int32_t deviceId) {
AttributionSourceState attributionSource = buildAttributionSource(callingPid, callingUid);
attributionSource.deviceId = deviceId;
return attributionSource;
}
// Utilities handling Binder calling identities (previously in CameraThreadState)
- virtual int getCallingUid();
- virtual int getCallingPid();
+ virtual int getCallingUid() const;
+ virtual int getCallingPid() const;
virtual int64_t clearCallingIdentity();
virtual void restoreCallingIdentity(int64_t token);
- virtual bool resolveClientUid(/*inout*/ int& clientUid);
- virtual bool resolveClientPid(/*inout*/ int& clientPid);
+ /**
+ * If flag::use_context_attribution_source() is enabled, check the calling attribution source
+ * and resolve its package name, or fill in the pid/uid/package name if necessary.
+ *
+ * @param resolvedAttributionSource The resolved attribution source.
+ * @param methodName The name of the method calling this function (for logging only).
+ * @param cameraIdMaybe The camera ID, if applicable.
+ * @return The status of the operation.
+ */
+ virtual binder::Status resolveAttributionSource(
+ /*inout*/ AttributionSourceState& resolvedAttributionSource,
+ const std::string& methodName,
+ const std::optional<std::string>& cameraIdMaybe = std::nullopt);
/**
* Pre-grants the permission if the attribution source uid is for an automotive
@@ -74,9 +83,10 @@
* which is located outside of the vehicle body frame because camera located inside the vehicle
* cabin would need user permission.
*/
- virtual bool checkPermissionForPreflight(const std::string &cameraId,
- const std::string &permission, const AttributionSourceState& attributionSource,
- const std::string& message, int32_t attributedOpCode);
+ virtual bool checkPermissionForPreflight(const std::string& cameraId,
+ const std::string& permission,
+ const AttributionSourceState& attributionSource,
+ const std::string& message, int32_t attributedOpCode);
// Can camera service trust the caller based on the calling UID?
virtual bool isTrustedCallingUid(uid_t uid);
@@ -98,17 +108,18 @@
// stats based on app ops may be slightly off.
virtual std::string getPackageNameFromUid(int clientUid) const;
- virtual status_t getUidForPackage(const std::string &packageName, int userId,
- /*inout*/uid_t& uid, int err);
+ virtual status_t getUidForPackage(const std::string& packageName, int userId,
+ /*inout*/ uid_t& uid, int err);
virtual bool isCallerCameraServerNotDelegating();
// Utils for checking specific permissions
virtual bool hasPermissionsForCamera(const std::string& cameraId,
- const AttributionSourceState& attributionSource);
+ const AttributionSourceState& attributionSource);
virtual bool hasPermissionsForSystemCamera(const std::string& cameraId,
- const AttributionSourceState& attributionSource, bool checkCameraPermissions = true);
- virtual bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
- const AttributionSourceState& attributionSource);
+ const AttributionSourceState& attributionSource,
+ bool checkCameraPermissions = true);
+ virtual bool hasPermissionsForCameraHeadlessSystemUser(
+ const std::string& cameraId, const AttributionSourceState& attributionSource);
virtual bool hasPermissionsForCameraPrivacyAllowlist(
const AttributionSourceState& attributionSource);
virtual bool hasPermissionsForOpenCloseListener(
@@ -127,8 +138,20 @@
protected:
wp<CameraService> mCameraService;
- bool checkAutomotivePrivilegedClient(const std::string &cameraId,
- const AttributionSourceState &attributionSource);
+ bool checkAutomotivePrivilegedClient(const std::string& cameraId,
+ const AttributionSourceState& attributionSource);
+
+ // If the package name is missing from the AttributionSource and a package name exists for the
+ // AttributionSource's uid, fills in the missing package name.
+ void resolveAttributionPackage(AttributionSourceState& resolvedAttributionSource);
+
+ virtual bool resolveClientUid(/*inout*/ int& clientUid);
+ virtual bool resolveClientPid(/*inout*/ int& clientPid);
+
+ virtual binder::Status errorNotTrusted(int clientPid, int clientUid,
+ const std::string& methodName,
+ const std::optional<std::string>& cameraIdMaybe,
+ const std::string& clientName, bool isPid) const;
private:
virtual const sp<IPermissionController>& getPermissionController() const;
@@ -143,39 +166,36 @@
* in the encapsulating class's methods.
*/
class AttributionAndPermissionUtilsEncapsulator {
-protected:
+ protected:
std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
-public:
+ public:
AttributionAndPermissionUtilsEncapsulator(
- std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)
- : mAttributionAndPermissionUtils(attributionAndPermissionUtils) { }
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)
+ : mAttributionAndPermissionUtils(attributionAndPermissionUtils) {}
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid) {
return AttributionAndPermissionUtils::buildAttributionSource(callingPid, callingUid);
}
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
- int32_t deviceId) {
- return AttributionAndPermissionUtils::buildAttributionSource(
- callingPid, callingUid, deviceId);
+ int32_t deviceId) {
+ return AttributionAndPermissionUtils::buildAttributionSource(callingPid, callingUid,
+ deviceId);
}
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
- const std::string& packageName, int32_t deviceId) {
- AttributionSourceState attributionSource = buildAttributionSource(callingPid, callingUid,
- deviceId);
+ const std::string& packageName,
+ int32_t deviceId) {
+ AttributionSourceState attributionSource =
+ buildAttributionSource(callingPid, callingUid, deviceId);
attributionSource.packageName = packageName;
return attributionSource;
}
- int getCallingUid() const {
- return mAttributionAndPermissionUtils->getCallingUid();
- }
+ int getCallingUid() const { return mAttributionAndPermissionUtils->getCallingUid(); }
- int getCallingPid() const {
- return mAttributionAndPermissionUtils->getCallingPid();
- }
+ int getCallingPid() const { return mAttributionAndPermissionUtils->getCallingPid(); }
int64_t clearCallingIdentity() const {
return mAttributionAndPermissionUtils->clearCallingIdentity();
@@ -185,56 +205,52 @@
mAttributionAndPermissionUtils->restoreCallingIdentity(token);
}
- bool resolveClientUid(/*inout*/ int& clientUid) const {
- return mAttributionAndPermissionUtils->resolveClientUid(clientUid);
- }
-
- bool resolveClientPid(/*inout*/ int& clientPid) const {
- return mAttributionAndPermissionUtils->resolveClientPid(clientPid);
+ binder::Status resolveAttributionSource(AttributionSourceState& resolvedAttributionSource,
+ const std::string& methodName,
+ const std::optional<std::string>& cameraIdMaybe) {
+ return mAttributionAndPermissionUtils->resolveAttributionSource(resolvedAttributionSource,
+ methodName, cameraIdMaybe);
}
// The word 'System' here does not refer to callers only on the system
// partition. They just need to have an android system uid.
- bool callerHasSystemUid() const {
- return (getCallingUid() < AID_APP_START);
- }
+ bool callerHasSystemUid() const { return (getCallingUid() < AID_APP_START); }
bool hasPermissionsForCamera(int callingPid, int callingUid, int32_t deviceId) const {
return hasPermissionsForCamera(std::string(), callingPid, callingUid, deviceId);
}
- bool hasPermissionsForCamera(int callingPid, int callingUid,
- const std::string& packageName, int32_t deviceId) const {
+ bool hasPermissionsForCamera(int callingPid, int callingUid, const std::string& packageName,
+ int32_t deviceId) const {
return hasPermissionsForCamera(std::string(), callingPid, callingUid, packageName,
- deviceId);
+ deviceId);
}
- bool hasPermissionsForCamera(const std::string& cameraId, int callingPid,
- int callingUid, int32_t deviceId) const {
- auto attributionSource = buildAttributionSource(callingPid, callingUid,
- deviceId);
+ bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid,
+ int32_t deviceId) const {
+ auto attributionSource = buildAttributionSource(callingPid, callingUid, deviceId);
return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
}
bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid,
- const std::string& packageName, int32_t deviceId) const {
- auto attributionSource = buildAttributionSource(callingPid, callingUid, packageName,
- deviceId);
+ const std::string& packageName, int32_t deviceId) const {
+ auto attributionSource =
+ buildAttributionSource(callingPid, callingUid, packageName, deviceId);
return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
}
bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid,
- bool checkCameraPermissions = true) const {
+ bool checkCameraPermissions = true) const {
auto attributionSource = buildAttributionSource(callingPid, callingUid);
return mAttributionAndPermissionUtils->hasPermissionsForSystemCamera(
- cameraId, attributionSource, checkCameraPermissions);
+ cameraId, attributionSource, checkCameraPermissions);
}
bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
- int callingUid) const {
+ int callingUid) const {
auto attributionSource = buildAttributionSource(callingPid, callingUid);
return mAttributionAndPermissionUtils->hasPermissionsForCameraHeadlessSystemUser(
- cameraId, attributionSource);
+ cameraId, attributionSource);
}
bool hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const {
@@ -249,9 +265,7 @@
attributionSource);
}
- bool isAutomotiveDevice() const {
- return mAttributionAndPermissionUtils->isAutomotiveDevice();
- }
+ bool isAutomotiveDevice() const { return mAttributionAndPermissionUtils->isAutomotiveDevice(); }
bool isAutomotivePrivilegedClient(int32_t uid) const {
return mAttributionAndPermissionUtils->isAutomotivePrivilegedClient(uid);
@@ -265,8 +279,8 @@
return mAttributionAndPermissionUtils->isHeadlessSystemUserMode();
}
- status_t getUidForPackage(const std::string &packageName, int userId,
- /*inout*/uid_t& uid, int err) const {
+ status_t getUidForPackage(const std::string& packageName, int userId,
+ /*inout*/ uid_t& uid, int err) const {
return mAttributionAndPermissionUtils->getUidForPackage(packageName, userId, uid, err);
}
@@ -281,4 +295,4 @@
} // namespace android
-#endif // ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
+#endif // ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index 84a2b4e..e393c44 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -335,26 +335,40 @@
/////////////// FilterCallback ///////////////////////
::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
- Mutex::Autolock _l(mCallbackLock);
- if (mTunerFilterCallback != nullptr) {
- mTunerFilterCallback->onFilterStatus(status);
+ shared_ptr<ITunerFilterCallback> cb(nullptr);
+ {
+ Mutex::Autolock _l(mCallbackLock);
+ cb = mTunerFilterCallback;
+ }
+ if (cb != nullptr) {
+ cb->onFilterStatus(status);
}
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterEvent(
const vector<DemuxFilterEvent>& events) {
- Mutex::Autolock _l(mCallbackLock);
- if (mTunerFilterCallback != nullptr) {
- mTunerFilterCallback->onFilterEvent(events);
+ shared_ptr<ITunerFilterCallback> cb(nullptr);
+ {
+ Mutex::Autolock _l(mCallbackLock);
+ cb = mTunerFilterCallback;
+ }
+ if (cb != nullptr) {
+ cb->onFilterEvent(events);
}
return ::ndk::ScopedAStatus::ok();
}
void TunerFilter::FilterCallback::sendSharedFilterStatus(int32_t status) {
- Mutex::Autolock _l(mCallbackLock);
- if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
- mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
+ shared_ptr<ITunerFilterCallback> cb(nullptr);
+ shared_ptr<ITunerFilterCallback> orig_cb(nullptr);
+ {
+ Mutex::Autolock _l(mCallbackLock);
+ cb = mTunerFilterCallback;
+ orig_cb = mOriginalCallback;
+ }
+ if (cb != nullptr && orig_cb != nullptr) {
+ cb->onFilterStatus(static_cast<DemuxFilterStatus>(status));
}
}