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

Commit d03b8797 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "fix-b-141847510-parametrize-device-and-factory"

* changes:
  audio: Parametrize core VTS tests
  audio: Parametrize effect VTS tests for V6.0
  audio: Extract utility functions
parents 356c0071 8613f809
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -114,6 +114,27 @@ inline ::testing::AssertionResult assertOk(const char* expr, const Return<Result
#define ASSERT_RESULT(expected, ret) ASSERT_PRED_FORMAT2(detail::assertResult, expected, ret)
#define EXPECT_RESULT(expected, ret) EXPECT_PRED_FORMAT2(detail::assertResult, expected, ret)

/** Unpack the provided result.
 * If the result is not OK, register a failure and return the default initializer value. */
template <class R>
static R extract(const Return<R>& ret) {
    if (!ret.isOk()) {
        EXPECT_IS_OK(ret);
        return R{};
    }
    return ret;
}

template <class Result, class Value>
static void expectValueOrFailure(Result res, Value expectedValue, Value actualValue,
                                 Result expectedFailure) {
    if (res == Result::OK) {
        ASSERT_EQ(expectedValue, actualValue);
    } else {
        ASSERT_EQ(expectedFailure, res) << "Unexpected result " << toString(res);
    }
}

}  // namespace utility
}  // namespace test
}  // namespace common
+6 −7
Original line number Diff line number Diff line
@@ -20,9 +20,6 @@
#include <functional>
#include <list>

#include <VtsHalHidlTargetTestEnvBase.h>
#include <gtest/gtest.h>

namespace android {
namespace hardware {
namespace audio {
@@ -34,18 +31,20 @@ namespace utility {
 * Avoid destroying static objects after main return.
 * Post main return destruction leads to incorrect gtest timing measurements as
 * well as harder debuging if anything goes wrong during destruction. */
class Environment : public ::testing::VtsHalHidlTargetTestEnvBase {
class EnvironmentTearDown {
  public:
    using TearDownFunc = std::function<void()>;
    void registerTearDown(TearDownFunc&& tearDown) { tearDowns.push_front(std::move(tearDown)); }

   private:
    void HidlTearDown() override {
  protected:
    void executeAllTearDowns() {
        // Call the tear downs in reverse order of insertion
        for (auto& tearDown : tearDowns) {
            tearDown();
        }
    }

  private:
    std::list<TearDownFunc> tearDowns;
};

+5 −4
Original line number Diff line number Diff line
@@ -60,19 +60,20 @@ TEST_IO_STREAM(SetConnectedState,
               "deconnection",
               testConnectedState(stream.get()))

TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", ASSERT_IS_OK(device->getHwAvSync()));
TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail",
               ASSERT_IS_OK(getDevice()->getHwAvSync()));

TEST_F(AudioPrimaryHidlTest, setMode) {
TEST_P(AudioPrimaryHidlTest, setMode) {
    doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
    // Test Invalid values
    for (AudioMode mode : {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
        SCOPED_TRACE("mode=" + toString(mode));
        ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode));
        ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(mode));
    }
    // Test valid values
    for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
                           AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
        SCOPED_TRACE("mode=" + toString(mode));
        ASSERT_OK(device->setMode(mode));
        ASSERT_OK(getDevice()->setMode(mode));
    }
}
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HARDWARE_AUDIO_CORE_2_0_ENVIRONMENT_TEARDOWN_H
#define ANDROID_HARDWARE_AUDIO_CORE_2_0_ENVIRONMENT_TEARDOWN_H

#include <VtsHalHidlTargetTestEnvBase.h>
#include <gtest/gtest.h>

#include "utility/EnvironmentTearDown.h"

class Environment : public ::android::hardware::audio::common::test::utility::EnvironmentTearDown,
                    public ::testing::VtsHalHidlTargetTestEnvBase {
  private:
    void HidlTearDown() override {
        executeAllTearDowns();
        VtsHalHidlTargetTestEnvBase::HidlTearDown();
    }
};

#endif  // ANDROID_HARDWARE_AUDIO_CORE_2_0_ENVIRONMENT_TEARDOWN_H
+29 −42
Original line number Diff line number Diff line
@@ -16,25 +16,14 @@

#include "AudioPrimaryHidlHalTest.h"

static void waitForDeviceDestruction() {
    // FIXME: there is no way to know when the remote IDevice is being destroyed
    //        Binder does not support testing if an object is alive, thus
    //        wait for 100ms to let the binder destruction propagates and
    //        the remote device has the time to be destroyed.
    //        flushCommand makes sure all local command are sent, thus should reduce
    //        the latency between local and remote destruction.
    IPCThreadState::self()->flushCommands();
    usleep(100 * 1000);
}

TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
    doc::test("Calling openDevice(\"primary\") should return the primary device.");
    struct WaitExecutor {
        ~WaitExecutor() { waitForDeviceDestruction(); }
        ~WaitExecutor() { DeviceManager::waitForInstanceDestruction(); }
    } waitExecutor;  // Make sure we wait for the device destruction on exiting from the test.
    Result result;
    sp<IDevice> baseDevice;
    ASSERT_OK(devicesFactory->openDevice("primary", returnIn(result, baseDevice)));
    ASSERT_OK(getDevicesFactory()->openDevice("primary", returnIn(result, baseDevice)));
    if (result != Result::OK && isPrimaryDeviceOptional()) {
        GTEST_SKIP() << "No primary device on this factory";  // returns
    }
@@ -50,10 +39,10 @@ TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
/////////////////////////// get(Active)Microphones ///////////////////////////
//////////////////////////////////////////////////////////////////////////////

TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
TEST_P(AudioPrimaryHidlTest, GetMicrophonesTest) {
    doc::test("Make sure getMicrophones always succeeds");
    hidl_vec<MicrophoneInfo> microphones;
    ASSERT_OK(device->getMicrophones(returnIn(res, microphones)));
    ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones)));
    ASSERT_OK(res);
    if (microphones.size() > 0) {
        // When there is microphone on the phone, try to open an input stream
@@ -75,14 +64,14 @@ TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
            }
            sp<IStreamIn> stream;
            AudioConfig suggestedConfig{};
            ASSERT_OK(device->openInputStream(ioHandle, microphone.deviceAddress, config, flags,
                                              initMetadata,
            ASSERT_OK(getDevice()->openInputStream(ioHandle, microphone.deviceAddress, config,
                                                   flags, initMetadata,
                                                   returnIn(res, stream, suggestedConfig)));
            if (res != Result::OK) {
                ASSERT_TRUE(stream == nullptr);
                AudioConfig suggestedConfigRetry{};
                ASSERT_OK(device->openInputStream(ioHandle, microphone.deviceAddress,
                                                  suggestedConfig, flags, initMetadata,
                ASSERT_OK(getDevice()->openInputStream(
                        ioHandle, microphone.deviceAddress, suggestedConfig, flags, initMetadata,
                        returnIn(res, stream, suggestedConfigRetry)));
            }
            ASSERT_OK(res);
@@ -131,7 +120,7 @@ TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
    }
}

TEST_F(AudioPrimaryHidlTest, SetConnectedState) {
TEST_P(AudioPrimaryHidlTest, SetConnectedState) {
    doc::test("Check that the HAL can be notified of device connection and deconnection");
    using AD = AudioDevice;
    for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
@@ -140,7 +129,7 @@ TEST_F(AudioPrimaryHidlTest, SetConnectedState) {
            SCOPED_TRACE("state=" + ::testing::PrintToString(state));
            DeviceAddress address = {};
            address.device = deviceType;
            auto ret = device->setConnectedState(address, state);
            auto ret = getDevice()->setConnectedState(address, state);
            ASSERT_TRUE(ret.isOk());
            if (ret == Result::NOT_SUPPORTED) {
                doc::partialTest("setConnectedState is not supported");
@@ -153,9 +142,7 @@ TEST_F(AudioPrimaryHidlTest, SetConnectedState) {
    // Because there is no way of knowing if the devices were connected before
    // calling setConnectedState, there is no way to restore the HAL to its
    // initial state. To workaround this, destroy the HAL at the end of this test.
    device.clear();
    waitForDeviceDestruction();
    ASSERT_NO_FATAL_FAILURE(initPrimaryDevice());
    ASSERT_TRUE(DeviceManager::getInstance().resetPrimary(getFactoryName()));
}

static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
@@ -199,7 +186,7 @@ static void checkGetHwAVSync(IDevice* device) {
    }
    ASSERT_OK(res);
}
TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(device.get()));
TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(getDevice().get()));

TEST_P(InputStreamTest, updateSinkMetadata) {
    doc::test("The HAL should not crash on metadata change");
@@ -259,58 +246,58 @@ TEST_P(OutputStreamTest, updateSourceMetadata) {
    ASSERT_OK(stream->updateSourceMetadata(initMetadata));
}

TEST_F(AudioPrimaryHidlTest, setMode) {
TEST_P(AudioPrimaryHidlTest, setMode) {
    doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
    // Test Invalid values
    for (int mode : {-2, -1, int(AudioMode::IN_COMMUNICATION) + 1}) {
        ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode(mode)))
        ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode)))
                << "mode=" << mode;
    }
    // Test valid values
    for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
                           AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
        ASSERT_OK(device->setMode(mode)) << "mode=" << toString(mode);
        ASSERT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode);
    }
}

TEST_F(AudioPrimaryHidlTest, setBtHfpSampleRate) {
TEST_P(AudioPrimaryHidlTest, setBtHfpSampleRate) {
    doc::test(
        "Make sure setBtHfpSampleRate either succeeds or "
        "indicates that it is not supported at all, or that the provided value is invalid");
    for (auto samplingRate : {8000, 16000, 22050, 24000}) {
        ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, device->setBtHfpSampleRate(samplingRate));
        ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setBtHfpSampleRate(samplingRate));
    }
}

TEST_F(AudioPrimaryHidlTest, setBtHfpVolume) {
TEST_P(AudioPrimaryHidlTest, setBtHfpVolume) {
    doc::test(
        "Make sure setBtHfpVolume is either not supported or "
        "only succeed if volume is in [0,1]");
    auto ret = device->setBtHfpVolume(0.0);
    auto ret = getDevice()->setBtHfpVolume(0.0);
    ASSERT_TRUE(ret.isOk());
    if (ret == Result::NOT_SUPPORTED) {
        doc::partialTest("setBtHfpVolume is not supported");
        return;
    }
    testUnitaryGain([](float volume) { return device->setBtHfpVolume(volume); });
    testUnitaryGain([this](float volume) { return getDevice()->setBtHfpVolume(volume); });
}

TEST_F(AudioPrimaryHidlTest, setBtScoHeadsetDebugName) {
TEST_P(AudioPrimaryHidlTest, setBtScoHeadsetDebugName) {
    doc::test(
        "Make sure setBtScoHeadsetDebugName either succeeds or "
        "indicates that it is not supported");
    ASSERT_RESULT(okOrNotSupported, device->setBtScoHeadsetDebugName("test"));
    ASSERT_RESULT(okOrNotSupported, getDevice()->setBtScoHeadsetDebugName("test"));
}

TEST_F(AudioPrimaryHidlTest, updateRotation) {
TEST_P(AudioPrimaryHidlTest, updateRotation) {
    doc::test("Check that the hal can receive the current rotation");
    for (Rotation rotation : {Rotation::DEG_0, Rotation::DEG_90, Rotation::DEG_180,
                              Rotation::DEG_270, Rotation::DEG_0}) {
        ASSERT_RESULT(okOrNotSupported, device->updateRotation(rotation));
        ASSERT_RESULT(okOrNotSupported, getDevice()->updateRotation(rotation));
    }
}

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