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

Commit 32ca66c0 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4765094 from 8f3b492c to pi-release

Change-Id: I82690c3829d09ac79465e6b977b08c4f853d749b
parents 16ba7ece 8f3b492c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ namespace audio {
    inline void PrintTo(const T& val, ::std::ostream* os) { *os << toString(val); }

namespace AUDIO_HAL_VERSION {
DEFINE_GTEST_PRINT_TO(IPrimaryDevice::TtyMode)
DEFINE_GTEST_PRINT_TO(Result)
}  // namespace AUDIO_HAL_VERSION

+59 −52
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <cstdio>
#include <initializer_list>
#include <limits>
#include <list>
#include <string>
#include <vector>

@@ -51,6 +52,7 @@ using std::initializer_list;
using std::string;
using std::to_string;
using std::vector;
using std::list;

using ::android::sp;
using ::android::hardware::Return;
@@ -104,6 +106,7 @@ using namespace ::android::hardware::audio::common::test::utility;
static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
static auto okOrNotSupportedOrInvalidArgs = {Result::OK, Result::NOT_SUPPORTED,
                                             Result::INVALID_ARGUMENTS};
static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};

class AudioHidlTestEnvironment : public ::Environment {
   public:
@@ -212,53 +215,59 @@ TEST_F(AudioPrimaryHidlTest, Init) {
template <class Property>
class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
   protected:
    /** Test a property getter and setter. */
    template <class Getter, class Setter>
    void testAccessors(const string& propertyName, const vector<Property>& valuesToTest,
                       Setter setter, Getter getter, const vector<Property>& invalidValues = {}) {
        Property initialValue;  // Save initial value to restore it at the end
                                // of the test
    enum Optionality { REQUIRED, OPTIONAL };
    struct Initial {  // Initial property value
        Initial(Property value, Optionality check = REQUIRED) : value(value), check(check) {}
        Property value;
        Optionality check;  // If this initial value should be checked
    };
    /** Test a property getter and setter.
     *  The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
     */
    template <Optionality optionality = REQUIRED, class Getter, class Setter>
    void testAccessors(const string& propertyName, const Initial expectedInitial,
                       list<Property> valuesToTest, Setter setter, Getter getter,
                       const vector<Property>& invalidValues = {}) {
        const auto expectedResults = {Result::OK,
                                      optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};

        Property initialValue = expectedInitial.value;
        ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
        ASSERT_OK(res);
        ASSERT_RESULT(expectedResults, res);
        if (res == Result::OK && expectedInitial.check == REQUIRED) {
            EXPECT_EQ(expectedInitial.value, initialValue);
        }

        valuesToTest.push_front(expectedInitial.value);
        valuesToTest.push_back(initialValue);
        for (Property setValue : valuesToTest) {
            SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
                         testing::PrintToString(setValue));
            ASSERT_OK((device.get()->*setter)(setValue));
            auto ret = (device.get()->*setter)(setValue);
            ASSERT_RESULT(expectedResults, ret);
            if (ret == Result::NOT_SUPPORTED) {
                doc::partialTest(propertyName + " setter is not supported");
                break;
            }
            Property getValue;
            // Make sure the getter returns the same value just set
            ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
            ASSERT_OK(res);
            ASSERT_RESULT(expectedResults, res);
            if (res == Result::NOT_SUPPORTED) {
                doc::partialTest(propertyName + " getter is not supported");
                continue;
            }
            EXPECT_EQ(setValue, getValue);
        }

        for (Property invalidValue : invalidValues) {
            SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
                         testing::PrintToString(invalidValue));
            EXPECT_RESULT(Result::INVALID_ARGUMENTS, (device.get()->*setter)(invalidValue));
            EXPECT_RESULT(invalidArgsOrNotSupported, (device.get()->*setter)(invalidValue));
        }

        ASSERT_OK((device.get()->*setter)(initialValue));  // restore initial value
    }

    /** Test the getter and setter of an optional feature. */
    template <class Getter, class Setter>
    void testOptionalAccessors(const string& propertyName, const vector<Property>& valuesToTest,
                               Setter setter, Getter getter,
                               const vector<Property>& invalidValues = {}) {
        doc::test("Test the optional " + propertyName + " getters and setter");
        {
            SCOPED_TRACE("Test feature support by calling the getter");
            Property initialValue;
            ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
            if (res == Result::NOT_SUPPORTED) {
                doc::partialTest(propertyName + " getter is not supported");
                return;
            }
            ASSERT_OK(res);  // If it is supported it must succeed
        }
        // The feature is supported, test it
        testAccessors(propertyName, valuesToTest, setter, getter, invalidValues);
        // Restore initial value
        EXPECT_RESULT(expectedResults, (device.get()->*setter)(initialValue));
    }
};

@@ -266,15 +275,13 @@ using BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;

TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
    doc::test("Check that the mic can be muted and unmuted");
    testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, &IDevice::getMicMute);
    testAccessors("mic mute", Initial{false}, {true}, &IDevice::setMicMute, &IDevice::getMicMute);
    // TODO: check that the mic is really muted (all sample are 0)
}

TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
    doc::test(
        "If master mute is supported, try to mute and unmute the master "
        "output");
    testOptionalAccessors("master mute", {true, false, true}, &IDevice::setMasterMute,
    doc::test("If master mute is supported, try to mute and unmute the master output");
    testAccessors<OPTIONAL>("master mute", Initial{false}, {true}, &IDevice::setMasterMute,
                            &IDevice::getMasterMute);
    // TODO: check that the master volume is really muted
}
@@ -282,8 +289,8 @@ TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
    doc::test("Test the master volume if supported");
    testOptionalAccessors(
        "master volume", {0, 0.5, 1}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
    testAccessors<OPTIONAL>(
        "master volume", Initial{1}, {0, 0.5}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
        {-0.1, 1.1, NAN, INFINITY, -INFINITY, 1 + std::numeric_limits<float>::epsilon()});
    // TODO: check that the master volume is really changed
}
@@ -957,7 +964,6 @@ TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream(
TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", ASSERT_OK(closeStream());
               ASSERT_RESULT(Result::INVALID_STATE, closeStream()))

static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
static void testCreateTooBigMmapBuffer(IStream* stream) {
    MmapBufferInfo info;
    Result res;
@@ -1415,34 +1421,35 @@ TEST_F(AudioPrimaryHidlTest, updateRotation) {

TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
    doc::test("Query and set the BT SCO NR&EC state");
    testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
    testAccessors<OPTIONAL>("BtScoNrecEnabled", Initial{false, OPTIONAL}, {true},
                            &IPrimaryDevice::setBtScoNrecEnabled,
                            &IPrimaryDevice::getBtScoNrecEnabled);
}

TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
    doc::test("Query and set the SCO whideband state");
    testOptionalAccessors("BtScoWideband", {true, false, true},
    testAccessors<OPTIONAL>("BtScoWideband", Initial{false, OPTIONAL}, {true},
                            &IPrimaryDevice::setBtScoWidebandEnabled,
                            &IPrimaryDevice::getBtScoWidebandEnabled);
}

TEST_F(BoolAccessorPrimaryHidlTest, setGetBtHfpEnabled) {
    doc::test("Query and set the BT HFP state");
    testOptionalAccessors("BtHfpEnabled", {true, false, true}, &IPrimaryDevice::setBtHfpEnabled,
                          &IPrimaryDevice::getBtHfpEnabled);
    testAccessors<OPTIONAL>("BtHfpEnabled", Initial{false, OPTIONAL}, {true},
                            &IPrimaryDevice::setBtHfpEnabled, &IPrimaryDevice::getBtHfpEnabled);
}

using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
    doc::test("Query and set the TTY mode state");
    testOptionalAccessors("TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
    testAccessors<OPTIONAL>("TTY mode", Initial{TtyMode::OFF},
                            {TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
                            &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
}

TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
    doc::test("Query and set the HAC state");
    testOptionalAccessors("HAC", {true, false, true}, &IPrimaryDevice::setHacEnabled,
    testAccessors<OPTIONAL>("HAC", Initial{false}, {true}, &IPrimaryDevice::setHacEnabled,
                            &IPrimaryDevice::getHacEnabled);
}

+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ using ::android::hardware::hidl_vec;

class ParametersUtil {
   public:
    Result setParam(const char* name, const char* value);
    Result getParam(const char* name, bool* value);
    Result getParam(const char* name, int* value);
    Result getParam(const char* name, String8* value, AudioParameter context = {});
+6 −0
Original line number Diff line number Diff line
@@ -112,6 +112,12 @@ std::unique_ptr<AudioParameter> ParametersUtil::getParams(const AudioParameter&
    return std::unique_ptr<AudioParameter>(new AudioParameter(paramsAndValues));
}

Result ParametersUtil::setParam(const char* name, const char* value) {
    AudioParameter param;
    param.add(String8(name), String8(value));
    return setParams(param);
}

Result ParametersUtil::setParam(const char* name, bool value) {
    AudioParameter param;
    param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff));
+44 −4
Original line number Diff line number Diff line
@@ -208,16 +208,56 @@ Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
    return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, enabled);
}

static const char* convertTtyModeFromHIDL(IPrimaryDevice::TtyMode mode) {
    switch (mode) {
        case IPrimaryDevice::TtyMode::OFF:
            return AUDIO_PARAMETER_VALUE_TTY_OFF;
        case IPrimaryDevice::TtyMode::VCO:
            return AUDIO_PARAMETER_VALUE_TTY_VCO;
        case IPrimaryDevice::TtyMode::HCO:
            return AUDIO_PARAMETER_VALUE_TTY_HCO;
        case IPrimaryDevice::TtyMode::FULL:
            return AUDIO_PARAMETER_VALUE_TTY_FULL;
        default:
            return nullptr;
    }
}
static IPrimaryDevice::TtyMode convertTtyModeToHIDL(const char* halMode) {
    if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
        return IPrimaryDevice::TtyMode::OFF;
    else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
        return IPrimaryDevice::TtyMode::VCO;
    else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
        return IPrimaryDevice::TtyMode::HCO;
    else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
        return IPrimaryDevice::TtyMode::FULL;
    return IPrimaryDevice::TtyMode(-1);
}

Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
    int halMode;
    String8 halMode;
    Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_TTY_MODE, &halMode);
    TtyMode mode = retval == Result::OK ? TtyMode(halMode) : TtyMode::OFF;
    _hidl_cb(retval, mode);
    if (retval != Result::OK) {
        _hidl_cb(retval, TtyMode::OFF);
        return Void();
    }
    TtyMode mode = convertTtyModeToHIDL(halMode);
    if (mode == TtyMode(-1)) {
        ALOGE("HAL returned invalid TTY value: %s", halMode.c_str());
        _hidl_cb(Result::INVALID_STATE, TtyMode::OFF);
        return Void();
    }
    _hidl_cb(Result::OK, mode);
    return Void();
}

Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
    return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, static_cast<int>(mode));
    const char* modeStr = convertTtyModeFromHIDL(mode);
    if (modeStr == nullptr) {
        ALOGW("Can not set an invalid TTY value: %d", mode);
        return Result::INVALID_ARGUMENTS;
    }
    return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, modeStr);
}

Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
Loading