Merge changes from topic "sp14-ipahal"

* changes:
  Update VTS tests for setDataWarningAndLimit
  Add VTS tests for setDataWarningAndLimit HAL interface
  Create VTS folder and put necessary setup code
  [SP14] Add HAL to set warning quota to tehtering offload hardware
This commit is contained in:
Junyu Lai
2021-01-29 00:57:56 +00:00
committed by Gerrit Code Review
12 changed files with 412 additions and 32 deletions

View File

@@ -507,7 +507,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.tetheroffload.control</name>
<version>1.0</version>
<version>1.1</version>
<interface>
<name>IOffloadControl</name>
<instance>default</instance>

View File

@@ -30,3 +30,17 @@ cc_test {
"vts",
],
}
cc_test_library {
name: "VtsHalTetheroffloadControlV1_0TargetTest-lib",
defaults: ["VtsHalTargetTestDefaults"],
export_include_dirs: ["include"],
static_libs: [
"android.hardware.tetheroffload.config@1.0",
"android.hardware.tetheroffload.control@1.0",
],
srcs: [
"OffloadControlTestBase.cpp",
"OffloadControlTestUtils.cpp",
],
}

View File

@@ -53,29 +53,6 @@ void OffloadControlTestBase::setupConfigHal() {
ASSERT_TRUE(ret.isOk());
}
void OffloadControlTestBase::prepareControlHal() {
control = createControl(std::get<1>(GetParam()));
ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
control_cb = new TetheringOffloadCallback();
ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
}
void OffloadControlTestBase::initOffload(const bool expected_result) {
auto init_cb = [&](bool success, std::string errMsg) {
std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
success ? "succeeded" : "failed", errMsg.c_str());
ASSERT_EQ(expected_result, success) << msg;
};
const Return<void> ret = control->initOffload(control_cb, init_cb);
ASSERT_TRUE(ret.isOk());
}
void OffloadControlTestBase::setupControlHal() {
prepareControlHal();
initOffload(true);
}
void OffloadControlTestBase::stopOffload(const ExpectBoolean value) {
auto cb = [&](bool success, const hidl_string& errMsg) {
switch (value) {

View File

@@ -36,7 +36,6 @@ using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::Void;
using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
@@ -64,17 +63,21 @@ class OffloadControlTestBase : public testing::TestWithParam<std::tuple<std::str
// Called once in setup stage to retrieve correct version of
// IOffloadControl object.
virtual sp<IOffloadControl> createControl(const std::string& serviceName) = 0;
virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl(
const std::string& serviceName) = 0;
// The IOffloadConfig HAL is tested more thoroughly elsewhere. Here the
// class just setup everything correctly and verify basic readiness.
void setupConfigHal();
void prepareControlHal();
virtual void prepareControlHal() = 0;
void initOffload(const bool expected_result);
virtual void initOffload(const bool expected_result) = 0;
void setupControlHal();
void setupControlHal() {
prepareControlHal();
initOffload(true);
};
void stopOffload(const ExpectBoolean value);
@@ -100,6 +103,6 @@ class OffloadControlTestBase : public testing::TestWithParam<std::tuple<std::str
};
sp<IOffloadConfig> config;
sp<IOffloadControl> control;
sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> control;
sp<TetheringOffloadCallback> control_cb;
};

View File

@@ -26,8 +26,28 @@ class OffloadControlTestV1_0_HalNotStarted : public OffloadControlTestBase {
prepareControlHal();
}
virtual sp<IOffloadControl> createControl(const std::string& serviceName) override {
return IOffloadControl::getService(serviceName);
virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl(
const std::string& serviceName) override {
return android::hardware::tetheroffload::control::V1_0::IOffloadControl::getService(
serviceName);
}
virtual void prepareControlHal() override {
control = createControl(std::get<1>(GetParam()));
ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
control_cb = new TetheringOffloadCallback();
ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
}
virtual void initOffload(const bool expected_result) override {
auto init_cb = [&](bool success, std::string errMsg) {
std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
success ? "succeeded" : "failed", errMsg.c_str());
ASSERT_EQ(expected_result, success) << msg;
};
const Return<void> ret = control->initOffload(control_cb, init_cb);
ASSERT_TRUE(ret.isOk());
}
};

View File

@@ -0,0 +1,16 @@
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "android.hardware.tetheroffload.control@1.1",
root: "android.hardware",
srcs: [
"types.hal",
"IOffloadControl.hal",
"ITetheringOffloadCallback.hal",
],
interfaces: [
"android.hardware.tetheroffload.control@1.0",
"android.hidl.base@1.0",
],
gen_java: true,
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2020 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.
*/
package android.hardware.tetheroffload.control@1.1;
import @1.0::IOffloadControl;
/**
* Interface used to control the lifecycle of tethering offload. Note that callbacks of 1.1 HAL
* can be registered with the existing callback registration methods from 1.0 HAL.
*/
interface IOffloadControl extends @1.0::IOffloadControl {
/**
* Instruct hardware to send callbacks after certain number of bytes have been transferred in
* either direction on this upstream interface.
*
* The specified quota bytes must be applied to all traffic on the given upstream interface.
* This includes hardware forwarded traffic, software forwarded traffic, and AP-originated
* traffic. IPv4 and IPv6 traffic both count towards the same quota. IP headers are included
* in the byte count quota, but, link-layer headers are not.
*
* This API may only be called while offload is occurring on this upstream. The hardware
* management process MUST NOT store the values when offload is not started and applies once
* offload is started. This is because the quota values would likely become stale over
* time and would not reflect any new traffic that has occurred.
*
* This API replaces {@link @1.0::IOffloadControl::setDataLimit}, the framework would always
* calls this API if 1.1 HAL is supported. Otherwise, calls the other one. Thus, no
* interaction between the two APIs need to be addressed. However, the hardware implementation
* still needs to keep functionality of both in case of shipping with older framework that
* doesn't support 1.1 HAL.
*
* The specified quota bytes MUST replace any previous quotas set by
* {@code setDataWarningAndLimit} specified on the same interface. It may be interpreted as
* "tell me when either <warningBytes> or <limitBytes> bytes have been transferred
* (in either direction), and stop offload when <limitBytes> bytes have been transferred,
* starting now and counting from zero on <upstream>."
*
* Once the {@code warningBytes} is reached, the callback registered in initOffload must be
* called with {@code OFFLOAD_WARNING_REACHED} to indicate this event. Once the event fires
* for this upstream, no further {@code OFFLOAD_WARNING_REACHED} event will be fired for this
* upstream unless this method is called again with the same interface. Note that there is
* no need to call initOffload again to resume offload if stopOffload was not called by the
* client.
*
* Similarly, Once the {@code limitBytes} is reached, the callback registered in initOffload
* must be called with {@code OFFLOAD_STOPPED_LIMIT_REACHED} to indicate this event. Once
* the event fires for this upstream, no further {@code OFFLOAD_STOPPED_LIMIT_REACHED}
* event will be fired for this upstream unless this method is called again with the same
* interface. However, unlike {@code warningBytes}, when {@code limitBytes} is reached,
* all offload must be stopped. If offload is desired again, the hardware management
* process must be completely reprogrammed by calling setUpstreamParameters and
* addDownstream again.
*
* Note that when one of the quota bytes is reached, the other one is still considered valid
* unless this method is called again with the same interface.
*
* @param upstream Upstream interface name that quota must apply to.
* @param warningBytes The quota of warning, defined as the number of bytes, starting from
* zero and counting from now.
* @param limitBytes The quota of limit, defined as the number of bytes, starting from zero
* and counting from now.
*
* @return success true if quota is applied, false otherwise
* @return errMsg a human readable string if error has occurred.
*/
setDataWarningAndLimit(string upstream, uint64_t warningBytes, uint64_t limitBytes)
generates (bool success, string errMsg);
};

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2020 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.
*/
package android.hardware.tetheroffload.control@1.1;
import @1.0::ITetheringOffloadCallback;
import OffloadCallbackEvent;
/**
* Callback providing information about status of hardware management process
* as well as providing a way to keep offloaded connections from timing out.
*/
interface ITetheringOffloadCallback extends @1.0::ITetheringOffloadCallback {
/**
* Called when an asynchronous event is generated by the hardware
* management process. Events which are common for 1.0 and 1.1 HAL
* MUST be fired on both 1.0 and 1.1 callback.
*/
oneway onEvent_1_1(OffloadCallbackEvent event);
};

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2020 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.
*/
package android.hardware.tetheroffload.control@1.1;
import @1.0::OffloadCallbackEvent;
enum OffloadCallbackEvent : @1.0::OffloadCallbackEvent {
/**
* This event is fired when the quota, applied in setDataWarning, has expired. It is
* recommended that the client query for statistics immediately after receiving this event.
* Note that hardware acceleration must not be stopped upon receiving this event.
*/
OFFLOAD_WARNING_REACHED = 6,
};

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2020 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.
cc_test {
name: "VtsHalTetheroffloadControlV1_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalTetheroffloadControlV1_1TargetTest.cpp"],
local_include_dirs: ["include"],
static_libs: [
"android.hardware.tetheroffload.config@1.0",
"android.hardware.tetheroffload.control@1.0",
"android.hardware.tetheroffload.control@1.1",
"VtsHalTetheroffloadControlV1_0TargetTest-lib",
],
test_suites: [
"general-tests",
"vts",
],
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2020 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.
*/
#include <OffloadControlTestV1_1.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
using android::hardware::tetheroffload::control::V1_1::IOffloadControl;
const hidl_string TEST_IFACE("rmnet_data0");
// Check that calling setDataWarningAndLimit() without first having called initOffload() returns
// false.
TEST_P(OffloadControlTestV1_1_HalNotStarted, SetDataWarningAndLimitWithoutInitReturnsFalse) {
const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 5000ULL, 5000ULL,
ASSERT_FALSE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
/*
* Tests for IOffloadControl::setDataWarningAndLimit().
*/
// Test that setDataWarningAndLimit() for an empty interface name fails.
TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitEmptyUpstreamIfaceFails) {
const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(
hidl_string(""), 12345ULL, 67890ULL, ASSERT_FALSE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitNonZeroOk) {
const Return<void> ret = getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 4000ULL, 5000ULL,
ASSERT_TRUE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
// are ever actually caused to be forwarded.
TEST_P(OffloadControlTestV1_1_HalStarted, SetDataWarningAndLimitZeroOk) {
const Return<void> ret =
getControlV1_1()->setDataWarningAndLimit(TEST_IFACE, 0ULL, 0ULL, ASSERT_TRUE_CALLBACK);
EXPECT_TRUE(ret.isOk());
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_1_HalNotStarted);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_1_HalStarted);
INSTANTIATE_TEST_CASE_P(
PerInstance, OffloadControlTestV1_1_HalNotStarted,
testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames(
IOffloadConfig::descriptor)),
testing::ValuesIn(android::hardware::getAllHalInstanceNames(
IOffloadControl::descriptor))),
android::hardware::PrintInstanceTupleNameToString<>);
INSTANTIATE_TEST_CASE_P(
PerInstance, OffloadControlTestV1_1_HalStarted,
testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames(
IOffloadConfig::descriptor)),
testing::ValuesIn(android::hardware::getAllHalInstanceNames(
IOffloadControl::descriptor))),
android::hardware::PrintInstanceTupleNameToString<>);

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2020 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.
*/
#pragma once
#include <OffloadControlTestV1_0.h>
#include <android/hardware/tetheroffload/control/1.1/IOffloadControl.h>
#include <android/hardware/tetheroffload/control/1.1/ITetheringOffloadCallback.h>
#include <gtest/gtest.h>
constexpr char kCallbackOnEvent_1_1[] = "onEvent_1_1";
class TetheringOffloadCallbackArgsV1_1 {
public:
android::hardware::tetheroffload::control::V1_1::OffloadCallbackEvent last_event;
};
class OffloadControlTestV1_1_HalNotStarted : public OffloadControlTestV1_0_HalNotStarted {
public:
virtual sp<android::hardware::tetheroffload::control::V1_0::IOffloadControl> createControl(
const std::string& serviceName) override {
return android::hardware::tetheroffload::control::V1_1::IOffloadControl::getService(
serviceName);
};
void prepareControlHal() override {
control = createControl(std::get<1>(GetParam()));
ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
control_cb_1_1 = new TetheringOffloadCallbackV1_1();
ASSERT_NE(nullptr, control_cb_1_1.get()) << "Could not get offload callback";
};
void initOffload(const bool expected_result) override {
auto init_cb = [&](bool success, std::string errMsg) {
std::string msg = StringPrintf("Unexpectedly %s to init offload: %s",
success ? "succeeded" : "failed", errMsg.c_str());
ASSERT_EQ(expected_result, success) << msg;
};
auto control = getControlV1_1();
ASSERT_NE(control, nullptr);
const Return<void> ret = control->initOffload(control_cb_1_1, init_cb);
ASSERT_TRUE(ret.isOk());
};
sp<android::hardware::tetheroffload::control::V1_1::IOffloadControl> getControlV1_1() {
// The cast is safe since only devices with V1.1+ HAL will be enumerated and pass in to the
// test.
return android::hardware::tetheroffload::control::V1_1::IOffloadControl::castFrom(control)
.withDefault(nullptr);
};
// Callback class for both new events.
class TetheringOffloadCallbackV1_1
: public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgsV1_1>,
public android::hardware::tetheroffload::control::V1_1::ITetheringOffloadCallback {
public:
Return<void> onEvent_1_1(
android::hardware::tetheroffload::control::V1_1::OffloadCallbackEvent event)
override {
const TetheringOffloadCallbackArgsV1_1 args{.last_event = event};
NotifyFromCallback(kCallbackOnEvent_1_1, args);
return Void();
};
Return<void> onEvent([[maybe_unused]] OffloadCallbackEvent event) override {
// Tested only in IOffloadControl 1.0.
return Void();
};
Return<void> updateTimeout([[maybe_unused]] const NatTimeoutUpdate& params) override {
// Tested only in IOffloadControl 1.0.
return Void();
};
};
sp<TetheringOffloadCallbackV1_1> control_cb_1_1;
};
class OffloadControlTestV1_1_HalStarted : public OffloadControlTestV1_1_HalNotStarted {
public:
virtual void SetUp() override {
setupConfigHal();
setupControlHal();
}
};