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

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

Merge "Add VTS tests for new methods in contexthub HAL 1.2" into sc-dev

parents 7810998b a2c3db1e
Loading
Loading
Loading
Loading
+6 −29
Original line number Diff line number Diff line
@@ -52,40 +52,17 @@ using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase;
using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase;
using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList;
using ::android::hardware::contexthub::vts_utils::getHubsSync;
using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
using ::android::hardware::contexthub::vts_utils::waitForCallback;

namespace {

// App ID with vendor "GoogT" (Google Testing), app identifier 0x555555. This
// app ID is reserved and must never appear in the list of loaded apps.
constexpr uint64_t kNonExistentAppId = 0x476f6f6754555555;

const std::vector<std::tuple<std::string, std::string>> kTestParameters =
        getHalAndHubIdList<IContexthub>();

class ContexthubHidlTest : public ContexthubHidlTestBase<IContexthub> {};

// Wait for a callback to occur (signaled by the given future) up to the
// provided timeout. If the future is invalid or the callback does not come
// within the given time, returns false.
template <class ReturnType>
bool waitForCallback(std::future<ReturnType> future, ReturnType* result,
                     std::chrono::milliseconds timeout = std::chrono::seconds(5)) {
    auto expiration = std::chrono::system_clock::now() + timeout;

    EXPECT_NE(result, nullptr);
    EXPECT_TRUE(future.valid());
    if (result != nullptr && future.valid()) {
        std::future_status status = future.wait_until(expiration);
        EXPECT_NE(status, std::future_status::timeout) << "Timed out waiting for callback";

        if (status == std::future_status::ready) {
            *result = future.get();
            return true;
        }
    }

    return false;
}
class ContexthubCallbackV1_0 : public ContexthubCallbackBase<IContexthubCallback> {};

// Ensures that the metadata reported in getHubs() is sane
TEST_P(ContexthubHidlTest, TestGetHubs) {
@@ -110,7 +87,7 @@ TEST_P(ContexthubHidlTest, TestGetHubs) {

TEST_P(ContexthubHidlTest, TestRegisterCallback) {
    ALOGD("TestRegisterCallback called, hubId %" PRIu32, getHubId());
    ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
    ASSERT_OK(registerCallback(new ContexthubCallbackV1_0()));
}

TEST_P(ContexthubHidlTest, TestRegisterNullCallback) {
@@ -119,7 +96,7 @@ TEST_P(ContexthubHidlTest, TestRegisterNullCallback) {
}

// Helper callback that puts the async appInfo callback data into a promise
class QueryAppsCallback : public ContexthubCallbackBase {
class QueryAppsCallback : public ContexthubCallbackV1_0 {
  public:
    virtual Return<void> handleAppsInfo(const hidl_vec<HubAppInfo>& appInfo) override {
        ALOGD("Got app info callback with %zu apps", appInfo.size());
@@ -150,7 +127,7 @@ TEST_P(ContexthubHidlTest, TestQueryApps) {

// Helper callback that puts the TransactionResult for the expectedTxnId into a
// promise
class TxnResultCallback : public ContexthubCallbackBase {
class TxnResultCallback : public ContexthubCallbackV1_0 {
  public:
    virtual Return<void> handleTxnResult(uint32_t txnId, TransactionResult result) override {
        ALOGD("Got transaction result callback for txnId %" PRIu32 " (expecting %" PRIu32
+4 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <cinttypes>

using ::android::hardware::contexthub::V1_0::IContexthubCallback;
using ::android::hardware::contexthub::V1_1::IContexthub;
using ::android::hardware::contexthub::V1_1::Setting;
using ::android::hardware::contexthub::V1_1::SettingValue;
@@ -45,10 +46,12 @@ const std::vector<std::tuple<std::string, std::string>> kTestParameters =

class ContexthubHidlTest : public ContexthubHidlTestBase<IContexthub> {};

class ContexthubCallbackV1_0 : public ContexthubCallbackBase<IContexthubCallback> {};

TEST_P(ContexthubHidlTest, TestOnSettingChanged) {
    // In VTS, we only test that sending the values doesn't cause things to blow up - other test
    // suites verify the expected E2E behavior in CHRE
    ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
    ASSERT_OK(registerCallback(new ContexthubCallbackV1_0()));
    hubApi->onSettingChanged(Setting::LOCATION, SettingValue::DISABLED);
    hubApi->onSettingChanged(Setting::LOCATION, SettingValue::ENABLED);
    ASSERT_OK(registerCallback(nullptr));
+164 −7
Original line number Diff line number Diff line
@@ -32,45 +32,202 @@

#include <cinttypes>

using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::contexthub::V1_0::ContextHub;
using ::android::hardware::contexthub::V1_0::Result;
using ::android::hardware::contexthub::V1_0::TransactionResult;
using ::android::hardware::contexthub::V1_1::SettingValue;
using ::android::hardware::contexthub::V1_2::ContextHubMsg;
using ::android::hardware::contexthub::V1_2::HubAppInfo;
using ::android::hardware::contexthub::V1_2::IContexthub;
using ::android::hardware::contexthub::V1_2::IContexthubCallback;
using ::android::hardware::contexthub::V1_2::Setting;
using ::android::hardware::contexthub::vts_utils::asBaseType;
using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase;
using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase;
using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList;
using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
using ::android::hardware::contexthub::vts_utils::waitForCallback;

namespace {

const std::vector<std::tuple<std::string, std::string>> kTestParameters =
        getHalAndHubIdList<IContexthub>();

class ContexthubHidlTest : public ContexthubHidlTestBase<IContexthub> {};
class ContexthubCallbackV1_2 : public ContexthubCallbackBase<IContexthubCallback> {
  public:
    virtual Return<void> handleClientMsg_1_2(
            const ContextHubMsg& /*msg*/,
            const hidl_vec<hidl_string>& /*msgContentPerms*/) override {
        ALOGD("Got client message callback");
        return Void();
    }

    virtual Return<void> handleAppsInfo_1_2(const hidl_vec<HubAppInfo>& /*appInfo*/) override {
        ALOGD("Got app info callback");
        return Void();
    }
};

class ContexthubHidlTest : public ContexthubHidlTestBase<IContexthub> {
  public:
    Result registerCallback_1_2(sp<IContexthubCallback> cb) {
        return hubApi->registerCallback_1_2(getHubId(), cb);
    }
};

// Ensures that the metadata reported in getHubs_1_2() is valid
TEST_P(ContexthubHidlTest, TestGetHubs_1_2) {
    hidl_vec<ContextHub> hubList;
    hubApi->getHubs_1_2(
            [&hubList](const hidl_vec<ContextHub>& hubs,
                       const hidl_vec<hidl_string>& /*hubPermissions*/) { hubList = hubs; });

    ALOGD("System reports %zu hubs", hubList.size());

    for (const ContextHub& hub : hubList) {
        ALOGD("Checking hub ID %" PRIu32, hub.hubId);

        EXPECT_FALSE(hub.name.empty());
        EXPECT_FALSE(hub.vendor.empty());
        EXPECT_FALSE(hub.toolchain.empty());
        EXPECT_GT(hub.peakMips, 0);
        EXPECT_GE(hub.stoppedPowerDrawMw, 0);
        EXPECT_GE(hub.sleepPowerDrawMw, 0);
        EXPECT_GT(hub.peakPowerDrawMw, 0);

        // Minimum 128 byte MTU as required by CHRE API v1.0
        EXPECT_GE(hub.maxSupportedMsgLen, UINT32_C(128));
    }
}

TEST_P(ContexthubHidlTest, TestRegisterCallback) {
    ALOGD("TestRegisterCallback called, hubId %" PRIu32, getHubId());
    ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
}

TEST_P(ContexthubHidlTest, TestRegisterNullCallback) {
    ALOGD("TestRegisterNullCallback called, hubId %" PRIu32, getHubId());
    ASSERT_OK(registerCallback_1_2(nullptr));
}

// In VTS, we only test that sending the values doesn't cause things to blow up - other test
// suites verify the expected E2E behavior in CHRE
TEST_P(ContexthubHidlTest, TestOnWifiSettingChanged) {
    ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
    ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
    hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::DISABLED);
    hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::ENABLED);
    ASSERT_OK(registerCallback(nullptr));
    ASSERT_OK(registerCallback_1_2(nullptr));
}

TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) {
    ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
    ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
    hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::DISABLED);
    hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::ENABLED);
    ASSERT_OK(registerCallback(nullptr));
    ASSERT_OK(registerCallback_1_2(nullptr));
}

TEST_P(ContexthubHidlTest, TestOnGlobalMicDisableSettingChanged) {
    ASSERT_OK(registerCallback(new ContexthubCallbackBase()));
    ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
    hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::DISABLED);
    hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::ENABLED);
    ASSERT_OK(registerCallback(nullptr));
    ASSERT_OK(registerCallback_1_2(nullptr));
}

// Helper callback that puts the async appInfo callback data into a promise
class QueryAppsCallback : public ContexthubCallbackV1_2 {
  public:
    virtual Return<void> handleAppsInfo_1_2(const hidl_vec<HubAppInfo>& appInfo) override {
        ALOGD("Got app info callback with %zu apps", appInfo.size());
        promise.set_value(appInfo);
        return Void();
    }

    std::promise<hidl_vec<HubAppInfo>> promise;
};

// Calls queryApps() and checks the returned metadata
TEST_P(ContexthubHidlTest, TestQueryApps) {
    hidl_vec<hidl_string> hubPerms;
    hubApi->getHubs_1_2([&hubPerms](const hidl_vec<ContextHub>& /*hubs*/,
                                    const hidl_vec<hidl_string>& hubPermissions) {
        hubPerms = hubPermissions;
    });

    ALOGD("TestQueryApps called, hubId %u", getHubId());
    sp<QueryAppsCallback> cb = new QueryAppsCallback();
    ASSERT_OK(registerCallback_1_2(cb));

    Result result = hubApi->queryApps(getHubId());
    ASSERT_OK(result);

    ALOGD("Waiting for app info callback");
    hidl_vec<HubAppInfo> appList;
    ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appList));
    for (const HubAppInfo& appInfo : appList) {
        EXPECT_NE(appInfo.info_1_0.appId, UINT64_C(0));
        EXPECT_NE(appInfo.info_1_0.appId, kNonExistentAppId);
        for (std::string permission : appInfo.permissions) {
            ASSERT_TRUE(hubPerms.contains(permission));
        }
    }
}

// Helper callback that puts the TransactionResult for the expectedTxnId into a
// promise
class TxnResultCallback : public ContexthubCallbackV1_2 {
  public:
    virtual Return<void> handleTxnResult(uint32_t txnId, TransactionResult result) override {
        ALOGD("Got transaction result callback for txnId %" PRIu32 " (expecting %" PRIu32
              ") with result %" PRId32,
              txnId, expectedTxnId, result);
        if (txnId == expectedTxnId) {
            promise.set_value(result);
        }
        return Void();
    }

    uint32_t expectedTxnId = 0;
    std::promise<TransactionResult> promise;
};

// Parameterized fixture that sets the callback to TxnResultCallback
class ContexthubTxnTest : public ContexthubHidlTest {
  public:
    virtual void SetUp() override {
        ContexthubHidlTest::SetUp();
        ASSERT_OK(registerCallback_1_2(cb));
    }

    sp<TxnResultCallback> cb = new TxnResultCallback();
};

TEST_P(ContexthubTxnTest, TestSendMessageToNonExistentNanoApp) {
    ContextHubMsg msg;
    msg.msg_1_0.appName = kNonExistentAppId;
    msg.msg_1_0.msgType = 1;
    msg.msg_1_0.msg.resize(4);
    std::fill(msg.msg_1_0.msg.begin(), msg.msg_1_0.msg.end(), 0);

    ALOGD("Sending message to non-existent nanoapp");
    Result result = hubApi->sendMessageToHub_1_2(getHubId(), msg);
    if (result != Result::OK && result != Result::BAD_PARAMS &&
        result != Result::TRANSACTION_FAILED) {
        FAIL() << "Got result " << asBaseType(result) << ", expected OK, BAD_PARAMS"
               << ", or TRANSACTION_FAILED";
    }
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest);
INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters),
                         android::hardware::PrintInstanceTupleNameToString<>);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubTxnTest);
INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubTxnTest, testing::ValuesIn(kTestParameters),
                         android::hardware::PrintInstanceTupleNameToString<>);

}  // anonymous namespace
+2 −1
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@ namespace vts_utils {

// Base callback implementation that just logs all callbacks by default, but
// records a failure if
class ContexthubCallbackBase : public V1_0::IContexthubCallback {
template <class CallbackType>
class ContexthubCallbackBase : public CallbackType {
  public:
    virtual Return<void> handleClientMsg(const V1_0::ContextHubMsg& /*msg*/) override {
        ALOGD("Got client message callback");
+27 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ namespace hardware {
namespace contexthub {
namespace vts_utils {

// App ID with vendor "GoogT" (Google Testing), app identifier 0x555555. This
// app ID is reserved and must never appear in the list of loaded apps.
constexpr uint64_t kNonExistentAppId = 0x476f6f6754555555;

#define ASSERT_OK(result) ASSERT_EQ(result, ::android::hardware::contexthub::V1_0::Result::OK)
#define EXPECT_OK(result) EXPECT_EQ(result, ::android::hardware::contexthub::V1_0::Result::OK)

@@ -64,6 +68,29 @@ static std::vector<std::tuple<std::string, std::string>> getHalAndHubIdList() {
    return parameters;
}

// Wait for a callback to occur (signaled by the given future) up to the
// provided timeout. If the future is invalid or the callback does not come
// within the given time, returns false.
template <class ReturnType>
bool waitForCallback(std::future<ReturnType> future, ReturnType* result,
                     std::chrono::milliseconds timeout = std::chrono::seconds(5)) {
    auto expiration = std::chrono::system_clock::now() + timeout;

    EXPECT_NE(result, nullptr);
    EXPECT_TRUE(future.valid());
    if (result != nullptr && future.valid()) {
        std::future_status status = future.wait_until(expiration);
        EXPECT_NE(status, std::future_status::timeout) << "Timed out waiting for callback";

        if (status == std::future_status::ready) {
            *result = future.get();
            return true;
        }
    }

    return false;
}

}  // namespace vts_utils
}  // namespace contexthub
}  // namespace hardware