Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea4fae56 authored by Xin Li's avatar Xin Li
Browse files

Merge tm-qpr-dev-plus-aosp-without-vendor@9129937

Bug: 248070379
Merged-In: I309f5fdb2088db1293a2278bc4a0518aa12b5601
Change-Id: I2b45fa3a80f13f47cb401184abf51896070388e2
parents d78bb405 867758e6
Loading
Loading
Loading
Loading
+42 −12
Original line number Diff line number Diff line
@@ -238,12 +238,27 @@ void Effect::effectOffloadParamToHal(const EffectOffloadParameter& offload,
}

// static
std::vector<uint8_t> Effect::parameterToHal(uint32_t paramSize, const void* paramData,
                                            uint32_t valueSize, const void** valueData) {
bool Effect::parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
                            const void** valueData, std::vector<uint8_t>* halParamBuffer) {
    constexpr size_t kMaxSize = EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t);
    if (paramSize > kMaxSize) {
        ALOGE("%s: Parameter size is too big: %" PRIu32, __func__, paramSize);
        return false;
    }
    size_t valueOffsetFromData = alignedSizeIn<uint32_t>(paramSize) * sizeof(uint32_t);
    if (valueOffsetFromData > kMaxSize) {
        ALOGE("%s: Aligned parameter size is too big: %zu", __func__, valueOffsetFromData);
        return false;
    }
    if (valueSize > kMaxSize - valueOffsetFromData) {
        ALOGE("%s: Value size is too big: %" PRIu32 ", max size is %zu", __func__, valueSize,
              kMaxSize - valueOffsetFromData);
        android_errorWriteLog(0x534e4554, "237291425");
        return false;
    }
    size_t halParamBufferSize = sizeof(effect_param_t) + valueOffsetFromData + valueSize;
    std::vector<uint8_t> halParamBuffer(halParamBufferSize, 0);
    effect_param_t* halParam = reinterpret_cast<effect_param_t*>(&halParamBuffer[0]);
    halParamBuffer->resize(halParamBufferSize, 0);
    effect_param_t* halParam = reinterpret_cast<effect_param_t*>(halParamBuffer->data());
    halParam->psize = paramSize;
    halParam->vsize = valueSize;
    memcpy(halParam->data, paramData, paramSize);
@@ -256,7 +271,7 @@ std::vector<uint8_t> Effect::parameterToHal(uint32_t paramSize, const void* para
            *valueData = halParam->data + valueOffsetFromData;
        }
    }
    return halParamBuffer;
    return true;
}

Result Effect::analyzeCommandStatus(const char* commandName, const char* context, status_t status) {
@@ -301,6 +316,11 @@ void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCa

Result Effect::getCurrentConfigImpl(uint32_t featureId, uint32_t configSize,
                                    GetCurrentConfigSuccessCallback onSuccess) {
    if (configSize > kMaxDataSize - sizeof(uint32_t)) {
        ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
        android_errorWriteLog(0x534e4554, "240266798");
        return Result::INVALID_ARGUMENTS;
    }
    uint32_t halCmd = featureId;
    std::vector<uint32_t> halResult(alignedSizeIn<uint32_t>(sizeof(uint32_t) + configSize), 0);
    uint32_t halResultSize = 0;
@@ -314,11 +334,15 @@ Result Effect::getParameterImpl(uint32_t paramSize, const void* paramData,
                                GetParameterSuccessCallback onSuccess) {
    // As it is unknown what method HAL uses for copying the provided parameter data,
    // it is safer to make sure that input and output buffers do not overlap.
    std::vector<uint8_t> halCmdBuffer =
        parameterToHal(paramSize, paramData, requestValueSize, nullptr);
    std::vector<uint8_t> halCmdBuffer;
    if (!parameterToHal(paramSize, paramData, requestValueSize, nullptr, &halCmdBuffer)) {
        return Result::INVALID_ARGUMENTS;
    }
    const void* valueData = nullptr;
    std::vector<uint8_t> halParamBuffer =
        parameterToHal(paramSize, paramData, replyValueSize, &valueData);
    std::vector<uint8_t> halParamBuffer;
    if (!parameterToHal(paramSize, paramData, replyValueSize, &valueData, &halParamBuffer)) {
        return Result::INVALID_ARGUMENTS;
    }
    uint32_t halParamBufferSize = halParamBuffer.size();

    return sendCommandReturningStatusAndData(
@@ -331,8 +355,12 @@ Result Effect::getParameterImpl(uint32_t paramSize, const void* paramData,

Result Effect::getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
                                       GetSupportedConfigsSuccessCallback onSuccess) {
    if (maxConfigs != 0 && configSize > (kMaxDataSize - 2 * sizeof(uint32_t)) / maxConfigs) {
        ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
        return Result::INVALID_ARGUMENTS;
    }
    uint32_t halCmd[2] = {featureId, maxConfigs};
    uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * sizeof(configSize);
    uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * configSize;
    std::vector<uint8_t> halResult(static_cast<size_t>(halResultSize), 0);
    return sendCommandReturningStatusAndData(
        EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS, "GET_FEATURE_SUPPORTED_CONFIGS", sizeof(halCmd),
@@ -472,8 +500,10 @@ Result Effect::setConfigImpl(int commandCode, const char* commandName, const Eff

Result Effect::setParameterImpl(uint32_t paramSize, const void* paramData, uint32_t valueSize,
                                const void* valueData) {
    std::vector<uint8_t> halParamBuffer =
        parameterToHal(paramSize, paramData, valueSize, &valueData);
    std::vector<uint8_t> halParamBuffer;
    if (!parameterToHal(paramSize, paramData, valueSize, &valueData, &halParamBuffer)) {
        return Result::INVALID_ARGUMENTS;
    }
    return sendCommandReturningStatus(EFFECT_CMD_SET_PARAM, "SET_PARAM", halParamBuffer.size(),
                                      &halParamBuffer[0]);
}
+5 −2
Original line number Diff line number Diff line
@@ -184,6 +184,9 @@ struct Effect : public IEffect {
    using GetSupportedConfigsSuccessCallback =
        std::function<void(uint32_t supportedConfigs, void* configsData)>;

    // Sets the limit on the maximum size of vendor-provided data structures.
    static constexpr size_t kMaxDataSize = 1 << 20;

    static const char* sContextResultOfCommand;
    static const char* sContextCallToCommand;
    static const char* sContextCallFunction;
@@ -211,8 +214,8 @@ struct Effect : public IEffect {
                                             channel_config_t* halConfig);
    static void effectOffloadParamToHal(const EffectOffloadParameter& offload,
                                        effect_offload_param_t* halOffload);
    static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData,
                                               uint32_t valueSize, const void** valueData);
    static bool parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
                               const void** valueData, std::vector<uint8_t>* halParamBuffer);

    Result analyzeCommandStatus(const char* commandName, const char* context, status_t status);
    void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
+53 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

#include <common/all-versions/VersionUtils.h>

#include <cutils/properties.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -623,6 +624,27 @@ TEST_P(AudioEffectHidlTest, GetParameter) {
    EXPECT_TRUE(ret.isOk());
}

TEST_P(AudioEffectHidlTest, GetParameterInvalidMaxReplySize) {
    description("Verify that GetParameter caps the maximum reply size");
    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
    if (!isNewDeviceLaunchingOnTPlus) {
        GTEST_SKIP() << "The test only applies to devices launching on T or later";
    }
    // Use a non-empty parameter to avoid being rejected by any earlier checks.
    hidl_vec<uint8_t> parameter;
    parameter.resize(16);
    // Use very large size to ensure that the service does not crash. Since parameters
    // are specific to each effect, and some effects may not have parameters at all,
    // simply checking the return value would not reveal an issue of using an uncapped value.
    const uint32_t veryLargeReplySize = std::numeric_limits<uint32_t>::max() - 100;
    Result retval = Result::OK;
    Return<void> ret =
            effect->getParameter(parameter, veryLargeReplySize,
                                 [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
    EXPECT_TRUE(ret.isOk());
    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
}

TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
    description("Verify that GetSupportedConfigsForFeature does not crash");
    Return<void> ret = effect->getSupportedConfigsForFeature(
@@ -643,6 +665,37 @@ TEST_P(AudioEffectHidlTest, SetCurrentConfigForFeature) {
    EXPECT_TRUE(ret.isOk());
}

TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeatureInvalidConfigSize) {
    description("Verify that GetSupportedConfigsForFeature caps the maximum config size");
    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
    if (!isNewDeviceLaunchingOnTPlus) {
        GTEST_SKIP() << "The test only applies to devices launching on T or later";
    }
    // Use very large size to ensure that the service does not crash.
    const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
    Result retval = Result::OK;
    Return<void> ret = effect->getSupportedConfigsForFeature(
            0, 1, veryLargeConfigSize,
            [&](Result r, uint32_t, const hidl_vec<uint8_t>&) { retval = r; });
    EXPECT_TRUE(ret.isOk());
    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
}

TEST_P(AudioEffectHidlTest, GetCurrentConfigForFeatureInvalidConfigSize) {
    description("Verify that GetCurrentConfigForFeature caps the maximum config size");
    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
    if (!isNewDeviceLaunchingOnTPlus) {
        GTEST_SKIP() << "The test only applies to devices launching on T or later";
    }
    // Use very large size to ensure that the service does not crash.
    const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
    Result retval = Result::OK;
    Return<void> ret = effect->getCurrentConfigForFeature(
            0, veryLargeConfigSize, [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
    EXPECT_TRUE(ret.isOk());
    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
}

// The main test class for Equalizer Audio Effect HIDL HAL.
class EqualizerAudioEffectHidlTest : public AudioEffectHidlTest {
  public:
+3 −1
Original line number Diff line number Diff line
@@ -33,7 +33,9 @@ parcelable EvsEventDesc {
    @utf8InCpp
    String deviceId;
    /**
     * Possible additional vendor information that is opaque to the EvsManager
     * Possible additional vendor information that is opaque to the EvsManager.
     * The size of the payload must not exceed 16-byte if the HIDL recipients are
     * expected to exist.
     */
    int[] payload;
}
+4 −1
Original line number Diff line number Diff line
@@ -47,7 +47,10 @@ oneway interface IEvsCameraStream {
    /**
     * Receives calls from the HAL each time an event happens.
     *
     * @param in event EVS event with possible event information.
     * @param in event EVS event with possible event information.  If ths HIDL
     *                 recipients are expected to exist, the size of the event
     *                 payload must not exceed 16 bytes; otherwise, a notification
     *                 will not reach them.
     */
    void notify(in EvsEventDesc event);
}
Loading