Merge "Add the error code "OPERATION_NOT_ALLOWED" and log the error." into oc-dr1-dev
diff --git a/audio/2.0/config/audio_policy_configuration.xsd b/audio/2.0/config/audio_policy_configuration.xsd
index 48b9a9b..c94da80 100644
--- a/audio/2.0/config/audio_policy_configuration.xsd
+++ b/audio/2.0/config/audio_policy_configuration.xsd
@@ -188,6 +188,7 @@
<xs:complexType>
<xs:sequence>
<xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="gains" type="gains" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="name" type="xs:token" use="required"/>
<xs:attribute name="role" type="role" use="required"/>
@@ -199,6 +200,10 @@
<xs:field xpath="samplingRate"/>
<xs:field xpath="channelMasks"/>
</xs:unique>
+ <xs:unique name="mixPortGainUniqueness">
+ <xs:selector xpath="gains/gain"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
@@ -365,16 +370,42 @@
<xs:attribute name="samplingRates" type="samplingRates" use="required"/>
<xs:attribute name="channelMasks" type="channelMask" use="required"/>
</xs:complexType>
+ <xs:simpleType name="gainMode">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+ <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+ <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="gains">
+ <xs:sequence>
+ <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ <xs:attribute name="mode" type="gainMode" use="required"/>
+ <xs:attribute name="channel_mask" type="channelMask" use="optional"/>
+ <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+ <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+ <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
<xs:complexType name="devicePorts">
<xs:sequence>
<xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="gains" type="gains" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="tagName" type="xs:token" use="required"/>
<xs:attribute name="type" type="audioDevice" use="required"/>
<xs:attribute name="role" type="role" use="required"/>
+ <xs:attribute name="address" type="xs:string" use="optional"/>
</xs:complexType>
<xs:unique name="devicePortProfileUniqueness">
<xs:selector xpath="profile"/>
@@ -382,6 +413,10 @@
<xs:field xpath="samplingRate"/>
<xs:field xpath="channelMasks"/>
</xs:unique>
+ <xs:unique name="devicePortGainUniqueness">
+ <xs:selector xpath="gains/gain"/>
+ <xs:field xpath="@name"/>
+ </xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index a27fd66..3b9d35c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -2458,7 +2458,8 @@
Stream stream = {streamId, StreamType::OUTPUT,
static_cast<uint32_t> (it.width),
static_cast<uint32_t> (it.height),
- static_cast<PixelFormat> (it.format), 0, 0,
+ static_cast<PixelFormat> (it.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {stream};
StreamConfiguration config = {streams,
@@ -2507,7 +2508,8 @@
static_cast<uint32_t> (0),
static_cast<uint32_t> (0),
static_cast<PixelFormat> (outputStreams[0].format),
- 0, 0, StreamRotation::ROTATION_0};
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+ StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {stream};
StreamConfiguration config = {streams,
StreamConfigurationMode::NORMAL_MODE};
@@ -2522,7 +2524,8 @@
static_cast<uint32_t> (UINT32_MAX),
static_cast<uint32_t> (UINT32_MAX),
static_cast<PixelFormat> (outputStreams[0].format),
- 0, 0, StreamRotation::ROTATION_0};
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+ StreamRotation::ROTATION_0};
streams[0] = stream;
config = {streams,
StreamConfigurationMode::NORMAL_MODE};
@@ -2537,7 +2540,8 @@
static_cast<uint32_t> (it.width),
static_cast<uint32_t> (it.height),
static_cast<PixelFormat> (UINT32_MAX),
- 0, 0, StreamRotation::ROTATION_0};
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+ StreamRotation::ROTATION_0};
streams[0] = stream;
config = {streams,
StreamConfigurationMode::NORMAL_MODE};
@@ -2551,7 +2555,8 @@
static_cast<uint32_t> (it.width),
static_cast<uint32_t> (it.height),
static_cast<PixelFormat> (it.format),
- 0, 0, static_cast<StreamRotation> (UINT32_MAX)};
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
+ static_cast<StreamRotation> (UINT32_MAX)};
streams[0] = stream;
config = {streams,
StreamConfigurationMode::NORMAL_MODE};
@@ -2633,7 +2638,8 @@
Stream outputStream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (outputIter.width),
static_cast<uint32_t> (outputIter.height),
- static_cast<PixelFormat> (outputIter.format), 0, 0,
+ static_cast<PixelFormat> (outputIter.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {
@@ -2695,12 +2701,14 @@
Stream previewStream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (previewIter.width),
static_cast<uint32_t> (previewIter.height),
- static_cast<PixelFormat> (previewIter.format), 0, 0,
+ static_cast<PixelFormat> (previewIter.format),
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0,
StreamRotation::ROTATION_0};
Stream blobStream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (blobIter.width),
static_cast<uint32_t> (blobIter.height),
- static_cast<PixelFormat> (blobIter.format), 0, 0,
+ static_cast<PixelFormat> (blobIter.format),
+ GRALLOC1_CONSUMER_USAGE_CPU_READ, 0,
StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {
previewStream, blobStream};
@@ -2756,7 +2764,8 @@
Stream stream = {streamId, StreamType::OUTPUT,
static_cast<uint32_t> (hfrStream.width),
static_cast<uint32_t> (hfrStream.height),
- static_cast<PixelFormat> (hfrStream.format), 0, 0,
+ static_cast<PixelFormat> (hfrStream.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {stream};
StreamConfiguration config = {streams,
@@ -2772,7 +2781,8 @@
stream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (0),
static_cast<uint32_t> (0),
- static_cast<PixelFormat> (hfrStream.format), 0, 0,
+ static_cast<PixelFormat> (hfrStream.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
StreamRotation::ROTATION_0};
streams[0] = stream;
config = {streams,
@@ -2787,7 +2797,8 @@
stream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (UINT32_MAX),
static_cast<uint32_t> (UINT32_MAX),
- static_cast<PixelFormat> (hfrStream.format), 0, 0,
+ static_cast<PixelFormat> (hfrStream.format),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
StreamRotation::ROTATION_0};
streams[0] = stream;
config = {streams,
@@ -2801,7 +2812,8 @@
stream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (hfrStream.width),
static_cast<uint32_t> (hfrStream.height),
- static_cast<PixelFormat> (UINT32_MAX), 0, 0,
+ static_cast<PixelFormat> (UINT32_MAX),
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
StreamRotation::ROTATION_0};
streams[0] = stream;
config = {streams,
@@ -2859,12 +2871,13 @@
static_cast<uint32_t> (videoIter.width),
static_cast<uint32_t> (videoIter.height),
static_cast<PixelFormat> (videoIter.format),
- 0, 0, StreamRotation::ROTATION_0};
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 0,
+ StreamRotation::ROTATION_0};
Stream blobStream = {streamId++, StreamType::OUTPUT,
static_cast<uint32_t> (blobIter.width),
static_cast<uint32_t> (blobIter.height),
static_cast<PixelFormat> (blobIter.format),
- GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
+ GRALLOC1_CONSUMER_USAGE_CPU_READ, 0,
StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {
videoStream, blobStream};
@@ -3587,7 +3600,7 @@
static_cast<uint32_t> (outputPreviewStreams[0].width),
static_cast<uint32_t> (outputPreviewStreams[0].height),
static_cast<PixelFormat> (outputPreviewStreams[0].format),
- 0, 0, StreamRotation::ROTATION_0};
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
::android::hardware::hidl_vec<Stream> streams = {*previewStream};
StreamConfiguration config = {streams,
StreamConfigurationMode::NORMAL_MODE};
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
index ada7d09..e332086 100644
--- a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
+++ b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
@@ -51,7 +51,7 @@
// the set of all currently connected displays
std::unordered_set<Display> mDisplays;
// true only when vsync is enabled
- bool mVsyncAllowed = false;
+ bool mVsyncAllowed = true;
// track invalid callbacks
int mInvalidHotplugCount = 0;
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
index 4e65a95..c66cdd0 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
@@ -297,6 +297,11 @@
: IComposerClient::Vsync::DISABLE;
Error error = mClient->setVsyncEnabled(display, vsync);
ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
+
+ // give the hwbinder thread some time to handle any pending vsync callback
+ if (!enabled) {
+ usleep(5 * 1000);
+ }
}
void ComposerClient::execute(TestCommandReader* reader,
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index c77b7d3..0f03546 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -61,6 +61,10 @@
// assume the first display is primary and is never removed
mPrimaryDisplay = waitForFirstDisplay();
+
+ // explicitly disable vsync
+ mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
+ mComposerCallback->setVsyncAllowed(false);
}
void TearDown() override {
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
index c833407..336cab4 100644
--- a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
@@ -485,15 +485,20 @@
// port settings reconfiguration during runtime. reconfigures sample rate and
// number
+typedef struct {
+ OMX_AUDIO_CODINGTYPE eEncoding;
+ AudioDecHidlTest::standardComp comp;
+} packedArgs;
void portReconfiguration(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer,
- OMX_AUDIO_CODINGTYPE eEncoding,
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
- Message msg,
- AudioDecHidlTest::standardComp comp =
- AudioDecHidlTest::standardComp::unknown_comp) {
+ Message msg, PortMode oPortMode, void* args) {
android::hardware::media::omx::V1_0::Status status;
+ packedArgs* audioArgs = static_cast<packedArgs*>(args);
+ OMX_AUDIO_CODINGTYPE eEncoding = audioArgs->eEncoding;
+ AudioDecHidlTest::standardComp comp = audioArgs->comp;
+ (void)oPortMode;
if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
@@ -579,7 +584,8 @@
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer,
OMX_AUDIO_CODINGTYPE eEncoding,
- OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
+ OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
+ AudioDecHidlTest::standardComp comp) {
android::hardware::media::omx::V1_0::Status status;
Message msg;
int timeOut = TIMEOUT_COUNTER;
@@ -590,8 +596,10 @@
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK) {
EXPECT_EQ(msg.type, Message::Type::EVENT);
- portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
- kPortIndexInput, kPortIndexOutput, msg);
+ packedArgs audioArgs = {eEncoding, comp};
+ portReconfiguration(omxNode, observer, iBuffer, oBuffer,
+ kPortIndexInput, kPortIndexOutput, msg,
+ PortMode::PRESET_BYTE_BUFFER, &audioArgs);
}
// status == TIMED_OUT, it could be due to process time being large
// than DEFAULT_TIMEOUT or component needs output buffers to start
@@ -655,8 +663,10 @@
// Port Reconfiguration
if (status == android::hardware::media::omx::V1_0::Status::OK &&
msg.type == Message::Type::EVENT) {
- portReconfiguration(omxNode, observer, iBuffer, oBuffer, eEncoding,
- kPortIndexInput, kPortIndexOutput, msg, comp);
+ packedArgs audioArgs = {eEncoding, comp};
+ portReconfiguration(omxNode, observer, iBuffer, oBuffer,
+ kPortIndexInput, kPortIndexOutput, msg,
+ PortMode::PRESET_BYTE_BUFFER, &audioArgs);
}
if (frameID == (int)Info->size() || frameID == (offset + range)) break;
@@ -800,8 +810,10 @@
(int)Info.size(), compName);
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
- kPortIndexInput, kPortIndexOutput);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
+ kPortIndexInput, kPortIndexOutput, compName);
+ packedArgs audioArgs = {eEncoding, compName};
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
EXPECT_EQ(timestampUslist.empty(), true);
// set state to idle
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
@@ -857,7 +869,9 @@
changeStateIdletoExecute(omxNode, observer);
// request EOS at the start
- testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+ packedArgs audioArgs = {eEncoding, compName};
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
EXPECT_GE(framesReceived, 0U);
@@ -944,8 +958,10 @@
compName);
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
- kPortIndexInput, kPortIndexOutput);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag);
+ kPortIndexInput, kPortIndexOutput, compName);
+ packedArgs audioArgs = {eEncoding, compName};
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, nullptr,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
EXPECT_GE(framesReceived, 1U);
@@ -960,8 +976,9 @@
compName, false);
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
- kPortIndexInput, kPortIndexOutput);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+ kPortIndexInput, kPortIndexOutput, compName);
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
EXPECT_GE(framesReceived, 1U);
@@ -1045,8 +1062,10 @@
(int)Info.size(), compName, false);
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
- kPortIndexInput, kPortIndexOutput);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag);
+ kPortIndexInput, kPortIndexOutput, compName);
+ packedArgs audioArgs = {eEncoding, compName};
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, nullptr,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, &audioArgs);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
framesReceived = 0;
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index e81e6dd..700d2f3 100755
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -406,7 +406,8 @@
void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer, bool signalEOS,
- bool& eosFlag, PortMode* portMode) {
+ bool& eosFlag, PortMode* portMode, portreconfig fptr,
+ OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput, void* args) {
android::hardware::media::omx::V1_0::Status status;
PortMode defaultPortMode[2], *pm;
@@ -443,9 +444,15 @@
status =
observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
if (status == android::hardware::media::omx::V1_0::Status::OK) {
- if (msg.data.eventData.event == OMX_EventBufferFlag) {
- // soft omx components donot send this, we will just ignore it
- // for now
+ if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
+ if (fptr) {
+ (*fptr)(omxNode, observer, iBuffer, oBuffer,
+ kPortIndexInput, kPortIndexOutput, msg, pm[1],
+ args);
+ } else {
+ // something unexpected happened
+ EXPECT_TRUE(false);
+ }
} else {
// something unexpected happened
EXPECT_TRUE(false);
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index d617e45..354b7a7 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -113,6 +113,12 @@
android::hardware::media::omx::V1_0::Message::Type::EVENT) {
*msg = *it;
msgQueue.erase(it);
+ // OMX_EventBufferFlag event is sent when the component has
+ // processed a buffer with its EOS flag set. This event is
+ // not sent by soft omx components. Vendor components can
+ // send this. From IOMX point of view, we will ignore this
+ // event.
+ if (msg->data.eventData.event == OMX_EventBufferFlag) break;
return ::android::hardware::media::omx::V1_0::Status::OK;
} else if (it->type == android::hardware::media::omx::V1_0::
Message::Type::FILL_BUFFER_DONE) {
@@ -299,9 +305,16 @@
android::Vector<BufferInfo>* oBuffer, OMX_U32 kPortIndexInput,
OMX_U32 kPortIndexOutput, int64_t timeoutUs = DEFAULT_TIMEOUT);
+typedef void (*portreconfig)(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+ android::Vector<BufferInfo>* iBuffer,
+ android::Vector<BufferInfo>* oBuffer,
+ OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
+ Message msg, PortMode oPortMode, void* args);
void testEOS(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer, bool signalEOS,
- bool& eosFlag, PortMode* portMode = nullptr);
+ bool& eosFlag, PortMode* portMode = nullptr,
+ portreconfig fptr = nullptr, OMX_U32 kPortIndexInput = 0,
+ OMX_U32 kPortIndexOutput = 1, void* args = nullptr);
#endif // MEDIA_HIDL_TEST_COMMON_H
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
index ac7f829..98b0317 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
@@ -485,8 +485,9 @@
android::Vector<BufferInfo>* iBuffer,
android::Vector<BufferInfo>* oBuffer,
OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput,
- Message msg, PortMode oPortMode) {
+ Message msg, PortMode oPortMode, void* args) {
android::hardware::media::omx::V1_0::Status status;
+ (void)args;
if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
@@ -586,9 +587,6 @@
std::cout << "[ ] Warning ! OMX_EventError/ "
"Decode Frame Call might be failed \n";
return;
- } else if (msg.data.eventData.event == OMX_EventBufferFlag) {
- // soft omx components donot send this, we will just ignore it
- // for now
} else {
// something unexpected happened
ASSERT_TRUE(false);
@@ -613,7 +611,7 @@
EXPECT_EQ(msg.type, Message::Type::EVENT);
portReconfiguration(omxNode, observer, iBuffer, oBuffer,
kPortIndexInput, kPortIndexOutput, msg,
- oPortMode);
+ oPortMode, nullptr);
}
// status == TIMED_OUT, it could be due to process time being large
// than DEFAULT_TIMEOUT or component needs output buffers to start
@@ -679,7 +677,7 @@
msg.type == Message::Type::EVENT) {
portReconfiguration(omxNode, observer, iBuffer, oBuffer,
kPortIndexInput, kPortIndexOutput, msg,
- oPortMode);
+ oPortMode, nullptr);
}
if (frameID == (int)Info->size() || frameID == (offset + range)) break;
@@ -845,7 +843,8 @@
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
kPortIndexInput, kPortIndexOutput, portMode[1]);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode);
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
EXPECT_EQ(timestampUslist.empty(), true);
// set state to idle
changeStateExecutetoIdle(omxNode, observer, &iBuffer, &oBuffer);
@@ -895,7 +894,8 @@
changeStateIdletoExecute(omxNode, observer);
// request EOS at the start
- testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
EXPECT_GE(framesReceived, 0U);
@@ -979,7 +979,8 @@
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
kPortIndexInput, kPortIndexOutput, portMode[1]);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode);
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, false, eosFlag, portMode,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
EXPECT_GE(framesReceived, 1U);
@@ -994,7 +995,8 @@
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
kPortIndexInput, kPortIndexOutput, portMode[1]);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
EXPECT_GE(framesReceived, 1U);
@@ -1077,7 +1079,8 @@
eleStream.close();
waitOnInputConsumption(omxNode, observer, &iBuffer, &oBuffer,
kPortIndexInput, kPortIndexOutput, portMode[1]);
- testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode);
+ testEOS(omxNode, observer, &iBuffer, &oBuffer, true, eosFlag, portMode,
+ portReconfiguration, kPortIndexInput, kPortIndexOutput, nullptr);
flushPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
kPortIndexOutput);
framesReceived = 0;
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index e67f94f..2f00fbb 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -44,6 +44,8 @@
{ 0x20, 0x04, 0x02, 0x01, 0x00 }
#define CORE_INIT_CMD \
{ 0x20, 0x01, 0x00 }
+#define CORE_INIT_CMD_NCI20 \
+ { 0x20, 0x01, 0x02, 0x00, 0x00 }
#define INVALID_COMMAND \
{ 0x20, 0x00, 0x00 }
@@ -290,16 +292,23 @@
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
EXPECT_TRUE(res.no_timeout);
+ cmd = CORE_INIT_CMD_NCI20;
+ } else {
+ cmd = CORE_INIT_CMD;
}
-
- cmd = CORE_INIT_CMD;
data = cmd;
+
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_INIT_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
EXPECT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
-
+ if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
+ res.args->last_data_[13] == 0x00) {
+ // Wait for CORE_CONN_CREDITS_NTF
+ res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+ EXPECT_TRUE(res.no_timeout);
+ }
// Send an Error Data Packet
cmd = INVALID_COMMAND;
data = cmd;
@@ -347,15 +356,23 @@
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
EXPECT_TRUE(res.no_timeout);
+ cmd = CORE_INIT_CMD_NCI20;
+ } else {
+ cmd = CORE_INIT_CMD;
}
-
- cmd = CORE_INIT_CMD;
data = cmd;
+
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_INIT_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
EXPECT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
+ if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
+ res.args->last_data_[13] == 0x00) {
+ // Wait for CORE_CONN_CREDITS_NTF
+ res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+ EXPECT_TRUE(res.no_timeout);
+ }
cmd = CORE_CONN_CREATE_CMD;
data = cmd;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 5a3046d..4684e0f 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -100,7 +100,8 @@
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
- radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError());
+ radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError() ||
+ radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE);
}
}
@@ -225,6 +226,7 @@
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
- radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
+ radioRsp->rspInfo.error == RadioError::SIM_ABSENT ||
+ radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
}
}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 466bea4..d93b176 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -397,7 +397,8 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+ radioRsp->rspInfo.error == RadioError::EMPTY_RECORD);
}
}
@@ -757,7 +758,8 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+ radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
}
/* Reset back to no carrier restriction */
@@ -771,8 +773,9 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
- }
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+ radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+ }
}
/*
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
index 0dc274a..da46e88 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -40,24 +40,6 @@
radioRsp->rspInfo.error == RadioError::NONE ||
radioRsp->rspInfo.error == RadioError::MODEM_ERR);
}
-
- // Test with sending random string
- serial = GetRandomSerialNumber();
- content = "0";
-
- radio->sendEnvelope(serial, content);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
- EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
- if (cardStatus.cardState == CardState::ABSENT) {
- std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
- ASSERT_TRUE(CheckGeneralError() ||
- radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
- radioRsp->rspInfo.error == RadioError::NONE ||
- radioRsp->rspInfo.error == RadioError::MODEM_ERR);
- }
}
/*
@@ -81,23 +63,6 @@
radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
radioRsp->rspInfo.error == RadioError::NONE);
}
-
- serial = GetRandomSerialNumber();
-
- // Test with sending random string
- commandResponse = "0";
-
- radio->sendTerminalResponseToSim(serial, commandResponse);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
- EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
- if (cardStatus.cardState == CardState::ABSENT) {
- std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
- ASSERT_TRUE(CheckGeneralError() ||
- radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
- }
}
/*
@@ -159,21 +124,4 @@
radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
}
-
- // Test with sending random string
- serial = GetRandomSerialNumber();
- contents = "0";
-
- radio->sendEnvelopeWithStatus(serial, contents);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
- EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
- if (cardStatus.cardState == CardState::ABSENT) {
- ASSERT_TRUE(CheckGeneralError() ||
- radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
- radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
- radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
- }
}
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
index ad30e49..10f8f62 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -15,6 +15,7 @@
*/
#include <radio_hidl_hal_utils_v1_1.h>
+#include <vector>
/*
* Test IRadio.setSimCardPower() for the response returned.
@@ -111,4 +112,139 @@
radioRsp_v1_1->rspInfo.error == RadioError::SIM_ABSENT ||
radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
}
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.setCarrierInfoForImsiEncryption() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
+ int serial = GetRandomSerialNumber();
+ ImsiEncryptionInfo imsiInfo;
+ imsiInfo.mcc = "310";
+ imsiInfo.mnc = "004";
+ imsiInfo.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+ imsiInfo.keyIdentifier = "Test";
+ imsiInfo.expirationTime = 20180101;
+
+ radio_v1_1->setCarrierInfoForImsiEncryption(serial, imsiInfo);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
+ radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+ }
+}
+
+/*
+ * Test IRadio.startKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, startKeepalive) {
+ std::vector<KeepaliveRequest> requests = {
+ {
+ // Invalid IPv4 source address
+ KeepaliveType::NATT_IPV4,
+ {192, 168, 0 /*, 100*/},
+ 1234,
+ {8, 8, 4, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid IPv4 destination address
+ KeepaliveType::NATT_IPV4,
+ {192, 168, 0, 100},
+ 1234,
+ {8, 8, 4, 4, 1, 2, 3, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid Keepalive Type
+ static_cast<KeepaliveType>(-1),
+ {192, 168, 0, 100},
+ 1234,
+ {8, 8, 4, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid IPv6 source address
+ KeepaliveType::NATT_IPV6,
+ {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+ 0xBE, 0xEF, 0xBD},
+ 1234,
+ {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x88, 0x44},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid IPv6 destination address
+ KeepaliveType::NATT_IPV6,
+ {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+ 0xBE, 0xEF},
+ 1234,
+ {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x88,
+ /*0x44*/},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid Context ID (cid), this should survive the initial
+ // range checking and fail in the modem data layer
+ KeepaliveType::NATT_IPV4,
+ {192, 168, 0, 100},
+ 1234,
+ {8, 8, 4, 4},
+ 4500,
+ 20000,
+ 0xBAD,
+ },
+ {
+ // Invalid Context ID (cid), this should survive the initial
+ // range checking and fail in the modem data layer
+ KeepaliveType::NATT_IPV6,
+ {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+ 0xBE, 0xEF},
+ 1234,
+ {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x88, 0x44},
+ 4500,
+ 20000,
+ 0xBAD,
+ }};
+
+ for (auto req = requests.begin(); req != requests.end(); req++) {
+ int serial = GetRandomSerialNumber();
+ radio_v1_1->startKeepalive(serial, *req);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+ ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+ radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+ }
+}
+
+/*
+ * Test IRadio.stopKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, stopKeepalive) {
+ int serial = GetRandomSerialNumber();
+
+ radio_v1_1->stopKeepalive(serial, 0xBAD);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+ ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+ radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+}
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
index dd4f1ef..c797e35 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
+++ b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
@@ -53,6 +53,7 @@
hidl_string imsi;
IccIoResult iccIoResult;
int channelId;
+ KeepaliveStatus keepaliveStatus;
// Sms
SendSmsResult sendSmsResult;
@@ -567,4 +568,4 @@
public:
virtual void SetUp() {}
virtual void TearDown() {}
-};
\ No newline at end of file
+};
diff --git a/radio/1.1/vts/functional/radio_response.cpp b/radio/1.1/vts/functional/radio_response.cpp
index 37b80b1..400ef3c 100644
--- a/radio/1.1/vts/functional/radio_response.cpp
+++ b/radio/1.1/vts/functional/radio_response.cpp
@@ -659,7 +659,9 @@
/* 1.1 Apis */
Return<void> RadioResponse_v1_1::setCarrierInfoForImsiEncryptionResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_1.notify();
return Void();
}
@@ -681,11 +683,16 @@
return Void();
}
-Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
- const KeepaliveStatus& /*status*/) {
+Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& info,
+ const KeepaliveStatus& status) {
+ rspInfo = info;
+ keepaliveStatus = status;
+ parent_v1_1.notify();
return Void();
}
-Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_1.notify();
return Void();
-}
\ No newline at end of file
+}
diff --git a/tetheroffload/Android.bp b/tetheroffload/Android.bp
index 4b50f11..f3c7021 100644
--- a/tetheroffload/Android.bp
+++ b/tetheroffload/Android.bp
@@ -1,5 +1,7 @@
// This is an autogenerated file, do not edit.
subdirs = [
"config/1.0",
+ "config/1.0/vts/functional",
"control/1.0",
+ "control/1.0/vts/functional",
]
diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..2e720c6
--- /dev/null
+++ b/tetheroffload/config/1.0/vts/functional/Android.bp
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 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: "VtsHalTetheroffloadConfigV1_0TargetTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalTetheroffloadConfigV1_0TargetTest.cpp"],
+ shared_libs: [
+ "android.hardware.tetheroffload.config@1.0",
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
new file mode 100644
index 0000000..fc61e1c
--- /dev/null
+++ b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "VtsOffloadConfigV1_0TargetTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::Void;
+using android::sp;
+
+#define ASSERT_TRUE_CALLBACK \
+ [&](bool success, const hidl_string& errMsg) { ASSERT_TRUE(success) << errMsg.c_str(); }
+
+#define ASSERT_FALSE_CALLBACK \
+ [&](bool success, const hidl_string& errMsg) { ASSERT_FALSE(success) << errMsg.c_str(); }
+
+const unsigned kFd1Groups = NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY;
+const unsigned kFd2Groups = NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY;
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+ return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int netlinkSocket(int protocol, unsigned groups) {
+ unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
+ if (s.get() < 0) {
+ return -errno;
+ }
+
+ const struct sockaddr_nl bind_addr = {
+ .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+ };
+ if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
+ return -errno;
+ }
+
+ const struct sockaddr_nl kernel_addr = {
+ .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+ };
+ if (::connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+ return -errno;
+ }
+
+ return s.release();
+}
+
+int netlinkSocket(unsigned groups) {
+ return netlinkSocket(NETLINK_NETFILTER, groups);
+}
+
+class OffloadConfigHidlTest : public testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+ ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IOffloadConfig> config;
+};
+
+// Ensure handles can be set with correct socket options.
+TEST_F(OffloadConfigHidlTest, TestSetHandles) {
+ unique_fd fd1(netlinkSocket(kFd1Groups));
+ if (fd1.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+ nativeHandle1->data[0] = fd1.release();
+ const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+ unique_fd fd2(netlinkSocket(kFd2Groups));
+ if (fd2.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+ nativeHandle2->data[0] = fd2.release();
+ const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+ const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+ ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when both FDs are empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandleNone) {
+ native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+ const hidl_handle h1 = hidl_handle(nativeHandle1);
+ native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+ const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+ const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+ ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD2 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle1Only) {
+ unique_fd fd1(netlinkSocket(kFd1Groups));
+ if (fd1.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+ nativeHandle1->data[0] = fd1.release();
+ const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+ native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+ const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+ const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+ ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD1 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
+ native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+ const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+ unique_fd fd2(netlinkSocket(kFd2Groups));
+ if (fd2.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+ nativeHandle2->data[0] = fd2.release();
+ const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+ const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+ ASSERT_TRUE(ret.isOk());
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGE("Test result with status=%d", status);
+ return status;
+}
diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..69fac6e
--- /dev/null
+++ b/tetheroffload/control/1.0/vts/functional/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 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_0TargetTest",
+ defaults: ["hidl_defaults"],
+ srcs: ["VtsHalTetheroffloadControlV1_0TargetTest.cpp"],
+ shared_libs: [
+ "android.hardware.tetheroffload.config@1.0",
+ "android.hardware.tetheroffload.control@1.0",
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
new file mode 100644
index 0000000..3d5cc81
--- /dev/null
+++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "VtsOffloadControlV1_0TargetTest"
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
+#include <android/hardware/tetheroffload/control/1.0/types.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
+using android::hardware::tetheroffload::control::V1_0::IPv4AddrPortPair;
+using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
+using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
+using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
+using android::hardware::tetheroffload::control::V1_0::NetworkProtocol;
+using android::hardware::Void;
+using android::sp;
+
+// We use #defines here so as to get local lamba captures and error message line numbers
+#define ASSERT_TRUE_CALLBACK \
+ [&](bool success, std::string errMsg) { \
+ if (!success) { \
+ ALOGI("Error message: %s", errMsg.c_str()); \
+ } \
+ ASSERT_TRUE(success); \
+ }
+
+#define ASSERT_FALSE_CALLBACK \
+ [&](bool success, std::string errMsg) { \
+ if (!success) { \
+ ALOGI("Error message: %s", errMsg.c_str()); \
+ } \
+ ASSERT_FALSE(success); \
+ }
+
+#define ASSERT_ZERO_BYTES_CALLBACK \
+ [&](uint64_t rxBytes, uint64_t txBytes) { \
+ EXPECT_EQ(0ULL, rxBytes); \
+ EXPECT_EQ(0ULL, txBytes); \
+ }
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+ return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int conntrackSocket(unsigned groups) {
+ unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
+ if (s.get() < 0) {
+ return -errno;
+ }
+
+ const struct sockaddr_nl bind_addr = {
+ .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+ };
+ if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) < 0) {
+ return -errno;
+ }
+
+ const struct sockaddr_nl kernel_addr = {
+ .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+ };
+ if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+ return -errno;
+ }
+
+ return s.release();
+}
+
+constexpr char kCallbackOnEvent[] = "onEvent";
+constexpr char kCallbackUpdateTimeout[] = "updateTimeout";
+
+class TetheringOffloadCallbackArgs {
+ public:
+ OffloadCallbackEvent last_event;
+ NatTimeoutUpdate last_params;
+};
+
+class OffloadControlHidlTestBase : public testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ setupConfigHal();
+ prepareControlHal();
+ }
+
+ virtual void TearDown() override { stopOffload(false); }
+
+ // The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
+ // setup everything correctly and verify basic readiness.
+ void setupConfigHal() {
+ config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+ ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+
+ unique_fd fd1(conntrackSocket(NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY));
+ if (fd1.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+ nativeHandle1->data[0] = fd1.release();
+ hidl_handle h1 = hidl_handle(nativeHandle1);
+
+ unique_fd fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
+ if (fd2.get() < 0) {
+ ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+ FAIL();
+ }
+ native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+ nativeHandle2->data[0] = fd2.release();
+ hidl_handle h2 = hidl_handle(nativeHandle2);
+
+ const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ void prepareControlHal() {
+ control = testing::VtsHalHidlTargetTestBase::getService<IOffloadControl>();
+ 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 initOffload(const bool expected_result) {
+ auto init_cb = [&](bool success, std::string errMsg) {
+ if (!success) {
+ ALOGI("Error message: %s", errMsg.c_str());
+ }
+ ASSERT_EQ(expected_result, success);
+ };
+ const Return<void> ret = control->initOffload(control_cb, init_cb);
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ void setupControlHal() {
+ prepareControlHal();
+ initOffload(true);
+ }
+
+ void stopOffload(const bool expected_result) {
+ auto cb = [&](bool success, const hidl_string& errMsg) {
+ if (!success) {
+ ALOGI("Error message: %s", errMsg.c_str());
+ }
+ ASSERT_EQ(expected_result, success);
+ };
+ const Return<void> ret = control->stopOffload(cb);
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ // Callback class for both events and NAT timeout updates.
+ class TetheringOffloadCallback
+ : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgs>,
+ public ITetheringOffloadCallback {
+ public:
+ TetheringOffloadCallback() = default;
+ virtual ~TetheringOffloadCallback() = default;
+
+ Return<void> onEvent(OffloadCallbackEvent event) override {
+ const TetheringOffloadCallbackArgs args{.last_event = event};
+ NotifyFromCallback(kCallbackOnEvent, args);
+ return Void();
+ };
+
+ Return<void> updateTimeout(const NatTimeoutUpdate& params) override {
+ const TetheringOffloadCallbackArgs args{.last_params = params};
+ NotifyFromCallback(kCallbackUpdateTimeout, args);
+ return Void();
+ };
+ };
+
+ sp<IOffloadConfig> config;
+ sp<IOffloadControl> control;
+ sp<TetheringOffloadCallback> control_cb;
+};
+
+// Call initOffload() multiple times. Check that non-first initOffload() calls return false.
+TEST_F(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
+ initOffload(true);
+ initOffload(false);
+ initOffload(false);
+ initOffload(false);
+ stopOffload(true); // balance out initOffload(true)
+}
+
+// Check that calling stopOffload() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
+ stopOffload(false);
+ stopOffload(false);
+ stopOffload(false);
+}
+
+// Check that calling stopOffload() after a complete init/stop cycle returns false.
+TEST_F(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
+ initOffload(true);
+ stopOffload(true); // balance out initOffload(true)
+ stopOffload(false);
+ stopOffload(false);
+}
+
+// Check that calling setLocalPrefixes() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
+ const vector<hidl_string> prefixes{hidl_string("2001:db8::/64")};
+ const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling getForwardedStats() without first having called initOffload()
+// returns zero bytes statistics.
+TEST_F(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
+ const hidl_string upstream("rmnet_data0");
+ const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setDataLimit() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
+ const hidl_string upstream("rmnet_data0");
+ const uint64_t limit = 5000ULL;
+ const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setUpstreamParameters() without first having called initOffload()
+// returns false.
+TEST_F(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr("192.0.2.0/24");
+ const hidl_string v4Gw("192.0.2.1");
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string prefix("192.0.2.0/24");
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string prefix("2001:db8::/64");
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string prefix("192.0.2.0/24");
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string prefix("2001:db8::/64");
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+class OffloadControlHidlTest : public OffloadControlHidlTestBase {
+ public:
+ virtual void SetUp() override {
+ setupConfigHal();
+ setupControlHal();
+ }
+
+ virtual void TearDown() override { stopOffload(true); }
+};
+
+/*
+ * Tests for IOffloadControl::setLocalPrefixes().
+ */
+
+// Test setLocalPrefixes() accepts an IPv4 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
+ const vector<hidl_string> prefixes{hidl_string("192.0.2.1")};
+ const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts an IPv6 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
+ const vector<hidl_string> prefixes{hidl_string("fe80::1")};
+ const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
+ const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("fe80::/64")};
+ const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setLocalPrefixes() fails given empty input. There is always
+// a non-empty set of local prefixes; when all networking interfaces are down
+// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
+ const vector<hidl_string> prefixes{};
+ const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() fails on incorrectly formed input strings.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
+ const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("invalid")};
+ const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::getForwardedStats().
+ */
+
+// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
+ const hidl_string upstream("invalid");
+ const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
+ const hidl_string upstream("rmnet_data0");
+ const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setDataLimit().
+ */
+
+// Test that setDataLimit() for an empty interface name fails.
+TEST_F(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
+ const hidl_string upstream("");
+ const uint64_t limit = 5000ULL;
+ const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
+ const hidl_string upstream("rmnet_data0");
+ const uint64_t limit = 5000ULL;
+ const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitZeroOk) {
+ const hidl_string upstream("rmnet_data0");
+ const uint64_t limit = 0ULL;
+ const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setUpstreamParameters().
+ */
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr("");
+ const hidl_string v4Gw("");
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr;
+ const hidl_string v4Gw;
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:3")};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr("192.0.2.2");
+ const hidl_string v4Gw("192.0.2.1");
+ const vector<hidl_string> v6Gws{};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr("192.0.2.2");
+ const hidl_string v4Gw("192.0.2.1");
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8::2")};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when all parameters are empty.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
+ const hidl_string iface("");
+ const hidl_string v4Addr("");
+ const hidl_string v4Gw("");
+ const vector<hidl_string> v6Gws{};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
+ const hidl_string v4Addr("192.0.2.2");
+ const hidl_string v4Gw("192.0.2.1");
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+ for (const auto& bogus : {"", "invalid"}) {
+ SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+ const hidl_string iface(bogus);
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Gw("192.0.2.1");
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+ for (const auto& bogus : {"invalid", "192.0.2"}) {
+ SCOPED_TRACE(StringPrintf("v4addr='%s'", bogus));
+ const hidl_string v4Addr(bogus);
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr("192.0.2.2");
+ const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+ for (const auto& bogus : {"invalid", "192.0.2"}) {
+ SCOPED_TRACE(StringPrintf("v4gateway='%s'", bogus));
+ const hidl_string v4Gw(bogus);
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
+ const hidl_string iface("rmnet_data0");
+ const hidl_string v4Addr("192.0.2.2");
+ const hidl_string v4Gw("192.0.2.1");
+ for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
+ SCOPED_TRACE(StringPrintf("v6gateway='%s'", bogus));
+ const vector<hidl_string> v6Gws{hidl_string("fe80::1"), hidl_string(bogus)};
+ const Return<void> ret =
+ control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+/*
+ * Tests for IOffloadControl::addDownstream().
+ */
+
+// Test addDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv4) {
+ const hidl_string iface("dummy0");
+ const hidl_string prefix("192.0.2.0/24");
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv6) {
+ const hidl_string iface("dummy0");
+ const hidl_string prefix("2001:db8::/64");
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, AddDownstreamEmptyFails) {
+ const hidl_string iface("");
+ const hidl_string prefix("");
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
+ const hidl_string prefix("192.0.2.0/24");
+ for (const auto& bogus : {"", "invalid"}) {
+ SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+ const hidl_string iface(bogus);
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+// Test addDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
+ const hidl_string iface("dummy0");
+ for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+ SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+ const hidl_string prefix(bogus);
+ const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+/*
+ * Tests for IOffloadControl::removeDownstream().
+ */
+
+// Test removeDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv4) {
+ const hidl_string iface("dummy0");
+ const hidl_string prefix("192.0.2.0/24");
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv6) {
+ const hidl_string iface("dummy0");
+ const hidl_string prefix("2001:db8::/64");
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
+ const hidl_string iface("");
+ const hidl_string prefix("");
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
+ const hidl_string prefix("192.0.2.0/24");
+ for (const auto& bogus : {"", "invalid"}) {
+ SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+ const hidl_string iface(bogus);
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+// Test removeDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
+ const hidl_string iface("dummy0");
+ for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+ SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+ const hidl_string prefix(bogus);
+ const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+ EXPECT_TRUE(ret.isOk());
+ }
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGE("Test result with status=%d", status);
+ return status;
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
index e4382bc..0851cb2 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -206,5 +206,7 @@
void stopWifi() {
sp<IWifi> wifi = getWifi();
ASSERT_NE(wifi, nullptr);
- ASSERT_EQ(HIDL_INVOKE(wifi, stop).code, WifiStatusCode::SUCCESS);
+ const auto status = HIDL_INVOKE(wifi, stop);
+ ASSERT_TRUE((status.code == WifiStatusCode::SUCCESS) ||
+ (status.code == WifiStatusCode::ERROR_NOT_AVAILABLE));
}
diff --git a/wifi/1.1/default/service.cpp b/wifi/1.1/default/service.cpp
index b3fcd50..b4aed6c 100644
--- a/wifi/1.1/default/service.cpp
+++ b/wifi/1.1/default/service.cpp
@@ -27,7 +27,7 @@
int main(int /*argc*/, char** argv) {
android::base::InitLogging(argv,
android::base::LogdLogger(android::base::SYSTEM));
- LOG(INFO) << "Wifi Hal is starting up...";
+ LOG(INFO) << "Wifi Hal is booting up...";
configureRpcThreadpool(1, true /* callerWillJoin */);
diff --git a/wifi/1.1/default/wifi.cpp b/wifi/1.1/default/wifi.cpp
index fe4f642..8456b90 100644
--- a/wifi/1.1/default/wifi.cpp
+++ b/wifi/1.1/default/wifi.cpp
@@ -108,14 +108,15 @@
LOG(ERROR) << "Failed to invoke onStart callback";
};
}
+ LOG(INFO) << "Wifi HAL started";
} else {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onFailure(wifi_status).isOk()) {
LOG(ERROR) << "Failed to invoke onFailure callback";
}
}
+ LOG(ERROR) << "Wifi HAL start failed";
}
- LOG(INFO) << "Wifi HAL started";
return wifi_status;
}
@@ -139,14 +140,15 @@
LOG(ERROR) << "Failed to invoke onStop callback";
};
}
+ LOG(INFO) << "Wifi HAL stopped";
} else {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onFailure(wifi_status).isOk()) {
LOG(ERROR) << "Failed to invoke onFailure callback";
}
}
+ LOG(ERROR) << "Wifi HAL stop failed";
}
- LOG(INFO) << "Wifi HAL stopped";
return wifi_status;
}
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index 55f5a87..90c36dd 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -32,6 +32,8 @@
using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
using ::android::hardware::wifi::offload::V1_0::ScanResult;
using ::android::hardware::wifi::offload::V1_0::ScanParam;
+using ::android::hardware::wifi::offload::V1_0::Ssid;
+using ::android::hardware::wifi::offload::V1_0::NetworkInfo;
using ::android::hardware::wifi::offload::V1_0::ScanFilter;
using ::android::hardware::wifi::offload::V1_0::ScanStats;
using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
@@ -45,7 +47,8 @@
constexpr char kOffloadCallbackSendError[] = "onError";
namespace {
-const uint8_t kSsid[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'};
const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
const int16_t kRssi = -60;
const uint32_t kFrequency = 2412;
@@ -53,6 +56,10 @@
const uint64_t kTsf = 0;
const uint16_t kCapability = 0;
const uint8_t kNetworkFlags = 0;
+const uint32_t kFrequency1 = 2412;
+const uint32_t kFrequency2 = 2437;
+const uint32_t kDisconnectedModeScanIntervalMs = 5000;
+const int16_t kRssiThreshold = -76;
}
class OffloadCallbackArgs {
@@ -133,7 +140,28 @@
*/
TEST_F(WifiOffloadHidlTest, configureScans) {
ScanParam* pScanParam = new ScanParam();
+ std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
+ pScanParam->disconnectedModeScanIntervalMs =
+ kDisconnectedModeScanIntervalMs;
+ pScanParam->frequencyList = frequencyList;
+ std::vector<Ssid> ssidList;
+ std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2};
+ for (const auto& ssid : ssids) {
+ Ssid tmp = ssid;
+ ssidList.push_back(tmp);
+ }
+ pScanParam->ssidList = ssidList;
ScanFilter* pScanFilter = new ScanFilter();
+ pScanFilter->rssiThreshold = kRssiThreshold;
+ std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2};
+ std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags};
+ std::vector<NetworkInfo> preferredNetworksList;
+ for (size_t i = 0; i < security_flags.size(); i++) {
+ NetworkInfo nwInfo;
+ nwInfo.ssid = match_ssids[i];
+ nwInfo.flags = security_flags[i];
+ preferredNetworksList.push_back(nwInfo);
+ }
const auto& result =
HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
ASSERT_EQ(OffloadStatusCode::OK, result.code);
@@ -154,7 +182,7 @@
TEST_F(WifiOffloadHidlTest, getScanResults) {
wifi_offload_->setEventCallback(wifi_offload_cb_);
std::vector<ScanResult> scan_results;
- std::vector<uint8_t> ssid(kSsid, kSsid + sizeof(kSsid));
+ std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
ScanResult scan_result;
scan_result.tsf = kTsf;
scan_result.rssi = kRssi;