Merge "NN HAL: Upgrade IPreparedModel::executeSynchronously to 1.3."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 0140275..6740bb5 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -2,6 +2,7 @@
ignore_merged_commits = true
[Builtin Hooks]
+bpfmt = true
clang_format = true
[Hook Scripts]
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 98e125b..0e18f48 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,6 +1,12 @@
{
"presubmit": [
{
+ "name": "vts_treble_vintf_framework_test"
+ },
+ {
+ "name": "vts_treble_vintf_vendor_test"
+ },
+ {
"name": "hidl_implementation_test"
}
]
diff --git a/audio/5.0/config/api/current.txt b/audio/5.0/config/api/current.txt
index c665781..a1d8e1e 100644
--- a/audio/5.0/config/api/current.txt
+++ b/audio/5.0/config/api/current.txt
@@ -237,6 +237,7 @@
method public audio.policy.configuration.V5_0.GainMode getMode();
method public String getName();
method public int getStepValueMB();
+ method public boolean getUseForVolume();
method public void setChannel_mask(String);
method public void setDefaultValueMB(int);
method public void setMaxRampMs(int);
@@ -246,6 +247,7 @@
method public void setMode(audio.policy.configuration.V5_0.GainMode);
method public void setName(String);
method public void setStepValueMB(int);
+ method public void setUseForVolume(boolean);
}
public class GlobalConfiguration {
diff --git a/audio/5.0/config/audio_policy_configuration.xsd b/audio/5.0/config/audio_policy_configuration.xsd
index 2e1a722..284d2e2 100644
--- a/audio/5.0/config/audio_policy_configuration.xsd
+++ b/audio/5.0/config/audio_policy_configuration.xsd
@@ -446,6 +446,7 @@
<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:attribute name="useForVolume" type="xs:boolean" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
diff --git a/audio/6.0/IDevice.hal b/audio/6.0/IDevice.hal
index e885fe2..122c550 100644
--- a/audio/6.0/IDevice.hal
+++ b/audio/6.0/IDevice.hal
@@ -280,4 +280,19 @@
*/
setConnectedState(DeviceAddress address, bool connected)
generates (Result retval);
+
+ /**
+ * Called by the framework to deinitialize the device and free up
+ * all currently allocated resources. It is recommended to close
+ * the device on the client side as soon as it is becomes unused.
+ *
+ * Note that all streams must be closed by the client before
+ * attempting to close the device they belong to.
+ *
+ * @return retval OK in case the success.
+ * INVALID_STATE if the device was already closed
+ * or there are streams currently opened.
+ */
+ @exit
+ close() generates (Result retval);
};
diff --git a/audio/6.0/IStream.hal b/audio/6.0/IStream.hal
index 451e116..d7d3c84 100644
--- a/audio/6.0/IStream.hal
+++ b/audio/6.0/IStream.hal
@@ -277,7 +277,7 @@
* @return retval OK in case the success.
* NOT_SUPPORTED on non mmap mode streams
* NOT_INITIALIZED in case of memory allocation error
- * INVALID_ARGUMENTS if the requested buffer size is too large
+ * INVALID_ARGUMENTS if the requested buffer size is invalid
* INVALID_STATE if called out of sequence
* @return info a MmapBufferInfo struct containing information on the MMMAP buffer created.
*/
@@ -300,13 +300,17 @@
/**
* Called by the framework to deinitialize the stream and free up
- * all the currently allocated resources. It is recommended to close
+ * all currently allocated resources. It is recommended to close
* the stream on the client side as soon as it is becomes unused.
*
+ * The client must ensure that this function is not called while
+ * audio data is being transferred through the stream's message queues.
+ *
* @return retval OK in case the success.
* NOT_SUPPORTED if called on IStream instead of input or
* output stream interface.
* INVALID_STATE if the stream was already closed.
*/
+ @exit
close() generates (Result retval);
};
diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt
index e67831c..ddd4d1c 100644
--- a/audio/6.0/config/api/current.txt
+++ b/audio/6.0/config/api/current.txt
@@ -237,6 +237,7 @@
method public audio.policy.configuration.V6_0.GainMode getMode();
method public String getName();
method public int getStepValueMB();
+ method public boolean getUseForVolume();
method public void setChannel_mask(String);
method public void setDefaultValueMB(int);
method public void setMaxRampMs(int);
@@ -246,6 +247,7 @@
method public void setMode(audio.policy.configuration.V6_0.GainMode);
method public void setName(String);
method public void setStepValueMB(int);
+ method public void setUseForVolume(boolean);
}
public class GlobalConfiguration {
diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd
index 29f6f38..3fab7dc 100644
--- a/audio/6.0/config/audio_policy_configuration.xsd
+++ b/audio/6.0/config/audio_policy_configuration.xsd
@@ -447,6 +447,7 @@
<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:attribute name="useForVolume" type="xs:boolean" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
diff --git a/audio/common/6.0/Android.bp b/audio/common/6.0/Android.bp
index 1a4e054..94f1cf8 100644
--- a/audio/common/6.0/Android.bp
+++ b/audio/common/6.0/Android.bp
@@ -12,6 +12,6 @@
interfaces: [
"android.hidl.safe_union@1.0",
],
- gen_java: false,
+ gen_java: true,
gen_java_constants: true,
}
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index 0c97c36..fa2f3a9 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -156,6 +156,11 @@
@export(name="audio_session_t", value_prefix="AUDIO_SESSION_")
enum AudioSessionConsts : int32_t {
/**
+ * Session for effects attached to a particular sink or source audio device
+ * (e.g an effect only applied to a speaker)
+ */
+ DEVICE = -2,
+ /**
* Session for effects attached to a particular output stream
* (value must be less than 0)
*/
diff --git a/audio/common/all-versions/test/utility/include/utility/PrettyPrintAudioTypes.h b/audio/common/all-versions/test/utility/include/utility/PrettyPrintAudioTypes.h
deleted file mode 100644
index 3833fd0..0000000
--- a/audio/common/all-versions/test/utility/include/utility/PrettyPrintAudioTypes.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_PRETTY_PRINT_AUDIO_TYPES_H
-#define ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_PRETTY_PRINT_AUDIO_TYPES_H
-
-#include <iosfwd>
-#include <utility>
-
-/** @file Use HIDL generated toString methods to pretty print gtest errors
- * Unfortunately Gtest does not offer a template to specialize, only
- * overloading PrintTo.
- * @note that this overload can NOT be template because
- * the fallback is already template, resulting in ambiguity.
- * @note that the overload MUST be in the exact namespace
- * the type is declared in, as per the ADL rules.
- */
-
-namespace android {
-namespace hardware {
-namespace audio {
-
-#define DEFINE_GTEST_PRINT_TO(T) \
- inline void PrintTo(const T& val, ::std::ostream* os) { *os << toString(val); }
-
-namespace CPP_VERSION {
-DEFINE_GTEST_PRINT_TO(IPrimaryDevice::TtyMode)
-DEFINE_GTEST_PRINT_TO(Result)
-} // namespace CPP_VERSION
-
-namespace common {
-namespace CPP_VERSION {
-DEFINE_GTEST_PRINT_TO(AudioConfig)
-DEFINE_GTEST_PRINT_TO(AudioMode)
-DEFINE_GTEST_PRINT_TO(AudioDevice)
-DEFINE_GTEST_PRINT_TO(AudioFormat)
-DEFINE_GTEST_PRINT_TO(AudioChannelMask)
-} // namespace CPP_VERSION
-} // namespace common
-
-#undef DEFINE_GTEST_PRINT_TO
-
-} // namespace audio
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_AUDIO_COMMON_TEST_UTILITY_PRETTY_PRINT_AUDIO_TYPES_H
diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp
index 11872c0..eddff55 100644
--- a/audio/core/all-versions/default/Conversions.cpp
+++ b/audio/core/all-versions/default/Conversions.cpp
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <log/log.h>
+#include <media/AudioContainers.h>
namespace android {
namespace hardware {
@@ -31,26 +32,22 @@
char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
memset(halAddress, 0, sizeof(halAddress));
uint32_t halDevice = static_cast<uint32_t>(address.device);
- const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
+ halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
address.address.mac[0], address.address.mac[1], address.address.mac[2],
address.address.mac[3], address.address.mac[4], address.address.mac[5]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+ } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
+ getAudioDeviceInAllUsbSet().count(halDevice) > 0) {
snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
address.address.alsa.device);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+ halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
}
return halAddress;
@@ -67,32 +64,28 @@
return OK;
}
- const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
- (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(device) > 0 ||
+ device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
int status =
sscanf(halAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &address->address.mac[0],
&address->address.mac[1], &address->address.mac[2], &address->address.mac[3],
&address->address.mac[4], &address->address.mac[5]);
return status == 6 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0) ||
- (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
int status =
sscanf(halAddress, "%hhu.%hhu.%hhu.%hhu", &address->address.ipv4[0],
&address->address.ipv4[1], &address->address.ipv4[2], &address->address.ipv4[3]);
return status == 4 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0 ||
- (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+ } else if (getAudioDeviceOutAllUsbSet().count(device) > 0 ||
+ getAudioDeviceInAllUsbSet().count(device) > 0) {
int status = sscanf(halAddress, "card=%d;device=%d", &address->address.alsa.card,
&address->address.alsa.device);
return status == 2 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0) ||
- (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
address->busAddress = halAddress;
return OK;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
- (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+ device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
address->rSubmixAddress = halAddress;
return OK;
}
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 1a9df21..21dab00 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -39,11 +39,10 @@
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
-Device::Device(audio_hw_device_t* device) : mDevice(device) {}
+Device::Device(audio_hw_device_t* device) : mIsClosed(false), mDevice(device) {}
Device::~Device() {
- int status = audio_hw_device_close(mDevice);
- ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status));
+ (void)doClose();
mDevice = nullptr;
}
@@ -54,10 +53,14 @@
void Device::closeInputStream(audio_stream_in_t* stream) {
mDevice->close_input_stream(mDevice, stream);
+ LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0");
+ --mOpenedStreamsCount;
}
void Device::closeOutputStream(audio_stream_out_t* stream) {
mDevice->close_output_stream(mDevice, stream);
+ LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0");
+ --mOpenedStreamsCount;
}
char* Device::halGetParameters(const char* keys) {
@@ -159,6 +162,7 @@
sp<IStreamOut> streamOut;
if (status == OK) {
streamOut = new StreamOut(this, halStream);
+ ++mOpenedStreamsCount;
}
HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
@@ -185,6 +189,7 @@
sp<IStreamIn> streamIn;
if (status == OK) {
streamIn = new StreamIn(this, halStream);
+ ++mOpenedStreamsCount;
}
HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
@@ -383,6 +388,18 @@
}
#endif
+Result Device::doClose() {
+ if (mIsClosed || mOpenedStreamsCount != 0) return Result::INVALID_STATE;
+ mIsClosed = true;
+ return analyzeStatus("close", audio_hw_device_close(mDevice));
+}
+
+#if MAJOR_VERSION >= 6
+Return<Result> Device::close() {
+ return doClose();
+}
+#endif
+
} // namespace implementation
} // namespace CPP_VERSION
} // namespace audio
diff --git a/audio/core/all-versions/default/PrimaryDevice.cpp b/audio/core/all-versions/default/PrimaryDevice.cpp
index 99590b0..3cf0932 100644
--- a/audio/core/all-versions/default/PrimaryDevice.cpp
+++ b/audio/core/all-versions/default/PrimaryDevice.cpp
@@ -31,7 +31,11 @@
PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
-PrimaryDevice::~PrimaryDevice() {}
+PrimaryDevice::~PrimaryDevice() {
+ // Do not call mDevice->close here. If there are any unclosed streams,
+ // they only hold IDevice instance, not IPrimaryDevice, thus IPrimaryDevice
+ // "part" of a device can be destroyed before the streams.
+}
// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
Return<Result> PrimaryDevice::initCheck() {
@@ -160,6 +164,11 @@
return mDevice->setConnectedState(address, connected);
}
#endif
+#if MAJOR_VERSION >= 6
+Return<Result> PrimaryDevice::close() {
+ return mDevice->close();
+}
+#endif
// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index d316f83..f1152ca 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -139,8 +139,7 @@
} // namespace
StreamIn::StreamIn(const sp<Device>& device, audio_stream_in_t* stream)
- : mIsClosed(false),
- mDevice(device),
+ : mDevice(device),
mStream(stream),
mStreamCommon(new Stream(&stream->common)),
mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)),
@@ -159,7 +158,9 @@
status_t status = EventFlag::deleteEventFlag(&mEfGroup);
ALOGE_IF(status, "read MQ event flag deletion error: %s", strerror(-status));
}
+#if MAJOR_VERSION <= 5
mDevice->closeInputStream(mStream);
+#endif
mStream = nullptr;
}
@@ -303,14 +304,16 @@
}
Return<Result> StreamIn::close() {
- if (mIsClosed) return Result::INVALID_STATE;
- mIsClosed = true;
- if (mReadThread.get()) {
- mStopReadThread.store(true, std::memory_order_release);
+ if (mStopReadThread.load(std::memory_order_relaxed)) { // only this thread writes
+ return Result::INVALID_STATE;
}
+ mStopReadThread.store(true, std::memory_order_release);
if (mEfGroup) {
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
}
+#if MAJOR_VERSION >= 6
+ mDevice->closeInputStream(mStream);
+#endif
return Result::OK;
}
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 82cc408..396d354 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -138,8 +138,7 @@
} // namespace
StreamOut::StreamOut(const sp<Device>& device, audio_stream_out_t* stream)
- : mIsClosed(false),
- mDevice(device),
+ : mDevice(device),
mStream(stream),
mStreamCommon(new Stream(&stream->common)),
mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)),
@@ -148,7 +147,7 @@
StreamOut::~StreamOut() {
ATRACE_CALL();
- close();
+ (void)close();
if (mWriteThread.get()) {
ATRACE_NAME("mWriteThread->join");
status_t status = mWriteThread->join();
@@ -159,10 +158,12 @@
ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status));
}
mCallback.clear();
+#if MAJOR_VERSION <= 5
mDevice->closeOutputStream(mStream);
// Closing the output stream in the HAL waits for the callback to finish,
// and joins the callback thread. Thus is it guaranteed that the callback
// thread will not be accessing our object anymore.
+#endif
mStream = nullptr;
}
@@ -291,14 +292,16 @@
#endif
Return<Result> StreamOut::close() {
- if (mIsClosed) return Result::INVALID_STATE;
- mIsClosed = true;
- if (mWriteThread.get()) {
- mStopWriteThread.store(true, std::memory_order_release);
+ if (mStopWriteThread.load(std::memory_order_relaxed)) { // only this thread writes
+ return Result::INVALID_STATE;
}
+ mStopWriteThread.store(true, std::memory_order_release);
if (mEfGroup) {
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
}
+#if MAJOR_VERSION >= 6
+ mDevice->closeOutputStream(mStream);
+#endif
return Result::OK;
}
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index e64f00f..11ab607 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -114,6 +114,9 @@
Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override;
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
#endif
+#if MAJOR_VERSION >= 6
+ Return<Result> close() override;
+#endif
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
@@ -124,11 +127,15 @@
void closeOutputStream(audio_stream_out_t* stream);
audio_hw_device_t* device() const { return mDevice; }
- private:
+ private:
+ bool mIsClosed;
audio_hw_device_t* mDevice;
+ int mOpenedStreamsCount = 0;
virtual ~Device();
+ Result doClose();
+
// Methods from ParametersUtil.
char* halGetParameters(const char* keys) override;
int halSetParameters(const char* keysAndValues) override;
diff --git a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
index 9d69cb0..f5f3848 100644
--- a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
+++ b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h
@@ -96,6 +96,9 @@
Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override;
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
#endif
+#if MAJOR_VERSION >= 6
+ Return<Result> close() override;
+#endif
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h
index 6209b8f..24f9944 100644
--- a/audio/core/all-versions/default/include/core/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/default/StreamIn.h
@@ -120,7 +120,6 @@
uint64_t* time);
private:
- bool mIsClosed;
const sp<Device> mDevice;
audio_stream_in_t* mStream;
const sp<Stream> mStreamCommon;
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index b098005..6334785 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -126,7 +126,6 @@
TimeSpec* timeStamp);
private:
- bool mIsClosed;
const sp<Device> mDevice;
audio_stream_out_t* mStream;
const sp<Stream> mStreamCommon;
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index e267a5e..709b7cd 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -22,18 +22,16 @@
GTEST_SKIP() << "No primary device on this factory"; // returns
}
- struct WaitExecutor {
- ~WaitExecutor() { DeviceManager::waitForInstanceDestruction(); }
- } waitExecutor; // Make sure we wait for the device destruction on exiting from the test.
- Result result;
- sp<IDevice> baseDevice;
- ASSERT_OK(getDevicesFactory()->openDevice("primary", returnIn(result, baseDevice)));
- ASSERT_OK(result);
- ASSERT_TRUE(baseDevice != nullptr);
-
- Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
- ASSERT_TRUE(primaryDevice.isOk());
- ASSERT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
+ { // Scope for device SPs
+ sp<IDevice> baseDevice =
+ DeviceManager::getInstance().get(getFactoryName(), DeviceManager::kPrimaryDevice);
+ ASSERT_TRUE(baseDevice != nullptr);
+ Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
+ EXPECT_TRUE(primaryDevice.isOk());
+ EXPECT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
+ }
+ EXPECT_TRUE(
+ DeviceManager::getInstance().reset(getFactoryName(), DeviceManager::kPrimaryDevice));
}
//////////////////////////////////////////////////////////////////////////////
@@ -54,7 +52,6 @@
doc::test(
"Make sure getMicrophones always succeeds"
"and getActiveMicrophones always succeeds when recording from these microphones.");
- AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
AudioConfig config{};
config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
config.sampleRateHz = 8000;
@@ -67,18 +64,14 @@
continue;
}
sp<IStreamIn> stream;
+ StreamHelper<IStreamIn> helper(stream);
AudioConfig suggestedConfig{};
- ASSERT_OK(getDevice()->openInputStream(ioHandle, microphone.deviceAddress, config,
- flags, initMetadata,
- returnIn(res, stream, suggestedConfig)));
- if (res != Result::OK) {
- ASSERT_TRUE(stream == nullptr);
- AudioConfig suggestedConfigRetry{};
- ASSERT_OK(getDevice()->openInputStream(
- ioHandle, microphone.deviceAddress, suggestedConfig, flags, initMetadata,
- returnIn(res, stream, suggestedConfigRetry)));
- }
- ASSERT_OK(res);
+ ASSERT_NO_FATAL_FAILURE(helper.open(
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openInputStream(handle, microphone.deviceAddress,
+ config, flags, initMetadata, cb);
+ },
+ config, &res, &suggestedConfig));
hidl_vec<MicrophoneInfo> activeMicrophones;
Result readRes;
typedef MessageQueue<IStreamIn::ReadParameters, kSynchronizedReadWrite> CommandMQ;
@@ -112,11 +105,8 @@
ASSERT_OK(res);
ASSERT_NE(0U, activeMicrophones.size());
}
- stream->close();
- // Workaround for b/139329877. Ensures the stream gets closed on the audio hal side.
- stream.clear();
- IPCThreadState::self()->flushCommands();
- usleep(1000);
+ helper.close(true /*clear*/, &res);
+ ASSERT_OK(res);
if (efGroup) {
EventFlag::deleteEventFlag(&efGroup);
}
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 30f8a7a..2afbbb8 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -83,7 +83,6 @@
for (auto& config : configs) {
// Some combinations of flags declared in the config file require special
// treatment.
- bool special = false;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
config.offloadInfo.sampleRateHz = config.sampleRateHz;
config.offloadInfo.channelMask = config.channelMask;
@@ -94,21 +93,13 @@
config.offloadInfo.bitWidth = 16;
config.offloadInfo.bufferSize = 256; // arbitrary value
config.offloadInfo.usage = AudioUsage::MEDIA;
- result.emplace_back(
- device, config,
- AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
- special = true;
- }
- if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) &&
- !(flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC)) {
result.emplace_back(device, config,
- AudioOutputFlag(AUDIO_OUTPUT_FLAG_DIRECT));
- special = true;
- }
- if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
- flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
- }
- if (!special) {
+ AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+ AUDIO_OUTPUT_FLAG_DIRECT));
+ } else {
+ if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
+ flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
+ }
result.emplace_back(device, config, AudioOutputFlag(flags));
}
}
@@ -144,3 +135,49 @@
}();
return parameters;
}
+
+TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
+ doc::test("Verify that a device can't be closed if there are streams opened");
+ DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
+ AudioConfig config{};
+ auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
+ SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
+ sp<IStreamOut> stream;
+ StreamHelper<IStreamOut> helper(stream);
+ AudioConfig suggestedConfig{};
+ ASSERT_NO_FATAL_FAILURE(helper.open(
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openOutputStream(handle, address, config, flags, initMetadata,
+ cb);
+ },
+ config, &res, &suggestedConfig));
+ ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
+ ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
+ ASSERT_OK(getDevice()->close());
+ ASSERT_TRUE(resetDevice());
+}
+
+TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
+ doc::test("Verify that a device can't be closed if there are streams opened");
+ auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName());
+ if (module->getInputProfiles().empty()) {
+ GTEST_SKIP() << "Device doesn't have input profiles";
+ }
+ DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
+ AudioConfig config{};
+ auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
+ SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
+ sp<IStreamIn> stream;
+ StreamHelper<IStreamIn> helper(stream);
+ AudioConfig suggestedConfig{};
+ ASSERT_NO_FATAL_FAILURE(helper.open(
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openInputStream(handle, address, config, flags, initMetadata,
+ cb);
+ },
+ config, &res, &suggestedConfig));
+ ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
+ ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
+ ASSERT_OK(getDevice()->close());
+ ASSERT_TRUE(resetDevice());
+}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 468f9b2..d0d39e8 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -58,7 +58,6 @@
#include "utility/AssertOk.h"
#include "utility/Documentation.h"
-#include "utility/PrettyPrintAudioTypes.h"
#include "utility/ReturnIn.h"
#include "utility/ValidateXml.h"
@@ -719,12 +718,6 @@
::testing::Values(AudioInputFlag::NONE)),
&DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedInputBufferSize, RequiredInputBufferSizeTest,
- ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
- ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig()),
- ::testing::Values(AudioInputFlag::NONE)),
- &DeviceConfigParameterToString);
-INSTANTIATE_TEST_CASE_P(
RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
::testing::Combine(
::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
@@ -816,60 +809,84 @@
////////////////////////// open{Output,Input}Stream //////////////////////////
//////////////////////////////////////////////////////////////////////////////
+// This class is also used by some device tests.
template <class Stream>
-class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
- protected:
+class StreamHelper {
+ public:
+ // StreamHelper doesn't own the stream, this is for simpler stream lifetime management.
+ explicit StreamHelper(sp<Stream>& stream) : mStream(stream) {}
template <class Open>
- void testOpen(Open openStream, const AudioConfig& config) {
+ void open(Open openStream, const AudioConfig& config, Result* res,
+ AudioConfig* suggestedConfigPtr) {
// FIXME: Open a stream without an IOHandle
// This is not required to be accepted by hal implementations
AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
AudioConfig suggestedConfig{};
- ASSERT_OK(openStream(ioHandle, config, returnIn(res, stream, suggestedConfig)));
-
- // TODO: only allow failure for RecommendedPlaybackAudioConfig
- switch (res) {
+ bool retryWithSuggestedConfig = true;
+ if (suggestedConfigPtr == nullptr) {
+ suggestedConfigPtr = &suggestedConfig;
+ retryWithSuggestedConfig = false;
+ }
+ ASSERT_OK(openStream(ioHandle, config, returnIn(*res, mStream, *suggestedConfigPtr)));
+ switch (*res) {
case Result::OK:
- ASSERT_TRUE(stream != nullptr);
- audioConfig = config;
+ ASSERT_TRUE(mStream != nullptr);
+ *suggestedConfigPtr = config;
break;
case Result::INVALID_ARGUMENTS:
- ASSERT_TRUE(stream == nullptr);
- AudioConfig suggestedConfigRetry;
- // Could not open stream with config, try again with the
- // suggested one
- ASSERT_OK(openStream(ioHandle, suggestedConfig,
- returnIn(res, stream, suggestedConfigRetry)));
- // This time it must succeed
- ASSERT_OK(res);
- ASSERT_TRUE(stream != nullptr);
- audioConfig = suggestedConfig;
+ ASSERT_TRUE(mStream == nullptr);
+ if (retryWithSuggestedConfig) {
+ AudioConfig suggestedConfigRetry;
+ ASSERT_OK(openStream(ioHandle, *suggestedConfigPtr,
+ returnIn(*res, mStream, suggestedConfigRetry)));
+ ASSERT_OK(*res);
+ ASSERT_TRUE(mStream != nullptr);
+ }
break;
default:
- FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
+ FAIL() << "Invalid return status: " << ::testing::PrintToString(*res);
}
+ }
+ void close(bool clear, Result* res) {
+ auto ret = mStream->close();
+ EXPECT_TRUE(ret.isOk());
+ *res = ret;
+ if (clear) {
+ mStream.clear();
+#if MAJOR_VERSION <= 5
+ // FIXME: there is no way to know when the remote IStream is being destroyed
+ // Binder does not support testing if an object is alive, thus
+ // wait for 100ms to let the binder destruction propagates and
+ // the remote device has the time to be destroyed.
+ // flushCommand makes sure all local command are sent, thus should reduce
+ // the latency between local and remote destruction.
+ IPCThreadState::self()->flushCommands();
+ usleep(100 * 1000);
+#endif
+ }
+ }
+
+ private:
+ sp<Stream>& mStream;
+};
+
+template <class Stream>
+class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
+ protected:
+ OpenStreamTest() : AudioHidlTestWithDeviceConfigParameter(), helper(stream) {}
+ template <class Open>
+ void testOpen(Open openStream, const AudioConfig& config) {
+ // TODO: only allow failure for RecommendedPlaybackAudioConfig
+ ASSERT_NO_FATAL_FAILURE(helper.open(openStream, config, &res, &audioConfig));
open = true;
}
- Return<Result> closeStream() {
+ Result closeStream(bool clear = true) {
open = false;
- auto res = stream->close();
- stream.clear();
- waitForStreamDestruction();
+ helper.close(clear, &res);
return res;
}
- static void waitForStreamDestruction() {
- // FIXME: there is no way to know when the remote IStream is being destroyed
- // Binder does not support testing if an object is alive, thus
- // wait for 100ms to let the binder destruction propagates and
- // the remote device has the time to be destroyed.
- // flushCommand makes sure all local command are sent, thus should reduce
- // the latency between local and remote destruction.
- IPCThreadState::self()->flushCommands();
- usleep(100 * 1000);
- }
-
private:
void TearDown() override {
if (open) {
@@ -882,6 +899,7 @@
AudioConfig audioConfig;
DeviceAddress address = {};
sp<Stream> stream;
+ StreamHelper<Stream> helper;
bool open = false;
};
@@ -930,12 +948,6 @@
::testing::Values(AudioOutputFlag::NONE)),
&DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedOutputStreamConfig, OutputStreamTest,
- ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
- ::testing::ValuesIn(ConfigHelper::getSupportedPlaybackAudioConfig()),
- ::testing::Values(AudioOutputFlag::NONE)),
- &DeviceConfigParameterToString);
-INSTANTIATE_TEST_CASE_P(
RecommendedOutputStreamConfigSupport, OutputStreamTest,
::testing::Combine(
::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
@@ -945,7 +957,7 @@
#elif MAJOR_VERSION >= 6
// For V6 and above test according to the audio policy manager configuration.
// This is more correct as CDD is written from the apps perspective.
-// Audio system provides necessary format conversions for the missing configurations.
+// Audio system provides necessary format conversions for missing configurations.
INSTANTIATE_TEST_CASE_P(DeclaredOutputStreamConfigSupport, OutputStreamTest,
::testing::ValuesIn(getOutputDeviceConfigParameters()),
&DeviceConfigParameterToString);
@@ -991,12 +1003,6 @@
::testing::Values(AudioInputFlag::NONE)),
&DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedInputStreamConfig, InputStreamTest,
- ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
- ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig()),
- ::testing::Values(AudioInputFlag::NONE)),
- &DeviceConfigParameterToString);
-INSTANTIATE_TEST_CASE_P(
RecommendedInputStreamConfigSupport, InputStreamTest,
::testing::Combine(
::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
@@ -1006,7 +1012,7 @@
#elif MAJOR_VERSION >= 6
// For V6 and above test according to the audio policy manager configuration.
// This is more correct as CDD is written from the apps perspective.
-// Audio system provides necessary format conversions for the missing configurations.
+// Audio system provides necessary format conversions for missing configurations.
INSTANTIATE_TEST_CASE_P(DeclaredInputStreamConfigSupport, InputStreamTest,
::testing::ValuesIn(getInputDeviceConfigParameters()),
&DeviceConfigParameterToString);
@@ -1195,26 +1201,21 @@
TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
// clang-format off
TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
- auto streamCopy = stream;
- ASSERT_OK(closeStream());
- ASSERT_RESULT(Result::INVALID_STATE, streamCopy->close());
- streamCopy.clear();
- waitForStreamDestruction())
+ ASSERT_OK(closeStream(false /*clear*/));
+ ASSERT_EQ(Result::INVALID_STATE, closeStream()))
// clang-format on
-static void testCreateTooBigMmapBuffer(IStream* stream) {
- MmapBufferInfo info;
- Result res;
- // Assume that int max is a value too big to be allocated
- // This is true currently with a 32bit media server, but might not when it
- // will run in 64 bit
- auto minSizeFrames = std::numeric_limits<int32_t>::max();
- ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
- ASSERT_RESULT(invalidArgsOrNotSupported, res);
+static void testMmapBufferOfInvalidSize(IStream* stream) {
+ for (int32_t value : {-1, 0, std::numeric_limits<int32_t>::max()}) {
+ MmapBufferInfo info;
+ Result res;
+ EXPECT_OK(stream->createMmapBuffer(value, returnIn(res, info)));
+ EXPECT_RESULT(invalidArgsOrNotSupported, res) << "value=" << value;
+ }
}
-TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
- testCreateTooBigMmapBuffer(stream.get()))
+TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer of invalid size must fail",
+ testMmapBufferOfInvalidSize(stream.get()))
static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
Result res;
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index 48aae8c..a2f4116 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -57,12 +57,6 @@
{24000, 48000}, {AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
- // TODO: retrieve audio config supported by the platform
- // as declared in the policy configuration
- return {};
- }
-
static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
if (!primaryHasMic()) return {};
return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
@@ -73,11 +67,6 @@
return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
{AudioFormat::PCM_16_BIT});
}
- static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
- // TODO: retrieve audio config supported by the platform
- // as declared in the policy configuration
- return {};
- }
static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
vector<uint32_t> sampleRates,
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index b6e2db0..d849f85 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -22,25 +22,33 @@
template <class Derived, class Key, class Interface>
class InterfaceManager {
public:
+ sp<Interface> getExisting(const Key& name) {
+ auto existing = instances.find(name);
+ return existing != instances.end() ? existing->second : sp<Interface>();
+ }
+
sp<Interface> get(const Key& name) {
auto existing = instances.find(name);
if (existing != instances.end()) return existing->second;
auto [inserted, _] = instances.emplace(name, Derived::createInterfaceInstance(name));
if (inserted->second) {
- environment->registerTearDown([name]() { (void)Derived::getInstance().reset(name); });
+ environment->registerTearDown(
+ [name]() { (void)Derived::getInstance().reset(name, false); });
}
return inserted->second;
}
// The test must check that reset was successful. Reset failure means that the test code
// is holding a strong reference to the device.
- bool reset(const Key& name) __attribute__((warn_unused_result)) {
+ bool reset(const Key& name, bool waitForDestruction) __attribute__((warn_unused_result)) {
auto iter = instances.find(name);
if (iter == instances.end()) return true;
::android::wp<Interface> weak = iter->second;
instances.erase(iter);
if (weak.promote() != nullptr) return false;
- waitForInstanceDestruction();
+ if (waitForDestruction) {
+ waitForInstanceDestruction();
+ }
return true;
}
@@ -100,7 +108,15 @@
}
bool reset(const std::string& factoryName, const std::string& name)
__attribute__((warn_unused_result)) {
- return InterfaceManager::reset(std::make_tuple(factoryName, name));
+#if MAJOR_VERSION <= 5
+ return InterfaceManager::reset(std::make_tuple(factoryName, name), true);
+#elif MAJOR_VERSION >= 6
+ {
+ sp<IDevice> device = getExisting(std::make_tuple(factoryName, name));
+ if (device != nullptr) device->close();
+ }
+ return InterfaceManager::reset(std::make_tuple(factoryName, name), false);
+#endif
}
bool resetPrimary(const std::string& factoryName) __attribute__((warn_unused_result)) {
return reset(factoryName, kPrimaryDevice);
diff --git a/audio/effect/6.0/IEffect.hal b/audio/effect/6.0/IEffect.hal
index b35afee..f4c50a2 100644
--- a/audio/effect/6.0/IEffect.hal
+++ b/audio/effect/6.0/IEffect.hal
@@ -407,9 +407,12 @@
/**
* Called by the framework to deinitialize the effect and free up
- * all the currently allocated resources. It is recommended to close
+ * all currently allocated resources. It is recommended to close
* the effect on the client side as soon as it is becomes unused.
*
+ * The client must ensure that this function is not called while
+ * audio data is being transferred through the effect's message queues.
+ *
* @return retval OK in case the success.
* INVALID_STATE if the effect was already closed.
*/
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 3c0d878..406a571 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -138,11 +138,11 @@
const char* Effect::sContextCallFunction = sContextCallToCommand;
Effect::Effect(effect_handle_t handle)
- : mIsClosed(false), mHandle(handle), mEfGroup(nullptr), mStopProcessThread(false) {}
+ : mHandle(handle), mEfGroup(nullptr), mStopProcessThread(false) {}
Effect::~Effect() {
ATRACE_CALL();
- close();
+ (void)close();
if (mProcessThread.get()) {
ATRACE_NAME("mProcessThread->join");
status_t status = mProcessThread->join();
@@ -154,8 +154,10 @@
}
mInBuffer.clear();
mOutBuffer.clear();
+#if MAJOR_VERSION <= 5
int status = EffectRelease(mHandle);
ALOGW_IF(status, "Error releasing effect %p: %s", mHandle, strerror(-status));
+#endif
EffectMap::getInstance().remove(mHandle);
mHandle = 0;
}
@@ -305,12 +307,11 @@
Result Effect::getCurrentConfigImpl(uint32_t featureId, uint32_t configSize,
GetCurrentConfigSuccessCallback onSuccess) {
uint32_t halCmd = featureId;
- uint32_t halResult[alignedSizeIn<uint32_t>(sizeof(uint32_t) + configSize)];
- memset(halResult, 0, sizeof(halResult));
+ std::vector<uint32_t> halResult(alignedSizeIn<uint32_t>(sizeof(uint32_t) + configSize), 0);
uint32_t halResultSize = 0;
- return sendCommandReturningStatusAndData(EFFECT_CMD_GET_FEATURE_CONFIG, "GET_FEATURE_CONFIG",
- sizeof(uint32_t), &halCmd, &halResultSize, halResult,
- sizeof(uint32_t), [&] { onSuccess(&halResult[1]); });
+ return sendCommandReturningStatusAndData(
+ EFFECT_CMD_GET_FEATURE_CONFIG, "GET_FEATURE_CONFIG", sizeof(uint32_t), &halCmd,
+ &halResultSize, &halResult[0], sizeof(uint32_t), [&] { onSuccess(&halResult[1]); });
}
Result Effect::getParameterImpl(uint32_t paramSize, const void* paramData,
@@ -337,8 +338,7 @@
GetSupportedConfigsSuccessCallback onSuccess) {
uint32_t halCmd[2] = {featureId, maxConfigs};
uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * sizeof(configSize);
- uint8_t halResult[halResultSize];
- memset(&halResult[0], 0, halResultSize);
+ std::vector<uint8_t> halResult(static_cast<size_t>(halResultSize), 0);
return sendCommandReturningStatusAndData(
EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS, "GET_FEATURE_SUPPORTED_CONFIGS", sizeof(halCmd),
halCmd, &halResultSize, &halResult[0], 2 * sizeof(uint32_t), [&] {
@@ -517,9 +517,9 @@
uint32_t halDataSize;
std::unique_ptr<uint8_t[]> halData = hidlVecToHal(volumes, &halDataSize);
uint32_t halResultSize = halDataSize;
- uint32_t halResult[volumes.size()];
+ std::vector<uint32_t> halResult(volumes.size(), 0);
Result retval = sendCommandReturningData(EFFECT_CMD_SET_VOLUME, "SET_VOLUME", halDataSize,
- &halData[0], &halResultSize, halResult);
+ &halData[0], &halResultSize, &halResult[0]);
hidl_vec<uint32_t> result;
if (retval == Result::OK) {
result.setToExternal(&halResult[0], halResultSize);
@@ -579,8 +579,6 @@
}
Return<void> Effect::getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) {
- uint32_t halResult[alignedSizeIn<uint32_t>(sizeof(uint32_t) + sizeof(channel_config_t))];
- memset(halResult, 0, sizeof(halResult));
EffectAuxChannelsConfig result;
Result retval = getCurrentConfigImpl(
EFFECT_FEATURE_AUX_CHANNELS, sizeof(channel_config_t), [&](void* configData) {
@@ -592,11 +590,12 @@
}
Return<Result> Effect::setAuxChannelsConfig(const EffectAuxChannelsConfig& config) {
- uint32_t halCmd[alignedSizeIn<uint32_t>(sizeof(uint32_t) + sizeof(channel_config_t))];
+ std::vector<uint32_t> halCmd(
+ alignedSizeIn<uint32_t>(sizeof(uint32_t) + sizeof(channel_config_t)), 0);
halCmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
effectAuxChannelsConfigToHal(config, reinterpret_cast<channel_config_t*>(&halCmd[1]));
return sendCommandReturningStatus(EFFECT_CMD_SET_FEATURE_CONFIG,
- "SET_FEATURE_CONFIG AUX_CHANNELS", sizeof(halCmd), halCmd);
+ "SET_FEATURE_CONFIG AUX_CHANNELS", halCmd.size(), &halCmd[0]);
}
Return<Result> Effect::setAudioSource(AudioSource source) {
@@ -690,24 +689,31 @@
Return<Result> Effect::setCurrentConfigForFeature(uint32_t featureId,
const hidl_vec<uint8_t>& configData) {
- uint32_t halCmd[alignedSizeIn<uint32_t>(sizeof(uint32_t) + configData.size())];
- memset(halCmd, 0, sizeof(halCmd));
+ std::vector<uint32_t> halCmd(alignedSizeIn<uint32_t>(sizeof(uint32_t) + configData.size()), 0);
halCmd[0] = featureId;
memcpy(&halCmd[1], &configData[0], configData.size());
return sendCommandReturningStatus(EFFECT_CMD_SET_FEATURE_CONFIG, "SET_FEATURE_CONFIG",
- sizeof(halCmd), halCmd);
+ halCmd.size(), &halCmd[0]);
}
Return<Result> Effect::close() {
- if (mIsClosed) return Result::INVALID_STATE;
- mIsClosed = true;
- if (mProcessThread.get()) {
- mStopProcessThread.store(true, std::memory_order_release);
+ if (mStopProcessThread.load(std::memory_order_relaxed)) { // only this thread modifies
+ return Result::INVALID_STATE;
}
+ mStopProcessThread.store(true, std::memory_order_release);
if (mEfGroup) {
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT));
}
+#if MAJOR_VERSION <= 5
return Result::OK;
+#elif MAJOR_VERSION >= 6
+ // No need to join the processing thread, it is part of the API contract that the client
+ // must finish processing before closing the effect.
+ Result retval =
+ analyzeStatus("EffectRelease", "", sContextCallFunction, EffectRelease(mHandle));
+ EffectMap::getInstance().remove(mHandle);
+ return retval;
+#endif
}
Return<void> Effect::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) {
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 3d99a0e..181e542 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -170,7 +170,6 @@
static const char* sContextCallToCommand;
static const char* sContextCallFunction;
- bool mIsClosed;
effect_handle_t mHandle;
sp<AudioBufferWrapper> mInBuffer;
sp<AudioBufferWrapper> mOutBuffer;
diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp
index 314830b..3d04c89 100644
--- a/automotive/audiocontrol/1.0/default/Android.bp
+++ b/automotive/audiocontrol/1.0/default/Android.bp
@@ -29,7 +29,7 @@
"liblog",
"libutils",
],
-
+ vintf_fragments: ["audiocontrol_manifest.xml"],
cflags: [
"-DLOG_TAG=\"AudCntrlDrv\"",
"-O0",
diff --git a/automotive/audiocontrol/1.0/default/audiocontrol_manifest.xml b/automotive/audiocontrol/1.0/default/audiocontrol_manifest.xml
new file mode 100644
index 0000000..0981eb7
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/audiocontrol_manifest.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.automotive.audiocontrol</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IAudioControl</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
\ No newline at end of file
diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp
index 7ef44fc..ebc2f8c 100644
--- a/automotive/can/1.0/default/service.cpp
+++ b/automotive/can/1.0/default/service.cpp
@@ -32,8 +32,8 @@
configureRpcThreadpool(16, true);
LOG(DEBUG) << "CAN controller service starting...";
- CanController canController;
- if (canController.registerAsService("socketcan") != OK) {
+ sp<CanController> canController(new CanController);
+ if (canController->registerAsService("socketcan") != OK) {
LOG(FATAL) << "Failed to register CAN controller";
return;
}
diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp
new file mode 100644
index 0000000..6e9e8aa
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/Android.bp
@@ -0,0 +1,13 @@
+aidl_interface {
+ name: "android.hardware.automotive.occupant_awareness",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/automotive/occupant_awareness/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ }
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/ConfidenceLevel.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/ConfidenceLevel.aidl
new file mode 100644
index 0000000..8597ddb
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/ConfidenceLevel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+@VintfStability
+@Backing(type="byte")
+enum ConfidenceLevel {
+ /**
+ * No prediction could be made.
+ */
+ NONE,
+ /**
+ * Best-guess, low-confidence prediction. Predictions exceeding this threshold are adequate
+ * for non-critical applications.
+ */
+ LOW,
+ /**
+ * High-confidence prediction. Predictions exceeding this threshold are adequate for
+ * applications that require reliable predictions.
+ */
+ HIGH,
+ /**
+ * Highest confidence rate achievable.
+ */
+ MAX,
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/DriverMonitoringDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/DriverMonitoringDetection.aidl
new file mode 100644
index 0000000..f5cc9d5
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/DriverMonitoringDetection.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.ConfidenceLevel;
+
+@VintfStability
+parcelable DriverMonitoringDetection {
+ /*
+ * Confidence of the computed attention data.
+ */
+ ConfidenceLevel confidenceScore;
+ /*
+ * Is the driver currently looking on-road?
+ */
+ boolean isLookingOnRoad;
+ /*
+ * Duration the driver has been looking on or off road, in milliseconds.
+ */
+ long gazeDurationMillis;
+}
+
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/GazeDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/GazeDetection.aidl
new file mode 100644
index 0000000..fc36e13
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/GazeDetection.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.VehicleRegion;
+import android.hardware.automotive.occupant_awareness.ConfidenceLevel;
+
+@VintfStability
+parcelable GazeDetection {
+ /*
+ * Confidence level for the gaze detection.
+ */
+ ConfidenceLevel gazeConfidence;
+ /*
+ * Head position, in millimeters. The vehicle coordinate system is specified in the cabin space
+ * configuration. headPosition is double[3] array.
+ */
+ double[] headPosition;
+ /*
+ * Unit vector for the head pose direction. The vehicle coordinate system is specified in the
+ * cabin space configuration. headAngleUnitVector is double[3] array.
+ */
+ double[] headAngleUnitVector;
+ /*
+ * Unit vector for the gaze direction. The vehicle coordinate system is specified in the cabin
+ * space configuration. gazeAngleUnitVector is double[3] array.
+ */
+ double[] gazeAngleUnitVector;
+ /*
+ * Current gaze target.
+ */
+ VehicleRegion gazeTarget;
+ /*
+ * Custom gaze target string. This only need to be populated when gazeTarget is CUSTOM_TARGET.
+ * Vendors should use "com.vendor_name.target_name" format to avoid name collision with other
+ * vendors.
+ */
+ String customGazeTarget;
+ /*
+ * Duration that the subject has been looking at the current gaze target in milliseconds.
+ */
+ long timeOnTargetMillis;
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwareness.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwareness.aidl
new file mode 100644
index 0000000..1df0bda
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwareness.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.OccupantAwarenessStatus;
+import android.hardware.automotive.occupant_awareness.Role;
+import android.hardware.automotive.occupant_awareness.IOccupantAwarenessClientCallback;
+import android.hardware.automotive.occupant_awareness.OccupantDetections;
+
+@VintfStability
+interface IOccupantAwareness {
+ /*
+ * System not able to generate any occupancy awareness.
+ */
+ const int CAP_NONE = 0;
+ /*
+ * System is able to detect the presence of humans.
+ */
+ const int CAP_PRESENCE_DETECTION = 1 << 0;
+ /*
+ * System is able to detect the gaze of humans.
+ */
+ const int CAP_GAZE_DETECTION = 1 << 1;
+ /*
+ * System is able to compute the attention details of humans.
+ */
+ const int CAP_DRIVER_MONITORING_DETECTION = 1 << 2;
+
+ /**
+ * Starts the occupant awareness detection system. This is a non-blocking function call.
+ * Once system is ready, state will be modified. State update can be inrquired using callback
+ * or getState() function.
+ * @return status is the current system state.
+ */
+ OccupantAwarenessStatus startDetection();
+
+ /**
+ * Stops the occupant awareness detection system. This is a non-blocking function call.
+ * Once system is reset, state will be modified. State update can be inrquired using callback
+ * or getState() function.
+ * @return status is the current system state.
+ */
+ OccupantAwarenessStatus stopDetection();
+
+ /**
+ * Returns list of Awareness Capability supported for the given type of occupants.
+ *
+ * @param out Bitwise OR of supported capabilities (CAP_* mask).
+ */
+ int getCapabilityForRole(in Role occupantRole);
+
+ /**
+ * Inquires the current state of the occupant awareness system.
+ * @param occupantRole specifies the role of occupants of interest.
+ * @param detectionCapability specifies a single detection capability (CAP_* ) of interest.
+ *
+ * @return status is the current system state.
+ */
+ OccupantAwarenessStatus getState(in Role occupantRole, in int detectionCapability);
+
+ /**
+ * Registers a callback for data streaming. Only single callback is supported. setCallback()
+ * should replace existing callback with new callback.
+ * @return: returns ok if successful.
+ */
+ void setCallback(in IOccupantAwarenessClientCallback callback);
+
+ /**
+ * Returns the most recent set of detections.
+ * @param OccupantDetections output detections.
+ * @return returns ok if successful.
+ */
+ void getLatestDetection(out OccupantDetections detections);
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwarenessClientCallback.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwarenessClientCallback.aidl
new file mode 100644
index 0000000..69f7b0b
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/IOccupantAwarenessClientCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.OccupantAwarenessStatus;
+import android.hardware.automotive.occupant_awareness.OccupantDetections;
+
+@VintfStability
+interface IOccupantAwarenessClientCallback {
+ /**
+ * A callback invoked when the system status changes.
+ *
+ * @param detectionFlags The detection subsystem(s) whose status has changed.
+ * @param status The new system status.
+ */
+ oneway void onSystemStatusChanged(in int detectionFlags, in OccupantAwarenessStatus status);
+
+ /**
+ * A callback invoked when a new set of detections are available.
+ *
+ * @param detections Occupant detections.
+ */
+ oneway void onDetectionEvent(in OccupantDetections detections);
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantAwarenessStatus.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantAwarenessStatus.aidl
new file mode 100644
index 0000000..6a3453d
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantAwarenessStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+@VintfStability
+@Backing(type="byte")
+enum OccupantAwarenessStatus {
+ /*
+ * System is online and ready to serve requests.
+ */
+ READY = 0,
+ /**
+ * Detection is not supported in this vehicle due to a permanent lack of capabilities. Clients
+ * need not retry.
+ */
+ NOT_SUPPORTED = 1,
+ /*
+ * The system has not yet been initialized. No requests can be served until the
+ * initialization process completes. This state does not indicate any error and
+ * clients should retry later.
+ */
+ NOT_INITIALIZED = 2,
+ /*
+ * A permanent failure has occurred. No detections will be provided.
+ */
+ FAILURE = 3,
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetection.aidl
new file mode 100644
index 0000000..47ca35a
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetection.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.Role;
+import android.hardware.automotive.occupant_awareness.PresenceDetection;
+import android.hardware.automotive.occupant_awareness.GazeDetection;
+import android.hardware.automotive.occupant_awareness.DriverMonitoringDetection;
+
+/*
+ * A complete detection for a single occupant in the vehicle. Includes data about the subject's
+ * presence in the vehicle, gaze and attention.
+ */
+ @VintfStability
+parcelable OccupantDetection {
+ /*
+ * Role of the occupant (e.g., driver, passenger).
+ */
+ Role role;
+ /*
+ * Occupant presence state for a single occupant.
+ * If the vector is empty, no data could be generated.
+ */
+ PresenceDetection[] presenceData;
+ /*
+ * Gaze data for a single occupant.
+ * If the vector is empty, no data could be generated.
+ */
+ GazeDetection[] gazeData;
+ /*
+ * Attention data for a single occupant.
+ * If the vector is empty, no data could be generated.
+ */
+ DriverMonitoringDetection[] attentionData;
+}
+
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetections.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetections.aidl
new file mode 100644
index 0000000..e8f6621
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/OccupantDetections.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+import android.hardware.automotive.occupant_awareness.OccupantDetection;
+
+@VintfStability
+parcelable OccupantDetections {
+ /**
+ * Timestamp that the underlying source image was captured, in milliseconds since Jan 1, 1970
+ * (Unix time).
+ */
+ long timeStampMillis;
+ /**
+ * A vector of detections for all occupants in the vehicle. One OccupantDetection will be
+ * generated per detected face.
+ */
+ OccupantDetection[] detections;
+}
+
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/PresenceDetection.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/PresenceDetection.aidl
new file mode 100644
index 0000000..a018106
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/PresenceDetection.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+@VintfStability
+parcelable PresenceDetection {
+ /*
+ * Boolean representing whether an occupant was detected.
+ */
+ boolean isOccupantDetected;
+ /**
+ * Duration that a particular occupant has been continuously
+ * detected, in milliseconds. Will be zero duration if the occupant is not
+ * currently detected.
+ */
+ long detectionDurationMillis;
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/Role.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/Role.aidl
new file mode 100644
index 0000000..42e86ad
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/Role.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+@VintfStability
+@Backing(type="int")
+enum Role {
+ /*
+ * All valid role(s) must have at least 1 bit set.
+ */
+ INVALID = 0,
+ /*
+ * System could not determine role for this occupant.
+ */
+ UNKNOWN = 1 << 0,
+ /*
+ * Occupants that the system detects as front seat passengers.
+ */
+ FRONT_PASSENGER = 1 << 1,
+ /*
+ * Occupants that the system detects as driver(s).
+ */
+ DRIVER = 1 << 2,
+ /*
+ * Occupants on left seat of row 2.
+ */
+ ROW_2_PASSENGER_LEFT = 1 << 3,
+ /*
+ * Occupants on center seat of row 2.
+ */
+ ROW_2_PASSENGER_CENTER = 1 << 4,
+ /*
+ * Occupants on right seat of row 2.
+ */
+ ROW_2_PASSENGER_RIGHT = 1 << 5,
+ /*
+ * Occupants on left seat of row 3.
+ */
+ ROW_3_PASSENGER_LEFT = 1 << 6,
+ /*
+ * Occupants on center seat of row 3.
+ */
+ ROW_3_PASSENGER_CENTER = 1 << 7,
+ /*
+ * Occupants on right seat of row 3.
+ */
+ ROW_3_PASSENGER_RIGHT = 1 << 8,
+
+ /*
+ * Occupants that the system detects as front seat occupant.
+ * FRONT_OCCUPANTS = DRIVER | FRONT_PASSENGER
+ */
+ FRONT_OCCUPANTS = 1 << 1 | 1 << 2,
+ /*
+ * Occupants of row 2.
+ * ROW_2_OCCUPANTS = ROW_2_PASSENGER_LEFT | ROW_2_PASSENGER_CENTER | ROW_2_PASSENGER_RIGHT
+ */
+ ROW_2_OCCUPANTS = 1 << 3 | 1 << 4 | 1 << 5,
+ /*
+ * Occupants of row 3.
+ * ROW_3_OCCUPANTS = ROW_3_PASSENGER_LEFT | ROW_3_PASSENGER_CENTER | ROW_3_PASSENGER_RIGHT
+ */
+ ROW_3_OCCUPANTS = 1 << 6 | 1 << 7 | 1 << 8,
+ /*
+ * All the occupants in the vehicle.
+ * ALL_OCCUPANTS = UNKNOWN | FRONT_OCCUPANTS | ROW_2_OCCUPANTS | ROW_3_OCCUPANTS
+ */
+ ALL_OCCUPANTS = 0x1FF,
+}
diff --git a/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/VehicleRegion.aidl b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/VehicleRegion.aidl
new file mode 100644
index 0000000..9ee9d52
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/android/hardware/automotive/occupant_awareness/VehicleRegion.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.occupant_awareness;
+
+@VintfStability
+@Backing(type="int")
+enum VehicleRegion {
+ /*
+ * List of targets in the car.
+ */
+ UNKNOWN = 0,
+ INSTRUMENT_CLUSTER = 1,
+ REAR_VIEW_MIRROR = 2,
+ LEFT_SIDE_MIRROR = 3,
+ RIGHT_SIDE_MIRROR = 4,
+ FORWARD_ROADWAY = 5,
+ LEFT_ROADWAY = 6,
+ RIGHT_ROADWAY = 7,
+ HEAD_UNIT_DISPLAY = 8,
+ /*
+ * Vendors can use this value along with customGazeTarget string to uniquely identify their
+ * custom region.
+ */
+ CUSTOM_TARGET = 200,
+}
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
new file mode 100644
index 0000000..1b2fba2
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_binary {
+ name: "android.hardware.automotive.occupant_awareness@1.0-service",
+ init_rc: ["android.hardware.automotive.occupant_awareness@1.0-service.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "OccupantAwareness.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libutils",
+ "android.hardware.automotive.occupant_awareness-ndk_platform",
+ ],
+}
diff --git a/automotive/occupant_awareness/aidl/default/OccupantAwareness.cpp b/automotive/occupant_awareness/aidl/default/OccupantAwareness.cpp
new file mode 100644
index 0000000..a156075
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/OccupantAwareness.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "OccupantAwareness.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ndk::ScopedAStatus;
+
+static const int32_t kAllCapabilities = OccupantAwareness::CAP_PRESENCE_DETECTION |
+ OccupantAwareness::CAP_GAZE_DETECTION |
+ OccupantAwareness::CAP_DRIVER_MONITORING_DETECTION;
+
+ScopedAStatus OccupantAwareness::startDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::NOT_SUPPORTED) {
+ mStatus = OccupantAwarenessStatus::NOT_SUPPORTED;
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities,
+ OccupantAwarenessStatus::NOT_SUPPORTED);
+ }
+ }
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::stopDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::NOT_INITIALIZED) {
+ mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities,
+ OccupantAwarenessStatus::NOT_INITIALIZED);
+ }
+ }
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getCapabilityForRole(Role occupantRole, int32_t* capabilities) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ // No awareness capability for default HAL.
+ *capabilities = 0;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ if (!isValidDetectionCapabilities(detectionCapability) ||
+ !isSingularCapability(detectionCapability)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) {
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ mCallback = callback;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getLatestDetection(OccupantDetections* detections) {
+ // No detection generated for default hal.
+ (void)detections;
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+}
+
+bool OccupantAwareness::isValidRole(Role occupantRole) {
+ int intVal = static_cast<int>(occupantRole);
+ int allOccupants = static_cast<int>(Role::ALL_OCCUPANTS);
+ return (occupantRole != Role::INVALID) && ((intVal & (~allOccupants)) == 0);
+}
+
+bool OccupantAwareness::isValidDetectionCapabilities(int detectionCapabilities) {
+ return (detectionCapabilities != CAP_NONE) &&
+ ((detectionCapabilities & (~kAllCapabilities)) == 0);
+}
+
+bool OccupantAwareness::isSingularCapability(int detectionCapability) {
+ // Check whether the value is 0, or the value has only one bit set.
+ return (detectionCapability & (detectionCapability - 1)) == 0;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/default/OccupantAwareness.h b/automotive/occupant_awareness/aidl/default/OccupantAwareness.h
new file mode 100644
index 0000000..ac51aa4
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/OccupantAwareness.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwareness.h>
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwarenessClientCallback.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::BnOccupantAwareness;
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwarenessClientCallback;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantAwarenessStatus;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetections;
+using ::aidl::android::hardware::automotive::occupant_awareness::Role;
+
+/**
+ * The default HAL mimics a system which has no Occupant awareness capability. The hal does not
+ * do any useful work, and returns appropriate failure code / status.
+ **/
+class OccupantAwareness : public BnOccupantAwareness {
+ public:
+ // Methods from ::android::hardware::automotive::occupant_awareness::IOccupantAwareness
+ // follow.
+ ndk::ScopedAStatus startDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus stopDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus getCapabilityForRole(Role occupantRole, int32_t* capabilities) override;
+ ndk::ScopedAStatus getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) override;
+ ndk::ScopedAStatus getLatestDetection(OccupantDetections* detections) override;
+
+ private:
+ bool isValidRole(Role occupantRole);
+ bool isValidDetectionCapabilities(int detectionCapabilities);
+ bool isSingularCapability(int detectionCapability);
+
+ std::mutex mMutex;
+ std::shared_ptr<IOccupantAwarenessClientCallback> mCallback = nullptr;
+ OccupantAwarenessStatus mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness@1.0-service.rc b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness@1.0-service.rc
new file mode 100644
index 0000000..35d5bca
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness@1.0-service.rc
@@ -0,0 +1,4 @@
+service hal_occupant_awareness_default /vendor/bin/hw/android.hardware.automotive.occupant_awareness@1.0-service
+ class hal
+ user system
+ group system
diff --git a/automotive/occupant_awareness/aidl/default/service.cpp b/automotive/occupant_awareness/aidl/default/service.cpp
new file mode 100644
index 0000000..44960fb
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/service.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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 "android.hardware.automotive.occupant_awareness@1.0-service"
+
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "OccupantAwareness.h"
+
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+using ::android::hardware::automotive::occupant_awareness::V1_0::implementation::OccupantAwareness;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+
+const static char kOccupantAwarenessServiceName[] = "default";
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ LOG(INFO) << "Occupant Awareness service is starting";
+ std::shared_ptr<OccupantAwareness> occupantAwareness = SharedRefBase::make<OccupantAwareness>();
+
+ const std::string instance =
+ std::string() + IOccupantAwareness::descriptor + "/" + kOccupantAwarenessServiceName;
+
+ binder_status_t status =
+ AServiceManager_addService(occupantAwareness->asBinder().get(), instance.c_str());
+ if (status == STATUS_OK) {
+ LOG(INFO) << "Service " << kOccupantAwarenessServiceName << " is ready";
+ ABinderProcess_joinThreadPool();
+ } else {
+ LOG(ERROR) << "Could not register service " << kOccupantAwarenessServiceName
+ << ", status: " << status;
+ }
+
+ // In normal operation, we don't expect the thread pool to exit.
+ LOG(ERROR) << "Occupant Awareness service is shutting down";
+ return 1;
+}
diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp
new file mode 100644
index 0000000..4b30866
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_binary {
+ name: "android.hardware.automotive.occupant_awareness@1.0-service_mock",
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "OccupantAwareness.cpp",
+ "DetectionGenerator.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libutils",
+ "android.hardware.automotive.occupant_awareness-ndk_platform",
+ ],
+}
diff --git a/automotive/occupant_awareness/aidl/mock/DetectionGenerator.cpp b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.cpp
new file mode 100644
index 0000000..79d4dbc
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/SystemClock.h>
+
+#include "DetectionGenerator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::ConfidenceLevel;
+using ::aidl::android::hardware::automotive::occupant_awareness::DriverMonitoringDetection;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetection;
+using ::aidl::android::hardware::automotive::occupant_awareness::PresenceDetection;
+
+static int64_t kNanoSecondsPerMilliSecond = 1000 * 1000;
+
+OccupantDetections DetectionGenerator::GetNextDetections() {
+ OccupantDetections detections;
+ detections.timeStampMillis = android::elapsedRealtimeNano() / kNanoSecondsPerMilliSecond;
+ int remainingRoles = getSupportedRoles();
+ while (remainingRoles) {
+ int currentRole = remainingRoles & (~(remainingRoles - 1));
+ remainingRoles = remainingRoles & (remainingRoles - 1);
+
+ OccupantDetection occupantDetection;
+ occupantDetection.role = static_cast<Role>(currentRole);
+
+ // Add presence detection object for this occupant.
+ PresenceDetection presenceDetection;
+ presenceDetection.isOccupantDetected = true;
+ presenceDetection.detectionDurationMillis = detections.timeStampMillis;
+ occupantDetection.presenceData.emplace_back(presenceDetection);
+
+ if (occupantDetection.role == Role::DRIVER) {
+ // Add driver monitoring detection object for this occupant.
+ DriverMonitoringDetection driverMonitoringDetection;
+ driverMonitoringDetection.confidenceScore = ConfidenceLevel::HIGH;
+ driverMonitoringDetection.isLookingOnRoad = 0;
+ driverMonitoringDetection.gazeDurationMillis = detections.timeStampMillis;
+ occupantDetection.attentionData.emplace_back(driverMonitoringDetection);
+ }
+
+ detections.detections.emplace_back(occupantDetection);
+ }
+ return detections;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/DetectionGenerator.h b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.h
new file mode 100644
index 0000000..0884685
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/DetectionGenerator.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwareness.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::BnOccupantAwareness;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetections;
+using ::aidl::android::hardware::automotive::occupant_awareness::Role;
+
+class DetectionGenerator {
+ public:
+ static int getSupportedRoles() {
+ return static_cast<int>(Role::DRIVER) | static_cast<int>(Role::FRONT_PASSENGER);
+ }
+ static int getSupportedCapabilities() {
+ return static_cast<int>(BnOccupantAwareness::CAP_PRESENCE_DETECTION) |
+ static_cast<int>(BnOccupantAwareness::CAP_DRIVER_MONITORING_DETECTION);
+ }
+
+ OccupantDetections GetNextDetections();
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/OccupantAwareness.cpp b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.cpp
new file mode 100644
index 0000000..910760a
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/SystemClock.h>
+
+#include "OccupantAwareness.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ndk::ScopedAStatus;
+
+static const int32_t kAllCapabilities = OccupantAwareness::CAP_PRESENCE_DETECTION |
+ OccupantAwareness::CAP_GAZE_DETECTION |
+ OccupantAwareness::CAP_DRIVER_MONITORING_DETECTION;
+
+constexpr int64_t kNanoSecondsPerMilliSecond = 1000 * 1000;
+
+ScopedAStatus OccupantAwareness::startDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::NOT_INITIALIZED) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ mStatus = OccupantAwarenessStatus::READY;
+ mWorkerThread = std::thread(startWorkerThread, this);
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities, mStatus);
+ }
+
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::stopDetection(OccupantAwarenessStatus* status) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStatus != OccupantAwarenessStatus::READY) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+ mWorkerThread.join();
+ if (mCallback) {
+ mCallback->onSystemStatusChanged(kAllCapabilities, mStatus);
+ }
+
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getCapabilityForRole(Role occupantRole, int32_t* capabilities) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ int intVal = static_cast<int>(occupantRole);
+ if ((intVal & DetectionGenerator::getSupportedRoles()) == intVal) {
+ int capabilities_ = DetectionGenerator::getSupportedCapabilities();
+ if (occupantRole != Role::DRIVER) {
+ capabilities_ &= ~CAP_DRIVER_MONITORING_DETECTION;
+ }
+ *capabilities = capabilities_;
+ } else {
+ *capabilities = 0;
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) {
+ if (!isValidRole(occupantRole)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ if (!isValidDetectionCapabilities(detectionCapability) ||
+ !isSingularCapability(detectionCapability)) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ int roleVal = static_cast<int>(occupantRole);
+
+ if (((roleVal & DetectionGenerator::getSupportedRoles()) != roleVal) ||
+ ((detectionCapability & DetectionGenerator::getSupportedCapabilities()) !=
+ detectionCapability)) {
+ *status = OccupantAwarenessStatus::NOT_SUPPORTED;
+ return ScopedAStatus::ok();
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ *status = mStatus;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) {
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ mCallback = callback;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus OccupantAwareness::getLatestDetection(OccupantDetections* detections) {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ if (mStatus != OccupantAwarenessStatus::READY) {
+ return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+ }
+
+ *detections = mLatestDetections;
+ return ScopedAStatus::ok();
+}
+
+bool OccupantAwareness::isValidRole(Role occupantRole) {
+ int intVal = static_cast<int>(occupantRole);
+ int allOccupants = static_cast<int>(Role::ALL_OCCUPANTS);
+ return (occupantRole != Role::INVALID) && ((intVal & (~allOccupants)) == 0);
+}
+
+bool OccupantAwareness::isValidDetectionCapabilities(int detectionCapabilities) {
+ return (detectionCapabilities != OccupantAwareness::CAP_NONE) &&
+ ((detectionCapabilities & (~kAllCapabilities)) == 0);
+}
+
+bool OccupantAwareness::isSingularCapability(int detectionCapability) {
+ // Check whether the value is 0, or the value has only one bit set.
+ return (detectionCapability & (detectionCapability - 1)) == 0;
+}
+
+void OccupantAwareness::startWorkerThread(OccupantAwareness* occupantAwareness) {
+ occupantAwareness->workerThreadFunction();
+}
+
+void OccupantAwareness::workerThreadFunction() {
+ bool isFirstDetection = true;
+ int64_t prevDetectionTimeMs;
+ while (mStatus == OccupantAwarenessStatus::READY) {
+ int64_t currentTimeMs = android::elapsedRealtimeNano() / kNanoSecondsPerMilliSecond;
+ if ((isFirstDetection) || (currentTimeMs - prevDetectionTimeMs > mDetectionDurationMs)) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mLatestDetections = mGenerator.GetNextDetections();
+ if (mCallback != nullptr) {
+ mCallback->onDetectionEvent(mLatestDetections);
+ }
+ isFirstDetection = false;
+ prevDetectionTimeMs = currentTimeMs;
+ }
+ }
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/OccupantAwareness.h b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.h
new file mode 100644
index 0000000..c5f6dd6
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/OccupantAwareness.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <thread>
+
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwareness.h>
+#include <aidl/android/hardware/automotive/occupant_awareness/BnOccupantAwarenessClientCallback.h>
+#include <utils/StrongPointer.h>
+
+#include "DetectionGenerator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace occupant_awareness {
+namespace V1_0 {
+namespace implementation {
+
+using ::aidl::android::hardware::automotive::occupant_awareness::BnOccupantAwareness;
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwarenessClientCallback;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantAwarenessStatus;
+using ::aidl::android::hardware::automotive::occupant_awareness::OccupantDetections;
+using ::aidl::android::hardware::automotive::occupant_awareness::Role;
+
+/**
+ * The mock HAL can detect presence of Driver and front passenger, and driver awareness detection
+ * for driver.
+ **/
+class OccupantAwareness : public BnOccupantAwareness {
+ public:
+ // Methods from ::android::hardware::automotive::occupant_awareness::IOccupantAwareness
+ // follow.
+ ndk::ScopedAStatus startDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus stopDetection(OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus getCapabilityForRole(Role occupantRole, int32_t* capabilities) override;
+ ndk::ScopedAStatus getState(Role occupantRole, int detectionCapability,
+ OccupantAwarenessStatus* status) override;
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IOccupantAwarenessClientCallback>& callback) override;
+ ndk::ScopedAStatus getLatestDetection(OccupantDetections* detections) override;
+
+ private:
+ bool isValidRole(Role occupantRole);
+ bool isValidDetectionCapabilities(int detectionCapabilities);
+ bool isSingularCapability(int detectionCapability);
+
+ void workerThreadFunction();
+ static void startWorkerThread(OccupantAwareness* occupantAwareness);
+
+ std::mutex mMutex;
+ std::shared_ptr<IOccupantAwarenessClientCallback> mCallback = nullptr;
+ OccupantAwarenessStatus mStatus = OccupantAwarenessStatus::NOT_INITIALIZED;
+
+ OccupantDetections mLatestDetections;
+ std::thread mWorkerThread;
+
+ DetectionGenerator mGenerator;
+
+ // Generate a new detection every 1ms.
+ const int64_t mDetectionDurationMs = 1;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace occupant_awareness
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/occupant_awareness/aidl/mock/service.cpp b/automotive/occupant_awareness/aidl/mock/service.cpp
new file mode 100644
index 0000000..d8860df
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/mock/service.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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 "android.hardware.automotive.occupant_awareness@1.0-service_mock"
+
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "OccupantAwareness.h"
+
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+using ::android::hardware::automotive::occupant_awareness::V1_0::implementation::OccupantAwareness;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+
+const static char kOccupantAwarenessServiceName[] = "default";
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ LOG(INFO) << "Occupant Awareness service is starting";
+ std::shared_ptr<OccupantAwareness> occupantAwareness = SharedRefBase::make<OccupantAwareness>();
+
+ const std::string instance =
+ std::string() + IOccupantAwareness::descriptor + "/" + kOccupantAwarenessServiceName;
+
+ binder_status_t status =
+ AServiceManager_addService(occupantAwareness->asBinder().get(), instance.c_str());
+ if (status == STATUS_OK) {
+ LOG(INFO) << "Service " << kOccupantAwarenessServiceName << " is ready";
+ ABinderProcess_joinThreadPool();
+ } else {
+ LOG(ERROR) << "Could not register service " << kOccupantAwarenessServiceName
+ << ", status: " << status;
+ }
+
+ // In normal operation, we don't expect the thread pool to exit.
+ LOG(ERROR) << "Occupant Awareness service is shutting down";
+ return 1;
+}
diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..1256b69
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp
@@ -0,0 +1,17 @@
+cc_test {
+ name: "VtsHalOccupantAwarenessV1_0TargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalOccupantAwarenessV1_0TargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ ],
+ static_libs: [
+ "android.hardware.automotive.occupant_awareness-cpp",
+ ],
+ test_suites: [
+ "vts-core",
+ ],
+}
diff --git a/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp b/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp
new file mode 100644
index 0000000..c431f9d
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "**** HAL log ****"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android-base/logging.h>
+#include <android/hardware/automotive/occupant_awareness/BnOccupantAwarenessClientCallback.h>
+#include <android/hardware/automotive/occupant_awareness/IOccupantAwareness.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <future>
+#include <vector>
+
+using namespace android::hardware::automotive::occupant_awareness;
+using android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+
+constexpr auto kTimeout = std::chrono::seconds(3);
+
+#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
+
+class OccupantAwarenessCallback : public BnOccupantAwarenessClientCallback {
+ public:
+ OccupantAwarenessCallback(const std::function<void(int, OccupantAwarenessStatus)>& callback)
+ : mCallback(callback) {}
+ Status onSystemStatusChanged(int detectionFlags, OccupantAwarenessStatus status) override {
+ mCallback(detectionFlags, status);
+ return Status::ok();
+ }
+
+ Status onDetectionEvent(const OccupantDetections& detections) override {
+ (void)detections;
+ return Status::ok();
+ }
+
+ private:
+ std::function<void(int, OccupantAwarenessStatus)> mCallback;
+};
+
+class OccupantAwarenessAidl : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ mOccupantAwarenessService =
+ android::waitForDeclaredService<IOccupantAwareness>(String16(GetParam().c_str()));
+ ASSERT_NE(mOccupantAwarenessService, nullptr);
+ }
+
+ sp<IOccupantAwareness> mOccupantAwarenessService;
+};
+
+// Test that startDetection() returns within the timeout.
+TEST_P(OccupantAwarenessAidl, StartDetectionTest) {
+ auto start = std::chrono::system_clock::now();
+ OccupantAwarenessStatus occupantAwarenessStatus;
+ Status status = mOccupantAwarenessService->startDetection(&occupantAwarenessStatus);
+ auto elapsed = std::chrono::system_clock::now() - start;
+ EXPECT_OK(status);
+ ASSERT_LE(elapsed, kTimeout);
+
+ EXPECT_OK(mOccupantAwarenessService->stopDetection(&occupantAwarenessStatus));
+}
+
+// Test that getCapabilityForRole() returns supported capabilities for the role. The test only
+// verifies that the IPC call returns successfully and does not verify the supported capabilities.
+TEST_P(OccupantAwarenessAidl, GetCapabilityTest) {
+ std::vector<Role> rolesToTest = {Role::FRONT_PASSENGER, Role::DRIVER,
+ Role::ROW_2_PASSENGER_LEFT, Role::ROW_2_PASSENGER_CENTER,
+ Role::ROW_2_PASSENGER_RIGHT, Role::ROW_3_PASSENGER_LEFT,
+ Role::ROW_3_PASSENGER_CENTER, Role::ROW_3_PASSENGER_RIGHT,
+ Role::FRONT_OCCUPANTS, Role::ROW_2_OCCUPANTS,
+ Role::ROW_3_OCCUPANTS, Role::ALL_OCCUPANTS};
+
+ for (auto role : rolesToTest) {
+ int32_t capabilities;
+ EXPECT_OK(mOccupantAwarenessService->getCapabilityForRole(role, &capabilities));
+ }
+}
+
+// Test that getCapabilityForRole() returns failure when arguments are invalid.
+TEST_P(OccupantAwarenessAidl, GetCapabilityFailureTest) {
+ int32_t capabilities;
+ EXPECT_FALSE(
+ mOccupantAwarenessService->getCapabilityForRole(Role::INVALID, &capabilities).isOk());
+
+ Role invalidRole = static_cast<Role>(static_cast<int>(Role::ALL_OCCUPANTS) + 1);
+ EXPECT_FALSE(
+ mOccupantAwarenessService->getCapabilityForRole(invalidRole, &capabilities).isOk());
+}
+
+// Test that getState() returns within the timeout. The test do not attempt to verify the state, but
+// only checks that the IPC call returns successfully.
+TEST_P(OccupantAwarenessAidl, GetStateTest) {
+ std::vector<Role> rolesToTest = {Role::FRONT_PASSENGER, Role::DRIVER,
+ Role::ROW_2_PASSENGER_LEFT, Role::ROW_2_PASSENGER_CENTER,
+ Role::ROW_2_PASSENGER_RIGHT, Role::ROW_3_PASSENGER_LEFT,
+ Role::ROW_3_PASSENGER_CENTER, Role::ROW_3_PASSENGER_RIGHT,
+ Role::FRONT_OCCUPANTS, Role::ROW_2_OCCUPANTS,
+ Role::ROW_3_OCCUPANTS, Role::ALL_OCCUPANTS};
+
+ std::vector<int> detectionCapabilities = {IOccupantAwareness::CAP_PRESENCE_DETECTION,
+ IOccupantAwareness::CAP_GAZE_DETECTION,
+ IOccupantAwareness::CAP_DRIVER_MONITORING_DETECTION};
+
+ for (auto role : rolesToTest) {
+ for (auto detectionCapability : detectionCapabilities) {
+ OccupantAwarenessStatus oasStatus;
+ EXPECT_OK(mOccupantAwarenessService->getState(role, detectionCapability, &oasStatus));
+ }
+ }
+}
+
+// Test that getState() returns failure with invalid args.
+TEST_P(OccupantAwarenessAidl, GetStateFailureTest) {
+ // Verify that getState() returns error when role is invalid (0).
+ OccupantAwarenessStatus oasStatus;
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(Role::INVALID, IOccupantAwareness::CAP_PRESENCE_DETECTION,
+ &oasStatus)
+ .isOk());
+
+ // Verify that getState() returns error when role is invalid (invalid flag).
+ int invalidRole = static_cast<int>(Role::ALL_OCCUPANTS) + 1;
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(static_cast<Role>(invalidRole),
+ IOccupantAwareness::CAP_PRESENCE_DETECTION, &oasStatus)
+ .isOk());
+
+ // Verify that getState() returns error when capability is invalid (none).
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(Role::FRONT_PASSENGER, IOccupantAwareness::CAP_NONE, &oasStatus)
+ .isOk());
+
+ // Verify that getState() returns error when capability is invalid (invalid flag).
+ int invalidDetectionFlags = 0x10;
+ EXPECT_FALSE(mOccupantAwarenessService
+ ->getState(Role::FRONT_PASSENGER, invalidDetectionFlags, &oasStatus)
+ .isOk());
+}
+
+// Test that setCallback() returns within the timeout.
+TEST_P(OccupantAwarenessAidl, SetCallbackTest) {
+ sp<OccupantAwarenessCallback> callback =
+ new OccupantAwarenessCallback([](int detectionFlags, OccupantAwarenessStatus status) {
+ (void)detectionFlags;
+ (void)status;
+ });
+ auto start = std::chrono::system_clock::now();
+ Status status = mOccupantAwarenessService->setCallback(callback);
+ auto elapsed = std::chrono::system_clock::now() - start;
+ EXPECT_OK(status);
+ ASSERT_LE(elapsed, kTimeout);
+}
+
+// Test that setCallback() returns failure with invalid args.
+TEST_P(OccupantAwarenessAidl, SetCallbackFailureTest) {
+ sp<OccupantAwarenessCallback> callback = nullptr;
+ Status status = mOccupantAwarenessService->setCallback(callback);
+ EXPECT_FALSE(status.isOk());
+}
+
+// Test that getLatestDetection() returns within the timeout.
+TEST_P(OccupantAwarenessAidl, GetLatestDetectionTest) {
+ auto start = std::chrono::system_clock::now();
+ OccupantDetections detections;
+ // Do not check status here, since error status is returned when no detection is present.
+ (void)mOccupantAwarenessService->getLatestDetection(&detections);
+ auto elapsed = std::chrono::system_clock::now() - start;
+ ASSERT_LE(elapsed, kTimeout);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ InstantiationName, OccupantAwarenessAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IOccupantAwareness::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index ed09859..f9c25d1 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -58,6 +58,7 @@
defaults: ["vhal_v2_0_defaults"],
srcs: [
"impl/vhal_v2_0/CommConn.cpp",
+ "impl/vhal_v2_0/EmulatedVehicleConnector.cpp",
"impl/vhal_v2_0/EmulatedVehicleHal.cpp",
"impl/vhal_v2_0/VehicleEmulator.cpp",
"impl/vhal_v2_0/PipeComm.cpp",
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index d1fd555..127eb98 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -20,8 +20,9 @@
#include <iostream>
-#include <vhal_v2_0/VehicleHalManager.h>
+#include <vhal_v2_0/EmulatedVehicleConnector.h>
#include <vhal_v2_0/EmulatedVehicleHal.h>
+#include <vhal_v2_0/VehicleHalManager.h>
using namespace android;
using namespace android::hardware;
@@ -29,9 +30,11 @@
int main(int /* argc */, char* /* argv */ []) {
auto store = std::make_unique<VehiclePropertyStore>();
- auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get());
+ auto connector = impl::makeEmulatedPassthroughConnector();
+ auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get());
auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
auto service = std::make_unique<VehicleHalManager>(hal.get());
+ connector->setValuePool(hal->getValuePool());
configureRpcThreadpool(4, true /* callerWillJoin */);
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h
new file mode 100644
index 0000000..56ecd67
--- /dev/null
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_VehicleConnector_H_
+#define android_hardware_automotive_vehicle_V2_0_VehicleConnector_H_
+
+#include <vector>
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+/**
+ * This file defines the interface of client/server pair for HAL-vehicle
+ * communication. Vehicle HAL may use this interface to talk to the vehicle
+ * regardless of the underlying communication channels.
+ */
+
+/**
+ * Vehicle HAL talks to the vehicle through a client, instead of accessing
+ * the car bus directly, to give us more flexibility on the implementation.
+ * Android OS do not need direct access to the vehicle, and the communication
+ * channel is also customizable.
+ *
+ * Client lives on the Android (HAL) side to talk to the vehicle
+ */
+class IVehicleClient {
+ public:
+ IVehicleClient() = default;
+
+ IVehicleClient(const IVehicleClient&) = delete;
+
+ IVehicleClient& operator=(const IVehicleClient&) = delete;
+
+ IVehicleClient(IVehicleClient&&) = default;
+
+ virtual ~IVehicleClient() = default;
+
+ // Get configuration of all properties from server
+ virtual std::vector<VehiclePropConfig> getAllPropertyConfig() const = 0;
+
+ // Send the set property request to server
+ virtual StatusCode setProperty(const VehiclePropValue& value) = 0;
+
+ // Receive a new property value from server
+ virtual void onPropertyValue(const VehiclePropValue& value) = 0;
+};
+
+/**
+ * Server lives on the vehicle side to talk to Android HAL
+ */
+class IVehicleServer {
+ public:
+ IVehicleServer() = default;
+
+ IVehicleServer(const IVehicleServer&) = delete;
+
+ IVehicleServer& operator=(const IVehicleServer&) = delete;
+
+ IVehicleServer(IVehicleServer&&) = default;
+
+ virtual ~IVehicleServer() = default;
+
+ // Receive the get property configuration request from HAL.
+ // Return a list of all property config
+ virtual std::vector<VehiclePropConfig> onGetAllPropertyConfig() const = 0;
+
+ // Receive the set property request from HAL.
+ // Process the setting and return the status code
+ virtual StatusCode onSetProperty(const VehiclePropValue& value) = 0;
+
+ // Receive a new property value from car (via direct connection to the car bus or the emulator)
+ // and forward the value to HAL
+ virtual void onPropertyValueFromCar(const VehiclePropValue& value) = 0;
+};
+
+/**
+ * If Android has direct access to the vehicle, then the client and
+ * the server may act in passthrough mode to avoid extra IPC
+ *
+ * Template is used here for spliting the logic of operating Android objects (VehicleClientType),
+ * talking to cars (VehicleServerType) and the commucation between client and server (passthrough
+ * mode in this case), so that we can easily combine different parts together without duplicating
+ * codes (for example, in Google VHAL, the server talks to the fake car in the same way no matter
+ * if it is on top of passthrough connector or VSOCK or any other communication channels between
+ * client and server)
+ *
+ * The alternative may be factoring the common logic of every operations for both client and
+ * server. Which is not always the case. Making sure different non-template connectors calling
+ * the same method is hard, especially when the engineer maintaining the code may not be aware
+ * of it when making changes. Template is a clean and easy way to solve this problem in this
+ * case.
+ */
+template <typename VehicleClientType, typename VehicleServerType>
+class IPassThroughConnector : public VehicleClientType, public VehicleServerType {
+ static_assert(std::is_base_of_v<IVehicleClient, VehicleClientType>);
+ static_assert(std::is_base_of_v<IVehicleServer, VehicleServerType>);
+
+ public:
+ std::vector<VehiclePropConfig> getAllPropertyConfig() const override {
+ return this->onGetAllPropertyConfig();
+ }
+
+ StatusCode setProperty(const VehiclePropValue& value) override {
+ return this->onSetProperty(value);
+ }
+
+ void onPropertyValueFromCar(const VehiclePropValue& value) override {
+ return this->onPropertyValue(value);
+ }
+
+ // To be implemented:
+ // virtual std::vector<VehiclePropConfig> onGetAllPropertyConfig() = 0;
+ // virtual void onPropertyValue(const VehiclePropValue& value) = 0;
+ // virtual StatusCode onSetProperty(const VehiclePropValue& value) = 0;
+};
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_V2_0_VehicleConnector_H_
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
index 8ee3c54..f8b10ca 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
@@ -61,7 +61,7 @@
struct VmsLayerAndPublisher {
VmsLayerAndPublisher(VmsLayer layer, int publisher_id)
- : layer(layer), publisher_id(publisher_id) {}
+ : layer(std::move(layer)), publisher_id(publisher_id) {}
VmsLayer layer;
int publisher_id;
};
@@ -69,6 +69,8 @@
// A VmsAssociatedLayer is used by subscribers to specify which publisher IDs
// are acceptable for a given layer.
struct VmsAssociatedLayer {
+ VmsAssociatedLayer(VmsLayer layer, std::vector<int> publisher_ids)
+ : layer(std::move(layer)), publisher_ids(std::move(publisher_ids)) {}
VmsLayer layer;
std::vector<int> publisher_ids;
};
@@ -77,7 +79,7 @@
// its dependencies. Dependencies can be empty.
struct VmsLayerOffering {
VmsLayerOffering(VmsLayer layer, std::vector<VmsLayer> dependencies)
- : layer(layer), dependencies(dependencies) {}
+ : layer(std::move(layer)), dependencies(std::move(dependencies)) {}
VmsLayerOffering(VmsLayer layer) : layer(layer), dependencies() {}
VmsLayer layer;
std::vector<VmsLayer> dependencies;
@@ -87,7 +89,7 @@
// with the specified publisher ID.
struct VmsOffers {
VmsOffers(int publisher_id, std::vector<VmsLayerOffering> offerings)
- : publisher_id(publisher_id), offerings(offerings) {}
+ : publisher_id(publisher_id), offerings(std::move(offerings)) {}
int publisher_id;
std::vector<VmsLayerOffering> offerings;
};
@@ -231,6 +233,24 @@
const int current_service_id, const int current_client_id,
int* new_service_id);
+// Returns true if the new sequence number of the availability state message is greater than
+// the last seen availability sequence number.
+bool isAvailabilitySequenceNumberNewer(const VehiclePropValue& availability_state,
+ const int last_seen_availability_sequence_number);
+
+// Returns sequence number of the availability state message.
+int32_t getSequenceNumberForAvailabilityState(const VehiclePropValue& availability_state);
+
+// Takes a availability state message and returns the associated layers that are
+// available to publish data.
+//
+// A subscriber can use this function when receiving an availability response or availability
+// change message to determine which associated layers are ready to publish data.
+// The caller of this function can optionally decide to not consume these layers
+// if the availability change has the sequence number less than the last seen
+// sequence number.
+std::vector<VmsAssociatedLayer> getAvailableLayers(const VehiclePropValue& availability_state);
+
} // namespace vms
} // namespace V2_0
} // namespace vehicle
diff --git a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
index 9eba905..a65cded 100644
--- a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
@@ -219,12 +219,9 @@
if (isValidVmsMessage(subscriptions_state) &&
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
- subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
- const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
- VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
- const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
- VmsSubscriptionsStateIntegerValuesIndex ::NUMBER_OF_ASSOCIATED_LAYERS)];
-
+ subscriptions_state.value.int32Values.size() >
+ toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)) {
+ int subscriptions_state_int_size = subscriptions_state.value.int32Values.size();
std::unordered_set<VmsLayer, VmsLayer::VmsLayerHashFunction> offered_layers;
for (const auto& offer : offers.offerings) {
offered_layers.insert(offer.layer);
@@ -232,33 +229,52 @@
std::vector<VmsLayer> subscribed_layers;
int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);
+
// Add all subscribed layers which are offered by the current publisher.
+ const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
+ VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
for (int i = 0; i < num_of_layers; i++) {
+ if (subscriptions_state_int_size < current_index + kLayerSize) {
+ return {};
+ }
VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
subscriptions_state.value.int32Values[current_index + 1],
subscriptions_state.value.int32Values[current_index + 2]);
if (offered_layers.find(layer) != offered_layers.end()) {
- subscribed_layers.push_back(layer);
+ subscribed_layers.push_back(std::move(layer));
}
current_index += kLayerSize;
}
+
// Add all subscribed associated layers which are offered by the current publisher.
// For this, we need to check if the associated layer has a publisher ID which is
// same as that of the current publisher.
- for (int i = 0; i < num_of_associated_layers; i++) {
- VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
- subscriptions_state.value.int32Values[current_index + 1],
- subscriptions_state.value.int32Values[current_index + 2]);
- current_index += kLayerSize;
- if (offered_layers.find(layer) != offered_layers.end()) {
- int32_t num_of_publisher_ids = subscriptions_state.value.int32Values[current_index];
- current_index++;
- for (int j = 0; j < num_of_publisher_ids; j++) {
- if (subscriptions_state.value.int32Values[current_index] ==
- offers.publisher_id) {
- subscribed_layers.push_back(layer);
- }
+ if (subscriptions_state_int_size >
+ toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)) {
+ const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
+ VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)];
+
+ for (int i = 0; i < num_of_associated_layers; i++) {
+ if (subscriptions_state_int_size < current_index + kLayerSize) {
+ return {};
+ }
+ VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
+ subscriptions_state.value.int32Values[current_index + 1],
+ subscriptions_state.value.int32Values[current_index + 2]);
+ current_index += kLayerSize;
+ if (offered_layers.find(layer) != offered_layers.end() &&
+ subscriptions_state_int_size > current_index) {
+ int32_t num_of_publisher_ids =
+ subscriptions_state.value.int32Values[current_index];
current_index++;
+ for (int j = 0; j < num_of_publisher_ids; j++) {
+ if (subscriptions_state_int_size > current_index &&
+ subscriptions_state.value.int32Values[current_index] ==
+ offers.publisher_id) {
+ subscribed_layers.push_back(std::move(layer));
+ }
+ current_index++;
+ }
}
}
}
@@ -300,6 +316,64 @@
return VmsSessionStatus::kInvalidMessage;
}
+bool isAvailabilitySequenceNumberNewer(const VehiclePropValue& availability_state,
+ const int last_seen_availability_sequence_number) {
+ return (isValidVmsMessage(availability_state) &&
+ (parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
+ parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
+ availability_state.value.int32Values.size() > kAvailabilitySequenceNumberIndex &&
+ availability_state.value.int32Values[kAvailabilitySequenceNumberIndex] >
+ last_seen_availability_sequence_number);
+}
+
+int32_t getSequenceNumberForAvailabilityState(const VehiclePropValue& availability_state) {
+ if (isValidVmsMessage(availability_state) &&
+ (parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
+ parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
+ availability_state.value.int32Values.size() > kAvailabilitySequenceNumberIndex) {
+ return availability_state.value.int32Values[kAvailabilitySequenceNumberIndex];
+ }
+ return -1;
+}
+
+std::vector<VmsAssociatedLayer> getAvailableLayers(const VehiclePropValue& availability_state) {
+ if (isValidVmsMessage(availability_state) &&
+ (parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
+ parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
+ availability_state.value.int32Values.size() >
+ toInt(VmsAvailabilityStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)) {
+ int availability_state_int_size = availability_state.value.int32Values.size();
+ const int32_t num_of_associated_layers = availability_state.value.int32Values[toInt(
+ VmsAvailabilityStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)];
+ int current_index = toInt(VmsAvailabilityStateIntegerValuesIndex::LAYERS_START);
+ std::vector<VmsAssociatedLayer> available_layers;
+ for (int i = 0; i < num_of_associated_layers; i++) {
+ if (availability_state_int_size < current_index + kLayerSize) {
+ return {};
+ }
+ VmsLayer layer = VmsLayer(availability_state.value.int32Values[current_index],
+ availability_state.value.int32Values[current_index + 1],
+ availability_state.value.int32Values[current_index + 2]);
+ current_index += kLayerSize;
+ std::vector<int> publisher_ids;
+ if (availability_state_int_size > current_index) {
+ int32_t num_of_publisher_ids = availability_state.value.int32Values[current_index];
+ current_index++;
+ for (int j = 0; j < num_of_publisher_ids; j++) {
+ if (availability_state_int_size > current_index) {
+ publisher_ids.push_back(
+ availability_state.value.int32Values[current_index]);
+ current_index++;
+ }
+ }
+ }
+ available_layers.emplace_back(layer, std::move(publisher_ids));
+ }
+ return available_layers;
+ }
+ return {};
+}
+
} // namespace vms
} // namespace V2_0
} // namespace vehicle
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index f41b33c..2dbcbba 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -948,6 +948,24 @@
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE},
.initialValue = {.stringValue = "Vendor String Property"}},
+
+ {.config =
+ {
+ .prop = toInt(VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .configArray =
+ {kMixedTypePropertyForTest,
+ (int)VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_INFO,
+ (int)VehicleVendorPermission::PERMISSION_SET_VENDOR_CATEGORY_INFO,
+ VENDOR_EXTENSION_INT_PROPERTY,
+ (int)VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_SEAT,
+ (int)VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE,
+ VENDOR_EXTENSION_FLOAT_PROPERTY,
+ (int)VehicleVendorPermission::PERMISSION_DEFAULT,
+ (int)VehicleVendorPermission::PERMISSION_DEFAULT},
+ },
+ .initialValue = {.int32Values = {1}}},
};
} // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
new file mode 100644
index 0000000..168999d
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <utils/SystemClock.h>
+
+#include "DefaultConfig.h"
+#include "EmulatedVehicleConnector.h"
+#include "JsonFakeValueGenerator.h"
+#include "LinearFakeValueGenerator.h"
+#include "Obd2SensorStore.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+void EmulatedVehicleClient::onPropertyValue(const VehiclePropValue& value) {
+ if (!mPropCallback) {
+ LOG(ERROR) << __func__ << ": PropertyCallBackType is not registered!";
+ return;
+ }
+ return mPropCallback(value);
+}
+
+void EmulatedVehicleClient::registerPropertyValueCallback(PropertyCallBackType&& callback) {
+ if (mPropCallback) {
+ LOG(ERROR) << __func__ << ": Cannot register multiple callbacks!";
+ return;
+ }
+ mPropCallback = std::move(callback);
+}
+
+GeneratorHub* EmulatedVehicleServer::getGenerator() {
+ return &mGeneratorHub;
+}
+
+VehiclePropValuePool* EmulatedVehicleServer::getValuePool() const {
+ if (!mValuePool) {
+ LOG(WARNING) << __func__ << ": Value pool not set!";
+ }
+ return mValuePool;
+}
+
+void EmulatedVehicleServer::setValuePool(VehiclePropValuePool* valuePool) {
+ if (!valuePool) {
+ LOG(WARNING) << __func__ << ": Setting value pool to nullptr!";
+ }
+ mValuePool = valuePool;
+}
+
+void EmulatedVehicleServer::onFakeValueGenerated(const VehiclePropValue& value) {
+ LOG(DEBUG) << __func__ << ": " << toString(value);
+ auto updatedPropValue = getValuePool()->obtain(value);
+ if (updatedPropValue) {
+ updatedPropValue->timestamp = value.timestamp;
+ updatedPropValue->status = VehiclePropertyStatus::AVAILABLE;
+ onPropertyValueFromCar(*updatedPropValue);
+ }
+}
+
+std::vector<VehiclePropConfig> EmulatedVehicleServer::onGetAllPropertyConfig() const {
+ std::vector<VehiclePropConfig> vehiclePropConfigs;
+ constexpr size_t numOfVehiclePropConfigs =
+ sizeof(kVehicleProperties) / sizeof(kVehicleProperties[0]);
+ vehiclePropConfigs.reserve(numOfVehiclePropConfigs);
+ for (auto& it : kVehicleProperties) {
+ vehiclePropConfigs.emplace_back(it.config);
+ }
+ return vehiclePropConfigs;
+}
+
+StatusCode EmulatedVehicleServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
+ LOG(INFO) << __func__;
+ const auto& v = request.value;
+ if (!v.int32Values.size()) {
+ LOG(ERROR) << __func__ << ": expected at least \"command\" field in int32Values";
+ return StatusCode::INVALID_ARG;
+ }
+
+ FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]);
+
+ switch (command) {
+ case FakeDataCommand::StartLinear: {
+ LOG(INFO) << __func__ << ", FakeDataCommand::StartLinear";
+ if (v.int32Values.size() < 2) {
+ LOG(ERROR) << __func__ << ": expected property ID in int32Values";
+ return StatusCode::INVALID_ARG;
+ }
+ if (!v.int64Values.size()) {
+ LOG(ERROR) << __func__ << ": interval is not provided in int64Values";
+ return StatusCode::INVALID_ARG;
+ }
+ if (v.floatValues.size() < 3) {
+ LOG(ERROR) << __func__ << ": expected at least 3 elements in floatValues, got: "
+ << v.floatValues.size();
+ return StatusCode::INVALID_ARG;
+ }
+ int32_t cookie = v.int32Values[1];
+ getGenerator()->registerGenerator(cookie,
+ std::make_unique<LinearFakeValueGenerator>(request));
+ break;
+ }
+ case FakeDataCommand::StartJson: {
+ LOG(INFO) << __func__ << ", FakeDataCommand::StartJson";
+ if (v.stringValue.empty()) {
+ LOG(ERROR) << __func__ << ": path to JSON file is missing";
+ return StatusCode::INVALID_ARG;
+ }
+ int32_t cookie = std::hash<std::string>()(v.stringValue);
+ getGenerator()->registerGenerator(cookie,
+ std::make_unique<JsonFakeValueGenerator>(request));
+ break;
+ }
+ case FakeDataCommand::StopLinear: {
+ LOG(INFO) << __func__ << ", FakeDataCommand::StopLinear";
+ if (v.int32Values.size() < 2) {
+ LOG(ERROR) << __func__ << ": expected property ID in int32Values";
+ return StatusCode::INVALID_ARG;
+ }
+ int32_t cookie = v.int32Values[1];
+ getGenerator()->unregisterGenerator(cookie);
+ break;
+ }
+ case FakeDataCommand::StopJson: {
+ LOG(INFO) << __func__ << ", FakeDataCommand::StopJson";
+ if (v.stringValue.empty()) {
+ LOG(ERROR) << __func__ << ": path to JSON file is missing";
+ return StatusCode::INVALID_ARG;
+ }
+ int32_t cookie = std::hash<std::string>()(v.stringValue);
+ getGenerator()->unregisterGenerator(cookie);
+ break;
+ }
+ case FakeDataCommand::KeyPress: {
+ LOG(INFO) << __func__ << ", FakeDataCommand::KeyPress";
+ int32_t keyCode = request.value.int32Values[2];
+ int32_t display = request.value.int32Values[3];
+ // Send back to HAL
+ onPropertyValueFromCar(
+ *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display));
+ onPropertyValueFromCar(
+ *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << ": unexpected command: " << toInt(command);
+ return StatusCode::INVALID_ARG;
+ }
+ }
+ return StatusCode::OK;
+}
+
+VehicleHal::VehiclePropValuePtr EmulatedVehicleServer::createApPowerStateReq(
+ VehicleApPowerStateReq state, int32_t param) {
+ auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2);
+ req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ);
+ req->areaId = 0;
+ req->timestamp = elapsedRealtimeNano();
+ req->status = VehiclePropertyStatus::AVAILABLE;
+ req->value.int32Values[0] = toInt(state);
+ req->value.int32Values[1] = param;
+ return req;
+}
+
+VehicleHal::VehiclePropValuePtr EmulatedVehicleServer::createHwInputKeyProp(
+ VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) {
+ auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3);
+ keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT);
+ keyEvent->areaId = 0;
+ keyEvent->timestamp = elapsedRealtimeNano();
+ keyEvent->status = VehiclePropertyStatus::AVAILABLE;
+ keyEvent->value.int32Values[0] = toInt(action);
+ keyEvent->value.int32Values[1] = keyCode;
+ keyEvent->value.int32Values[2] = targetDisplay;
+ return keyEvent;
+}
+
+StatusCode EmulatedVehicleServer::onSetProperty(const VehiclePropValue& value) {
+ // Some properties need to be treated non-trivially
+ switch (value.prop) {
+ case AP_POWER_STATE_REPORT:
+ switch (value.value.int32Values[0]) {
+ case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT):
+ case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED):
+ case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
+ // CPMS is in WAIT_FOR_VHAL state, simply move to ON
+ // Send back to HAL
+ onPropertyValueFromCar(
+ *createApPowerStateReq(VehicleApPowerStateReq::ON, 0));
+ break;
+ case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY):
+ case toInt(VehicleApPowerStateReport::SHUTDOWN_START):
+ // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command
+ // Send back to HAL
+ onPropertyValueFromCar(
+ *createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0));
+ break;
+ case toInt(VehicleApPowerStateReport::ON):
+ case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE):
+ case toInt(VehicleApPowerStateReport::SHUTDOWN_PREPARE):
+ // Do nothing
+ break;
+ default:
+ // Unknown state
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ // In the real vhal, the value will be sent to Car ECU.
+ // We just pretend it is done here.
+ return StatusCode::OK;
+}
+
+StatusCode EmulatedVehicleServer::onSetPropertyFromVehicle(const VehiclePropValue& value) {
+ if (value.prop == kGenerateFakeDataControllingProperty) {
+ auto status = handleGenerateFakeDataRequest(value);
+ return status;
+ } else {
+ // Send back to HAL
+ onPropertyValueFromCar(value);
+ return StatusCode::OK;
+ }
+}
+
+EmulatedPassthroughConnectorPtr makeEmulatedPassthroughConnector() {
+ return std::make_unique<EmulatedPassthroughConnector>();
+}
+
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
new file mode 100644
index 0000000..d424cd8
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_
+
+#include <vhal_v2_0/VehicleConnector.h>
+#include <vhal_v2_0/VehicleHal.h>
+
+#include "GeneratorHub.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+// Extension of the client/server interfaces for emulated vehicle
+
+class EmulatedVehicleClient : public IVehicleClient {
+ public:
+ // Type of callback function for handling the new property values
+ using PropertyCallBackType = std::function<void(const VehiclePropValue&)>;
+
+ // Method from IVehicleClient
+ void onPropertyValue(const VehiclePropValue& value) override;
+
+ // Request to change the value on the VEHICLE side (for testing)
+ virtual StatusCode setPropertyFromVehicle(const VehiclePropValue& value) = 0;
+
+ void registerPropertyValueCallback(PropertyCallBackType&& callback);
+
+ private:
+ PropertyCallBackType mPropCallback;
+};
+
+class EmulatedVehicleServer : public IVehicleServer {
+ public:
+ // Methods from IVehicleServer
+
+ std::vector<VehiclePropConfig> onGetAllPropertyConfig() const override;
+
+ StatusCode onSetProperty(const VehiclePropValue& value) override;
+
+ // Process the request to change the value on the VEHICLE side (for testing)
+ StatusCode onSetPropertyFromVehicle(const VehiclePropValue& value);
+
+ // Set the Property Value Pool used in this server
+ void setValuePool(VehiclePropValuePool* valuePool);
+
+ private:
+ GeneratorHub* getGenerator();
+
+ VehiclePropValuePool* getValuePool() const;
+
+ void onFakeValueGenerated(const VehiclePropValue& value);
+
+ StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
+
+ VehicleHal::VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param);
+
+ VehicleHal::VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action,
+ int32_t keyCode, int32_t targetDisplay);
+
+ // private data members
+
+ GeneratorHub mGeneratorHub{
+ std::bind(&EmulatedVehicleServer::onFakeValueGenerated, this, std::placeholders::_1)};
+
+ VehiclePropValuePool* mValuePool{nullptr};
+};
+
+class EmulatedPassthroughConnector
+ : public IPassThroughConnector<EmulatedVehicleClient, EmulatedVehicleServer> {
+ public:
+ StatusCode setPropertyFromVehicle(const VehiclePropValue& value) override {
+ return this->onSetPropertyFromVehicle(value);
+ }
+};
+
+// Helper functions
+
+using EmulatedPassthroughConnectorPtr = std::unique_ptr<EmulatedPassthroughConnector>;
+
+EmulatedPassthroughConnectorPtr makeEmulatedPassthroughConnector();
+
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index dc051d8..6508efe 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -87,17 +87,19 @@
return sensorStore;
}
-EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore)
+EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore,
+ EmulatedVehicleClient* client)
: mPropStore(propStore),
mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)),
mRecurrentTimer(
std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)),
- mGeneratorHub(
- std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1)) {
+ mVehicleClient(client) {
initStaticConfig();
for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
mPropStore->registerProperty(kVehicleProperties[i].config);
}
+ mVehicleClient->registerPropertyValueCallback(
+ std::bind(&EmulatedVehicleHal::onPropertyValue, this, std::placeholders::_1));
}
VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get(
@@ -162,7 +164,8 @@
}
if (propValue.prop == kGenerateFakeDataControllingProperty) {
- StatusCode status = handleGenerateFakeDataRequest(propValue);
+ // send the generator controlling request to the server
+ auto status = mVehicleClient->setPropertyFromVehicle(propValue);
if (status != StatusCode::OK) {
return status;
}
@@ -186,29 +189,6 @@
// Placeholder for future implementation of VMS property in the default hal. For
// now, just returns OK; otherwise, hal clients crash with property not supported.
return StatusCode::OK;
- case AP_POWER_STATE_REPORT:
- switch (propValue.value.int32Values[0]) {
- case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT):
- case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED):
- case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
- // CPMS is in WAIT_FOR_VHAL state, simply move to ON
- doHalEvent(createApPowerStateReq(VehicleApPowerStateReq::ON, 0));
- break;
- case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY):
- case toInt(VehicleApPowerStateReport::SHUTDOWN_START):
- // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command
- doHalEvent(createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0));
- break;
- case toInt(VehicleApPowerStateReport::ON):
- case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE):
- case toInt(VehicleApPowerStateReport::SHUTDOWN_PREPARE):
- // Do nothing
- break;
- default:
- // Unknown state
- break;
- }
- break;
}
}
@@ -231,10 +211,16 @@
/**
* After checking all conditions, such as the property is available, a real vhal will
* sent the events to Car ECU to take actions.
- * Google HAL will just add a timestamp for the value and triggle the callback to android.
*/
VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(propValue);
updatedPropValue->timestamp = elapsedRealtimeNano();
+
+ // Send the value to the vehicle server, the server will talk to the (real or emulated) car
+ auto setValueStatus = mVehicleClient->setProperty(*updatedPropValue);
+ if (setValueStatus != StatusCode::OK) {
+ return setValueStatus;
+ }
+
if (!mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus)) {
return StatusCode::INTERNAL_ERROR;
}
@@ -361,144 +347,19 @@
}
bool EmulatedVehicleHal::setPropertyFromVehicle(const VehiclePropValue& propValue) {
- static constexpr bool shouldUpdateStatus = true;
-
- if (propValue.prop == kGenerateFakeDataControllingProperty) {
- StatusCode status = handleGenerateFakeDataRequest(propValue);
- if (status != StatusCode::OK) {
- return false;
- }
- }
-
- if (mPropStore->writeValue(propValue, shouldUpdateStatus)) {
- doHalEvent(getValuePool()->obtain(propValue));
- return true;
- } else {
- return false;
- }
+ return mVehicleClient->setPropertyFromVehicle(propValue) == StatusCode::OK;
}
std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const {
return mPropStore->readAllValues();
}
-StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
- ALOGI("%s", __func__);
- const auto& v = request.value;
- if (!v.int32Values.size()) {
- ALOGE("%s: expected at least \"command\" field in int32Values", __func__);
- return StatusCode::INVALID_ARG;
- }
-
- FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]);
-
- switch (command) {
- case FakeDataCommand::StartLinear: {
- ALOGI("%s, FakeDataCommand::StartLinear", __func__);
- if (v.int32Values.size() < 2) {
- ALOGE("%s: expected property ID in int32Values", __func__);
- return StatusCode::INVALID_ARG;
- }
- if (!v.int64Values.size()) {
- ALOGE("%s: interval is not provided in int64Values", __func__);
- return StatusCode::INVALID_ARG;
- }
- if (v.floatValues.size() < 3) {
- ALOGE("%s: expected at least 3 elements in floatValues, got: %zu", __func__,
- v.floatValues.size());
- return StatusCode::INVALID_ARG;
- }
- int32_t cookie = v.int32Values[1];
- mGeneratorHub.registerGenerator(cookie,
- std::make_unique<LinearFakeValueGenerator>(request));
- break;
- }
- case FakeDataCommand::StartJson: {
- ALOGI("%s, FakeDataCommand::StartJson", __func__);
- if (v.stringValue.empty()) {
- ALOGE("%s: path to JSON file is missing", __func__);
- return StatusCode::INVALID_ARG;
- }
- int32_t cookie = std::hash<std::string>()(v.stringValue);
- mGeneratorHub.registerGenerator(cookie,
- std::make_unique<JsonFakeValueGenerator>(request));
- break;
- }
- case FakeDataCommand::StopLinear: {
- ALOGI("%s, FakeDataCommand::StopLinear", __func__);
- if (v.int32Values.size() < 2) {
- ALOGE("%s: expected property ID in int32Values", __func__);
- return StatusCode::INVALID_ARG;
- }
- int32_t cookie = v.int32Values[1];
- mGeneratorHub.unregisterGenerator(cookie);
- break;
- }
- case FakeDataCommand::StopJson: {
- ALOGI("%s, FakeDataCommand::StopJson", __func__);
- if (v.stringValue.empty()) {
- ALOGE("%s: path to JSON file is missing", __func__);
- return StatusCode::INVALID_ARG;
- }
- int32_t cookie = std::hash<std::string>()(v.stringValue);
- mGeneratorHub.unregisterGenerator(cookie);
- break;
- }
- case FakeDataCommand::KeyPress: {
- ALOGI("%s, FakeDataCommand::KeyPress", __func__);
- int32_t keyCode = request.value.int32Values[2];
- int32_t display = request.value.int32Values[3];
- doHalEvent(
- createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display));
- doHalEvent(createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
- break;
- }
- default: {
- ALOGE("%s: unexpected command: %d", __func__, command);
- return StatusCode::INVALID_ARG;
- }
- }
- return StatusCode::OK;
-}
-
-VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createApPowerStateReq(
- VehicleApPowerStateReq state, int32_t param) {
- auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2);
- req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ);
- req->areaId = 0;
- req->timestamp = elapsedRealtimeNano();
- req->status = VehiclePropertyStatus::AVAILABLE;
- req->value.int32Values[0] = toInt(state);
- req->value.int32Values[1] = param;
- return req;
-}
-
-VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp(
- VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) {
- auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3);
- keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT);
- keyEvent->areaId = 0;
- keyEvent->timestamp = elapsedRealtimeNano();
- keyEvent->status = VehiclePropertyStatus::AVAILABLE;
- keyEvent->value.int32Values[0] = toInt(action);
- keyEvent->value.int32Values[1] = keyCode;
- keyEvent->value.int32Values[2] = targetDisplay;
- return keyEvent;
-}
-
-void EmulatedVehicleHal::onFakeValueGenerated(const VehiclePropValue& value) {
- ALOGD("%s: %s", __func__, toString(value).c_str());
- static constexpr bool shouldUpdateStatus = false;
-
+void EmulatedVehicleHal::onPropertyValue(const VehiclePropValue& value) {
+ static constexpr bool shouldUpdateStatus = true;
VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
- if (updatedPropValue) {
- updatedPropValue->timestamp = value.timestamp;
- updatedPropValue->status = VehiclePropertyStatus::AVAILABLE;
- mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus);
- auto changeMode = mPropStore->getConfigOrDie(value.prop)->changeMode;
- if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) {
- doHalEvent(std::move(updatedPropValue));
- }
+
+ if (mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus)) {
+ doHalEvent(std::move(updatedPropValue));
}
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index 78895e3..98315ec 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -30,6 +30,7 @@
#include "vhal_v2_0/VehiclePropertyStore.h"
#include "DefaultConfig.h"
+#include "EmulatedVehicleConnector.h"
#include "GeneratorHub.h"
#include "VehicleEmulator.h"
@@ -44,7 +45,8 @@
/** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */
class EmulatedVehicleHal : public EmulatedVehicleHalIface {
public:
- EmulatedVehicleHal(VehiclePropertyStore* propStore);
+ EmulatedVehicleHal(VehiclePropertyStore* propStore,
+ EmulatedVehicleClient* client);
~EmulatedVehicleHal() = default;
// Methods from VehicleHal
@@ -66,10 +68,7 @@
}
StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
- void onFakeValueGenerated(const VehiclePropValue& value);
- VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param);
- VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
- int32_t targetDisplay);
+ void onPropertyValue(const VehiclePropValue& value);
void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
bool isContinuousProperty(int32_t propId) const;
@@ -85,7 +84,7 @@
VehiclePropertyStore* mPropStore;
std::unordered_set<int32_t> mHvacPowerProps;
RecurrentTimer mRecurrentTimer;
- GeneratorHub mGeneratorHub;
+ EmulatedVehicleClient* mVehicleClient;
};
} // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
index 6754843..2eedecd 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
@@ -29,3 +29,64 @@
],
srcs: ["VehicleHalProto.proto"]
}
+
+cc_library_static {
+ name: "android.hardware.automotive.vehicle@2.0-grpc",
+ vendor: true,
+ include_dirs: [
+ "external/protobuf/src",
+ ],
+ generated_headers: [
+ "DefaultVehicleHalProtoStub_h",
+ ],
+ export_generated_headers: [
+ "DefaultVehicleHalProtoStub_h",
+ ],
+ generated_sources: [
+ "DefaultVehicleHalProtoStub_cc",
+ ],
+ shared_libs: [
+ "libgrpc++_unsecure",
+ ],
+ cflags: [
+ "-Wno-unused-parameter"
+ ],
+}
+
+genrule {
+ name: "DefaultVehicleHalProtoStub_h",
+ tools: [
+ "aprotoc",
+ "protoc-gen-grpc-cpp-plugin",
+ ],
+ cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+ srcs: [
+ "VehicleHalProto.proto",
+ "VehicleServer.proto",
+ ],
+ out: [
+ "VehicleHalProto.pb.h",
+ "VehicleHalProto.grpc.pb.h",
+ "VehicleServer.pb.h",
+ "VehicleServer.grpc.pb.h",
+ ],
+}
+
+genrule {
+ name: "DefaultVehicleHalProtoStub_cc",
+ tools: [
+ "aprotoc",
+ "protoc-gen-grpc-cpp-plugin",
+ ],
+ cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+ srcs: [
+ "VehicleHalProto.proto",
+ "VehicleServer.proto",
+ ],
+ out: [
+ "VehicleHalProto.pb.cc",
+ "VehicleHalProto.grpc.pb.cc",
+ "VehicleServer.pb.cc",
+ "VehicleServer.grpc.pb.cc",
+ ],
+}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
index 2ef64fb..04df5a8 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleHalProto.proto
@@ -15,7 +15,6 @@
*/
syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
package emulator;
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto
new file mode 100644
index 0000000..7ce3c32
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/VehicleServer.proto
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package emulator;
+
+import "google/protobuf/empty.proto";
+import "VehicleHalProto.proto";
+
+// correspond to StatusCode defined in types.hal
+enum VehicleHalStatusCode {
+ OK = 0;
+ TRY_AGAIN = 1;
+ INVALID_ARG = 2;
+ NOT_AVAILABLE = 3;
+ ACCESS_DENIED = 4;
+ INTERNAL_ERROR = 5;
+}
+
+message VehicleHalCallStatus {
+ required VehicleHalStatusCode status_code = 1;
+}
+
+service VehicleServer {
+ rpc GetAllPropertyConfig(google.protobuf.Empty) returns (stream VehiclePropConfig) {}
+
+ // Change the property value of the vehicle
+ rpc SetProperty(VehiclePropValue) returns (VehicleHalCallStatus) {}
+
+ // Start a vehicle property value stream
+ rpc StartPropertyValuesStream(google.protobuf.Empty) returns (stream VehiclePropValue) {}
+}
+
diff --git a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
index 8b547f1..a48d19c 100644
--- a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
@@ -279,7 +279,7 @@
VmsOffers offers = {123,
{VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
VmsLayerOffering(VmsLayer(2, 0, 1))}};
- auto message = createBaseVmsMessage(2);
+ auto message = createBaseVmsMessage(16);
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
2, // number of layers
@@ -308,9 +308,28 @@
testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
+void testGetSubscribedLayersMalformedData(VmsMessageType type) {
+ VmsOffers offers = {123,
+ {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
+ VmsLayerOffering(VmsLayer(2, 0, 1))}};
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values = hidl_vec<int32_t>{toInt(type), 1234}; // sequence number
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ auto result = getSubscribedLayers(*message, offers);
+ EXPECT_EQ(static_cast<int>(result.size()), 0);
+}
+
+TEST(VmsUtilsTest, subscribedLayersForMalformedChange) {
+ testGetSubscribedLayersMalformedData(VmsMessageType::SUBSCRIPTIONS_CHANGE);
+}
+
+TEST(VmsUtilsTest, subscribedLayersForMalformedResponse) {
+ testGetSubscribedLayersMalformedData(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
+}
+
void testSubscribedLayersWithDifferentSubtype(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
- auto message = createBaseVmsMessage(2);
+ auto message = createBaseVmsMessage(7);
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
1, // number of layers
@@ -332,7 +351,7 @@
void subscribedLayersWithDifferentVersion(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
- auto message = createBaseVmsMessage(2);
+ auto message = createBaseVmsMessage(7);
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
1, // number of layers
@@ -353,7 +372,7 @@
void subscribedLayersWithDifferentPublisherId(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
- auto message = createBaseVmsMessage(2);
+ auto message = createBaseVmsMessage(9);
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
0, // number of layers
@@ -475,6 +494,113 @@
EXPECT_EQ(new_service_id, 123);
}
+TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingSmallerNumberForChange) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
+ EXPECT_TRUE(isAvailabilitySequenceNumberNewer(*message, 1233));
+}
+
+TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingSmallerNumberForResponse) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
+ EXPECT_TRUE(isAvailabilitySequenceNumberNewer(*message, 1233));
+}
+
+TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingGreaterNumberForChange) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
+ EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1235));
+}
+
+TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingGreaterNumberForResponse) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
+ EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1235));
+}
+
+TEST(VmsUtilsTest, newAvailabilitySequenceNumberForSameNumberForChange) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
+ EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1234));
+}
+
+TEST(VmsUtilsTest, newAvailabilitySequenceNumberForSameNumberForResponse) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
+ EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1234));
+}
+
+TEST(VmsUtilsTest, validSequenceNumberForAvailabilityChange) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
+ EXPECT_EQ(getSequenceNumberForAvailabilityState(*message), 1234);
+}
+
+TEST(VmsUtilsTest, validSequenceNumberForAvailabilityResponse) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
+ EXPECT_EQ(getSequenceNumberForAvailabilityState(*message), 1234);
+}
+
+TEST(VmsUtilsTest, invalidAvailabilityState) {
+ auto message = createBaseVmsMessage(1);
+ EXPECT_EQ(getSequenceNumberForAvailabilityState(*message), -1);
+}
+
+void testGetAvailableLayers(VmsMessageType type) {
+ auto message = createBaseVmsMessage(13);
+ message->value.int32Values = hidl_vec<int32_t>{toInt(type),
+ 1234, // sequence number
+ 2, // number of associated layers
+ 1, // associated layer 1
+ 0, 1,
+ 2, // number of publisher IDs
+ 111, // publisher IDs
+ 123,
+ 2, // associated layer 2
+ 0, 1, 0}; // number of publisher IDs
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ auto result = getAvailableLayers(*message);
+ EXPECT_EQ(static_cast<int>(result.size()), 2);
+ EXPECT_EQ(result.at(0).layer, VmsLayer(1, 0, 1));
+ EXPECT_EQ(result.at(0).publisher_ids.at(0), 111);
+ EXPECT_EQ(result.at(0).publisher_ids.at(1), 123);
+ EXPECT_EQ(result.at(1).layer, VmsLayer(2, 0, 1));
+ EXPECT_EQ(static_cast<int>(result.at(1).publisher_ids.size()), 0);
+}
+
+TEST(VmsUtilsTest, availableLayersForChange) {
+ testGetAvailableLayers(VmsMessageType::AVAILABILITY_CHANGE);
+}
+
+TEST(VmsUtilsTest, availableLayersForResponse) {
+ testGetAvailableLayers(VmsMessageType::AVAILABILITY_RESPONSE);
+}
+
+void testGetAvailableLayersMalformedData(VmsMessageType type) {
+ auto message = createBaseVmsMessage(2);
+ message->value.int32Values = hidl_vec<int32_t>{toInt(type), 1234}; // sequence number
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ auto result = getAvailableLayers(*message);
+ EXPECT_EQ(static_cast<int>(result.size()), 0);
+}
+
+TEST(VmsUtilsTest, availableLayersForMalformedChange) {
+ testGetAvailableLayersMalformedData(VmsMessageType::AVAILABILITY_CHANGE);
+}
+
+TEST(VmsUtilsTest, availableLayersForMalformedResponse) {
+ testGetAvailableLayersMalformedData(VmsMessageType::AVAILABILITY_RESPONSE);
+}
+
} // namespace
} // namespace vms
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index bc0b4d3..24fcf76 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2349,6 +2349,116 @@
| VehiclePropertyType:INT32
| VehicleArea:SEAT),
+ /**
+ * Support customize permissions for vendor properties
+ *
+ * Implement this property if vehicle hal support customize vendor permissions feature.
+ * VehiclePropConfig.configArray is used to indicate vendor properties and permissions
+ * which selected for this vendor property. The permission must be one of enum in
+ * VehicleVendorPermission.
+ * The configArray is set as follows:
+ * configArray[n] = propId : property ID for the vendor property
+ * configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission
+ * for reading value of the property.
+ * configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission
+ * for writing value of the property.
+ *
+ * For example:
+ * configArray = {
+ * vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE,
+ * vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE,
+ * }
+ * If vendor properties are not in this array, they will have the default vendor permission.
+ * If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In
+ * the example, Android can not write value for vendor_prop_2.
+ *
+ * @change_mode VehiclePropertyChangeMode:STATIC
+ * @access VehiclePropertyAccess:READ
+ */
+ SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = (
+ 0x0F05
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:BOOLEAN
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Allow disabling optional featurs from vhal.
+ *
+ * This property reports optional features that should be disabled.
+ * All allowed optional features for the system is declared in Car service overlay,
+ * config_allowed_optional_car_features.
+ * This property allows disabling features defined in the overlay. Without this property,
+ * all the features declared in the overlay will be enabled.
+ *
+ * Value read should include all features disabled with ',' separation.
+ * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
+ * @change_mode VehiclePropertyChangeMode:STATIC
+ * @access VehiclePropertyAccess:READ
+ */
+ DISABLED_OPTIONAL_FEATURES = (
+ 0x0F06
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:STRING
+ | VehicleArea:GLOBAL),
+
+};
+
+/**
+ * Used by SUPPORT_CUSTOMIZE_VENDOR_PERMISSION to indicate the permission of vendor properties.
+ */
+enum VehicleVendorPermission : int32_t {
+ PERMISSION_DEFAULT = 0x00000000,
+
+ // permissions for the property related with window
+ PERMISSION_SET_VENDOR_CATEGORY_WINDOW= 0X00000001,
+ PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 0x00000002,
+ // permissions for the property related with door
+ PERMISSION_SET_VENDOR_CATEGORY_DOOR = 0x00000003,
+ PERMISSION_GET_VENDOR_CATEGORY_DOOR = 0x00000004,
+ // permissions for the property related with seat
+ PERMISSION_SET_VENDOR_CATEGORY_SEAT = 0x00000005,
+ PERMISSION_GET_VENDOR_CATEGORY_SEAT = 0x00000006,
+ // permissions for the property related with mirror
+ PERMISSION_SET_VENDOR_CATEGORY_MIRROR= 0x00000007,
+ PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 0x00000008,
+
+ // permissions for the property related with car's information
+ PERMISSION_SET_VENDOR_CATEGORY_INFO = 0x00000009,
+ PERMISSION_GET_VENDOR_CATEGORY_INFO = 0x0000000A,
+ // permissions for the property related with car's engine
+ PERMISSION_SET_VENDOR_CATEGORY_ENGINE= 0x0000000B,
+ PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 0x0000000C,
+ // permissions for the property related with car's HVAC
+ PERMISSION_SET_VENDOR_CATEGORY_HVAC = 0x0000000D,
+ PERMISSION_GET_VENDOR_CATEGORY_HVAC = 0x0000000E,
+ // permissions for the property related with car's light
+ PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 0x0000000F,
+ PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 0x00000010,
+
+ // permissions reserved for other vendor permission
+ PERMISSION_SET_VENDOR_CATEGORY_1 = 0x00010000,
+ PERMISSION_GET_VENDOR_CATEGORY_1 = 0x00011000,
+ PERMISSION_SET_VENDOR_CATEGORY_2 = 0x00020000,
+ PERMISSION_GET_VENDOR_CATEGORY_2 = 0x00021000,
+ PERMISSION_SET_VENDOR_CATEGORY_3 = 0x00030000,
+ PERMISSION_GET_VENDOR_CATEGORY_3 = 0x00031000,
+ PERMISSION_SET_VENDOR_CATEGORY_4 = 0x00040000,
+ PERMISSION_GET_VENDOR_CATEGORY_4 = 0x00041000,
+ PERMISSION_SET_VENDOR_CATEGORY_5 = 0x00050000,
+ PERMISSION_GET_VENDOR_CATEGORY_5 = 0x00051000,
+ PERMISSION_SET_VENDOR_CATEGORY_6 = 0x00060000,
+ PERMISSION_GET_VENDOR_CATEGORY_6 = 0x00061000,
+ PERMISSION_SET_VENDOR_CATEGORY_7 = 0x00070000,
+ PERMISSION_GET_VENDOR_CATEGORY_7 = 0x00071000,
+ PERMISSION_SET_VENDOR_CATEGORY_8 = 0x00080000,
+ PERMISSION_GET_VENDOR_CATEGORY_8 = 0x00081000,
+ PERMISSION_SET_VENDOR_CATEGORY_9 = 0x00090000,
+ PERMISSION_GET_VENDOR_CATEGORY_9 = 0x00091000,
+ PERMISSION_SET_VENDOR_CATEGORY_10 = 0x000A0000,
+ PERMISSION_GET_VENDOR_CATEGORY_10 = 0x000A1000,
+
+ // Indicate not available for android to access.
+ PERMISSION_NOT_ACCESSIBLE = 0xF0000000
};
/**
diff --git a/biometrics/face/1.0/vts/functional/Android.bp b/biometrics/face/1.0/vts/functional/Android.bp
index fa68c4e..f2598a7 100644
--- a/biometrics/face/1.0/vts/functional/Android.bp
+++ b/biometrics/face/1.0/vts/functional/Android.bp
@@ -19,6 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalBiometricsFaceV1_0TargetTest.cpp"],
static_libs: ["android.hardware.biometrics.face@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
index a4e95ed..7ac44a4 100644
--- a/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
+++ b/biometrics/face/1.0/vts/functional/VtsHalBiometricsFaceV1_0TargetTest.cpp
@@ -20,9 +20,10 @@
#include <android/hardware/biometrics/face/1.0/IBiometricsFaceClientCallback.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include <cstdint>
@@ -124,27 +125,11 @@
}
};
-// Test environment for the BiometricsFace HAL.
-class FaceHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // Get the test environment singleton.
- static FaceHidlEnvironment* Instance() {
- static FaceHidlEnvironment* instance = new FaceHidlEnvironment;
- return instance;
- }
-
- void registerTestServices() override { registerTestService<IBiometricsFace>(); }
-
- private:
- FaceHidlEnvironment() = default;
-};
-
// Test class for the BiometricsFace HAL.
-class FaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class FaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
void SetUp() override {
- mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFace>(
- FaceHidlEnvironment::Instance()->getServiceName<IBiometricsFace>());
+ mService = IBiometricsFace::getService(GetParam());
ASSERT_NE(mService, nullptr);
mCallback = new FaceCallback();
mCallback->SetWaitTimeoutDefault(kTimeout);
@@ -167,7 +152,7 @@
// generateChallenge should always return a unique, cryptographically secure,
// non-zero number.
-TEST_F(FaceHidlTest, GenerateChallengeTest) {
+TEST_P(FaceHidlTest, GenerateChallengeTest) {
std::map<uint64_t, int> m;
for (int i = 0; i < kGenerateChallengeIterations; ++i) {
Return<void> ret =
@@ -182,7 +167,7 @@
}
// enroll with an invalid (all zeroes) HAT should fail.
-TEST_F(FaceHidlTest, EnrollZeroHatTest) {
+TEST_P(FaceHidlTest, EnrollZeroHatTest) {
// Filling HAT with zeros
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; i++) {
@@ -200,7 +185,7 @@
}
// enroll with an invalid HAT should fail.
-TEST_F(FaceHidlTest, EnrollGarbageHatTest) {
+TEST_P(FaceHidlTest, EnrollGarbageHatTest) {
// Filling HAT with pseudorandom invalid data.
// Using default seed to make the test reproducible.
std::mt19937 gen(std::mt19937::default_seed);
@@ -221,7 +206,7 @@
}
// setFeature with an invalid (all zeros) HAT should fail.
-TEST_F(FaceHidlTest, SetFeatureZeroHatTest) {
+TEST_P(FaceHidlTest, SetFeatureZeroHatTest) {
hidl_vec<uint8_t> token(69);
for (size_t i = 0; i < 69; i++) {
token[i] = 0;
@@ -232,7 +217,7 @@
}
// setFeature with an invalid HAT should fail.
-TEST_F(FaceHidlTest, SetFeatureGarbageHatTest) {
+TEST_P(FaceHidlTest, SetFeatureGarbageHatTest) {
// Filling HAT with pseudorandom invalid data.
// Using default seed to make the test reproducible.
std::mt19937 gen(std::mt19937::default_seed);
@@ -254,16 +239,16 @@
ASSERT_TRUE(res.isOk());
}
-TEST_F(FaceHidlTest, GetFeatureRequireAttentionTest) {
+TEST_P(FaceHidlTest, GetFeatureRequireAttentionTest) {
assertGetFeatureFails(mService, 0 /* faceId */, Feature::REQUIRE_ATTENTION);
}
-TEST_F(FaceHidlTest, GetFeatureRequireDiversityTest) {
+TEST_P(FaceHidlTest, GetFeatureRequireDiversityTest) {
assertGetFeatureFails(mService, 0 /* faceId */, Feature::REQUIRE_DIVERSITY);
}
// revokeChallenge should always return within the timeout
-TEST_F(FaceHidlTest, RevokeChallengeTest) {
+TEST_P(FaceHidlTest, RevokeChallengeTest) {
auto start = std::chrono::system_clock::now();
Return<Status> ret = mService->revokeChallenge();
auto elapsed = std::chrono::system_clock::now() - start;
@@ -272,14 +257,14 @@
}
// The call to getAuthenticatorId should succeed.
-TEST_F(FaceHidlTest, GetAuthenticatorIdTest) {
+TEST_P(FaceHidlTest, GetAuthenticatorIdTest) {
Return<void> ret = mService->getAuthenticatorId(
[](const OptionalUint64& res) { ASSERT_EQ(Status::OK, res.status); });
ASSERT_TRUE(ret.isOk());
}
// The call to enumerate should succeed.
-TEST_F(FaceHidlTest, EnumerateTest) {
+TEST_P(FaceHidlTest, EnumerateTest) {
Return<Status> ret = mService->enumerate();
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
auto res = mCallback->WaitForCallback(kCallbackNameOnEnumerate);
@@ -288,21 +273,21 @@
}
// The call to remove should succeed for any faceId
-TEST_F(FaceHidlTest, RemoveFaceTest) {
+TEST_P(FaceHidlTest, RemoveFaceTest) {
// Remove a face
Return<Status> ret = mService->remove(kFaceId);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Remove should accept 0 to delete all faces
-TEST_F(FaceHidlTest, RemoveAllFacesTest) {
+TEST_P(FaceHidlTest, RemoveAllFacesTest) {
// Remove all faces
Return<Status> ret = mService->remove(0);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
}
// Active user should successfully set to a writable location.
-TEST_F(FaceHidlTest, SetActiveUserTest) {
+TEST_P(FaceHidlTest, SetActiveUserTest) {
// Create an active user
Return<Status> ret = mService->setActiveUser(2, kFacedataDir);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
@@ -313,7 +298,7 @@
}
// Active user should fail to set to an unwritable location.
-TEST_F(FaceHidlTest, SetActiveUserUnwritableTest) {
+TEST_P(FaceHidlTest, SetActiveUserUnwritableTest) {
// Create an active user to an unwritable location (device root dir)
Return<Status> ret = mService->setActiveUser(3, "/");
ASSERT_NE(Status::OK, static_cast<Status>(ret));
@@ -324,7 +309,7 @@
}
// Active user should fail to set to a null location.
-TEST_F(FaceHidlTest, SetActiveUserNullTest) {
+TEST_P(FaceHidlTest, SetActiveUserNullTest) {
// Create an active user to a null location.
Return<Status> ret = mService->setActiveUser(4, nullptr);
ASSERT_NE(Status::OK, static_cast<Status>(ret));
@@ -336,7 +321,7 @@
// Cancel should always return CANCELED from any starting state including
// the IDLE state.
-TEST_F(FaceHidlTest, CancelTest) {
+TEST_P(FaceHidlTest, CancelTest) {
Return<Status> ret = mService->cancel();
// check that we were able to make an IPC request successfully
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
@@ -347,7 +332,7 @@
EXPECT_EQ(FaceError::CANCELED, res.args->error);
}
-TEST_F(FaceHidlTest, OnLockoutChangedTest) {
+TEST_P(FaceHidlTest, OnLockoutChangedTest) {
// Update active user and ensure onLockoutChanged was called.
Return<Status> ret = mService->setActiveUser(kUserId + 1, kFacedataDir);
ASSERT_EQ(Status::OK, static_cast<Status>(ret));
@@ -359,11 +344,7 @@
} // anonymous namespace
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(FaceHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- FaceHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, FaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBiometricsFace::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
index e14e3d7..a2211f4 100644
--- a/bluetooth/1.0/default/bluetooth_hci.cc
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -89,6 +89,9 @@
if (!hidl_status.isOk()) {
ALOGE("VendorInterface -> Unable to call scoDataReceived()");
}
+ },
+ [cb](const hidl_vec<uint8_t>&) {
+ ALOGE("VendorInterface -> No callback for ISO packets in HAL V1_0");
});
if (!rc) {
auto hidl_status = cb->initializationComplete(Status::INITIALIZATION_ERROR);
diff --git a/bluetooth/1.0/default/h4_protocol.cc b/bluetooth/1.0/default/h4_protocol.cc
index 98e3273..8c24f76 100644
--- a/bluetooth/1.0/default/h4_protocol.cc
+++ b/bluetooth/1.0/default/h4_protocol.cc
@@ -58,6 +58,9 @@
case HCI_PACKET_TYPE_SCO_DATA:
sco_cb_(hci_packetizer_.GetPacket());
break;
+ case HCI_PACKET_TYPE_ISO_DATA:
+ iso_cb_(hci_packetizer_.GetPacket());
+ break;
default:
LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__,
static_cast<int>(hci_packet_type_));
diff --git a/bluetooth/1.0/default/h4_protocol.h b/bluetooth/1.0/default/h4_protocol.h
index 0d0a1ca..0c82fd6 100644
--- a/bluetooth/1.0/default/h4_protocol.h
+++ b/bluetooth/1.0/default/h4_protocol.h
@@ -31,11 +31,12 @@
class H4Protocol : public HciProtocol {
public:
H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb,
- PacketReadCallback sco_cb)
+ PacketReadCallback sco_cb, PacketReadCallback iso_cb)
: uart_fd_(fd),
event_cb_(event_cb),
acl_cb_(acl_cb),
sco_cb_(sco_cb),
+ iso_cb_(iso_cb),
hci_packetizer_([this]() { OnPacketReady(); }) {}
size_t Send(uint8_t type, const uint8_t* data, size_t length);
@@ -50,6 +51,7 @@
PacketReadCallback event_cb_;
PacketReadCallback acl_cb_;
PacketReadCallback sco_cb_;
+ PacketReadCallback iso_cb_;
HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN};
hci::HciPacketizer hci_packetizer_;
diff --git a/bluetooth/1.0/default/hci_internals.h b/bluetooth/1.0/default/hci_internals.h
index 1e1f300..24e944f 100644
--- a/bluetooth/1.0/default/hci_internals.h
+++ b/bluetooth/1.0/default/hci_internals.h
@@ -24,7 +24,8 @@
HCI_PACKET_TYPE_COMMAND = 1,
HCI_PACKET_TYPE_ACL_DATA = 2,
HCI_PACKET_TYPE_SCO_DATA = 3,
- HCI_PACKET_TYPE_EVENT = 4
+ HCI_PACKET_TYPE_EVENT = 4,
+ HCI_PACKET_TYPE_ISO_DATA = 5,
};
// 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
diff --git a/bluetooth/1.0/default/test/h4_protocol_unittest.cc b/bluetooth/1.0/default/test/h4_protocol_unittest.cc
index ba56c0d..283243d 100644
--- a/bluetooth/1.0/default/test/h4_protocol_unittest.cc
+++ b/bluetooth/1.0/default/test/h4_protocol_unittest.cc
@@ -42,11 +42,15 @@
static char sample_data1[100] = "A point is that which has no part.";
static char sample_data2[100] = "A line is breadthless length.";
static char sample_data3[100] = "The ends of a line are points.";
+static char sample_data4[100] =
+ "A plane surface is a surface which lies evenly with the straight ...";
static char acl_data[100] =
"A straight line is a line which lies evenly with the points on itself.";
static char sco_data[100] =
"A surface is that which has length and breadth only.";
static char event_data[100] = "The edges of a surface are lines.";
+static char iso_data[100] =
+ "A plane angle is the inclination to one another of two lines in a ...";
MATCHER_P3(HidlVecMatches, preamble, preamble_length, payload, "") {
size_t length = strlen(payload) + preamble_length;
@@ -75,9 +79,9 @@
int sockfd[2];
socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
- H4Protocol* h4_hci =
- new H4Protocol(sockfd[0], event_cb_.AsStdFunction(),
- acl_cb_.AsStdFunction(), sco_cb_.AsStdFunction());
+ H4Protocol* h4_hci = new H4Protocol(
+ sockfd[0], event_cb_.AsStdFunction(), acl_cb_.AsStdFunction(),
+ sco_cb_.AsStdFunction(), iso_cb_.AsStdFunction());
fd_watcher_.WatchFdForNonBlockingReads(
sockfd[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
protocol_ = h4_hci;
@@ -184,9 +188,35 @@
}
}
+ void WriteAndExpectInboundIsoData(char* payload) {
+ // h4 type[1] + handle[2] + size[1]
+ char preamble[4] = {HCI_PACKET_TYPE_ISO_DATA, 20, 17, 0};
+ preamble[3] = strlen(payload) & 0xFF;
+
+ ALOGD("%s writing", __func__);
+ TEMP_FAILURE_RETRY(write(fake_uart_, preamble, sizeof(preamble)));
+ TEMP_FAILURE_RETRY(write(fake_uart_, payload, strlen(payload)));
+
+ ALOGD("%s waiting", __func__);
+ std::mutex mutex;
+ std::condition_variable done;
+ EXPECT_CALL(iso_cb_, Call(HidlVecMatches(preamble + 1, sizeof(preamble) - 1,
+ payload)))
+ .WillOnce(Notify(&mutex, &done));
+
+ // Fail if it takes longer than 100 ms.
+ auto timeout_time =
+ std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
+ {
+ std::unique_lock<std::mutex> lock(mutex);
+ done.wait_until(lock, timeout_time);
+ }
+ }
+
testing::MockFunction<void(const hidl_vec<uint8_t>&)> event_cb_;
testing::MockFunction<void(const hidl_vec<uint8_t>&)> acl_cb_;
testing::MockFunction<void(const hidl_vec<uint8_t>&)> sco_cb_;
+ testing::MockFunction<void(const hidl_vec<uint8_t>&)> iso_cb_;
async::AsyncFdWatcher fd_watcher_;
H4Protocol* protocol_;
int fake_uart_;
@@ -197,6 +227,7 @@
SendAndReadUartOutbound(HCI_PACKET_TYPE_COMMAND, sample_data1);
SendAndReadUartOutbound(HCI_PACKET_TYPE_ACL_DATA, sample_data2);
SendAndReadUartOutbound(HCI_PACKET_TYPE_SCO_DATA, sample_data3);
+ SendAndReadUartOutbound(HCI_PACKET_TYPE_ISO_DATA, sample_data4);
}
// Ensure we properly parse data coming from the UART
@@ -204,6 +235,7 @@
WriteAndExpectInboundAclData(acl_data);
WriteAndExpectInboundScoData(sco_data);
WriteAndExpectInboundEvent(event_data);
+ WriteAndExpectInboundIsoData(iso_data);
}
} // namespace implementation
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index d56e344..d809313 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -162,14 +162,14 @@
bool VendorInterface::Initialize(
InitializeCompleteCallback initialize_complete_cb,
PacketReadCallback event_cb, PacketReadCallback acl_cb,
- PacketReadCallback sco_cb) {
+ PacketReadCallback sco_cb, PacketReadCallback iso_cb) {
if (g_vendor_interface) {
ALOGE("%s: No previous Shutdown()?", __func__);
return false;
}
g_vendor_interface = new VendorInterface();
return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
- sco_cb);
+ sco_cb, iso_cb);
}
void VendorInterface::Shutdown() {
@@ -185,7 +185,8 @@
bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
PacketReadCallback event_cb,
PacketReadCallback acl_cb,
- PacketReadCallback sco_cb) {
+ PacketReadCallback sco_cb,
+ PacketReadCallback iso_cb) {
initialize_complete_cb_ = initialize_complete_cb;
// Initialize vendor interface
@@ -248,7 +249,7 @@
if (fd_count == 1) {
hci::H4Protocol* h4_hci =
- new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb);
+ new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb, iso_cb);
fd_watcher_.WatchFdForNonBlockingReads(
fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
hci_ = h4_hci;
diff --git a/bluetooth/1.0/default/vendor_interface.h b/bluetooth/1.0/default/vendor_interface.h
index 1d69040..040f31a 100644
--- a/bluetooth/1.0/default/vendor_interface.h
+++ b/bluetooth/1.0/default/vendor_interface.h
@@ -38,7 +38,7 @@
public:
static bool Initialize(InitializeCompleteCallback initialize_complete_cb,
PacketReadCallback event_cb, PacketReadCallback acl_cb,
- PacketReadCallback sco_cb);
+ PacketReadCallback sco_cb, PacketReadCallback iso_cb);
static void Shutdown();
static VendorInterface* get();
@@ -51,7 +51,7 @@
bool Open(InitializeCompleteCallback initialize_complete_cb,
PacketReadCallback event_cb, PacketReadCallback acl_cb,
- PacketReadCallback sco_cb);
+ PacketReadCallback sco_cb, PacketReadCallback iso_cb);
void Close();
void OnTimeout();
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index beb9a3e..ef02eff 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -24,8 +24,9 @@
#include <utils/Log.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include <queue>
@@ -137,30 +138,12 @@
std::chrono::steady_clock::time_point start_time_;
};
-// Test environment for Bluetooth HIDL HAL.
-class BluetoothHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static BluetoothHidlEnvironment* Instance() {
- static BluetoothHidlEnvironment* instance = new BluetoothHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IBluetoothHci>();
- }
-
- private:
- BluetoothHidlEnvironment() {}
-};
-
// The main test class for Bluetooth HIDL HAL.
-class BluetoothHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class BluetoothHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
// currently test passthrough mode only
- bluetooth =
- ::testing::VtsHalHidlTargetTestBase::getService<IBluetoothHci>();
+ bluetooth = IBluetoothHci::getService(GetParam());
ASSERT_NE(bluetooth, nullptr);
ALOGI("%s: getService() for bluetooth is %s", __func__,
bluetooth->isRemote() ? "remote" : "local");
@@ -617,10 +600,10 @@
}
// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
-TEST_F(BluetoothHidlTest, InitializeAndClose) {}
+TEST_P(BluetoothHidlTest, InitializeAndClose) {}
// Send an HCI Reset with sendHciCommand and wait for a command complete event.
-TEST_F(BluetoothHidlTest, HciReset) {
+TEST_P(BluetoothHidlTest, HciReset) {
hidl_vec<uint8_t> cmd = COMMAND_HCI_RESET;
bluetooth->sendHciCommand(cmd);
@@ -628,7 +611,7 @@
}
// Read and check the HCI version of the controller.
-TEST_F(BluetoothHidlTest, HciVersionTest) {
+TEST_P(BluetoothHidlTest, HciVersionTest) {
hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
bluetooth->sendHciCommand(cmd);
@@ -649,7 +632,7 @@
}
// Send an unknown HCI command and wait for the error message.
-TEST_F(BluetoothHidlTest, HciUnknownCommand) {
+TEST_P(BluetoothHidlTest, HciUnknownCommand) {
hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
bluetooth->sendHciCommand(cmd);
@@ -676,14 +659,14 @@
}
// Enter loopback mode, but don't send any packets.
-TEST_F(BluetoothHidlTest, WriteLoopbackMode) {
+TEST_P(BluetoothHidlTest, WriteLoopbackMode) {
std::vector<uint16_t> sco_connection_handles;
std::vector<uint16_t> acl_connection_handles;
enterLoopbackMode(sco_connection_handles, acl_connection_handles);
}
// Enter loopback mode and send single packets.
-TEST_F(BluetoothHidlTest, LoopbackModeSinglePackets) {
+TEST_P(BluetoothHidlTest, LoopbackModeSinglePackets) {
setBufferSizes();
std::vector<uint16_t> sco_connection_handles;
@@ -720,7 +703,7 @@
}
// Enter loopback mode and send packets for bandwidth measurements.
-TEST_F(BluetoothHidlTest, LoopbackModeBandwidth) {
+TEST_P(BluetoothHidlTest, LoopbackModeBandwidth) {
setBufferSizes();
std::vector<uint16_t> sco_connection_handles;
@@ -758,11 +741,8 @@
}
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(BluetoothHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- BluetoothHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, BluetoothHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IBluetoothHci::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/bluetooth/1.1/Android.bp b/bluetooth/1.1/Android.bp
new file mode 100644
index 0000000..4204aed
--- /dev/null
+++ b/bluetooth/1.1/Android.bp
@@ -0,0 +1,18 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.bluetooth@1.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IBluetoothHci.hal",
+ "IBluetoothHciCallbacks.hal",
+ ],
+ interfaces: [
+ "android.hardware.bluetooth@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/bluetooth/1.1/IBluetoothHci.hal b/bluetooth/1.1/IBluetoothHci.hal
new file mode 100644
index 0000000..0f69c6e
--- /dev/null
+++ b/bluetooth/1.1/IBluetoothHci.hal
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth@1.1;
+
+import @1.0::HciPacket;
+import @1.0::IBluetoothHci;
+import IBluetoothHciCallbacks;
+
+/**
+ * The Host Controller Interface (HCI) is the layer defined by the Bluetooth
+ * specification between the software that runs on the host and the Bluetooth
+ * controller chip. This boundary is the natural choice for a Hardware
+ * Abstraction Layer (HAL). Dealing only in HCI packets and events simplifies
+ * the stack and abstracts away power management, initialization, and other
+ * implementation-specific details related to the hardware.
+ */
+interface IBluetoothHci extends @1.0::IBluetoothHci {
+ /**
+ * Same as @1.0, but uses 1.1 Callbacks version
+ */
+ initialize_1_1(@1.1::IBluetoothHciCallbacks callback);
+
+ /**
+ * Send an ISO data packet (as specified in the Bluetooth Specification
+ * V6.0) to the Bluetooth controller.
+ * Packets must be processed in order.
+ * @param data HCI data packet to be sent
+ */
+ sendIsoData(HciPacket data);
+};
diff --git a/bluetooth/1.1/IBluetoothHciCallbacks.hal b/bluetooth/1.1/IBluetoothHciCallbacks.hal
new file mode 100644
index 0000000..62cbe45
--- /dev/null
+++ b/bluetooth/1.1/IBluetoothHciCallbacks.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth@1.1;
+
+import @1.0::HciPacket;
+import @1.0::IBluetoothHciCallbacks;
+
+/**
+ * The interface from the Bluetooth Controller to the stack.
+ */
+interface IBluetoothHciCallbacks extends @1.0::IBluetoothHciCallbacks {
+ /**
+ * Send a ISO data packet form the controller to the host.
+ * @param data the ISO HCI packet to be passed to the host stack
+ */
+ isoDataReceived(HciPacket data);
+};
diff --git a/bluetooth/1.1/default/Android.bp b/bluetooth/1.1/default/Android.bp
new file mode 100644
index 0000000..4f7fecb
--- /dev/null
+++ b/bluetooth/1.1/default/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+ name: "android.hardware.bluetooth@1.1-service",
+ defaults: ["hidl_defaults"],
+ relative_install_path: "hw",
+ vendor: true,
+ init_rc: ["android.hardware.bluetooth@1.1-service.rc"],
+ srcs: [
+ "service.cpp",
+ "bluetooth_hci.cc",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libdl",
+ "libbase",
+ "libutils",
+ "libhardware",
+ "libhidlbase",
+ "android.hardware.bluetooth@1.0-impl",
+ "android.hardware.bluetooth@1.1",
+ ],
+
+ static_libs: [
+ "android.hardware.bluetooth-hci",
+ ],
+}
diff --git a/bluetooth/1.1/default/OWNERS b/bluetooth/1.1/default/OWNERS
new file mode 100644
index 0000000..0c01df6
--- /dev/null
+++ b/bluetooth/1.1/default/OWNERS
@@ -0,0 +1,3 @@
+zachoverflow@google.com
+mylesgw@google.com
+jpawlowski@google.com
diff --git a/bluetooth/1.1/default/android.hardware.bluetooth@1.1-service.rc b/bluetooth/1.1/default/android.hardware.bluetooth@1.1-service.rc
new file mode 100644
index 0000000..49f0be3
--- /dev/null
+++ b/bluetooth/1.1/default/android.hardware.bluetooth@1.1-service.rc
@@ -0,0 +1,9 @@
+service vendor.bluetooth-1-1 /vendor/bin/hw/android.hardware.bluetooth@1.1-service
+ interface android.hardware.bluetooth@1.1::IBluetoothHci default
+ interface android.hardware.bluetooth@1.0::IBluetoothHci default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ writepid /dev/stune/foreground/tasks
+
diff --git a/bluetooth/1.1/default/bluetooth_hci.cc b/bluetooth/1.1/default/bluetooth_hci.cc
new file mode 100644
index 0000000..7ccce80
--- /dev/null
+++ b/bluetooth/1.1/default/bluetooth_hci.cc
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2016 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 "android.hardware.bluetooth@1.1-impl"
+#include "bluetooth_hci.h"
+
+#include <log/log.h>
+
+#include "vendor_interface.h"
+
+using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_1 {
+namespace implementation {
+
+static const uint8_t HCI_DATA_TYPE_COMMAND = 1;
+static const uint8_t HCI_DATA_TYPE_ACL = 2;
+static const uint8_t HCI_DATA_TYPE_SCO = 3;
+static const uint8_t HCI_DATA_TYPE_ISO = 5;
+
+class BluetoothDeathRecipient : public hidl_death_recipient {
+ public:
+ BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
+
+ virtual void serviceDied(
+ uint64_t /*cookie*/,
+ const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+ ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
+ has_died_ = true;
+ mHci->close();
+ }
+ sp<IBluetoothHci> mHci;
+ bool getHasDied() const { return has_died_; }
+ void setHasDied(bool has_died) { has_died_ = has_died; }
+
+ private:
+ bool has_died_;
+};
+
+BluetoothHci::BluetoothHci()
+ : death_recipient_(new BluetoothDeathRecipient(this)) {}
+
+Return<void> BluetoothHci::initialize_1_1(
+ const ::android::sp<V1_1::IBluetoothHciCallbacks>& cb) {
+ ALOGI("BluetoothHci::initialize_1_1()");
+ if (cb == nullptr) {
+ ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+ return Void();
+ }
+
+ death_recipient_->setHasDied(false);
+ cb->linkToDeath(death_recipient_, 0);
+
+ bool rc = VendorInterface::Initialize(
+ [cb](bool status) {
+ auto hidl_status = cb->initializationComplete(
+ status ? V1_0::Status::SUCCESS
+ : V1_0::Status::INITIALIZATION_ERROR);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call initializationComplete()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->hciEventReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call hciEventReceived()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->aclDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call aclDataReceived()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->scoDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call scoDataReceived()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->isoDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call isoDataReceived()");
+ }
+ });
+ if (!rc) {
+ auto hidl_status =
+ cb->initializationComplete(V1_0::Status::INITIALIZATION_ERROR);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
+ }
+ }
+
+ unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
+ if (death_recipient->getHasDied())
+ ALOGI("Skipping unlink call, service died.");
+ else
+ cb->unlinkToDeath(death_recipient);
+ };
+
+ return Void();
+}
+
+class OldCbWrapper : public V1_1::IBluetoothHciCallbacks {
+ public:
+ const ::android::sp<V1_0::IBluetoothHciCallbacks> old_cb_;
+ OldCbWrapper(const ::android::sp<V1_0::IBluetoothHciCallbacks>& old_cb)
+ : old_cb_(old_cb) {}
+
+ virtual ~OldCbWrapper() = default;
+
+ Return<void> initializationComplete(V1_0::Status status) override {
+ return old_cb_->initializationComplete(status);
+ };
+
+ Return<void> hciEventReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& event) override {
+ return old_cb_->hciEventReceived(event);
+ };
+
+ Return<void> aclDataReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& data) override {
+ return old_cb_->aclDataReceived(data);
+ };
+
+ Return<void> scoDataReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& data) override {
+ return old_cb_->scoDataReceived(data);
+ };
+
+ Return<void> isoDataReceived(
+ const ::android::hardware::hidl_vec<uint8_t>&) override {
+ ALOGE("Please use HAL V1_1 for ISO.");
+ return Void();
+ };
+};
+
+Return<void> BluetoothHci::initialize(
+ const ::android::sp<V1_0::IBluetoothHciCallbacks>& cb) {
+ ALOGE("Using initialize from HAL V1_0 instead of initialize_1_1.");
+ return initialize_1_1(new OldCbWrapper(cb));
+}
+
+Return<void> BluetoothHci::close() {
+ ALOGI("BluetoothHci::close()");
+ unlink_cb_(death_recipient_);
+ VendorInterface::Shutdown();
+ return Void();
+}
+
+Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
+ sendDataToController(HCI_DATA_TYPE_COMMAND, command);
+ return Void();
+}
+
+Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
+ sendDataToController(HCI_DATA_TYPE_ACL, data);
+ return Void();
+}
+
+Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
+ sendDataToController(HCI_DATA_TYPE_SCO, data);
+ return Void();
+}
+
+Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& data) {
+ sendDataToController(HCI_DATA_TYPE_ISO, data);
+ return Void();
+}
+
+void BluetoothHci::sendDataToController(const uint8_t type,
+ const hidl_vec<uint8_t>& data) {
+ VendorInterface::get()->Send(type, data.data(), data.size());
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/1.1/default/bluetooth_hci.h b/bluetooth/1.1/default/bluetooth_hci.h
new file mode 100644
index 0000000..5f59cb0
--- /dev/null
+++ b/bluetooth/1.1/default/bluetooth_hci.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HIDL_GENERATED_android_hardware_bluetooth_V1_1_BluetoothHci_H_
+#define HIDL_GENERATED_android_hardware_bluetooth_V1_1_BluetoothHci_H_
+
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHciCallbacks.h>
+
+#include <hidl/MQDescriptor.h>
+
+#include <functional>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+
+class BluetoothDeathRecipient;
+
+class BluetoothHci : public V1_1::IBluetoothHci {
+ public:
+ BluetoothHci();
+ Return<void> initialize(
+ const ::android::sp<V1_0::IBluetoothHciCallbacks>& cb) override;
+ Return<void> initialize_1_1(
+ const ::android::sp<V1_1::IBluetoothHciCallbacks>& cb) override;
+ Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
+ Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
+ Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
+ Return<void> sendIsoData(const hidl_vec<uint8_t>& data) override;
+ Return<void> close() override;
+
+ private:
+ void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data);
+ ::android::sp<BluetoothDeathRecipient> death_recipient_;
+ std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+
+#endif // HIDL_GENERATED_android_hardware_bluetooth_V1_1_BluetoothHci_H_
diff --git a/bluetooth/1.1/default/service.cpp b/bluetooth/1.1/default/service.cpp
new file mode 100644
index 0000000..affa855
--- /dev/null
+++ b/bluetooth/1.1/default/service.cpp
@@ -0,0 +1,43 @@
+//
+// Copyright 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#define LOG_TAG "android.hardware.bluetooth@1.1-service"
+
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "bluetooth_hci.h"
+
+// Generated HIDL files
+using android::hardware::bluetooth::V1_1::IBluetoothHci;
+using android::hardware::bluetooth::V1_1::implementation::BluetoothHci;
+
+using android::sp;
+using android::status_t;
+
+int main() {
+ ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/);
+
+ sp bluetoothHci = new BluetoothHci();
+ const status_t status = bluetoothHci->registerAsService();
+ if (status != ::android::OK) {
+ ALOGE("Cannot register Bluetooth HAL service");
+ return 1; // or handle error
+ }
+
+ ::android::hardware::joinRpcThreadpool();
+ return 1; // joinRpcThreadpool should never return
+}
diff --git a/bluetooth/1.1/vts/OWNERS b/bluetooth/1.1/vts/OWNERS
new file mode 100644
index 0000000..ff6fd93
--- /dev/null
+++ b/bluetooth/1.1/vts/OWNERS
@@ -0,0 +1,6 @@
+zachoverflow@google.com
+siyuanh@google.com
+mylesgw@google.com
+jpawlowski@google.com
+hsz@google.com
+
diff --git a/vibrator/1.4/vts/functional/Android.bp b/bluetooth/1.1/vts/functional/Android.bp
similarity index 65%
copy from vibrator/1.4/vts/functional/Android.bp
copy to bluetooth/1.1/vts/functional/Android.bp
index 202a824..8d6d749 100644
--- a/vibrator/1.4/vts/functional/Android.bp
+++ b/bluetooth/1.1/vts/functional/Android.bp
@@ -15,19 +15,13 @@
//
cc_test {
- name: "VtsHalVibratorV1_4TargetTest",
+ name: "VtsHalBluetoothV1_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["VtsHalVibratorV1_4TargetTest.cpp"],
+ srcs: ["VtsHalBluetoothV1_1TargetTest.cpp"],
static_libs: [
- "android.hardware.vibrator@1.0",
- "android.hardware.vibrator@1.1",
- "android.hardware.vibrator@1.2",
- "android.hardware.vibrator@1.3",
- "android.hardware.vibrator@1.4",
+ "android.hardware.bluetooth@1.1",
+ "android.hardware.bluetooth@1.0",
+ "libbluetooth-types",
],
- test_suites: [
- "general-tests",
- "vts-core",
- ],
+ test_suites: ["general-tests", "vts-core"],
}
-
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
new file mode 100644
index 0000000..659b2c8
--- /dev/null
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
@@ -0,0 +1,760 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "bluetooth_hidl_hal_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/bluetooth/1.0/types.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHciCallbacks.h>
+#include <hardware/bluetooth.h>
+#include <utils/Log.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <chrono>
+#include <queue>
+#include <thread>
+
+using ::android::sp;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::bluetooth::V1_0::Status;
+using ::android::hardware::bluetooth::V1_1::IBluetoothHci;
+using ::android::hardware::bluetooth::V1_1::IBluetoothHciCallbacks;
+
+#define HCI_MINIMUM_HCI_VERSION 5 // Bluetooth Core Specification 3.0 + HS
+#define HCI_MINIMUM_LMP_VERSION 5 // Bluetooth Core Specification 3.0 + HS
+#define NUM_HCI_COMMANDS_BANDWIDTH 1000
+#define NUM_SCO_PACKETS_BANDWIDTH 1000
+#define NUM_ACL_PACKETS_BANDWIDTH 1000
+#define WAIT_FOR_INIT_TIMEOUT std::chrono::milliseconds(2000)
+#define WAIT_FOR_HCI_EVENT_TIMEOUT std::chrono::milliseconds(2000)
+#define WAIT_FOR_SCO_DATA_TIMEOUT std::chrono::milliseconds(1000)
+#define WAIT_FOR_ACL_DATA_TIMEOUT std::chrono::milliseconds(1000)
+#define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(200)
+
+#define COMMAND_HCI_SHOULD_BE_UNKNOWN \
+ { 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }
+#define COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION \
+ { 0x01, 0x10, 0x00 }
+#define COMMAND_HCI_READ_BUFFER_SIZE \
+ { 0x05, 0x10, 0x00 }
+#define COMMAND_HCI_WRITE_LOOPBACK_MODE_LOCAL \
+ { 0x02, 0x18, 0x01, 0x01 }
+#define COMMAND_HCI_RESET \
+ { 0x03, 0x0c, 0x00 }
+#define COMMAND_HCI_WRITE_LOCAL_NAME \
+ { 0x13, 0x0c, 0xf8 }
+#define HCI_STATUS_SUCCESS 0x00
+#define HCI_STATUS_UNKNOWN_HCI_COMMAND 0x01
+
+#define EVENT_CONNECTION_COMPLETE 0x03
+#define EVENT_COMMAND_COMPLETE 0x0e
+#define EVENT_COMMAND_STATUS 0x0f
+#define EVENT_NUMBER_OF_COMPLETED_PACKETS 0x13
+#define EVENT_LOOPBACK_COMMAND 0x19
+
+#define EVENT_CODE_BYTE 0
+#define EVENT_LENGTH_BYTE 1
+#define EVENT_FIRST_PAYLOAD_BYTE 2
+#define EVENT_COMMAND_STATUS_STATUS_BYTE 2
+#define EVENT_COMMAND_STATUS_ALLOWED_PACKETS_BYTE 3
+#define EVENT_COMMAND_STATUS_OPCODE_LSBYTE 4 // Bytes 4 and 5
+#define EVENT_COMMAND_COMPLETE_ALLOWED_PACKETS_BYTE 2
+#define EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE 3 // Bytes 3 and 4
+#define EVENT_COMMAND_COMPLETE_STATUS_BYTE 5
+#define EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE 6
+#define EVENT_LOCAL_HCI_VERSION_BYTE EVENT_COMMAND_COMPLETE_FIRST_PARAM_BYTE
+#define EVENT_LOCAL_LMP_VERSION_BYTE EVENT_LOCAL_HCI_VERSION_BYTE + 3
+
+#define EVENT_CONNECTION_COMPLETE_PARAM_LENGTH 11
+#define EVENT_CONNECTION_COMPLETE_TYPE 11
+#define EVENT_CONNECTION_COMPLETE_TYPE_SCO 0
+#define EVENT_CONNECTION_COMPLETE_TYPE_ACL 1
+#define EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE 3
+#define EVENT_COMMAND_STATUS_LENGTH 4
+
+#define EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES 2
+
+#define ACL_BROADCAST_FLAG_OFFSET 6
+#define ACL_BROADCAST_FLAG_POINT_TO_POINT 0x0
+#define ACL_BROADCAST_POINT_TO_POINT \
+ (ACL_BROADCAST_FLAG_POINT_TO_POINT << ACL_BROADCAST_FLAG_OFFSET)
+
+#define ACL_PACKET_BOUNDARY_FLAG_OFFSET 4
+#define ACL_PACKET_BOUNDARY_FLAG_FIRST_AUTO_FLUSHABLE 0x2
+#define ACL_PACKET_BOUNDARY_FIRST_AUTO_FLUSHABLE \
+ (ACL_PACKET_BOUNDARY_FLAG_FIRST_AUTO_FLUSHABLE \
+ << ACL_PACKET_BOUNDARY_FLAG_OFFSET)
+
+// To be removed in VTS release builds
+#define ACL_HANDLE_QCA_DEBUG_MESSAGE 0xedc
+
+constexpr char kCallbackNameAclEventReceived[] = "aclDataReceived";
+constexpr char kCallbackNameHciEventReceived[] = "hciEventReceived";
+constexpr char kCallbackNameInitializationComplete[] = "initializationComplete";
+constexpr char kCallbackNameScoEventReceived[] = "scoDataReceived";
+constexpr char kCallbackNameIsoEventReceived[] = "isoDataReceived";
+
+class ThroughputLogger {
+ public:
+ ThroughputLogger(std::string task)
+ : task_(task), start_time_(std::chrono::steady_clock::now()) {}
+
+ ~ThroughputLogger() {
+ if (total_bytes_ == 0) return;
+ std::chrono::duration<double> duration =
+ std::chrono::steady_clock::now() - start_time_;
+ double s = duration.count();
+ if (s == 0) return;
+ double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
+ ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
+ total_bytes_, s);
+ }
+
+ void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
+
+ private:
+ size_t total_bytes_;
+ std::string task_;
+ std::chrono::steady_clock::time_point start_time_;
+};
+
+// The main test class for Bluetooth HIDL HAL.
+class BluetoothHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ // currently test passthrough mode only
+ bluetooth = IBluetoothHci::getService(GetParam());
+ ASSERT_NE(bluetooth, nullptr);
+ ALOGI("%s: getService() for bluetooth is %s", __func__,
+ bluetooth->isRemote() ? "remote" : "local");
+
+ bluetooth_hci_death_recipient = new BluetoothHciDeathRecipient();
+ ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
+ ASSERT_TRUE(
+ bluetooth->linkToDeath(bluetooth_hci_death_recipient, 0).isOk());
+
+ bluetooth_cb = new BluetoothHciCallbacks(*this);
+ ASSERT_NE(bluetooth_cb, nullptr);
+
+ max_acl_data_packet_length = 0;
+ max_sco_data_packet_length = 0;
+ max_acl_data_packets = 0;
+ max_sco_data_packets = 0;
+
+ initialized = false;
+ event_cb_count = 0;
+ acl_cb_count = 0;
+ sco_cb_count = 0;
+
+ ASSERT_FALSE(initialized);
+ // Should not be checked in production code
+ ASSERT_TRUE(bluetooth->initialize(bluetooth_cb).isOk());
+
+ bluetooth_cb->SetWaitTimeout(kCallbackNameInitializationComplete,
+ WAIT_FOR_INIT_TIMEOUT);
+ bluetooth_cb->SetWaitTimeout(kCallbackNameHciEventReceived,
+ WAIT_FOR_HCI_EVENT_TIMEOUT);
+ bluetooth_cb->SetWaitTimeout(kCallbackNameAclEventReceived,
+ WAIT_FOR_ACL_DATA_TIMEOUT);
+ bluetooth_cb->SetWaitTimeout(kCallbackNameScoEventReceived,
+ WAIT_FOR_SCO_DATA_TIMEOUT);
+
+ EXPECT_TRUE(
+ bluetooth_cb->WaitForCallback(kCallbackNameInitializationComplete)
+ .no_timeout);
+
+ ASSERT_TRUE(initialized);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown");
+ // Should not be checked in production code
+ ASSERT_TRUE(bluetooth->close().isOk());
+ std::this_thread::sleep_for(INTERFACE_CLOSE_DELAY_MS);
+ handle_no_ops();
+ EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
+ EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
+ EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
+ EXPECT_EQ(static_cast<size_t>(0), iso_queue.size());
+ }
+
+ void setBufferSizes();
+
+ // Functions called from within tests in loopback mode
+ void sendAndCheckHCI(int num_packets);
+ void sendAndCheckSCO(int num_packets, size_t size, uint16_t handle);
+ void sendAndCheckACL(int num_packets, size_t size, uint16_t handle);
+
+ // Helper functions to try to get a handle on verbosity
+ void enterLoopbackMode(std::vector<uint16_t>* sco_handles,
+ std::vector<uint16_t>* acl_handles);
+ void handle_no_ops();
+ void wait_for_event(bool timeout_is_error);
+ void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
+ int wait_for_completed_packets_event(uint16_t handle);
+
+ class BluetoothHciDeathRecipient : public hidl_death_recipient {
+ public:
+ void serviceDied(
+ uint64_t /*cookie*/,
+ const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/)
+ override {
+ FAIL();
+ }
+ };
+
+ // A simple test implementation of BluetoothHciCallbacks.
+ class BluetoothHciCallbacks
+ : public ::testing::VtsHalHidlTargetCallbackBase<BluetoothHidlTest>,
+ public IBluetoothHciCallbacks {
+ BluetoothHidlTest& parent_;
+
+ public:
+ BluetoothHciCallbacks(BluetoothHidlTest& parent) : parent_(parent){};
+
+ virtual ~BluetoothHciCallbacks() = default;
+
+ Return<void> initializationComplete(Status status) override {
+ parent_.initialized = (status == Status::SUCCESS);
+ NotifyFromCallback(kCallbackNameInitializationComplete);
+ ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
+ return Void();
+ };
+
+ Return<void> hciEventReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& event) override {
+ parent_.event_cb_count++;
+ parent_.event_queue.push(event);
+ NotifyFromCallback(kCallbackNameHciEventReceived);
+ ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
+ return Void();
+ };
+
+ Return<void> aclDataReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& data) override {
+ parent_.acl_cb_count++;
+ parent_.acl_queue.push(data);
+ NotifyFromCallback(kCallbackNameAclEventReceived);
+ return Void();
+ };
+
+ Return<void> scoDataReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& data) override {
+ parent_.sco_cb_count++;
+ parent_.sco_queue.push(data);
+ NotifyFromCallback(kCallbackNameScoEventReceived);
+ return Void();
+ };
+
+ Return<void> isoDataReceived(
+ const ::android::hardware::hidl_vec<uint8_t>& data) override {
+ parent_.iso_cb_count++;
+ parent_.iso_queue.push(data);
+ NotifyFromCallback(kCallbackNameIsoEventReceived);
+ return Void();
+ };
+ };
+
+ sp<IBluetoothHci> bluetooth;
+ sp<BluetoothHciCallbacks> bluetooth_cb;
+ sp<BluetoothHciDeathRecipient> bluetooth_hci_death_recipient;
+ std::queue<hidl_vec<uint8_t>> event_queue;
+ std::queue<hidl_vec<uint8_t>> acl_queue;
+ std::queue<hidl_vec<uint8_t>> sco_queue;
+ std::queue<hidl_vec<uint8_t>> iso_queue;
+
+ bool initialized;
+
+ int event_cb_count;
+ int sco_cb_count;
+ int acl_cb_count;
+ int iso_cb_count;
+
+ int max_acl_data_packet_length;
+ int max_sco_data_packet_length;
+ int max_acl_data_packets;
+ int max_sco_data_packets;
+};
+
+// Discard NO-OPs from the event queue.
+void BluetoothHidlTest::handle_no_ops() {
+ while (event_queue.size() > 0) {
+ hidl_vec<uint8_t> event = event_queue.front();
+ EXPECT_GE(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ bool event_is_no_op =
+ (event[EVENT_CODE_BYTE] == EVENT_COMMAND_COMPLETE) &&
+ (event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE] == 0x00) &&
+ (event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1] == 0x00);
+ event_is_no_op |= (event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS) &&
+ (event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE] == 0x00) &&
+ (event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1] == 0x00);
+ if (event_is_no_op) {
+ event_queue.pop();
+ } else {
+ break;
+ }
+ }
+ // To be removed in VTS release builds
+ while (acl_queue.size() > 0) {
+ hidl_vec<uint8_t> acl_packet = acl_queue.front();
+ uint16_t connection_handle = acl_packet[1] & 0xF;
+ connection_handle <<= 8;
+ connection_handle |= acl_packet[0];
+ bool packet_is_no_op = connection_handle == ACL_HANDLE_QCA_DEBUG_MESSAGE;
+ if (packet_is_no_op) {
+ acl_queue.pop();
+ } else {
+ break;
+ }
+ }
+}
+
+// Receive an event, discarding NO-OPs.
+void BluetoothHidlTest::wait_for_event(bool timeout_is_error = true) {
+ hidl_vec<uint8_t> event;
+ do {
+ bool no_timeout =
+ bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout;
+ EXPECT_TRUE(no_timeout || !timeout_is_error);
+ if (no_timeout && timeout_is_error) {
+ EXPECT_LT(static_cast<size_t>(0), event_queue.size());
+ }
+ if (event_queue.size() == 0) {
+ // WaitForCallback timed out.
+ return;
+ }
+ handle_no_ops();
+ } while (event_queue.size() == 0);
+}
+
+// Wait until a COMMAND_COMPLETE is received.
+void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
+ wait_for_event();
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+}
+
+// Send the command to read the controller's buffer sizes.
+void BluetoothHidlTest::setBufferSizes() {
+ hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_BUFFER_SIZE;
+ bluetooth->sendHciCommand(cmd);
+
+ wait_for_event();
+ if (event_queue.size() == 0) return;
+
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+
+ EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+
+ max_acl_data_packet_length =
+ event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 1] +
+ (event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 2] << 8);
+ max_sco_data_packet_length = event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 3];
+ max_acl_data_packets = event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 4] +
+ (event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 5] << 8);
+ max_sco_data_packets = event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 6] +
+ (event[EVENT_COMMAND_COMPLETE_STATUS_BYTE + 7] << 8);
+
+ ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
+ static_cast<int>(max_acl_data_packet_length),
+ static_cast<int>(max_acl_data_packets),
+ static_cast<int>(max_sco_data_packet_length),
+ static_cast<int>(max_sco_data_packets));
+}
+
+// Send an HCI command (in Loopback mode) and check the response.
+void BluetoothHidlTest::sendAndCheckHCI(int num_packets) {
+ ThroughputLogger logger = {__func__};
+ int command_size = 0;
+ for (int n = 0; n < num_packets; n++) {
+ // Send an HCI packet
+ std::vector<uint8_t> write_name = COMMAND_HCI_WRITE_LOCAL_NAME;
+ // With a name
+ char new_name[] = "John Jacob Jingleheimer Schmidt ___________________0";
+ size_t new_name_length = strlen(new_name);
+ for (size_t i = 0; i < new_name_length; i++)
+ write_name.push_back(static_cast<uint8_t>(new_name[i]));
+ // And the packet number
+ size_t i = new_name_length - 1;
+ for (int digits = n; digits > 0; digits = digits / 10, i--)
+ write_name[i] = static_cast<uint8_t>('0' + digits % 10);
+ // And padding
+ for (size_t i = 0; i < 248 - new_name_length; i++)
+ write_name.push_back(static_cast<uint8_t>(0));
+
+ hidl_vec<uint8_t> cmd = write_name;
+ bluetooth->sendHciCommand(cmd);
+
+ // Check the loopback of the HCI packet
+ wait_for_event();
+ if (event_queue.size() == 0) return;
+
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+ size_t compare_length =
+ (cmd.size() > static_cast<size_t>(0xff) ? static_cast<size_t>(0xff)
+ : cmd.size());
+ EXPECT_GT(event.size(), compare_length + EVENT_FIRST_PAYLOAD_BYTE - 1);
+
+ EXPECT_EQ(EVENT_LOOPBACK_COMMAND, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(compare_length, event[EVENT_LENGTH_BYTE]);
+
+ // Don't compare past the end of the event.
+ if (compare_length + EVENT_FIRST_PAYLOAD_BYTE > event.size()) {
+ compare_length = event.size() - EVENT_FIRST_PAYLOAD_BYTE;
+ ALOGE("Only comparing %d bytes", static_cast<int>(compare_length));
+ }
+
+ if (n == num_packets - 1) {
+ command_size = cmd.size();
+ }
+
+ for (size_t i = 0; i < compare_length; i++)
+ EXPECT_EQ(cmd[i], event[EVENT_FIRST_PAYLOAD_BYTE + i]);
+ }
+ logger.setTotalBytes(command_size * num_packets * 2);
+}
+
+// Send a SCO data packet (in Loopback mode) and check the response.
+void BluetoothHidlTest::sendAndCheckSCO(int num_packets, size_t size,
+ uint16_t handle) {
+ ThroughputLogger logger = {__func__};
+ for (int n = 0; n < num_packets; n++) {
+ // Send a SCO packet
+ hidl_vec<uint8_t> sco_packet;
+ std::vector<uint8_t> sco_vector;
+ sco_vector.push_back(static_cast<uint8_t>(handle & 0xff));
+ sco_vector.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8));
+ sco_vector.push_back(static_cast<uint8_t>(size & 0xff));
+ sco_vector.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
+ for (size_t i = 0; i < size; i++) {
+ sco_vector.push_back(static_cast<uint8_t>(i + n));
+ }
+ sco_packet = sco_vector;
+ bluetooth->sendScoData(sco_vector);
+
+ // Check the loopback of the SCO packet
+ EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameScoEventReceived)
+ .no_timeout);
+ hidl_vec<uint8_t> sco_loopback = sco_queue.front();
+ sco_queue.pop();
+
+ EXPECT_EQ(sco_packet.size(), sco_loopback.size());
+ size_t successful_bytes = 0;
+
+ for (size_t i = 0; i < sco_packet.size(); i++) {
+ if (sco_packet[i] == sco_loopback[i]) {
+ successful_bytes = i;
+ } else {
+ ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
+ sco_packet[i], sco_loopback[i]);
+ ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
+ sco_packet[i + 1], sco_loopback[i + 1]);
+ break;
+ }
+ }
+ EXPECT_EQ(sco_packet.size(), successful_bytes + 1);
+ }
+ logger.setTotalBytes(num_packets * size * 2);
+}
+
+// Send an ACL data packet (in Loopback mode) and check the response.
+void BluetoothHidlTest::sendAndCheckACL(int num_packets, size_t size,
+ uint16_t handle) {
+ ThroughputLogger logger = {__func__};
+ for (int n = 0; n < num_packets; n++) {
+ // Send an ACL packet
+ hidl_vec<uint8_t> acl_packet;
+ std::vector<uint8_t> acl_vector;
+ acl_vector.push_back(static_cast<uint8_t>(handle & 0xff));
+ acl_vector.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
+ ACL_BROADCAST_POINT_TO_POINT |
+ ACL_PACKET_BOUNDARY_FIRST_AUTO_FLUSHABLE);
+ acl_vector.push_back(static_cast<uint8_t>(size & 0xff));
+ acl_vector.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
+ for (size_t i = 0; i < size; i++) {
+ acl_vector.push_back(static_cast<uint8_t>(i + n));
+ }
+ acl_packet = acl_vector;
+ bluetooth->sendAclData(acl_vector);
+
+ // Check the loopback of the ACL packet
+ EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameAclEventReceived)
+ .no_timeout);
+ hidl_vec<uint8_t> acl_loopback = acl_queue.front();
+ acl_queue.pop();
+
+ EXPECT_EQ(acl_packet.size(), acl_loopback.size());
+ size_t successful_bytes = 0;
+
+ for (size_t i = 0; i < acl_packet.size(); i++) {
+ if (acl_packet[i] == acl_loopback[i]) {
+ successful_bytes = i;
+ } else {
+ ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
+ acl_packet[i], acl_loopback[i]);
+ ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
+ acl_packet[i + 1], acl_loopback[i + 1]);
+ break;
+ }
+ }
+ EXPECT_EQ(acl_packet.size(), successful_bytes + 1);
+ }
+ logger.setTotalBytes(num_packets * size * 2);
+}
+
+// Return the number of completed packets reported by the controller.
+int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
+ int packets_processed = 0;
+ wait_for_event(false);
+ if (event_queue.size() == 0) {
+ ALOGW("%s: WaitForCallback timed out.", __func__);
+ return packets_processed;
+ }
+ while (event_queue.size() > 0) {
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+
+ EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
+
+ uint16_t event_handle = event[3] + (event[4] << 8);
+ EXPECT_EQ(handle, event_handle);
+
+ packets_processed += event[5] + (event[6] << 8);
+ }
+ return packets_processed;
+}
+
+// Send local loopback command and initialize SCO and ACL handles.
+void BluetoothHidlTest::enterLoopbackMode(std::vector<uint16_t>* sco_handles,
+ std::vector<uint16_t>* acl_handles) {
+ hidl_vec<uint8_t> cmd = COMMAND_HCI_WRITE_LOOPBACK_MODE_LOCAL;
+ bluetooth->sendHciCommand(cmd);
+
+ // Receive connection complete events with data channels
+ int connection_event_count = 0;
+ bool command_complete_received = false;
+ while (true) {
+ wait_for_event(false);
+ if (event_queue.size() == 0) {
+ // Fail if there was no event received or no connections completed.
+ EXPECT_TRUE(command_complete_received);
+ EXPECT_LT(0, connection_event_count);
+ return;
+ }
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
+ EXPECT_EQ(event[EVENT_LENGTH_BYTE],
+ EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
+ uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
+
+ EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
+ connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
+
+ // Save handles
+ uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
+ event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1] << 8;
+ if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
+ sco_handles->push_back(handle);
+ else
+ acl_handles->push_back(handle);
+
+ ALOGD("Connect complete type = %d handle = %d",
+ event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
+ connection_event_count++;
+ } else {
+ EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+ command_complete_received = true;
+ }
+ }
+}
+
+// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
+TEST_P(BluetoothHidlTest, InitializeAndClose) {}
+
+// Send an HCI Reset with sendHciCommand and wait for a command complete event.
+TEST_P(BluetoothHidlTest, HciReset) {
+ hidl_vec<uint8_t> cmd = COMMAND_HCI_RESET;
+ bluetooth->sendHciCommand(cmd);
+
+ wait_for_command_complete_event(cmd);
+}
+
+// Read and check the HCI version of the controller.
+TEST_P(BluetoothHidlTest, HciVersionTest) {
+ hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
+ bluetooth->sendHciCommand(cmd);
+
+ wait_for_event();
+ if (event_queue.size() == 0) return;
+
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+ EXPECT_GT(event.size(), static_cast<size_t>(EVENT_LOCAL_LMP_VERSION_BYTE));
+
+ EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+
+ EXPECT_LE(HCI_MINIMUM_HCI_VERSION, event[EVENT_LOCAL_HCI_VERSION_BYTE]);
+ EXPECT_LE(HCI_MINIMUM_LMP_VERSION, event[EVENT_LOCAL_LMP_VERSION_BYTE]);
+}
+
+// Send an unknown HCI command and wait for the error message.
+TEST_P(BluetoothHidlTest, HciUnknownCommand) {
+ hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
+ bluetooth->sendHciCommand(cmd);
+
+ wait_for_event();
+ if (event_queue.size() == 0) return;
+
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ if (event[EVENT_CODE_BYTE] == EVENT_COMMAND_COMPLETE) {
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+ event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+ } else {
+ EXPECT_EQ(EVENT_COMMAND_STATUS, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+ event[EVENT_COMMAND_STATUS_STATUS_BYTE]);
+ }
+}
+
+// Enter loopback mode, but don't send any packets.
+TEST_P(BluetoothHidlTest, WriteLoopbackMode) {
+ std::vector<uint16_t> sco_connection_handles;
+ std::vector<uint16_t> acl_connection_handles;
+ enterLoopbackMode(&sco_connection_handles, &acl_connection_handles);
+}
+
+// Enter loopback mode and send single packets.
+TEST_P(BluetoothHidlTest, LoopbackModeSinglePackets) {
+ setBufferSizes();
+
+ std::vector<uint16_t> sco_connection_handles;
+ std::vector<uint16_t> acl_connection_handles;
+ enterLoopbackMode(&sco_connection_handles, &acl_connection_handles);
+
+ sendAndCheckHCI(1);
+
+ // This should work, but breaks on some current platforms. Figure out how to
+ // grandfather older devices but test new ones.
+ if (0 && sco_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_sco_data_packet_length);
+ sendAndCheckSCO(1, max_sco_data_packet_length, sco_connection_handles[0]);
+ int sco_packets_sent = 1;
+ int completed_packets =
+ wait_for_completed_packets_event(sco_connection_handles[0]);
+ if (sco_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+ sco_packets_sent, completed_packets);
+ }
+ }
+
+ if (acl_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_acl_data_packet_length);
+ sendAndCheckACL(1, max_acl_data_packet_length, acl_connection_handles[0]);
+ int acl_packets_sent = 1;
+ int completed_packets =
+ wait_for_completed_packets_event(acl_connection_handles[0]);
+ if (acl_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+ acl_packets_sent, completed_packets);
+ }
+ }
+}
+
+// Enter loopback mode and send packets for bandwidth measurements.
+TEST_P(BluetoothHidlTest, LoopbackModeBandwidth) {
+ setBufferSizes();
+
+ std::vector<uint16_t> sco_connection_handles;
+ std::vector<uint16_t> acl_connection_handles;
+ enterLoopbackMode(&sco_connection_handles, &acl_connection_handles);
+
+ sendAndCheckHCI(NUM_HCI_COMMANDS_BANDWIDTH);
+
+ // This should work, but breaks on some current platforms. Figure out how to
+ // grandfather older devices but test new ones.
+ if (0 && sco_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_sco_data_packet_length);
+ sendAndCheckSCO(NUM_SCO_PACKETS_BANDWIDTH, max_sco_data_packet_length,
+ sco_connection_handles[0]);
+ int sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
+ int completed_packets =
+ wait_for_completed_packets_event(sco_connection_handles[0]);
+ if (sco_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+ sco_packets_sent, completed_packets);
+ }
+ }
+
+ if (acl_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_acl_data_packet_length);
+ sendAndCheckACL(NUM_ACL_PACKETS_BANDWIDTH, max_acl_data_packet_length,
+ acl_connection_handles[0]);
+ int acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
+ int completed_packets =
+ wait_for_completed_packets_event(acl_connection_handles[0]);
+ if (acl_packets_sent != completed_packets) {
+ ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+ acl_packets_sent, completed_packets);
+ }
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, BluetoothHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IBluetoothHci::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/bluetooth/audio/2.0/vts/functional/Android.bp b/bluetooth/audio/2.0/vts/functional/Android.bp
index b672fe4..b778b97 100644
--- a/bluetooth/audio/2.0/vts/functional/Android.bp
+++ b/bluetooth/audio/2.0/vts/functional/Android.bp
@@ -9,4 +9,5 @@
shared_libs: [
"libfmq",
],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp b/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp
index 9572d3f..b3cb6f7 100644
--- a/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp
+++ b/bluetooth/audio/2.0/vts/functional/VtsHalBluetoothAudioV2_0TargetTest.cpp
@@ -21,12 +21,13 @@
#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvider.h>
#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.h>
#include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
#include <hidl/MQDescriptor.h>
+#include <hidl/ServiceManagement.h>
#include <utils/Log.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::sp;
using ::android::hardware::hidl_vec;
@@ -105,34 +106,13 @@
}
} // namespace
-// Test environment for Bluetooth Audio HAL.
-class BluetoothAudioHidlEnvironment
- : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static BluetoothAudioHidlEnvironment* Instance() {
- static BluetoothAudioHidlEnvironment* instance =
- new BluetoothAudioHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IBluetoothAudioProvidersFactory>();
- }
-
- private:
- BluetoothAudioHidlEnvironment() {}
-};
-
// The base test class for Bluetooth Audio HAL.
class BluetoothAudioProvidersFactoryHidlTest
- : public ::testing::VtsHalHidlTargetTestBase {
+ : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- providers_factory_ = ::testing::VtsHalHidlTargetTestBase::getService<
- IBluetoothAudioProvidersFactory>(
- BluetoothAudioHidlEnvironment::Instance()
- ->getServiceName<IBluetoothAudioProvidersFactory>());
+ providers_factory_ =
+ IBluetoothAudioProvidersFactory::getService(GetParam());
ASSERT_NE(providers_factory_, nullptr);
}
@@ -300,13 +280,13 @@
/**
* Test whether we can get the FactoryService from HIDL
*/
-TEST_F(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
+TEST_P(BluetoothAudioProvidersFactoryHidlTest, GetProvidersFactoryService) {}
/**
* Test whether we can open a provider for each provider returned by
* getProviderCapabilities() with non-empty capabalities
*/
-TEST_F(BluetoothAudioProvidersFactoryHidlTest,
+TEST_P(BluetoothAudioProvidersFactoryHidlTest,
OpenProviderAndCheckCapabilitiesBySession) {
for (auto session_type : session_types_) {
GetProviderCapabilitiesHelper(session_type);
@@ -341,14 +321,14 @@
/**
* Test whether we can open a provider of type
*/
-TEST_F(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
+TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest, OpenA2dpSoftwareProvider) {}
/**
* Test whether each provider of type
* SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
* different PCM config
*/
-TEST_F(BluetoothAudioProviderA2dpSoftwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpSoftwareHidlTest,
StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
bool is_codec_config_valid;
std::unique_ptr<DataMQ> tempDataMQ;
@@ -616,14 +596,14 @@
/**
* Test whether we can open a provider of type
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest, OpenA2dpHardwareProvider) {}
/**
* Test whether each provider of type
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* SBC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpSbcHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -658,7 +638,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* AAC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpAacHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -693,7 +673,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* LDAC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpLdacHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -728,7 +708,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* AptX hardware encoding config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpAptxHardwareSession) {
if (!IsOffloadSupported()) {
return;
@@ -767,7 +747,7 @@
* SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
* an invalid codec config
*/
-TEST_F(BluetoothAudioProviderA2dpHardwareHidlTest,
+TEST_P(BluetoothAudioProviderA2dpHardwareHidlTest,
StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
if (!IsOffloadSupported()) {
return;
@@ -857,7 +837,7 @@
* SessionType::HEARING_AID_HARDWARE_ENCODING_DATAPATH can be started and
* stopped with SBC hardware encoding config
*/
-TEST_F(BluetoothAudioProviderHearingAidSoftwareHidlTest,
+TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
OpenHearingAidSoftwareProvider) {}
/**
@@ -865,7 +845,7 @@
* SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
* stopped with different PCM config
*/
-TEST_F(BluetoothAudioProviderHearingAidSoftwareHidlTest,
+TEST_P(BluetoothAudioProviderHearingAidSoftwareHidlTest,
StartAndEndHearingAidSessionWithPossiblePcmConfig) {
bool is_codec_config_valid;
std::unique_ptr<DataMQ> tempDataMQ;
@@ -904,12 +884,25 @@
} // SampleRate
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(
- BluetoothAudioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- BluetoothAudioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+static const std::vector<std::string> kAudioInstances =
+ android::hardware::getAllHalInstanceNames(
+ IBluetoothAudioProvidersFactory::descriptor);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProvidersFactoryHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderA2dpSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderA2dpHardwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHearingAidSoftwareHidlTest,
+ testing::ValuesIn(kAudioInstances),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/broadcastradio/1.1/default/service.cpp b/broadcastradio/1.1/default/service.cpp
index f8af0b7..29dc76f 100644
--- a/broadcastradio/1.1/default/service.cpp
+++ b/broadcastradio/1.1/default/service.cpp
@@ -20,6 +20,7 @@
#include "BroadcastRadioFactory.h"
+using android::sp;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::broadcastradio::V1_1::implementation::BroadcastRadioFactory;
@@ -27,8 +28,8 @@
int main(int /* argc */, char** /* argv */) {
configureRpcThreadpool(4, true);
- BroadcastRadioFactory broadcastRadioFactory;
- auto status = broadcastRadioFactory.registerAsService();
+ sp<BroadcastRadioFactory> broadcastRadioFactory(new BroadcastRadioFactory());
+ auto status = broadcastRadioFactory->registerAsService();
CHECK_EQ(status, android::OK) << "Failed to register Broadcast Radio HAL implementation";
joinRpcThreadpool();
diff --git a/broadcastradio/2.0/default/service.cpp b/broadcastradio/2.0/default/service.cpp
index 349aba2..bd746fd 100644
--- a/broadcastradio/2.0/default/service.cpp
+++ b/broadcastradio/2.0/default/service.cpp
@@ -19,6 +19,7 @@
#include "BroadcastRadio.h"
#include "VirtualRadio.h"
+using android::sp;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::broadcastradio::V2_0::implementation::BroadcastRadio;
@@ -30,13 +31,13 @@
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
configureRpcThreadpool(4, true);
- BroadcastRadio broadcastRadio(gAmFmRadio);
- auto amFmStatus = broadcastRadio.registerAsService("amfm");
+ sp<BroadcastRadio> broadcastRadio(new BroadcastRadio(gAmFmRadio));
+ auto amFmStatus = broadcastRadio->registerAsService("amfm");
CHECK_EQ(amFmStatus, android::OK)
<< "Failed to register Broadcast Radio AM/FM HAL implementation";
- BroadcastRadio dabRadio(gDabRadio);
- auto dabStatus = dabRadio.registerAsService("dab");
+ sp<BroadcastRadio> dabRadio(new BroadcastRadio(gDabRadio));
+ auto dabStatus = dabRadio->registerAsService("dab");
CHECK_EQ(dabStatus, android::OK) << "Failed to register Broadcast Radio DAB HAL implementation";
joinRpcThreadpool();
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index 76f9778..ac32c95 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -252,8 +252,7 @@
// No need to use bytesPerPixel and bytesPerStride because we are using
// an 1-D buffer and accressRegion.
mMapperV4->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
- const auto& /*bytesPerStride*/) {
+ [&](const auto& tmpError, const auto& tmpPtr) {
if (tmpError == MapperErrorV4::NONE) {
ret = tmpPtr;
} else {
@@ -301,7 +300,13 @@
}
if (mMapperV4 != nullptr) {
- return lockYCbCrInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf, cpuUsage, accessRegion);
+ // No device currently supports IMapper 4.0 so it is safe to just return an error code here.
+ //
+ // This will be supported by a combination of lock and BufferMetadata getters. We are going
+ // to refactor all the IAllocator/IMapper versioning code into a shared library. We will
+ // then add the IMapper 4.0 lockYCbCr support then.
+ ALOGE("%s: MapperV4 doesn't support lockYCbCr directly!", __FUNCTION__);
+ return {};
}
if (mMapperV3 != nullptr) {
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 5fe7b19..080fa19 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -25,6 +25,7 @@
"libcamera_metadata",
"libcutils",
"libfmq",
+ "libgralloctypes",
"libgui",
"libui",
],
@@ -41,13 +42,7 @@
"android.hardware.camera.metadata@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
- "android.hardware.graphics.allocator@2.0",
- "android.hardware.graphics.allocator@3.0",
- "android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.common@1.0",
- "android.hardware.graphics.mapper@2.0",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.graphics.mapper@4.0",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 49f9fe1..9416a54 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -26,21 +26,21 @@
#include <inttypes.h>
-#include <android/hardware/camera/device/1.0/ICameraDevice.h>
-#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-#include <android/hardware/camera/device/3.5/ICameraDevice.h>
-#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
-#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
-#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
-#include <android/hardware/camera/metadata/3.4/types.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
#include <CameraMetadata.h>
#include <CameraParameters.h>
+#include <android/hardware/camera/device/1.0/ICameraDevice.h>
+#include <android/hardware/camera/device/3.2/ICameraDevice.h>
+#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.5/ICameraDevice.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
+#include <android/hardware/camera/metadata/3.4/types.h>
+#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <binder/MemoryHeapBase.h>
#include <cutils/properties.h>
#include <fmq/MessageQueue.h>
#include <grallocusage/GrallocUsageConversion.h>
@@ -52,14 +52,9 @@
#include <system/camera.h>
#include <system/camera_metadata.h>
#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
-#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <android/hardware/graphics/mapper/2.0/types.h>
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
-#include <android/hardware/graphics/mapper/4.0/IMapper.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
@@ -1494,7 +1489,7 @@
ADD_FAILURE();
}
- std::lock_guard<std::mutex> l(mLock);
+ std::unique_lock<std::mutex> l(mLock);
for (const auto& buf : buffers) {
bool found = false;
for (size_t idx = 0; idx < mOutstandingBufferIds.size(); idx++) {
@@ -1514,6 +1509,10 @@
ALOGE("%s: unknown buffer ID %" PRIu64, __FUNCTION__, buf.bufferId);
ADD_FAILURE();
}
+ if (!hasOutstandingBuffersLocked()) {
+ l.unlock();
+ mFlushedCondition.notify_one();
+ }
return Void();
}
@@ -6307,102 +6306,15 @@
PixelFormat format, hidl_handle *buffer_handle /*out*/) {
ASSERT_NE(buffer_handle, nullptr);
- sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
- android::hardware::graphics::allocator::V2_0::IAllocator::getService();
- sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocatorV3 =
- android::hardware::graphics::allocator::V3_0::IAllocator::getService();
- sp<android::hardware::graphics::allocator::V4_0::IAllocator> allocatorV4 =
- android::hardware::graphics::allocator::V4_0::IAllocator::getService();
+ buffer_handle_t buffer;
+ uint32_t stride;
- sp<android::hardware::graphics::mapper::V4_0::IMapper> mapperV4 =
- android::hardware::graphics::mapper::V4_0::IMapper::getService();
- sp<android::hardware::graphics::mapper::V3_0::IMapper> mapperV3 =
- android::hardware::graphics::mapper::V3_0::IMapper::getService();
- sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
- android::hardware::graphics::mapper::V2_0::IMapper::getService();
- if (mapperV4 != nullptr && allocatorV4 != nullptr) {
- ::android::hardware::hidl_vec<uint8_t> descriptor;
- android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo descriptorInfo{};
- descriptorInfo.name = "VtsHalCameraProviderV2_4";
- descriptorInfo.width = width;
- descriptorInfo.height = height;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format =
- static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
- descriptorInfo.usage = usage;
+ android::status_t err = android::GraphicBufferAllocator::get().allocate(
+ width, height, static_cast<int32_t>(format), 1u /*layerCount*/, usage, &buffer, &stride,
+ "VtsHalCameraProviderV2_4");
+ ASSERT_EQ(err, android::NO_ERROR);
- auto ret = mapperV4->createDescriptor(
- descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V4_0::Error err,
- ::android::hardware::hidl_vec<uint8_t> desc) {
- ASSERT_EQ(err, android::hardware::graphics::mapper::V4_0::Error::NONE);
- descriptor = desc;
- });
- ASSERT_TRUE(ret.isOk());
-
- ret = allocatorV4->allocate(
- descriptor, 1u,
- [&](android::hardware::graphics::mapper::V4_0::Error err, uint32_t /*stride*/,
- const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>&
- buffers) {
- ASSERT_EQ(android::hardware::graphics::mapper::V4_0::Error::NONE, err);
- ASSERT_EQ(buffers.size(), 1u);
- *buffer_handle = buffers[0];
- });
- ASSERT_TRUE(ret.isOk());
- } else if (mapperV3 != nullptr && allocatorV3 != nullptr) {
- ::android::hardware::hidl_vec<uint32_t> descriptor;
- android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
- descriptorInfo.width = width;
- descriptorInfo.height = height;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format =
- static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
- descriptorInfo.usage = usage;
-
- auto ret = mapperV3->createDescriptor(
- descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V3_0::Error err,
- ::android::hardware::hidl_vec<uint32_t> desc) {
- ASSERT_EQ(err, android::hardware::graphics::mapper::V3_0::Error::NONE);
- descriptor = desc;
- });
- ASSERT_TRUE(ret.isOk());
-
- ret = allocatorV3->allocate(descriptor, 1u,
- [&](android::hardware::graphics::mapper::V3_0::Error err, uint32_t /*stride*/,
- const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
- ASSERT_EQ(android::hardware::graphics::mapper::V3_0::Error::NONE, err);
- ASSERT_EQ(buffers.size(), 1u);
- *buffer_handle = buffers[0];
- });
- ASSERT_TRUE(ret.isOk());
- } else {
- ::android::hardware::hidl_vec<uint32_t> descriptor;
- ASSERT_NE(mapper.get(), nullptr);
- ASSERT_NE(allocator.get(), nullptr);
- android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
- descriptorInfo.width = width;
- descriptorInfo.height = height;
- descriptorInfo.layerCount = 1;
- descriptorInfo.format = format;
- descriptorInfo.usage = usage;
-
- auto ret = mapper->createDescriptor(
- descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
- ::android::hardware::hidl_vec<uint32_t> desc) {
- ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
- descriptor = desc;
- });
- ASSERT_TRUE(ret.isOk());
-
- ret = allocator->allocate(descriptor, 1u,
- [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
- const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
- ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
- ASSERT_EQ(buffers.size(), 1u);
- *buffer_handle = buffers[0];
- });
- ASSERT_TRUE(ret.isOk());
- }
+ buffer_handle->setTo(const_cast<native_handle_t*>(buffer), true /*shouldOwn*/);
}
void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
diff --git a/cas/1.2/Android.bp b/cas/1.2/Android.bp
index af98b2e..fbb38b0 100644
--- a/cas/1.2/Android.bp
+++ b/cas/1.2/Android.bp
@@ -7,10 +7,10 @@
enabled: true,
},
srcs: [
+ "types.hal",
"ICas.hal",
"ICasListener.hal",
"IMediaCasService.hal",
- "types.hal",
],
interfaces: [
"android.hardware.cas@1.0",
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 799ab07..7883dd9 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -83,8 +83,8 @@
"compatibility_matrix.current.xml",
],
kernel_configs: [
- "kernel_config_current_4.9",
"kernel_config_current_4.14",
"kernel_config_current_4.19",
+ "kernel_config_current_5.4",
]
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index fb8d395..b0a82a5 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -49,6 +49,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.automotive.occupant_awareness</name>
+ <interface>
+ <name>IOccupantAwareness</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.automotive.vehicle</name>
<version>2.0</version>
@@ -75,7 +82,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.bluetooth</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IBluetoothHci</name>
<instance>default</instance>
@@ -155,7 +162,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
- <version>1.0-2</version>
+ <version>1.0-3</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
@@ -189,7 +196,7 @@
- test DeviceManifestTest#GnssHalVersionCompatibility.
-->
<version>1.1</version>
- <version>2.0</version>
+ <version>2.0-1</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
@@ -256,7 +263,7 @@
<hal format="hidl" optional="false">
<name>android.hardware.keymaster</name>
<version>3.0</version>
- <version>4.0</version>
+ <version>4.0-1</version>
<interface>
<name>IKeymasterDevice</name>
<instance>default</instance>
@@ -264,7 +271,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.keymaster</name>
- <version>4.0</version>
+ <version>4.0-1</version>
<interface>
<name>IKeymasterDevice</name>
<instance>strongbox</instance>
@@ -280,7 +287,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.media.c2</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IComponentStore</name>
<regex-instance>default[0-9]*</regex-instance>
@@ -349,7 +356,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio</name>
- <version>1.4</version>
+ <version>1.5</version>
<interface>
<name>IRadio</name>
<instance>slot1</instance>
@@ -367,10 +374,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.radio.config</name>
- <!--
- See compatibility_matrix.4.xml on versioning of radio config HAL.
- -->
- <version>1.1</version>
+ <version>1.3</version>
<interface>
<name>IRadioConfig</name>
<instance>default</instance>
@@ -508,7 +512,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.wifi.hostapd</name>
- <version>1.0-1</version>
+ <version>1.0-2</version>
<interface>
<name>IHostapd</name>
<instance>default</instance>
diff --git a/configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy b/configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy
index 937fddd..a609620 100644
--- a/configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy
+++ b/configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy
@@ -45,6 +45,7 @@
getdents64: 1
clock_gettime: 1
getpid: 1
+gettid: 1
# used during process crash by crash_dump to dump process info
rt_sigprocmask: 1
diff --git a/current.txt b/current.txt
index b46f37f..cdd98a9 100644
--- a/current.txt
+++ b/current.txt
@@ -576,35 +576,79 @@
b69a7615c508acf5c5201efd1bfa3262167874fc3594e2db5a3ff93addd8ac75 android.hardware.keymaster@4.0::IKeymasterDevice
eb2fa0c883c2185d514be0b84c179b283753ef0c1b77b45b4f359bd23bba8b75 android.hardware.neuralnetworks@1.0::IPreparedModel
f1109cbb10297b7429a11fab42afa912710b303c9bf20bd5cdb8bd57b9c84186 android.hardware.neuralnetworks@1.0::types
-9d8ee57c490ffeaa28f702eaea8d198cb510e4bbfb99e6cb5f63e73341057c7c android.hardware.neuralnetworks@1.1::types
+5f6d3097ba84cb63c430787123f4de1b31c11f90b531b98eae9a8623a5ae962a android.hardware.neuralnetworks@1.1::types
fb382e986c10b8fbb797a8546e8f9ea6d1107bfe6f3fb7e57f6bbbf1f807a906 android.hardware.neuralnetworks@1.2::IDevice
40e71cd693de5b832325c5d8f081f2ff20a7ba2b89d401cee5b4b3eb0e241681 android.hardware.neuralnetworks@1.2::IPreparedModel
-71c0f7127335e5b74d1615d5e7f129831b43ffbae5318ad0924d7d8d8910a859 android.hardware.neuralnetworks@1.2::types
+2d5483fbf59d5fd2de94665a6df05da5c3d09de67561d0db5e9f09e59e9aea46 android.hardware.neuralnetworks@1.2::types
a785a57447a81e9c130eef6904c3a5c256076c6a04588c40620ebd6fa2660d77 android.hardware.radio@1.2::types
1a6e2bd289f22931c526b21916910f1d4c436b7acb9556e4243de4ce8e6cc2e4 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
fd65298e1e09e0e3c781ab18305920d757dbe55a3b459ce17814ec5cf6dfee99 android.hardware.wifi@1.0::IWifiP2pIface
# HALs released in Android R
+e966a3437d6a98d9d9e14e9d672088771716031900c0deb55a0946c751a03a44 android.hardware.audio@6.0::types
+2736c59abaccacac407ebe80c5e48d446edf015051d05632fb679ba471779e6e android.hardware.audio@6.0::IDevice
+2402876cbc23c0de3690a665eca84fd3857d1808dba5cad25ce272f81ecef8c9 android.hardware.audio@6.0::IDevicesFactory
+bca5379d5065e2e08b6ad7308ffc8a71a972fc0698bec678ea32eea786d01cb5 android.hardware.audio@6.0::IPrimaryDevice
+7318b521ea12fdd4b6e3f381085c71784c810d1ec7a8d701ec2250f3f86712e4 android.hardware.audio@6.0::IStream
+2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn
+78e4138cc8307c11fc777c3bd376e581ba4ba48196b05ca1d7cdfa515c87b48a android.hardware.audio@6.0::IStreamOut
+997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback
+0b291ebd7e94dd1cfaadd41a8b9a80bc9389bbb76f5ad5b3df94db5fe7faea9d android.hardware.audio.common@6.0::types
+817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types
+525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect
+8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect
+461b1114cb35d89f87e5694e0792ba53c112a7fa9a14d9b95188cf9c4764be23 android.hardware.audio.effect@6.0::IBassBoostEffect
+8bc597d166e07e9eba633267fc2872c4c53d13d3f0025b778c98e13324a165de android.hardware.audio.effect@6.0::IDownmixEffect
+9ee022c81e79da6051fde0836c1c1c4d5414e0c9a6cccc0ce17a90346ceb1391 android.hardware.audio.effect@6.0::IEffect
+75c99a70577d543359910a0b378bcbf5a0d6076712e58e6864cd8803f76c8684 android.hardware.audio.effect@6.0::IEffectBufferProviderCallback
+5910bdd600fc6501a67233a9a3f4f21dda86af08c05497322712600131d1fa8f android.hardware.audio.effect@6.0::IEffectsFactory
+dd377f404a8e71f6191d295e10067db629b0f0c28e594af906f2bea5d87fe2cc android.hardware.audio.effect@6.0::IEnvironmentalReverbEffect
+455e085e136767302ec34d02b51a085c310e79bf500b76dda7c96a7f3637f11a android.hardware.audio.effect@6.0::IEqualizerEffect
+24b5e107a0cbd2b322f764a4d5f7fb8b5d8c337a060b9a4a26b9af050c57b5d0 android.hardware.audio.effect@6.0::ILoudnessEnhancerEffect
+4aae0a13f53a8ce20fad372de2d1d864a0bae194b0f1b1d2c090367af8615af2 android.hardware.audio.effect@6.0::INoiseSuppressionEffect
+5237c42d3913ef569f07bec802568084b615155d05a7951e75085da54856508c android.hardware.audio.effect@6.0::IPresetReverbEffect
+282193799d60bff27a84c65a36218c1e7d8f582f5828e2e059383d1b90aa56bd android.hardware.audio.effect@6.0::IVirtualizerEffect
+0868e00f7c5ee16723bda1a8f57099763d04100ae7126a1c2d3a9a87c844a7e8 android.hardware.audio.effect@6.0::IVisualizerEffect
+79e115c8f8970b8b914bafc66df5425e065fda4dcda97222966ef12451d2a1cc android.hardware.bluetooth@1.1::IBluetoothHci
+40ab2c6866c18d32baf6e49e3053949e79601f56963a791e93e68b9ee18f718d android.hardware.bluetooth@1.1::IBluetoothHciCallbacks
07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
c1aa508d00b66ed5feefea398fd5edf28fa651ac89773adad7dfda4e0a73a952 android.hardware.cas@1.2::ICas
9811f867def49b420d8c707f7e38d3bdd64f835244e1d2a5e9762ab9835672dc android.hardware.cas@1.2::ICasListener
f18695dd36ee205640b8326a17453858a7b4596653aaa6ef0016b0aef1bd4dac android.hardware.cas@1.2::IMediaCasService
4d85e814f94949dae4dc6cb82bbd7d6bb24ffafda6ddb2eac928d2a4fc2e21ce android.hardware.cas@1.2::types
+66931c2506fbb5af61f20138cb05e0a09e7bf67d6964c231d27c648933bb33ec android.hardware.drm@1.3::ICryptoFactory
+994d08ab27d613022c258a9ec48cece7adf2a305e92df5d76ef923e2c6665f64 android.hardware.drm@1.3::IDrmFactory
+3dacec7801968e1e4479724dc0180442d9e915466bff051f80996266b1a51c2c android.hardware.gnss@2.1::IGnss
+ba62e1e8993bfb9f27fa04816fa0f2241ae2d01edfa3d0c04182e2e5de80045c android.hardware.gnss@2.1::IGnssCallback
+ccdf3c0fb2c02a6d4dc57afb276c3497ae8172b80b00ebc0bf8a0238dd38b01d android.hardware.gnss@2.1::IGnssConfiguration
+5a125c49ca83629e22afc8c39e865509343bfa2c38f0baea9a186bbac103492d android.hardware.gnss@2.1::IGnssMeasurement
+0bfb291708dd4a7c6ec6b9883e2b8592357edde8d7e962ef83918e4a2154ce69 android.hardware.gnss@2.1::IGnssMeasurementCallback
ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth
26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback
db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types
+c228aaa27f66c48e147159a4f4996c5273191fece1b08de31bd171c61334855e android.hardware.keymaster@4.1::IKeymasterDevice
+adb0efdf1462e9b2e742c0dcadd598666aac551f178be06e755bfcdf5797abd0 android.hardware.keymaster@4.1::IOperation
+7a04ea5595ed418ca3e91c28b8bd7353dd988be9be7b0c8c9e64fb4b77bd4523 android.hardware.keymaster@4.1::types
+df9c79c4fdde2821550c6d5c3d07f5ec0adfb1b702561ce543c906ddef698703 android.hardware.media.c2@1.1::IComponent
+a3eddd9bbdc87e8c22764070037dd1154f1cf006e6fba93364c4f85d4c134a19 android.hardware.media.c2@1.1::IComponentStore
9e59fffceed0dd72a9799e04505db5f777bbbea1af0695ba4107ef6d967c6fda android.hardware.neuralnetworks@1.3::IDevice
258825966435b3ed08832055bb736d81516013e405f161d9ccde9a90cfcdde83 android.hardware.neuralnetworks@1.3::IPreparedModel
94e803236398bed1febb11cc21051bc42ec003700139b099d6c479e02a7ca3c3 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
-c511b1427b1c3f76af90967bbddaaf250db983a8d3abb9ff189fb5a807cf3d4d android.hardware.neuralnetworks@1.3::types
+cf1d55e8c68300090747ab90b94c22e4c859b29c84ced68a317c595bb115eab2 android.hardware.neuralnetworks@1.3::types
3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi
+03d37dfebbc27b13adce1ed6389ac483bf7cf32488ca14037c5569bc3e903e4f android.hardware.wifi.hostapd@1.2::IHostapd
+2defa258951e25a132aaeb36e3febe6f41bf9c6dbb1b1ebdf0b41708ab4e107e android.hardware.wifi.hostapd@1.2::types
a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
44445b8a03d7b9e68b2fbd954672c18a8fce9e32851b0692f4f4ab3407f86ecb android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
c9273429fcf98d797d3bb07fdba6f1be95bf960f9255cde169fd1ca4db85f856 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
9b0a3ab6f4f74b971ed094426d8a443e29b512ff03e1ab50c07156396cdb2483 android.hardware.wifi.supplicant@1.3::types
-d3636ff9d5fef59f59f678887209156b2608d29f676fb1e600fe33b7e57a8a61 android.hardware.radio@1.5::types
-c8e81d912827a5d49b2ddcdc4eb4556c5d231a899a1dca879309e04210daa4a0 android.hardware.radio@1.5::IRadio
-a62a93faf173b14a6175b683ebf61ffa568dc61f81e369d2dce7b1265e86cf2f android.hardware.radio@1.5::IRadioIndication
-260ce05806d753d728f844d405e832179ed7d9b65986ec18fef3d21cf7285587 android.hardware.radio@1.5::IRadioResponse
+eaf870a7439838c66127a74e1896c4a2346979c116eb1931785ebb4d353230ae android.hardware.radio@1.5::types
+584001c25a16e3a29d496cff28dee690833cd2bda5376febe01cecd476ce876f android.hardware.radio@1.5::IRadio
+3afac66f21a33bc9c4b80481c7d5540038348651d9a7d8af64ea13610af138da android.hardware.radio@1.5::IRadioIndication
+caf00e0d942b77b17d7061b38de11e5b19e1da90d4818434cb4916ba89e30686 android.hardware.radio@1.5::IRadioResponse
+55f0a15642869ec98a55ea0a5ac049d3e1a6245ff7750deb6bcb7182057eee83 android.hardware.radio.config@1.3::types
+b27ab0cd40b0b078cdcd024bfe1061c4c4c065f3519eeb9347fa359a3268a5ae android.hardware.radio.config@1.3::IRadioConfig
+742360c775313438b0f82256eac62fb5bbc76a6ae6f388573f3aa142fb2c1eea android.hardware.radio.config@1.3::IRadioConfigIndication
+7683fed9d253956071f18b152e6be657719536f98d9b534433d5e411bcde5061 android.hardware.radio.config@1.3::IRadioConfigResponse
diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp
index a950c57..9049af2 100644
--- a/drm/1.0/Android.bp
+++ b/drm/1.0/Android.bp
@@ -17,5 +17,5 @@
interfaces: [
"android.hidl.base@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/drm/1.3/Android.bp b/drm/1.3/Android.bp
new file mode 100644
index 0000000..b0ffcb9
--- /dev/null
+++ b/drm/1.3/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.drm@1.3",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IDrmFactory.hal",
+ "ICryptoFactory.hal",
+ ],
+ interfaces: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/drm/1.3/ICryptoFactory.hal b/drm/1.3/ICryptoFactory.hal
new file mode 100644
index 0000000..d7864eb
--- /dev/null
+++ b/drm/1.3/ICryptoFactory.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.3;
+
+import @1.2::ICryptoFactory;
+
+/**
+ * ICryptoFactory is the main entry point for interacting with a vendor's
+ * crypto HAL to create crypto plugins. Crypto plugins create crypto sessions
+ * which are used by a codec to decrypt protected video content.
+ *
+ * The 1.3 factory must always create 1.2 ICryptoPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ *
+ * The ICryptoFactory hal is required because all top-level interfaces
+ * have to be updated in a minor uprev.
+ */
+interface ICryptoFactory extends @1.2::ICryptoFactory {
+};
diff --git a/drm/1.3/IDrmFactory.hal b/drm/1.3/IDrmFactory.hal
new file mode 100644
index 0000000..5208028
--- /dev/null
+++ b/drm/1.3/IDrmFactory.hal
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.3;
+
+import @1.2::IDrmFactory;
+
+/**
+ * IDrmFactory is the main entry point for interacting with a vendor's
+ * drm HAL to create drm plugin instances. A drm plugin instance
+ * creates drm sessions which are used to obtain keys for a crypto
+ * session so it can decrypt protected video content.
+ *
+ * The 1.3 factory must always create 1.2 IDrmPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ */
+
+interface IDrmFactory extends @1.2::IDrmFactory {
+ /**
+ * Return vector of uuids identifying crypto schemes supported by this HAL.
+ *
+ * @return schemes Vector of uuids for which isCryptoSchemeSupported is true;
+ * each uuid can be used as input to createPlugin.
+ */
+ getSupportedCryptoSchemes() generates(vec<uint8_t[16]> schemes);
+};
diff --git a/gatekeeper/1.0/vts/functional/Android.bp b/gatekeeper/1.0/vts/functional/Android.bp
index f55e5d2..a115285 100644
--- a/gatekeeper/1.0/vts/functional/Android.bp
+++ b/gatekeeper/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalGatekeeperV1_0TargetTest.cpp"],
static_libs: ["android.hardware.gatekeeper@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
index 715e9fc..afc737c 100644
--- a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
+++ b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
@@ -24,7 +24,10 @@
#include <inttypes.h>
#include <unistd.h>
+#include <gtest/gtest.h>
#include <hardware/hw_auth_token.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <android/log.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -32,9 +35,6 @@
#include <log/log.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::gatekeeper::V1_0::IGatekeeper;
@@ -78,22 +78,8 @@
return auth_token;
}
-// Test environment for Gatekeeper HIDL HAL.
-class GatekeeperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GatekeeperHidlEnvironment* Instance() {
- static GatekeeperHidlEnvironment* instance = new GatekeeperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IGatekeeper>(); }
- private:
- GatekeeperHidlEnvironment() {}
-};
-
// The main test class for Gatekeeper HIDL HAL.
-class GatekeeperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class GatekeeperHidlTest : public ::testing::TestWithParam<std::string> {
protected:
void setUid(uint32_t uid) { uid_ = uid; }
@@ -204,8 +190,7 @@
GatekeeperHidlTest() : uid_(0) {}
virtual void SetUp() override {
GatekeeperResponse rsp;
- gatekeeper_ = ::testing::VtsHalHidlTargetTestBase::getService<IGatekeeper>(
- GatekeeperHidlEnvironment::Instance()->getServiceName<IGatekeeper>());
+ gatekeeper_ = IGatekeeper::getService(GetParam());
ASSERT_NE(nullptr, gatekeeper_.get());
doDeleteAllUsers(rsp);
}
@@ -219,7 +204,7 @@
/**
* Ensure we can enroll new password
*/
-TEST_F(GatekeeperHidlTest, EnrollSuccess) {
+TEST_P(GatekeeperHidlTest, EnrollSuccess) {
hidl_vec<uint8_t> password;
GatekeeperResponse rsp;
ALOGI("Testing Enroll (expected success)");
@@ -231,7 +216,7 @@
/**
* Ensure we can not enroll empty password
*/
-TEST_F(GatekeeperHidlTest, EnrollNoPassword) {
+TEST_P(GatekeeperHidlTest, EnrollNoPassword) {
hidl_vec<uint8_t> password;
GatekeeperResponse rsp;
ALOGI("Testing Enroll (expected failure)");
@@ -242,7 +227,7 @@
/**
* Ensure we can successfully verify previously enrolled password
*/
-TEST_F(GatekeeperHidlTest, VerifySuccess) {
+TEST_P(GatekeeperHidlTest, VerifySuccess) {
GatekeeperResponse enrollRsp;
GatekeeperResponse verifyRsp;
hidl_vec<uint8_t> password;
@@ -258,7 +243,7 @@
* Ensure we can securely update password (keep the same
* secure user_id) if we prove we know old password
*/
-TEST_F(GatekeeperHidlTest, TrustedReenroll) {
+TEST_P(GatekeeperHidlTest, TrustedReenroll) {
GatekeeperResponse enrollRsp;
GatekeeperRequest reenrollReq;
GatekeeperResponse reenrollRsp;
@@ -297,7 +282,7 @@
* Ensure we can update password (and get new
* secure user_id) if we don't know old password
*/
-TEST_F(GatekeeperHidlTest, UntrustedReenroll) {
+TEST_P(GatekeeperHidlTest, UntrustedReenroll) {
GatekeeperResponse enrollRsp;
GatekeeperResponse reenrollRsp;
GatekeeperResponse verifyRsp;
@@ -327,7 +312,7 @@
/**
* Ensure we dont get successful verify with invalid data
*/
-TEST_F(GatekeeperHidlTest, VerifyNoData) {
+TEST_P(GatekeeperHidlTest, VerifyNoData) {
hidl_vec<uint8_t> password;
hidl_vec<uint8_t> passwordHandle;
GatekeeperResponse verifyRsp;
@@ -341,7 +326,7 @@
/**
* Ensure we can not verify password after we enrolled it and then deleted user
*/
-TEST_F(GatekeeperHidlTest, DeleteUserTest) {
+TEST_P(GatekeeperHidlTest, DeleteUserTest) {
hidl_vec<uint8_t> password;
GatekeeperResponse enrollRsp;
GatekeeperResponse verifyRsp;
@@ -368,7 +353,7 @@
/**
* Ensure we can not delete a user that does not exist
*/
-TEST_F(GatekeeperHidlTest, DeleteInvalidUserTest) {
+TEST_P(GatekeeperHidlTest, DeleteInvalidUserTest) {
hidl_vec<uint8_t> password;
GatekeeperResponse enrollRsp;
GatekeeperResponse verifyRsp;
@@ -400,7 +385,7 @@
* Ensure we can not verify passwords after we enrolled them and then deleted
* all users
*/
-TEST_F(GatekeeperHidlTest, DeleteAllUsersTest) {
+TEST_P(GatekeeperHidlTest, DeleteAllUsersTest) {
struct UserData {
uint32_t userId;
hidl_vec<uint8_t> password;
@@ -448,11 +433,7 @@
ALOGI("Testing deleteAllUsers done: rsp=%" PRIi32, delAllRsp.code);
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(GatekeeperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GatekeeperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GatekeeperHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGatekeeper::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
index 1a80ecf..6183a1a 100644
--- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
+++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
@@ -22,6 +22,7 @@
#include <log/log.h>
#include <chrono>
+#include <cmath>
#include <condition_variable>
#include <mutex>
@@ -403,6 +404,34 @@
}
/*
+ * InjectSeedLocation:
+ * Injects a seed location and ensures the injected seed location is not fused in the resulting
+ * GNSS location.
+ */
+TEST_P(GnssHalTest, InjectSeedLocation) {
+ // An arbitrary position in North Pacific Ocean (where no VTS labs will ever likely be located).
+ const double seedLatDegrees = 32.312894;
+ const double seedLngDegrees = -172.954117;
+ const float seedAccuracyMeters = 150.0;
+
+ auto result = gnss_hal_->injectLocation(seedLatDegrees, seedLngDegrees, seedAccuracyMeters);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ StartAndGetSingleLocation(false);
+
+ // Ensure we don't get a location anywhere within 111km (1 degree of lat or lng) of the seed
+ // location.
+ EXPECT_TRUE(std::abs(last_location_.latitudeDegrees - seedLatDegrees) > 1.0 ||
+ std::abs(last_location_.longitudeDegrees - seedLngDegrees) > 1.0);
+
+ StopAndClearLocations();
+
+ auto resultVoid = gnss_hal_->deleteAidingData(IGnss::GnssAidingData::DELETE_POSITION);
+ ASSERT_TRUE(resultVoid.isOk());
+}
+
+/*
* GetAllExtentions:
* Tries getting all optional extensions, and ensures a valid return
* null or actual extension, no crash.
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 95bd7f3..9c498d5 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -14,6 +14,8 @@
"libhidlbase",
"libutils",
"liblog",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
],
diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp
index 4abe707..5043649 100644
--- a/gnss/1.1/default/Gnss.cpp
+++ b/gnss/1.1/default/Gnss.cpp
@@ -44,7 +44,7 @@
auto svStatus = this->getMockSvStatus();
this->reportSvStatus(svStatus);
- auto location = Utils::getMockLocation();
+ auto location = Utils::getMockLocationV1_0();
this->reportLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
@@ -197,14 +197,14 @@
Return<GnssSvStatus> Gnss::getMockSvStatus() const {
std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
GnssSvInfo mockGnssSvInfoList[] = {
- Utils::getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
- Utils::getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
- Utils::getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
- Utils::getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
- Utils::getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
- Utils::getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
- Utils::getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
- Utils::getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
+ Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
+ Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
+ Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
+ Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
+ Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
+ Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
+ Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
+ Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
for (uint32_t i = 0; i < svStatus.numSvs; i++) {
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.cpp b/gnss/1.1/vts/functional/gnss_hal_test.cpp
index 2c8a7b1..b87f558 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test.cpp
@@ -175,6 +175,48 @@
return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0;
}
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation() {
+ const int kLocationsToAwait = 3;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ const int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
+ EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)", sv_status_cbq_size,
+ kLocationsToAwait, location_called_count);
+
+ // Find first non-GPS constellation to blacklist
+ const int kGnssSvStatusTimeout = 2;
+ GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
+ for (int i = 0; i < sv_status_cbq_size; ++i) {
+ IGnssCallback::GnssSvStatus gnss_sv_status;
+ gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
+ for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+ const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+ if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
+ (gnss_sv.constellation != GnssConstellationType::GPS)) {
+ // found a non-GPS constellation
+ constellation_to_blacklist = gnss_sv.constellation;
+ break;
+ }
+ }
+ if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
+ break;
+ }
+ }
+
+ if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
+ ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
+ // Proceed functionally to blacklist something.
+ constellation_to_blacklist = GnssConstellationType::GLONASS;
+ }
+ return constellation_to_blacklist;
+}
+
GnssHalTest::GnssCallback::GnssCallback()
: info_cbq_("system_info"),
name_cbq_("name"),
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.h b/gnss/1.1/vts/functional/gnss_hal_test.h
index 169cd62..b0e52be 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.h
+++ b/gnss/1.1/vts/functional/gnss_hal_test.h
@@ -28,6 +28,7 @@
using android::hardware::gnss::V1_0::GnssLocation;
using android::hardware::gnss::common::GnssCallbackEventQueue;
+using android::hardware::gnss::V1_0::GnssConstellationType;
using android::hardware::gnss::V1_0::GnssLocationFlags;
using android::hardware::gnss::V1_1::IGnss;
using android::hardware::gnss::V1_1::IGnssCallback;
@@ -139,6 +140,16 @@
*/
bool IsGnssHalVersion_1_1() const;
+ /*
+ * startLocationAndGetNonGpsConstellation:
+ * 1. Start location
+ * 2. Find and return first non-GPS constellation
+ *
+ * Note that location is not stopped in this method. The client should call
+ * StopAndClearLocations() after the call.
+ */
+ GnssConstellationType startLocationAndGetNonGpsConstellation();
+
sp<IGnss> gnss_hal_; // GNSS HAL to call into
sp<GnssCallback> gnss_cb_; // Primary callback interface
};
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index 79da84a..afba61f 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -352,7 +352,7 @@
}
/*
- * BlacklistConstellation:
+ * BlacklistConstellationWithLocationOff:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus for any non-GPS constellations.
@@ -361,50 +361,19 @@
* GnssStatus does not use any constellation but GPS.
* 4a & b) Clean up by turning off location, and send in empty blacklist.
*/
-TEST_P(GnssHalTest, BlacklistConstellation) {
+TEST_P(GnssHalTest, BlacklistConstellationWithLocationOff) {
if (!IsGnssHalVersion_1_1()) {
ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
return;
}
const int kLocationsToAwait = 3;
-
- gnss_cb_->location_cbq_.reset();
- StartAndCheckLocations(kLocationsToAwait);
- const int location_called_count = gnss_cb_->location_cbq_.calledCount();
-
- // Tolerate 1 less sv status to handle edge cases in reporting.
- int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
- EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
- ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)", sv_status_cbq_size,
- kLocationsToAwait, location_called_count);
-
// Find first non-GPS constellation to blacklist
- const int kGnssSvStatusTimeout = 2;
- GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
- for (int i = 0; i < sv_status_cbq_size; ++i) {
- IGnssCallback::GnssSvStatus gnss_sv_status;
- gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
- for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
- const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
- if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
- (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
- (gnss_sv.constellation != GnssConstellationType::GPS)) {
- // found a non-GPS constellation
- constellation_to_blacklist = gnss_sv.constellation;
- break;
- }
- }
- if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
- break;
- }
- }
+ GnssConstellationType constellation_to_blacklist = startLocationAndGetNonGpsConstellation();
- if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
- ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
- // Proceed functionally to blacklist something.
- constellation_to_blacklist = GnssConstellationType::GLONASS;
- }
+ // Turns off location
+ StopAndClearLocations();
+
IGnssConfiguration::BlacklistedSource source_to_blacklist;
source_to_blacklist.constellation = constellation_to_blacklist;
source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
@@ -418,6 +387,7 @@
sources.resize(1);
sources[0] = source_to_blacklist;
+ // setBlacklist when location is off.
auto result = gnss_configuration_hal->setBlacklist(sources);
ASSERT_TRUE(result.isOk());
EXPECT_TRUE(result);
@@ -429,10 +399,82 @@
StartAndCheckLocations(kLocationsToAwait);
// Tolerate 1 less sv status to handle edge cases in reporting.
- sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
+ int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_status_cbq_size,
kLocationsToAwait);
+ const int kGnssSvStatusTimeout = 2;
+ for (int i = 0; i < sv_status_cbq_size; ++i) {
+ IGnssCallback::GnssSvStatus gnss_sv_status;
+ gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
+ for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+ const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+ EXPECT_FALSE((gnss_sv.constellation == source_to_blacklist.constellation) &&
+ (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+/*
+ * BlacklistConstellationWithLocationOn:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Turns off location, and blacklist first non-GPS constellations.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_P(GnssHalTest, BlacklistConstellationWithLocationOn) {
+ if (!IsGnssHalVersion_1_1()) {
+ ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
+ return;
+ }
+
+ const int kLocationsToAwait = 3;
+ // Find first non-GPS constellation to blacklist
+ GnssConstellationType constellation_to_blacklist = startLocationAndGetNonGpsConstellation();
+
+ IGnssConfiguration::BlacklistedSource source_to_blacklist;
+ source_to_blacklist.constellation = constellation_to_blacklist;
+ source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blacklist;
+
+ // setBlacklist when location is still on
+ auto result = gnss_configuration_hal->setBlacklist(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // Turns off location
+ StopAndClearLocations();
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_status_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
+ EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_status_cbq_size,
+ kLocationsToAwait);
+ const int kGnssSvStatusTimeout = 2;
for (int i = 0; i < sv_status_cbq_size; ++i) {
IGnssCallback::GnssSvStatus gnss_sv_status;
gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 3ba89da..37de55d 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -25,7 +25,7 @@
"AGnss.cpp",
"AGnssRil.cpp",
"Gnss.cpp",
- "GnssBatching.cpp",
+ "GnssBatching.cpp",
"GnssMeasurement.cpp",
"GnssMeasurementCorrections.cpp",
"GnssVisibilityControl.cpp",
@@ -35,9 +35,10 @@
"libhidlbase",
"libutils",
"liblog",
- "android.hardware.gnss@2.0",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@2.0",
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
],
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index 3d64fc3..09f2fc0 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -19,7 +19,6 @@
#include "Gnss.h"
#include <log/log.h>
-#include <utils/SystemClock.h>
#include "AGnss.h"
#include "AGnssRil.h"
@@ -47,24 +46,6 @@
sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
-namespace {
-
-V2_0::GnssLocation getMockLocationV2_0() {
- const ElapsedRealtime timestamp = {
- .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
- ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
- .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
- // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
- // In an actual implementation provide an estimate of the synchronization uncertainty
- // or don't set the field.
- .timeUncertaintyNs = 1000000};
-
- V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp};
- return location;
-}
-
-} // namespace
-
Gnss::Gnss() : mMinIntervalMs(1000) {}
Gnss::~Gnss() {
@@ -86,7 +67,7 @@
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
- const auto location = getMockLocationV2_0();
+ const auto location = Utils::getMockLocationV2_0();
this->reportLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index 1f95ff9..d778d50 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "GnssMeasurement"
#include "GnssMeasurement.h"
+#include "Utils.h"
#include <log/log.h>
#include <utils/SystemClock.h>
@@ -29,6 +30,7 @@
using GnssConstellationType = V2_0::GnssConstellationType;
using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementState = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
+using Utils = common::Utils;
sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback = nullptr;
@@ -81,7 +83,7 @@
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
- auto measurement = this->getMockMeasurement();
+ auto measurement = Utils::getMockMeasurementV2_0();
this->reportMeasurement(measurement);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
@@ -97,60 +99,6 @@
}
}
-GnssData GnssMeasurement::getMockMeasurement() {
- V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = {
- .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY,
- .svid = (int16_t)6,
- .constellation = V1_0::GnssConstellationType::UNKNOWN,
- .timeOffsetNs = 0.0,
- .receivedSvTimeInNs = 8195997131077,
- .receivedSvTimeUncertaintyInNs = 15,
- .cN0DbHz = 30.0,
- .pseudorangeRateMps = -484.13739013671875,
- .pseudorangeRateUncertaintyMps = 1.0379999876022339,
- .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
- GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
- .accumulatedDeltaRangeM = 0.0,
- .accumulatedDeltaRangeUncertaintyM = 0.0,
- .carrierFrequencyHz = 1.59975e+09,
- .multipathIndicator =
- V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
- V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
- V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
- .v1_1 = measurement_1_1,
- .codeType = "C",
- .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
- GnssMeasurementState::STATE_SUBFRAME_SYNC |
- GnssMeasurementState::STATE_TOW_DECODED |
- GnssMeasurementState::STATE_GLO_STRING_SYNC |
- GnssMeasurementState::STATE_GLO_TOD_DECODED,
- .constellation = GnssConstellationType::GLONASS,
- };
-
- hidl_vec<IGnssMeasurementCallback::GnssMeasurement> measurements(1);
- measurements[0] = measurement_2_0;
- V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000,
- .fullBiasNs = -1226701900521857520,
- .biasNs = 0.59689998626708984,
- .biasUncertaintyNs = 47514.989972114563,
- .driftNsps = -51.757811607455452,
- .driftUncertaintyNsps = 310.64968328491528,
- .hwClockDiscontinuityCount = 1};
-
- ElapsedRealtime timestamp = {
- .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
- ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
- .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
- // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
- // In an actual implementation provide an estimate of the synchronization uncertainty
- // or don't set the field.
- .timeUncertaintyNs = 1000000};
-
- GnssData gnssData = {
- .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
- return gnssData;
-}
-
void GnssMeasurement::reportMeasurement(const GnssData& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
diff --git a/gnss/2.0/default/GnssMeasurement.h b/gnss/2.0/default/GnssMeasurement.h
index c24c00e..d8ffd59 100644
--- a/gnss/2.0/default/GnssMeasurement.h
+++ b/gnss/2.0/default/GnssMeasurement.h
@@ -59,7 +59,6 @@
private:
void start();
void stop();
- GnssData getMockMeasurement();
void reportMeasurement(const GnssData&);
static sp<IGnssMeasurementCallback> sCallback;
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 9aa1334..da5289d 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -28,6 +28,7 @@
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
+ "android.hardware.gnss@2.1",
"android.hardware.gnss@common-vts-lib",
],
test_suites: ["general-tests", "vts-core"],
diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp
new file mode 100644
index 0000000..8b0c374
--- /dev/null
+++ b/gnss/2.1/Android.bp
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.gnss@2.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IGnss.hal",
+ "IGnssCallback.hal",
+ "IGnssMeasurement.hal",
+ "IGnssMeasurementCallback.hal",
+ "IGnssConfiguration.hal",
+ ],
+ interfaces: [
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@2.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/gnss/2.1/IGnss.hal b/gnss/2.1/IGnss.hal
new file mode 100644
index 0000000..2d63392
--- /dev/null
+++ b/gnss/2.1/IGnss.hal
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.1;
+
+import @2.0::IGnss;
+
+import IGnssCallback;
+import IGnssMeasurement;
+import IGnssConfiguration;
+
+/**
+ * Represents the standard GNSS (Global Navigation Satellite System) interface.
+ */
+interface IGnss extends @2.0::IGnss {
+ /**
+ * Opens the interface and provides the callback routines to the implementation of this
+ * interface.
+ *
+ * The framework calls this method to instruct the GPS engine to prepare for serving requests
+ * from the framework. The GNSS HAL implementation must respond to all GNSS requests from the
+ * framework upon successful return from this method until cleanup() method is called to
+ * close this interface.
+ *
+ * @param callback Callback interface for IGnss.
+ *
+ * @return success Returns true on success.
+ */
+ setCallback_2_1(IGnssCallback callback) generates (bool success);
+
+ /**
+ * This method returns the IGnssMeasurement interface.
+ *
+ * At least one of getExtensionGnssMeasurement(), getExtensionGnssMeasurement_1_1(),
+ * getExtensionGnssMeasurement_2_0(), and getExtensionGnssMeasurement_2_1() methods must return
+ * a non-null handle, and the other methods must return nullptr.
+ *
+ * @return gnssMeasurementIface Handle to the IGnssMeasurement interface.
+ */
+ getExtensionGnssMeasurement_2_1() generates (IGnssMeasurement gnssMeasurementIface);
+
+ /**
+ * This method returns the IGnssConfiguration interface.
+ *
+ * At least one of getExtensionGnssConfiguration(), getExtensionGnssConfiguration_1_1(),
+ * getExtensionGnssConfiguration_2_0(), and getExtensionGnssConfiguration_2_1() methods must
+ * return a non-null handle, and the other methods must return nullptr.
+ *
+ * @return gnssConfigurationIface Handle to the IGnssConfiguration interface.
+ */
+ getExtensionGnssConfiguration_2_1() generates (IGnssConfiguration gnssConfigurationIface);
+};
\ No newline at end of file
diff --git a/gnss/2.1/IGnssCallback.hal b/gnss/2.1/IGnssCallback.hal
new file mode 100644
index 0000000..da70742
--- /dev/null
+++ b/gnss/2.1/IGnssCallback.hal
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.1;
+
+import @2.0::IGnssCallback;
+
+/**
+ * This interface is required for the HAL to communicate certain information
+ * like status and location info back to the platform, the platform implements
+ * the interfaces and passes a handle to the HAL.
+ */
+interface IGnssCallback extends @2.0::IGnssCallback {
+
+ /** Extends a GnssSvInfo, adding a basebandCN0DbHz. */
+ struct GnssSvInfo {
+ /**
+ * GNSS satellite information for a single satellite and frequency.
+ */
+ @2.0::IGnssCallback.GnssSvInfo v2_0;
+
+ /**
+ * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+ * the measured C/N0 value for the signal measured at the baseband.
+ *
+ * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+ * which is reported in cN0DbHz.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+ * processes one of the components, then the reported basebandCN0DbHz reflects only the
+ * component that is processed.
+ *
+ * This value is mandatory. Like cN0DbHz, it may be reported as 0 for satellites being
+ * reported that may be searched for, but not yet tracked.
+ */
+ double basebandCN0DbHz;
+ };
+
+ /**
+ * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
+ *
+ * @param svInfoList SV info list information from HAL.
+ */
+ gnssSvStatusCb_2_1(vec<GnssSvInfo> svInfoList);
+};
diff --git a/gnss/2.1/IGnssConfiguration.hal b/gnss/2.1/IGnssConfiguration.hal
new file mode 100644
index 0000000..8360ba9
--- /dev/null
+++ b/gnss/2.1/IGnssConfiguration.hal
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.1;
+
+import @2.0::IGnssConfiguration;
+import @2.0::GnssConstellationType;
+
+/**
+ * Extended interface for GNSS Configuration support.
+ */
+interface IGnssConfiguration extends @2.0::IGnssConfiguration {
+ /**
+ * Represents a blacklisted source, updating the GnssConstellationType to 2.0, which supports
+ * IRNSS.
+ */
+ struct BlacklistedSource {
+ /**
+ * Defines the constellation of the given satellite(s).
+ */
+ GnssConstellationType constellation;
+
+ /**
+ * Satellite (space vehicle) ID number, as defined in GnssSvInfo::svid
+ *
+ * Or 0 to blacklist all svid's for the specified constellation
+ */
+ int16_t svid;
+ };
+
+ /**
+ * Injects a vector of BlacklistedSource(s) which the HAL must not use to calculate the
+ * GNSS location output.
+ *
+ * The superset of all satellite sources provided, including wildcards, in the latest call
+ * to this method, is the set of satellites sources that must not be used in calculating
+ * location.
+ *
+ * All measurements from the specified satellites, across frequency bands, are blacklisted
+ * together.
+ *
+ * If this method is never called after the IGnssConfiguration.hal connection is made on boot,
+ * or is called with an empty vector, then no satellites are to be blacklisted as a result of
+ * this API.
+ *
+ * This blacklist must be considered as an additional source of which satellites
+ * should not be trusted for location on top of existing sources of similar information
+ * such as satellite broadcast health being unhealthy and measurement outlier removal.
+ *
+ * @param blacklist The BlacklistedSource(s) of satellites the HAL must not use.
+ *
+ * @return success Whether the HAL accepts and abides by the provided blacklist.
+ */
+ setBlacklist_2_1(vec<BlacklistedSource> blacklist) generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/2.1/IGnssMeasurement.hal b/gnss/2.1/IGnssMeasurement.hal
new file mode 100644
index 0000000..d2c76e6
--- /dev/null
+++ b/gnss/2.1/IGnssMeasurement.hal
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.1;
+
+import @1.0::IGnssMeasurement;
+import @1.1::IGnssMeasurement;
+import @2.0::IGnssMeasurement;
+import IGnssMeasurementCallback;
+
+/**
+ * Extended interface for GNSS Measurements support.
+ */
+interface IGnssMeasurement extends @2.0::IGnssMeasurement {
+
+ /**
+ * Initializes the interface and registers the callback routines with the HAL. After a
+ * successful call to 'setCallback_2_1' the HAL must begin to provide updates at an average
+ * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
+ * can be tolerated.)
+ *
+ * @param callback Handle to GnssMeasurement callback interface.
+ * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
+ * no clock discontinuities are expected and, when supported, carrier phase should be
+ * continuous in good signal conditions. All non-blacklisted, healthy constellations,
+ * satellites and frequency bands that the chipset supports must be reported in this mode.
+ * The GNSS chipset is allowed to consume more power in this mode. If false, API must behave
+ * as in HAL V1_0, optimizing power via duty cycling, constellations and frequency limits,
+ * etc.
+ *
+ * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
+ * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
+ * for any other error. The HAL must not generate any other updates upon returning this
+ * error code.
+ */
+ setCallback_2_1(IGnssMeasurementCallback callback, bool enableFullTracking)
+ generates (GnssMeasurementStatus initRet);
+};
diff --git a/gnss/2.1/IGnssMeasurementCallback.hal b/gnss/2.1/IGnssMeasurementCallback.hal
new file mode 100644
index 0000000..ca6175f
--- /dev/null
+++ b/gnss/2.1/IGnssMeasurementCallback.hal
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@2.1;
+
+import @1.0::IGnssMeasurementCallback;
+import @1.1::IGnssMeasurementCallback;
+import @2.0::IGnssMeasurementCallback;
+import @2.0::ElapsedRealtime;
+
+/** The callback interface to report measurements from the HAL. */
+interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback {
+
+ /**
+ * Extends a GNSS Measurement, adding a basebandCN0DbHz.
+ */
+ struct GnssMeasurement {
+ /**
+ * GNSS measurement information for a single satellite and frequency, as in the 2.0 version
+ * of the HAL.
+ */
+ @2.0::IGnssMeasurementCallback.GnssMeasurement v2_0;
+
+ /**
+ * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+ * the measured C/N0 value for the signal measured at the baseband.
+ *
+ * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+ * which is reported in cN0DbHz.
+ *
+ * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+ * processes one of the components, then the reported basebandCN0DbHz reflects only the
+ * component that is processed.
+ *
+ * This value is mandatory.
+ */
+ double basebandCN0DbHz;
+ };
+
+ /**
+ * Complete set of GNSS Measurement data, same as 2.0 with additional double (i.e.,
+ * basebandCN0DbHz) in measurements.
+ */
+ struct GnssData {
+ /** The full set of satellite measurement observations. */
+ vec<GnssMeasurement> measurements;
+
+ /** The GNSS clock time reading. */
+ GnssClock clock;
+
+ /**
+ * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos()
+ * clock.
+ */
+ ElapsedRealtime elapsedRealtime;
+ };
+
+ /**
+ * Callback for the hal to pass a GnssData structure back to the client.
+ *
+ * @param data Contains a reading of GNSS measurements.
+ */
+ gnssMeasurementCb_2_1(GnssData data);
+};
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
new file mode 100644
index 0000000..57233aa
--- /dev/null
+++ b/gnss/2.1/default/Android.bp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_binary {
+ name: "android.hardware.gnss@2.1-service",
+ init_rc: ["android.hardware.gnss@2.1-service.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ vintf_fragments: ["android.hardware.gnss@2.1-service.xml"],
+ srcs: [
+ "Gnss.cpp",
+ "GnssMeasurement.cpp",
+ "GnssConfiguration.cpp",
+ "service.cpp"
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@2.0",
+ ],
+ static_libs: [
+ "android.hardware.gnss@common-default-lib",
+ ],
+}
diff --git a/gnss/2.1/default/Gnss.cpp b/gnss/2.1/default/Gnss.cpp
new file mode 100644
index 0000000..384fd49
--- /dev/null
+++ b/gnss/2.1/default/Gnss.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gnss"
+
+#include "Gnss.h"
+#include "GnssMeasurement.h"
+#include "Utils.h"
+
+#include <log/log.h>
+
+using ::android::hardware::gnss::common::Utils;
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+sp<V2_1::IGnssCallback> Gnss::sGnssCallback_2_1 = nullptr;
+
+Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
+
+Gnss::~Gnss() {
+ stop();
+}
+
+Return<bool> Gnss::start() {
+ ALOGD("start");
+ if (mIsActive) {
+ ALOGW("Gnss has started. Restarting...");
+ stop();
+ }
+
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
+ this->reportSvStatus(svStatus);
+
+ const auto location = Utils::getMockLocationV2_0();
+ this->reportLocation(location);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+ }
+ });
+ return true;
+}
+
+hidl_vec<GnssSvInfo> Gnss::filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList) {
+ for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+ if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
+ gnssSvInfoList[i].v2_0.v1_0.svFlag &=
+ ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
+ }
+ }
+ return gnssSvInfoList;
+}
+
+Return<bool> Gnss::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ return true;
+}
+
+// Methods from V1_0::IGnss follow.
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
+ // TODO implement
+ return bool{};
+}
+
+Return<void> Gnss::cleanup() {
+ // TODO implement
+ return Void();
+}
+
+Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::injectLocation(double, double, float) {
+ // TODO implement
+ return bool{};
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
+ // TODO implement
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
+ V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
+ uint32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ // TODO implement
+ return ::android::sp<V1_0::IAGnssRil>{};
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssGeofencing>{};
+}
+
+Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
+ // TODO implement
+ return ::android::sp<V1_0::IAGnss>{};
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssNi>{};
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssMeasurement>{};
+}
+
+Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssNavigationMessage>{};
+}
+
+Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssXtra>{};
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssConfiguration>{};
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssDebug>{};
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ // TODO implement
+ return ::android::sp<V1_0::IGnssBatching>{};
+}
+
+// Methods from V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>&) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
+ V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
+ uint32_t, bool) {
+ return true;
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
+ // TODO implement
+ return ::android::sp<V1_1::IGnssConfiguration>{};
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+ // TODO implement
+ return ::android::sp<V1_1::IGnssMeasurement>{};
+}
+
+Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from V2_0::IGnss follow.
+Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>&) {
+ // TODO implement
+ return bool{};
+}
+
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IGnssConfiguration>{};
+}
+
+Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IGnssDebug>{};
+}
+
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IAGnss>{};
+}
+
+Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IAGnssRil>{};
+}
+
+Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IGnssMeasurement>{};
+}
+
+Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
+Gnss::getExtensionMeasurementCorrections() {
+ // TODO implement
+ return ::android::sp<measurement_corrections::V1_0::IMeasurementCorrections>{};
+}
+
+Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
+ // TODO implement
+ return ::android::sp<visibility_control::V1_0::IGnssVisibilityControl>{};
+}
+
+Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
+ // TODO implement
+ return ::android::sp<V2_0::IGnssBatching>{};
+}
+
+Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from V2_1::IGnss follow.
+Return<bool> Gnss::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
+ ALOGD("Gnss::setCallback_2_1");
+ if (callback == nullptr) {
+ ALOGE("%s: Null callback ignored", __func__);
+ return false;
+ }
+
+ sGnssCallback_2_1 = callback;
+
+ using Capabilities = V2_0::IGnssCallback::Capabilities;
+ const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
+ Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
+ auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_0(capabilities);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020};
+
+ ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ auto gnssName = "Android Mock GNSS Implementation v2.1";
+ ret = sGnssCallback_2_1->gnssNameCb(gnssName);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+
+ return true;
+}
+
+Return<sp<V2_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_1() {
+ ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
+ return new GnssMeasurement();
+}
+
+Return<sp<V2_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_1() {
+ return mGnssConfiguration;
+}
+
+void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback_2_1 == nullptr) {
+ ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
+ return;
+ }
+ auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+void Gnss::reportLocation(const V2_0::GnssLocation& location) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback_2_1 == nullptr) {
+ ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
+ return;
+ }
+ auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/Gnss.h b/gnss/2.1/default/Gnss.h
new file mode 100644
index 0000000..674b070
--- /dev/null
+++ b/gnss/2.1/default/Gnss.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
+#include "GnssConfiguration.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+
+using GnssSvInfo = IGnssCallback::GnssSvInfo;
+
+namespace implementation {
+
+struct Gnss : public IGnss {
+ Gnss();
+ ~Gnss();
+ // Methods from V1_0::IGnss follow.
+ Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+ Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
+ Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
+ Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
+ Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
+ Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override;
+ Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override;
+ Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+ Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+ Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+ // Methods from V1_1::IGnss follow.
+ Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
+ Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs, bool lowPowerMode) override;
+ Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
+ Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+ Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
+
+ // Methods from V2_0::IGnss follow.
+ Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
+ Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
+ Return<sp<V2_0::IGnssDebug>> getExtensionGnssDebug_2_0() override;
+ Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
+ Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
+ Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
+ Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
+ getExtensionMeasurementCorrections() override;
+ Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
+ override;
+ Return<sp<V2_0::IGnssBatching>> getExtensionGnssBatching_2_0() override;
+ Return<bool> injectBestLocation_2_0(const V2_0::GnssLocation& location) override;
+
+ // Methods from V2_1::IGnss follow.
+ Return<bool> setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) override;
+ Return<sp<V2_1::IGnssMeasurement>> getExtensionGnssMeasurement_2_1() override;
+ Return<sp<V2_1::IGnssConfiguration>> getExtensionGnssConfiguration_2_1() override;
+
+ private:
+ void reportLocation(const V2_0::GnssLocation&) const;
+ void reportSvStatus(const hidl_vec<GnssSvInfo>&) const;
+
+ static sp<V2_1::IGnssCallback> sGnssCallback_2_1;
+ std::atomic<long> mMinIntervalMs;
+ sp<GnssConfiguration> mGnssConfiguration;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+ mutable std::mutex mMutex;
+ hidl_vec<GnssSvInfo> filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList);
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/GnssConfiguration.cpp b/gnss/2.1/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..cd8f07f
--- /dev/null
+++ b/gnss/2.1/default/GnssConfiguration.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssConfiguration"
+
+#include "GnssConfiguration.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enable) {
+ ALOGD("setSuplEs enable: %d", enable);
+ // Method deprecated in 2.0 and not expected to be called by the framework.
+ return false;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock> gpsLock) {
+ ALOGD("setGpsLock gpsLock: %hhu", static_cast<GpsLock>(gpsLock));
+ // Method deprecated in 2.0 and not expected to be called by the framework.
+ return false;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) {
+ return true;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) {
+ return true;
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>&) {
+ // TODO (b/122463906): Reuse 1.1 implementation.
+ return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+ ALOGD("setEsExtensionSec emergencyExtensionSeconds: %d", emergencyExtensionSeconds);
+ return true;
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist_2_1(
+ const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& sourceList) {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ mBlacklistedConstellationSet.clear();
+ mBlacklistedSourceSet.clear();
+ for (auto source : sourceList) {
+ if (source.svid == 0) {
+ // Wildcard blacklist, i.e., blacklist entire constellation.
+ mBlacklistedConstellationSet.insert(source.constellation);
+ } else {
+ mBlacklistedSourceSet.insert(source);
+ }
+ }
+ return true;
+}
+
+Return<bool> GnssConfiguration::isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const {
+ std::unique_lock<std::recursive_mutex> lock(mMutex);
+ if (mBlacklistedConstellationSet.find(gnssSvInfo.v2_0.constellation) !=
+ mBlacklistedConstellationSet.end()) {
+ return true;
+ }
+ BlacklistedSourceV2_1 source = {.constellation = gnssSvInfo.v2_0.constellation,
+ .svid = gnssSvInfo.v2_0.v1_0.svid};
+ return (mBlacklistedSourceSet.find(source) != mBlacklistedSourceSet.end());
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/gnss/2.1/default/GnssConfiguration.h b/gnss/2.1/default/GnssConfiguration.h
new file mode 100644
index 0000000..662d61d
--- /dev/null
+++ b/gnss/2.1/default/GnssConfiguration.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.1/IGnssCallback.h>
+#include <android/hardware/gnss/2.1/IGnssConfiguration.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <mutex>
+#include <unordered_set>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using BlacklistedSourceV2_1 =
+ ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource;
+using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
+using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
+
+struct BlacklistedSourceHashV2_1 {
+ inline int operator()(const BlacklistedSourceV2_1& source) const {
+ return int(source.constellation) * 1000 + int(source.svid);
+ }
+};
+
+struct BlacklistedSourceEqualV2_1 {
+ inline bool operator()(const BlacklistedSourceV2_1& s1, const BlacklistedSourceV2_1& s2) const {
+ return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
+ }
+};
+
+using BlacklistedSourceSetV2_1 =
+ std::unordered_set<BlacklistedSourceV2_1, BlacklistedSourceHashV2_1,
+ BlacklistedSourceEqualV2_1>;
+using BlacklistedConstellationSetV2_1 = std::unordered_set<GnssConstellationTypeV2_0>;
+
+struct GnssConfiguration : public IGnssConfiguration {
+ // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override;
+ Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override;
+ Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ std::recursive_mutex& getMutex() const;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+ Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+
+ // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist_2_1(
+ const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ Return<bool> isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+
+ private:
+ mutable std::recursive_mutex mMutex;
+
+ BlacklistedSourceSetV2_1 mBlacklistedSourceSet;
+ BlacklistedConstellationSetV2_1 mBlacklistedConstellationSet;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H
\ No newline at end of file
diff --git a/gnss/2.1/default/GnssMeasurement.cpp b/gnss/2.1/default/GnssMeasurement.cpp
new file mode 100644
index 0000000..ebfa7dd
--- /dev/null
+++ b/gnss/2.1/default/GnssMeasurement.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssMeasurement"
+
+#include "GnssMeasurement.h"
+#include <log/log.h>
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+
+using common::Utils;
+
+namespace V2_1 {
+namespace implementation {
+
+sp<V2_1::IGnssMeasurementCallback> GnssMeasurement::sCallback = nullptr;
+
+GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {}
+
+GnssMeasurement::~GnssMeasurement() {
+ stop();
+}
+
+// Methods from V1_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>&) {
+ // TODO implement
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+Return<void> GnssMeasurement::close() {
+ ALOGD("close");
+ std::unique_lock<std::mutex> lock(mMutex);
+ stop();
+ sCallback = nullptr;
+ return Void();
+}
+
+// Methods from V1_1::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>&, bool) {
+ // TODO implement
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+// Methods from V2_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>&, bool) {
+ // TODO implement
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+// Methods from V2_1::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_1(
+ const sp<V2_1::IGnssMeasurementCallback>& callback, bool) {
+ ALOGD("setCallback_2_1");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+
+ if (mIsActive) {
+ ALOGW("GnssMeasurement callback already set. Resetting the callback...");
+ stop();
+ }
+ start();
+
+ return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+void GnssMeasurement::start() {
+ ALOGD("start");
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ auto measurement = Utils::getMockMeasurementV2_1();
+ this->reportMeasurement(measurement);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
+ }
+ });
+}
+
+void GnssMeasurement::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
+void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) {
+ ALOGD("reportMeasurement()");
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sCallback == nullptr) {
+ ALOGE("%s: GnssMeasurement::sCallback is null.", __func__);
+ return;
+ }
+ auto ret = sCallback->gnssMeasurementCb_2_1(data);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/GnssMeasurement.h b/gnss/2.1/default/GnssMeasurement.h
new file mode 100644
index 0000000..ee32903
--- /dev/null
+++ b/gnss/2.1/default/GnssMeasurement.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_1 {
+namespace implementation {
+
+using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct GnssMeasurement : public IGnssMeasurement {
+ GnssMeasurement();
+ ~GnssMeasurement();
+ // Methods from V1_0::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from V1_1::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
+
+ // Methods from V2_0::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
+
+ // Methods from V2_1::IGnssMeasurement follow.
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_1(
+ const sp<V2_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
+
+ private:
+ void start();
+ void stop();
+ void reportMeasurement(const GnssDataV2_1&);
+
+ static sp<IGnssMeasurementCallback> sCallback;
+ std::atomic<long> mMinIntervalMillis;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+ mutable std::mutex mMutex;
+};
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.1/default/OWNERS b/gnss/2.1/default/OWNERS
new file mode 100644
index 0000000..b7b4a2e
--- /dev/null
+++ b/gnss/2.1/default/OWNERS
@@ -0,0 +1,4 @@
+gomo@google.com
+smalkos@google.com
+wyattriley@google.com
+yuhany@google.com
diff --git a/gnss/2.1/default/android.hardware.gnss@2.1-service.rc b/gnss/2.1/default/android.hardware.gnss@2.1-service.rc
new file mode 100644
index 0000000..5926c77
--- /dev/null
+++ b/gnss/2.1/default/android.hardware.gnss@2.1-service.rc
@@ -0,0 +1,4 @@
+service vendor.gnss-2-1 /vendor/bin/hw/android.hardware.gnss@2.1-service
+ class hal
+ user system
+ group system
diff --git a/gnss/2.1/default/android.hardware.gnss@2.1-service.xml b/gnss/2.1/default/android.hardware.gnss@2.1-service.xml
new file mode 100644
index 0000000..12a1fdf
--- /dev/null
+++ b/gnss/2.1/default/android.hardware.gnss@2.1-service.xml
@@ -0,0 +1,12 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <version>2.1</version>
+ <version>1.1</version>
+ <interface>
+ <name>IGnss</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/gnss/2.1/default/service.cpp b/gnss/2.1/default/service.cpp
new file mode 100644
index 0000000..5e004d5
--- /dev/null
+++ b/gnss/2.1/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.gnss@2.1-service"
+
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include "Gnss.h"
+
+using ::android::OK;
+using ::android::sp;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::gnss::V2_1::IGnss;
+using ::android::hardware::gnss::V2_1::implementation::Gnss;
+
+int main(int /* argc */, char* /* argv */[]) {
+ sp<IGnss> gnss = new Gnss();
+ configureRpcThreadpool(1, true /* will join */);
+ if (gnss->registerAsService() != OK) {
+ ALOGE("Could not register gnss 2.1 service.");
+ return 1;
+ }
+ joinRpcThreadpool();
+
+ ALOGE("Service exited!");
+ return 1;
+}
\ No newline at end of file
diff --git a/gnss/2.1/vts/OWNERS b/gnss/2.1/vts/OWNERS
new file mode 100644
index 0000000..b7b4a2e
--- /dev/null
+++ b/gnss/2.1/vts/OWNERS
@@ -0,0 +1,4 @@
+gomo@google.com
+smalkos@google.com
+wyattriley@google.com
+yuhany@google.com
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
new file mode 100644
index 0000000..8340499
--- /dev/null
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalGnssV2_1TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "gnss_hal_test.cpp",
+ "gnss_hal_test_cases.cpp",
+ "VtsHalGnssV2_1TargetTest.cpp",
+ ],
+ static_libs: [
+ "android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
+ "android.hardware.gnss@1.0",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@2.1",
+ "android.hardware.gnss@common-vts-lib",
+ ],
+ test_suites: ["general-tests", "vts-core"],
+}
diff --git a/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp
new file mode 100644
index 0000000..e61d885
--- /dev/null
+++ b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "VtsHalGnssV2_1TargetTest"
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "gnss_hal_test.h"
+
+using android::hardware::gnss::V2_1::IGnss;
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GnssHalTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp
new file mode 100644
index 0000000..7cfe0db
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHalTest"
+
+#include <gnss_hal_test.h>
+#include <chrono>
+#include "Utils.h"
+
+#include <gtest/gtest.h>
+
+using ::android::hardware::gnss::common::Utils;
+
+// Implementations for the main test class for GNSS HAL
+void GnssHalTest::SetUp() {
+ gnss_hal_ = IGnss::getService(GetParam());
+ ASSERT_NE(gnss_hal_, nullptr);
+
+ SetUpGnssCallback();
+}
+
+void GnssHalTest::TearDown() {
+ if (gnss_hal_ != nullptr) {
+ gnss_hal_->cleanup();
+ gnss_hal_ = nullptr;
+ }
+
+ // Set to nullptr to destruct the callback event queues and warn of any unprocessed events.
+ gnss_cb_ = nullptr;
+}
+
+void GnssHalTest::SetUpGnssCallback() {
+ gnss_cb_ = new GnssCallback();
+ ASSERT_NE(gnss_cb_, nullptr);
+
+ auto result = gnss_hal_->setCallback_2_1(gnss_cb_);
+ if (!result.isOk()) {
+ ALOGE("result of failed setCallback %s", result.description().c_str());
+ }
+
+ ASSERT_TRUE(result.isOk());
+ ASSERT_TRUE(result);
+
+ /*
+ * All capabilities, name and systemInfo callbacks should trigger
+ */
+ EXPECT_TRUE(gnss_cb_->capabilities_cbq_.retrieve(gnss_cb_->last_capabilities_, TIMEOUT_SEC));
+ EXPECT_TRUE(gnss_cb_->info_cbq_.retrieve(gnss_cb_->last_info_, TIMEOUT_SEC));
+ EXPECT_TRUE(gnss_cb_->name_cbq_.retrieve(gnss_cb_->last_name_, TIMEOUT_SEC));
+
+ EXPECT_EQ(gnss_cb_->capabilities_cbq_.calledCount(), 1);
+ EXPECT_EQ(gnss_cb_->info_cbq_.calledCount(), 1);
+ EXPECT_EQ(gnss_cb_->name_cbq_.calledCount(), 1);
+}
+
+void GnssHalTest::StopAndClearLocations() {
+ const auto result = gnss_hal_->stop();
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ /*
+ * Clear notify/waiting counter, allowing up till the timeout after
+ * the last reply for final startup messages to arrive (esp. system
+ * info.)
+ */
+ while (gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, TIMEOUT_SEC)) {
+ }
+ gnss_cb_->location_cbq_.reset();
+}
+
+void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
+ const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider)
+ const int kPreferredTimeMsec = 0; // Ideally immediate
+
+ const auto result = gnss_hal_->setPositionMode_1_1(
+ IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
+ min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
+
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+bool GnssHalTest::StartAndCheckFirstLocation() {
+ const auto result = gnss_hal_->start();
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ /*
+ * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
+ * so allow time to demodulate ephemeris over the air.
+ */
+ const int kFirstGnssLocationTimeoutSeconds = 75;
+
+ EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_,
+ kFirstGnssLocationTimeoutSeconds));
+ int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+ EXPECT_EQ(locationCalledCount, 1);
+
+ if (locationCalledCount > 0) {
+ // don't require speed on first fix
+ CheckLocation(gnss_cb_->last_location_, false);
+ return true;
+ }
+ return false;
+}
+
+void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) {
+ const bool check_more_accuracies =
+ (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017);
+
+ Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies);
+}
+
+void GnssHalTest::StartAndCheckLocations(int count) {
+ const int kMinIntervalMsec = 500;
+ const int kLocationTimeoutSubsequentSec = 2;
+ const bool kLowPowerMode = false;
+
+ SetPositionMode(kMinIntervalMsec, kLowPowerMode);
+
+ EXPECT_TRUE(StartAndCheckFirstLocation());
+
+ for (int i = 1; i < count; i++) {
+ EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_,
+ kLocationTimeoutSubsequentSec));
+ int locationCalledCount = gnss_cb_->location_cbq_.calledCount();
+ EXPECT_EQ(locationCalledCount, i + 1);
+ // Don't cause confusion by checking details if no location yet
+ if (locationCalledCount > 0) {
+ // Should be more than 1 location by now, but if not, still don't check first fix speed
+ CheckLocation(gnss_cb_->last_location_, locationCalledCount > 1);
+ }
+ }
+}
+
+GnssHalTest::GnssCallback::GnssCallback()
+ : info_cbq_("system_info"),
+ name_cbq_("name"),
+ capabilities_cbq_("capabilities"),
+ location_cbq_("location"),
+ sv_info_list_cbq_("sv_info") {}
+
+Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
+ const IGnssCallback_1_0::GnssSystemInfo& info) {
+ ALOGI("Info received, year %d", info.yearOfHw);
+ info_cbq_.store(info);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
+ ALOGI("Capabilities received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
+ ALOGI("Capabilities (v2.0) received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
+ ALOGI("Name received: %s", name.c_str());
+ name_cbq_.store(name);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) {
+ ALOGI("Location received");
+ GnssLocation_2_0 location_v2_0;
+ location_v2_0.v1_0 = location;
+ return gnssLocationCbImpl(location_v2_0);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) {
+ ALOGI("Location (v2.0) received");
+ return gnssLocationCbImpl(location);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) {
+ location_cbq_.store(location);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus&) {
+ ALOGI("gnssSvStatusCb");
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb_2_1(
+ const hidl_vec<IGnssCallback_2_1::GnssSvInfo>& svInfoList) {
+ ALOGI("gnssSvStatusCb_2_1. Size = %d", (int)svInfoList.size());
+ sv_info_list_cbq_.store(svInfoList);
+ return Void();
+}
+
+Return<void> GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_1(
+ const IGnssMeasurementCallback_2_1::GnssData& data) {
+ ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size());
+ measurement_cbq_.store(data);
+ return Void();
+}
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h
new file mode 100644
index 0000000..2e1add0
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GNSS_HAL_TEST_H_
+#define GNSS_HAL_TEST_H_
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssCallbackEventQueue.h"
+
+#include <gtest/gtest.h>
+
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+using android::hardware::gnss::common::GnssCallbackEventQueue;
+using android::hardware::gnss::V1_0::GnssLocationFlags;
+using android::hardware::gnss::V2_1::IGnss;
+
+using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
+
+using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback;
+using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback;
+using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback;
+
+using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback;
+
+using android::sp;
+
+#define TIMEOUT_SEC 2 // for basic commands/responses
+
+// The main test class for GNSS HAL.
+class GnssHalTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override;
+
+ virtual void TearDown() override;
+
+ /* Callback class for data & Event. */
+ class GnssCallback : public IGnssCallback_2_1 {
+ public:
+ IGnssCallback_1_0::GnssSystemInfo last_info_;
+ android::hardware::hidl_string last_name_;
+ uint32_t last_capabilities_;
+ GnssLocation_2_0 last_location_;
+
+ GnssCallbackEventQueue<IGnssCallback_1_0::GnssSystemInfo> info_cbq_;
+ GnssCallbackEventQueue<android::hardware::hidl_string> name_cbq_;
+ GnssCallbackEventQueue<uint32_t> capabilities_cbq_;
+ GnssCallbackEventQueue<GnssLocation_2_0> location_cbq_;
+ GnssCallbackEventQueue<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list_cbq_;
+
+ GnssCallback();
+ virtual ~GnssCallback() = default;
+
+ // Dummy callback handlers
+ Return<void> gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override {
+ return Void();
+ }
+ Return<void> gnssNmeaCb(int64_t /* timestamp */,
+ const android::hardware::hidl_string& /* nmea */) override {
+ return Void();
+ }
+ Return<void> gnssAcquireWakelockCb() override { return Void(); }
+ Return<void> gnssReleaseWakelockCb() override { return Void(); }
+ Return<void> gnssRequestLocationCb(bool /* independentFromGnss */) override {
+ return Void();
+ }
+ Return<void> gnssRequestTimeCb() override { return Void(); }
+ // Actual (test) callback handlers
+ Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
+ Return<void> gnssLocationCb(const GnssLocation_1_0& location) override;
+ Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
+ Return<void> gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) override;
+ Return<void> gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus& svStatus) override;
+
+ // New in v2.0
+ Return<void> gnssLocationCb_2_0(const GnssLocation_2_0& location) override;
+ Return<void> gnssRequestLocationCb_2_0(bool /* independentFromGnss */,
+ bool /* isUserEmergency */) override {
+ return Void();
+ }
+ Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
+ Return<void> gnssSvStatusCb_2_0(const hidl_vec<IGnssCallback_2_0::GnssSvInfo>&) override {
+ return Void();
+ }
+
+ // New in v2.1
+ Return<void> gnssSvStatusCb_2_1(
+ const hidl_vec<IGnssCallback_2_1::GnssSvInfo>& svInfoList) override;
+
+ private:
+ Return<void> gnssLocationCbImpl(const GnssLocation_2_0& location);
+ };
+
+ /* Callback class for GnssMeasurement. */
+ class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 {
+ public:
+ GnssCallbackEventQueue<IGnssMeasurementCallback_2_1::GnssData> measurement_cbq_;
+
+ GnssMeasurementCallback() : measurement_cbq_("measurement"){};
+ virtual ~GnssMeasurementCallback() = default;
+
+ // Methods from V1_0::IGnssMeasurementCallback follow.
+ Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override {
+ return Void();
+ }
+
+ // Methods from V1_1::IGnssMeasurementCallback follow.
+ Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override {
+ return Void();
+ }
+
+ // Methods from V2_0::IGnssMeasurementCallback follow.
+ Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override {
+ return Void();
+ }
+
+ // Methods from V2_1::IGnssMeasurementCallback follow.
+ Return<void> gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override;
+ };
+
+ /*
+ * SetUpGnssCallback:
+ * Set GnssCallback and verify the result.
+ */
+ void SetUpGnssCallback();
+
+ /*
+ * StartAndCheckFirstLocation:
+ * Helper function to start location, and check the first one.
+ *
+ * <p> Note this leaves the Location request active, to enable Stop call vs. other call
+ * reordering tests.
+ *
+ * returns true if a location was successfully generated
+ */
+ bool StartAndCheckFirstLocation();
+
+ /*
+ * CheckLocation:
+ * Helper function to vet Location fields
+ *
+ * check_speed: true if speed related fields are also verified.
+ */
+ void CheckLocation(const GnssLocation_2_0& location, const bool check_speed);
+
+ /*
+ * StartAndCheckLocations:
+ * Helper function to collect, and check a number of
+ * normal ~1Hz locations.
+ *
+ * Note this leaves the Location request active, to enable Stop call vs. other call
+ * reordering tests.
+ */
+ void StartAndCheckLocations(int count);
+
+ /*
+ * StopAndClearLocations:
+ * Helper function to stop locations, and clear any remaining notifications
+ */
+ void StopAndClearLocations();
+
+ /*
+ * SetPositionMode:
+ * Helper function to set positioning mode and verify output
+ */
+ void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+
+ sp<IGnss> gnss_hal_; // GNSS HAL to call into
+ sp<GnssCallback> gnss_cb_; // Primary callback interface
+};
+
+#endif // GNSS_HAL_TEST_H_
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
new file mode 100644
index 0000000..45a3d2a
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHalTestCases"
+
+#include <gnss_hal_test.h>
+#include "Utils.h"
+
+#include <gtest/gtest.h>
+
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+
+using android::hardware::gnss::common::Utils;
+
+using IGnssMeasurement_2_1 = android::hardware::gnss::V2_1::IGnssMeasurement;
+using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
+using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
+using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
+using IGnssConfiguration_2_1 = android::hardware::gnss::V2_1::IGnssConfiguration;
+using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
+using IGnssConfiguration_1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
+using IGnssConfiguration_1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
+
+using android::hardware::gnss::V2_0::GnssConstellationType;
+using android::hardware::gnss::V2_1::IGnssConfiguration;
+
+/*
+ * SetupTeardownCreateCleanup:
+ * Requests the gnss HAL then calls cleanup
+ *
+ * Empty test fixture to verify basic Setup & Teardown
+ */
+TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
+
+/*
+ * TestGnssMeasurementExtension:
+ * Gets the GnssMeasurementExtension and verifies that it returns an actual extension.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementExtension) {
+ auto gnssMeasurement_2_1 = gnss_hal_->getExtensionGnssMeasurement_2_1();
+ auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0();
+ auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1();
+ auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
+ ASSERT_TRUE(gnssMeasurement_2_1.isOk() && gnssMeasurement_2_0.isOk() &&
+ gnssMeasurement_1_1.isOk() && gnssMeasurement_1_0.isOk());
+ sp<IGnssMeasurement_2_1> iGnssMeas_2_1 = gnssMeasurement_2_1;
+ sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
+ sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
+ sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
+ // At least one interface is non-null.
+ int numNonNull = (int)(iGnssMeas_2_1 != nullptr) + (int)(iGnssMeas_2_0 != nullptr) +
+ (int)(iGnssMeas_1_1 != nullptr) + (int)(iGnssMeas_1_0 != nullptr);
+ ASSERT_TRUE(numNonNull >= 1);
+}
+
+/*
+ * TestGnssConfigurationExtension:
+ * Gets the GnssConfigurationExtension and verifies that it returns an actual extension.
+ */
+TEST_P(GnssHalTest, TestGnssConfigurationExtension) {
+ auto gnssConfiguration_2_1 = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ auto gnssConfiguration_2_0 = gnss_hal_->getExtensionGnssConfiguration_2_0();
+ auto gnssConfiguration_1_1 = gnss_hal_->getExtensionGnssConfiguration_1_1();
+ auto gnssConfiguration_1_0 = gnss_hal_->getExtensionGnssConfiguration();
+ ASSERT_TRUE(gnssConfiguration_2_1.isOk() && gnssConfiguration_2_0.isOk() &&
+ gnssConfiguration_1_1.isOk() && gnssConfiguration_1_0.isOk());
+ sp<IGnssConfiguration_2_1> iGnssConfig_2_1 = gnssConfiguration_2_1;
+ sp<IGnssConfiguration_2_0> iGnssConfig_2_0 = gnssConfiguration_2_0;
+ sp<IGnssConfiguration_1_1> iGnssConfig_1_1 = gnssConfiguration_1_1;
+ sp<IGnssConfiguration_1_0> iGnssConfig_1_0 = gnssConfiguration_1_0;
+ // At least one interface is non-null.
+ int numNonNull = (int)(iGnssConfig_2_1 != nullptr) + (int)(iGnssConfig_2_0 != nullptr) +
+ (int)(iGnssConfig_1_1 != nullptr) + (int)(iGnssConfig_1_0 != nullptr);
+ ASSERT_TRUE(numNonNull >= 1);
+}
+
+/*
+ * TestGnssMeasurementFields:
+ * Sets a GnssMeasurementCallback, waits for a measurement, and verifies
+ * 1. basebandCN0DbHz is valid
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementFields) {
+ const int kFirstGnssMeasurementTimeoutSeconds = 10;
+
+ auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_1();
+ ASSERT_TRUE(gnssMeasurement.isOk());
+
+ // Skip test if GnssMeasurement v2.1 is not supported
+ sp<IGnssMeasurement_2_1> iGnssMeasurement = gnssMeasurement;
+ if (iGnssMeasurement == nullptr) {
+ return;
+ }
+
+ sp<GnssMeasurementCallback> callback = new GnssMeasurementCallback();
+ auto result = iGnssMeasurement->setCallback_2_1(callback, /* enableFullTracking= */ true);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
+
+ IGnssMeasurementCallback_2_1::GnssData lastMeasurement;
+ ASSERT_TRUE(callback->measurement_cbq_.retrieve(lastMeasurement,
+ kFirstGnssMeasurementTimeoutSeconds));
+ EXPECT_EQ(callback->measurement_cbq_.calledCount(), 1);
+ ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+ for (auto measurement : lastMeasurement.measurements) {
+ // Verify basebandCn0DbHz is valid.
+ ASSERT_TRUE(measurement.basebandCN0DbHz > 0.0 && measurement.basebandCN0DbHz <= 65.0);
+ }
+
+ iGnssMeasurement->close();
+}
+
+/*
+ * TestGnssSvInfoFields:
+ * Gets 1 location and a GnssSvInfo, and verifies
+ * 1. basebandCN0DbHz is valid.
+ */
+TEST_P(GnssHalTest, TestGnssSvInfoFields) {
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckFirstLocation();
+ int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size, 0);
+ ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
+ sv_info_list_cbq_size, location_called_count);
+
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> last_sv_info_list;
+ ASSERT_TRUE(gnss_cb_->sv_info_list_cbq_.retrieve(last_sv_info_list, 1));
+
+ bool nonZeroCn0Found = false;
+ for (auto sv_info : last_sv_info_list) {
+ ASSERT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
+ if (sv_info.basebandCN0DbHz > 0.0) {
+ nonZeroCn0Found = true;
+ }
+ }
+ // Assert at least one value is non-zero. Zero is ok in status as it's possibly
+ // reporting a searched but not found satellite.
+ ASSERT_TRUE(nonZeroCn0Found);
+ StopAndClearLocations();
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ * or a source with constellation == UNKNOWN if none are found sufficient times
+ * TODO(skz): create a template for this to reduce code duplication of v2.1 and v2.0 since both
+ * are using vectors.
+ */
+IGnssConfiguration::BlacklistedSource FindStrongFrequentNonGpsSource(
+ const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+ const int min_observations) {
+ struct ComparableBlacklistedSource {
+ IGnssConfiguration::BlacklistedSource id;
+
+ ComparableBlacklistedSource() {
+ id.constellation = GnssConstellationType::UNKNOWN;
+ id.svid = 0;
+ }
+
+ bool operator<(const ComparableBlacklistedSource& compare) const {
+ return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+ (id.constellation < compare.id.constellation)));
+ }
+ };
+
+ struct SignalCounts {
+ int observations;
+ float max_cn0_dbhz;
+ };
+
+ std::map<ComparableBlacklistedSource, SignalCounts> mapSignals;
+
+ for (const auto& sv_info_vec : sv_info_list) {
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ ComparableBlacklistedSource source;
+ source.id.svid = gnss_sv.v2_0.v1_0.svid;
+ source.id.constellation = gnss_sv.v2_0.constellation;
+
+ const auto& itSignal = mapSignals.find(source);
+ if (itSignal == mapSignals.end()) {
+ SignalCounts counts;
+ counts.observations = 1;
+ counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ mapSignals.insert(
+ std::pair<ComparableBlacklistedSource, SignalCounts>(source, counts));
+ } else {
+ itSignal->second.observations++;
+ if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
+ itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
+ }
+ }
+ }
+ }
+ }
+
+ float max_cn0_dbhz_with_sufficient_count = 0.;
+ int total_observation_count = 0;
+ int blacklisted_source_count_observation = 0;
+
+ ComparableBlacklistedSource source_to_blacklist; // initializes to zero = UNKNOWN constellation
+ for (auto const& pairSignal : mapSignals) {
+ total_observation_count += pairSignal.second.observations;
+ if ((pairSignal.second.observations >= min_observations) &&
+ (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+ source_to_blacklist = pairSignal.first;
+ blacklisted_source_count_observation = pairSignal.second.observations;
+ max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+ }
+ }
+ ALOGD("Among %d observations, chose svid %d, constellation %d, "
+ "with %d observations at %.1f max CNo",
+ total_observation_count, source_to_blacklist.id.svid,
+ (int)source_to_blacklist.id.constellation, blacklisted_source_count_observation,
+ max_cn0_dbhz_with_sufficient_count);
+
+ return source_to_blacklist.id;
+}
+
+/*
+ * BlacklistIndividualSatellites:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for common satellites (strongest and one other.)
+ * 2a & b) Turns off location, and blacklists common satellites.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use those satellites.
+ * 4a & b) Turns off location, and send in empty blacklist.
+ * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does re-use at least the previously strongest satellite
+ * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
+ * formerly strongest satellite
+ */
+TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
+ const int kLocationsToAwait = 3;
+ const int kRetriesToUnBlacklist = 10;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ /*
+ * Identify strongest SV seen at least kLocationsToAwait -1 times
+ * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
+ * observability (one epoch RF null)
+ */
+
+ const int kGnssSvInfoListTimeout = 2;
+ std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+ int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+ kGnssSvInfoListTimeout);
+
+ ASSERT_EQ(count, sv_info_list_cbq_size);
+
+ IGnssConfiguration::BlacklistedSource source_to_blacklist =
+ FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+
+ if (source_to_blacklist.constellation == GnssConstellationType::UNKNOWN) {
+ // Cannot find a non-GPS satellite. Let the test pass.
+ ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
+ return;
+ }
+
+ // Stop locations, blacklist the common SV
+ StopAndClearLocations();
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(1);
+ sources[0] = source_to_blacklist;
+
+ auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // retry and ensure satellite not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blacklist.svid) &&
+ (gnss_sv.v2_0.constellation == source_to_blacklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clear blacklist and restart - this time updating the blacklist while location is still on
+ sources.resize(0);
+
+ result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ bool strongest_sv_is_reobserved = false;
+ // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
+ int unblacklist_loops_remaining = kRetriesToUnBlacklist;
+ while (!strongest_sv_is_reobserved && (unblacklist_loops_remaining-- > 0)) {
+ StopAndClearLocations();
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // early exit loop if test is being run with insufficient signal
+ location_called_count = gnss_cb_->location_cbq_.calledCount();
+ if (location_called_count == 0) {
+ ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
+ }
+ ASSERT_TRUE(location_called_count > 0);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Clear blacklist, observed %d GnssSvInfo, while awaiting %d Locations"
+ ", tries remaining %d",
+ sv_info_list_cbq_size, kLocationsToAwait, unblacklist_loops_remaining);
+
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svid == source_to_blacklist.svid) &&
+ (gnss_sv.v2_0.constellation == source_to_blacklist.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+ strongest_sv_is_reobserved = true;
+ break;
+ }
+ }
+ if (strongest_sv_is_reobserved) break;
+ }
+ }
+ EXPECT_TRUE(strongest_sv_is_reobserved);
+ StopAndClearLocations();
+}
+
+/*
+ * BlacklistConstellation:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Turns off location, and blacklist first non-GPS constellations.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_P(GnssHalTest, BlacklistConstellation) {
+ const int kLocationsToAwait = 3;
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+ const int location_called_count = gnss_cb_->location_cbq_.calledCount();
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+ sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+
+ // Find first non-GPS constellation to blacklist
+ const int kGnssSvInfoListTimeout = 2;
+ GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::UNKNOWN) &&
+ (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
+ // found a non-GPS constellation
+ constellation_to_blacklist = gnss_sv.v2_0.constellation;
+ break;
+ }
+ }
+ if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
+ break;
+ }
+ }
+
+ // Turns off location
+ StopAndClearLocations();
+
+ if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
+ ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
+ // Proceed functionally to blacklist something.
+ constellation_to_blacklist = GnssConstellationType::GLONASS;
+ }
+ IGnssConfiguration::BlacklistedSource source_to_blacklist_1;
+ source_to_blacklist_1.constellation = constellation_to_blacklist;
+ source_to_blacklist_1.svid = 0; // documented wildcard for all satellites in this constellation
+
+ // IRNSS was added in 2.0. Always attempt to blacklist IRNSS to verify that the new enum is
+ // supported.
+ IGnssConfiguration::BlacklistedSource source_to_blacklist_2;
+ source_to_blacklist_2.constellation = GnssConstellationType::IRNSS;
+ source_to_blacklist_2.svid = 0; // documented wildcard for all satellites in this constellation
+
+ auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
+ ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+ sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+ ASSERT_NE(gnss_configuration_hal, nullptr);
+
+ hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+ sources.resize(2);
+ sources[0] = source_to_blacklist_1;
+ sources[1] = source_to_blacklist_2;
+
+ auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ // retry and ensure constellation not used
+ gnss_cb_->sv_info_list_cbq_.reset();
+
+ gnss_cb_->location_cbq_.reset();
+ StartAndCheckLocations(kLocationsToAwait);
+
+ // Tolerate 1 less sv status to handle edge cases in reporting.
+ sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+ EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+ ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
+ kLocationsToAwait);
+ for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+ hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+ gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+ for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+ const auto& gnss_sv = sv_info_vec[iSv];
+ EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_1.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_2.constellation) &&
+ (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+ }
+ }
+
+ // clean up
+ StopAndClearLocations();
+ sources.resize(0);
+ result = gnss_configuration_hal->setBlacklist_2_1(sources);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
\ No newline at end of file
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 4ea97fa..577f6ae 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -28,6 +28,10 @@
],
export_include_dirs: ["include"],
shared_libs: [
+ "libhidlbase",
+ "libutils",
"android.hardware.gnss@1.0",
+ "android.hardware.gnss@2.0",
+ "android.hardware.gnss@2.1",
],
}
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index b9a06e8..ccb91b1 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -16,6 +16,7 @@
#include <Constants.h>
#include <Utils.h>
+#include <utils/SystemClock.h>
namespace android {
namespace hardware {
@@ -23,31 +24,193 @@
namespace common {
using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
+using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
+using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
+using ElapsedRealtime = V2_0::ElapsedRealtime;
+using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags;
+using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
+using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback;
-GnssLocation Utils::getMockLocation() {
- GnssLocation location = {.gnssLocationFlags = 0xFF,
- .latitudeDegrees = kMockLatitudeDegrees,
- .longitudeDegrees = kMockLongitudeDegrees,
- .altitudeMeters = kMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
- .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
- .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
- .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
- .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
- .timestamp = kMockTimestamp};
+GnssDataV2_1 Utils::getMockMeasurementV2_1() {
+ GnssDataV2_0 gnssDataV2_0 = Utils::getMockMeasurementV2_0();
+ V2_1::IGnssMeasurementCallback::GnssMeasurement gnssMeasurementV2_1 = {
+ .v2_0 = gnssDataV2_0.measurements[0],
+ .basebandCN0DbHz = 25.0,
+ };
+ hidl_vec<V2_1::IGnssMeasurementCallback::GnssMeasurement> measurements(1);
+ measurements[0] = gnssMeasurementV2_1;
+ GnssDataV2_1 gnssDataV2_1 = {
+ .measurements = measurements,
+ .clock = gnssDataV2_0.clock,
+ .elapsedRealtime = gnssDataV2_0.elapsedRealtime,
+ };
+ return gnssDataV2_1;
+}
+
+GnssDataV2_0 Utils::getMockMeasurementV2_0() {
+ V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = {
+ .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY,
+ .svid = (int16_t)6,
+ .constellation = V1_0::GnssConstellationType::UNKNOWN,
+ .timeOffsetNs = 0.0,
+ .receivedSvTimeInNs = 8195997131077,
+ .receivedSvTimeUncertaintyInNs = 15,
+ .cN0DbHz = 30.0,
+ .pseudorangeRateMps = -484.13739013671875,
+ .pseudorangeRateUncertaintyMps = 1.0379999876022339,
+ .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
+ GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
+ .accumulatedDeltaRangeM = 0.0,
+ .accumulatedDeltaRangeUncertaintyM = 0.0,
+ .carrierFrequencyHz = 1.59975e+09,
+ .multipathIndicator =
+ V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
+ V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
+ V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
+ .v1_1 = measurement_1_1,
+ .codeType = "C",
+ .state = GnssMeasurementStateV2_0::STATE_CODE_LOCK |
+ GnssMeasurementStateV2_0::STATE_BIT_SYNC |
+ GnssMeasurementStateV2_0::STATE_SUBFRAME_SYNC |
+ GnssMeasurementStateV2_0::STATE_TOW_DECODED |
+ GnssMeasurementStateV2_0::STATE_GLO_STRING_SYNC |
+ GnssMeasurementStateV2_0::STATE_GLO_TOD_DECODED,
+ .constellation = GnssConstellationTypeV2_0::GLONASS,
+ };
+
+ hidl_vec<IGnssMeasurementCallbackV2_0::GnssMeasurement> measurements(1);
+ measurements[0] = measurement_2_0;
+ V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000,
+ .fullBiasNs = -1226701900521857520,
+ .biasNs = 0.59689998626708984,
+ .biasUncertaintyNs = 47514.989972114563,
+ .driftNsps = -51.757811607455452,
+ .driftUncertaintyNsps = 310.64968328491528,
+ .hwClockDiscontinuityCount = 1};
+
+ ElapsedRealtime timestamp = {
+ .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+ ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ GnssDataV2_0 gnssData = {
+ .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
+ return gnssData;
+}
+
+V2_0::GnssLocation Utils::getMockLocationV2_0() {
+ const V2_0::ElapsedRealtime timestamp = {
+ .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+ V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocationV1_0(),
+ .elapsedRealtime = timestamp};
return location;
}
-GnssSvInfo Utils::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
- float elevationDegrees, float azimuthDegrees) {
- GnssSvInfo svInfo = {.svid = svid,
- .constellation = type,
- .cN0Dbhz = cN0DbHz,
- .elevationDegrees = elevationDegrees,
- .azimuthDegrees = azimuthDegrees,
- .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
- GnssSvFlags::HAS_ALMANAC_DATA};
+V1_0::GnssLocation Utils::getMockLocationV1_0() {
+ V1_0::GnssLocation location = {
+ .gnssLocationFlags = 0xFF,
+ .latitudeDegrees = kMockLatitudeDegrees,
+ .longitudeDegrees = kMockLongitudeDegrees,
+ .altitudeMeters = kMockAltitudeMeters,
+ .speedMetersPerSec = kMockSpeedMetersPerSec,
+ .bearingDegrees = kMockBearingDegrees,
+ .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+ .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+ .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+ .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+ .timestamp = kMockTimestamp};
+ return location;
+}
+
+hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
+ GnssSvInfoV1_0 gnssSvInfoV1_0 =
+ Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS, 32.5, 59.1, 166.5);
+ GnssSvInfoV2_0 gnssSvInfoV2_0 =
+ Utils::getMockSvInfoV2_0(gnssSvInfoV1_0, V2_0::GnssConstellationType::GPS);
+ hidl_vec<GnssSvInfoV2_1> gnssSvInfoList = {
+ Utils::getMockSvInfoV2_1(gnssSvInfoV2_0, 27.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GPS, 27.0,
+ 29.0, 56.5),
+ V2_0::GnssConstellationType::GPS),
+ 22.0),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GPS, 30.5,
+ 71.0, 77.0),
+ V2_0::GnssConstellationType::GPS),
+ 25.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(26, V1_0::GnssConstellationType::GPS, 24.1,
+ 28.0, 253.0),
+ V2_0::GnssConstellationType::GPS),
+ 19.1),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GLONASS,
+ 20.5, 11.5, 116.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 15.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GLONASS,
+ 21.5, 28.5, 186.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 16.5),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(18, V1_0::GnssConstellationType::GLONASS,
+ 28.3, 38.8, 69.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 25.3),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(10, V1_0::GnssConstellationType::GLONASS,
+ 25.0, 66.0, 247.0),
+ V2_0::GnssConstellationType::GLONASS),
+ 20.0),
+ getMockSvInfoV2_1(
+ getMockSvInfoV2_0(getMockSvInfoV1_0(3, V1_0::GnssConstellationType::UNKNOWN,
+ 22.0, 35.0, 112.0),
+ V2_0::GnssConstellationType::IRNSS),
+ 19.7),
+ };
+ return gnssSvInfoList;
+}
+
+GnssSvInfoV2_1 Utils::getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz) {
+ GnssSvInfoV2_1 gnssSvInfoV2_1 = {
+ .v2_0 = gnssSvInfoV2_0,
+ .basebandCN0DbHz = basebandCN0DbHz,
+ };
+ return gnssSvInfoV2_1;
+}
+
+GnssSvInfoV2_0 Utils::getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0,
+ V2_0::GnssConstellationType type) {
+ GnssSvInfoV2_0 gnssSvInfoV2_0 = {
+ .v1_0 = gnssSvInfoV1_0,
+ .constellation = type,
+ };
+ return gnssSvInfoV2_0;
+}
+
+GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
+ float cN0DbHz, float elevationDegrees,
+ float azimuthDegrees) {
+ GnssSvInfoV1_0 svInfo = {.svid = svid,
+ .constellation = type,
+ .cN0Dbhz = cN0DbHz,
+ .elevationDegrees = elevationDegrees,
+ .azimuthDegrees = azimuthDegrees,
+ .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
+ GnssSvFlags::HAS_ALMANAC_DATA};
return svInfo;
}
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 47c8812..e0c61a4 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -18,20 +18,34 @@
#define android_hardware_gnss_common_default_Utils_H_
#include <android/hardware/gnss/1.0/IGnss.h>
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <android/hardware/gnss/2.1/IGnss.h>
-using GnssConstellationType = ::android::hardware::gnss::V1_0::GnssConstellationType;
-using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
-using GnssSvInfo = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvInfo;
+using ::android::hardware::hidl_vec;
namespace android {
namespace hardware {
namespace gnss {
namespace common {
+using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
+using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
+using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo;
+using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo;
+using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
+
struct Utils {
- static GnssLocation getMockLocation();
- static GnssSvInfo getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
- float elevationDegrees, float azimuthDegrees);
+ static GnssDataV2_0 getMockMeasurementV2_0();
+ static GnssDataV2_1 getMockMeasurementV2_1();
+ static V2_0::GnssLocation getMockLocationV2_0();
+ static V1_0::GnssLocation getMockLocationV1_0();
+ static hidl_vec<GnssSvInfoV2_1> getMockSvInfoListV2_1();
+ static GnssSvInfoV2_1 getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz);
+ static GnssSvInfoV2_0 getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0,
+ V2_0::GnssConstellationType type);
+ static GnssSvInfoV1_0 getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
+ float cN0DbHz, float elevationDegrees,
+ float azimuthDegrees);
};
} // namespace common
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
new file mode 100644
index 0000000..e0c7674
--- /dev/null
+++ b/graphics/common/aidl/Android.bp
@@ -0,0 +1,21 @@
+aidl_interface {
+ name: "vintf-graphics-common",
+ host_supported: true,
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ srcs: [
+ "android/hardware/graphics/common/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ enabled: false,
+ },
+ cpp: {
+ enabled: false,
+ },
+ },
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/BlendMode.aidl b/graphics/common/aidl/android/hardware/graphics/common/BlendMode.aidl
new file mode 100644
index 0000000..2428135
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/BlendMode.aidl
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * Blend modes, settable per layer.
+ */
+@VintfStability
+@Backing(type="int")
+enum BlendMode {
+ INVALID = 0,
+
+ /** colorOut = colorSrc */
+ NONE = 1,
+
+ /** colorOut = colorSrc + colorDst * (1 - alphaSrc) */
+ PREMULTIPLIED = 2,
+
+ /** colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc) */
+ COVERAGE = 3,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/ChromaSiting.aidl b/graphics/common/aidl/android/hardware/graphics/common/ChromaSiting.aidl
new file mode 100644
index 0000000..562a664
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/ChromaSiting.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe standard chroma siting
+ */
+@VintfStability
+@Backing(type="long")
+enum ChromaSiting {
+ /* This format does not have chroma siting. */
+ NONE = 0,
+
+ /* This format has chroma siting but the type being used is unknown. */
+ UNKNOWN = 1,
+
+ /* Cb and Cr are sited interstitially, halfway between alternate luma samples.
+ * This is used by 4:2:0 for JPEG/JFIF, H.261, MPEG-1. */
+ SITED_INTERSTITIAL = 2,
+
+ /* Cb and Cr are horizontally sited coincident with a luma sample.
+ * Cb and Cr are vertically sited interstitially.
+ * This is used by 4:2:0 for MPEG-2 frame pictures. */
+ COSITED_HORIZONTAL = 3,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Compression.aidl b/graphics/common/aidl/android/hardware/graphics/common/Compression.aidl
new file mode 100644
index 0000000..4cca1ba
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/Compression.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe standard compression strategies
+ */
+@VintfStability
+@Backing(type="long")
+enum Compression {
+ /* Represents all uncompressed buffers */
+ NONE = 0,
+
+ /* VESA Display Stream Compression (DSC) */
+ DISPLAY_STREAM_COMPRESSION = 1,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
new file mode 100644
index 0000000..81a21ab
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
@@ -0,0 +1,682 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+@VintfStability
+@Backing(type="int")
+enum Dataspace {
+ /**
+ * Default-assumption data space, when not explicitly specified.
+ *
+ * It is safest to assume the buffer is an image with sRGB primaries and
+ * encoding ranges, but the consumer and/or the producer of the data may
+ * simply be using defaults. No automatic gamma transform should be
+ * expected, except for a possible display gamma transform when drawn to a
+ * screen.
+ */
+ UNKNOWN = 0x0,
+
+ /**
+ * Arbitrary dataspace with manually defined characteristics. Definition
+ * for colorspaces or other meaning must be communicated separately.
+ *
+ * This is used when specifying primaries, transfer characteristics,
+ * etc. separately.
+ *
+ * A typical use case is in video encoding parameters (e.g. for H.264),
+ * where a colorspace can have separately defined primaries, transfer
+ * characteristics, etc.
+ */
+ ARBITRARY = 0x1,
+
+ /**
+ * Color-description aspects
+ *
+ * The following aspects define various characteristics of the color
+ * specification. These represent bitfields, so that a data space value
+ * can specify each of them independently.
+ */
+
+ STANDARD_SHIFT = 16,
+
+ /**
+ * Standard aspect
+ *
+ * Defines the chromaticity coordinates of the source primaries in terms of
+ * the CIE 1931 definition of x and y specified in ISO 11664-1.
+ */
+ STANDARD_MASK = 63 << 16, // 63 << STANDARD_SHIFT = 0x3F
+
+ /**
+ * Chromacity coordinates are unknown or are determined by the application.
+ * Implementations shall use the following suggested standards:
+ *
+ * All YCbCr formats: BT709 if size is 720p or larger (since most video
+ * content is letterboxed this corresponds to width is
+ * 1280 or greater, or height is 720 or greater).
+ * BT601_625 if size is smaller than 720p or is JPEG.
+ * All RGB formats: BT709.
+ *
+ * For all other formats standard is undefined, and implementations should use
+ * an appropriate standard for the data represented.
+ */
+ STANDARD_UNSPECIFIED = 0 << 16, // STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.300 0.600
+ * blue 0.150 0.060
+ * red 0.640 0.330
+ * white (D65) 0.3127 0.3290
+ *
+ * Use the unadjusted KR = 0.2126, KB = 0.0722 luminance interpretation
+ * for RGB conversion.
+ */
+ STANDARD_BT709 = 1 << 16, // 1 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.290 0.600
+ * blue 0.150 0.060
+ * red 0.640 0.330
+ * white (D65) 0.3127 0.3290
+ *
+ * KR = 0.299, KB = 0.114. This adjusts the luminance interpretation
+ * for RGB conversion from the one purely determined by the primaries
+ * to minimize the color shift into RGB space that uses BT.709
+ * primaries.
+ */
+ STANDARD_BT601_625 = 2 << 16, // 2 << STANDARD_SHIFT,
+
+ /**
+ * Primaries: x y
+ * green 0.290 0.600
+ * blue 0.150 0.060
+ * red 0.640 0.330
+ * white (D65) 0.3127 0.3290
+ *
+ * Use the unadjusted KR = 0.222, KB = 0.071 luminance interpretation
+ * for RGB conversion.
+ */
+ STANDARD_BT601_625_UNADJUSTED = 3 << 16, // 3 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.310 0.595
+ * blue 0.155 0.070
+ * red 0.630 0.340
+ * white (D65) 0.3127 0.3290
+ *
+ * KR = 0.299, KB = 0.114. This adjusts the luminance interpretation
+ * for RGB conversion from the one purely determined by the primaries
+ * to minimize the color shift into RGB space that uses BT.709
+ * primaries.
+ */
+ STANDARD_BT601_525 = 4 << 16, // 4 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.310 0.595
+ * blue 0.155 0.070
+ * red 0.630 0.340
+ * white (D65) 0.3127 0.3290
+ *
+ * Use the unadjusted KR = 0.212, KB = 0.087 luminance interpretation
+ * for RGB conversion (as in SMPTE 240M).
+ */
+ STANDARD_BT601_525_UNADJUSTED = 5 << 16, // 5 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.170 0.797
+ * blue 0.131 0.046
+ * red 0.708 0.292
+ * white (D65) 0.3127 0.3290
+ *
+ * Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation
+ * for RGB conversion.
+ */
+ STANDARD_BT2020 = 6 << 16, // 6 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.170 0.797
+ * blue 0.131 0.046
+ * red 0.708 0.292
+ * white (D65) 0.3127 0.3290
+ *
+ * Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation
+ * for RGB conversion using the linear domain.
+ */
+ STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16, // 7 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.21 0.71
+ * blue 0.14 0.08
+ * red 0.67 0.33
+ * white (C) 0.310 0.316
+ *
+ * Use the unadjusted KR = 0.30, KB = 0.11 luminance interpretation
+ * for RGB conversion.
+ */
+ STANDARD_BT470M = 8 << 16, // 8 << STANDARD_SHIFT
+
+ /**
+ * Primaries: x y
+ * green 0.243 0.692
+ * blue 0.145 0.049
+ * red 0.681 0.319
+ * white (C) 0.310 0.316
+ *
+ * Use the unadjusted KR = 0.254, KB = 0.068 luminance interpretation
+ * for RGB conversion.
+ */
+ STANDARD_FILM = 9 << 16, // 9 << STANDARD_SHIFT
+
+ /**
+ * SMPTE EG 432-1 and SMPTE RP 431-2. (DCI-P3)
+ * Primaries: x y
+ * green 0.265 0.690
+ * blue 0.150 0.060
+ * red 0.680 0.320
+ * white (D65) 0.3127 0.3290
+ */
+ STANDARD_DCI_P3 = 10 << 16, // 10 << STANDARD_SHIFT
+
+ /**
+ * Adobe RGB
+ * Primaries: x y
+ * green 0.210 0.710
+ * blue 0.150 0.060
+ * red 0.640 0.330
+ * white (D65) 0.3127 0.3290
+ */
+ STANDARD_ADOBE_RGB = 11 << 16, // 11 << STANDARD_SHIFT
+
+
+
+ TRANSFER_SHIFT = 22,
+
+ /**
+ * Transfer aspect
+ *
+ * Transfer characteristics are the opto-electronic transfer characteristic
+ * at the source as a function of linear optical intensity (luminance).
+ *
+ * For digital signals, E corresponds to the recorded value. Normally, the
+ * transfer function is applied in RGB space to each of the R, G and B
+ * components independently. This may result in color shift that can be
+ * minized by applying the transfer function in Lab space only for the L
+ * component. Implementation may apply the transfer function in RGB space
+ * for all pixel formats if desired.
+ */
+
+ TRANSFER_MASK = 31 << 22, // 31 << TRANSFER_SHIFT = 0x1F
+
+ /**
+ * Transfer characteristics are unknown or are determined by the
+ * application.
+ *
+ * Implementations should use the following transfer functions:
+ *
+ * For YCbCr formats: use TRANSFER_SMPTE_170M
+ * For RGB formats: use TRANSFER_SRGB
+ *
+ * For all other formats transfer function is undefined, and implementations
+ * should use an appropriate standard for the data represented.
+ */
+ TRANSFER_UNSPECIFIED = 0 << 22, // 0 << TRANSFER_SHIFT
+
+ /**
+ * Transfer characteristic curve:
+ * E = L
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal
+ */
+ TRANSFER_LINEAR = 1 << 22, // 1 << TRANSFER_SHIFT
+
+ /**
+ * Transfer characteristic curve:
+ *
+ * E = 1.055 * L^(1/2.4) - 0.055 for 0.0031308 <= L <= 1
+ * = 12.92 * L for 0 <= L < 0.0031308
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal
+ */
+ TRANSFER_SRGB = 2 << 22, // 2 << TRANSFER_SHIFT
+
+ /**
+ * BT.601 525, BT.601 625, BT.709, BT.2020
+ *
+ * Transfer characteristic curve:
+ * E = 1.099 * L ^ 0.45 - 0.099 for 0.018 <= L <= 1
+ * = 4.500 * L for 0 <= L < 0.018
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal
+ */
+ TRANSFER_SMPTE_170M = 3 << 22, // 3 << TRANSFER_SHIFT
+
+ /**
+ * Assumed display gamma 2.2.
+ *
+ * Transfer characteristic curve:
+ * E = L ^ (1/2.2)
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal
+ */
+ TRANSFER_GAMMA2_2 = 4 << 22, // 4 << TRANSFER_SHIFT
+
+ /**
+ * display gamma 2.6.
+ *
+ * Transfer characteristic curve:
+ * E = L ^ (1/2.6)
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal
+ */
+ TRANSFER_GAMMA2_6 = 5 << 22, // 5 << TRANSFER_SHIFT
+
+ /**
+ * display gamma 2.8.
+ *
+ * Transfer characteristic curve:
+ * E = L ^ (1/2.8)
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal
+ */
+ TRANSFER_GAMMA2_8 = 6 << 22, // 6 << TRANSFER_SHIFT
+
+ /**
+ * SMPTE ST 2084 (Dolby Perceptual Quantizer)
+ *
+ * Transfer characteristic curve:
+ * E = ((c1 + c2 * L^n) / (1 + c3 * L^n)) ^ m
+ * c1 = c3 - c2 + 1 = 3424 / 4096 = 0.8359375
+ * c2 = 32 * 2413 / 4096 = 18.8515625
+ * c3 = 32 * 2392 / 4096 = 18.6875
+ * m = 128 * 2523 / 4096 = 78.84375
+ * n = 0.25 * 2610 / 4096 = 0.1593017578125
+ * L - luminance of image 0 <= L <= 1 for HDR colorimetry.
+ * L = 1 corresponds to 10000 cd/m2
+ * E - corresponding electrical signal
+ */
+ TRANSFER_ST2084 = 7 << 22, // 7 << TRANSFER_SHIFT
+
+ /**
+ * ARIB STD-B67 Hybrid Log Gamma
+ *
+ * Transfer characteristic curve:
+ * E = r * L^0.5 for 0 <= L <= 1
+ * = a * ln(L - b) + c for 1 < L
+ * a = 0.17883277
+ * b = 0.28466892
+ * c = 0.55991073
+ * r = 0.5
+ * L - luminance of image 0 <= L for HDR colorimetry. L = 1 corresponds
+ * to reference white level of 100 cd/m2
+ * E - corresponding electrical signal
+ */
+ TRANSFER_HLG = 8 << 22, // 8 << TRANSFER_SHIFT
+
+ RANGE_SHIFT = 27,
+
+ /**
+ * Range aspect
+ *
+ * Defines the range of values corresponding to the unit range of 0-1.
+ * This is defined for YCbCr only, but can be expanded to RGB space.
+ */
+ RANGE_MASK = 7 << 27, // 7 << RANGE_SHIFT = 0x7
+
+ /**
+ * Range is unknown or are determined by the application. Implementations
+ * shall use the following suggested ranges:
+ *
+ * All YCbCr formats: limited range.
+ * All RGB or RGBA formats (including RAW and Bayer): full range.
+ * All Y formats: full range
+ *
+ * For all other formats range is undefined, and implementations should use
+ * an appropriate range for the data represented.
+ */
+ RANGE_UNSPECIFIED = 0 << 27, // 0 << RANGE_SHIFT = 0x0
+
+ /**
+ * Full range uses all values for Y, Cb and Cr from
+ * 0 to 2^b-1, where b is the bit depth of the color format.
+ */
+ RANGE_FULL = 1 << 27, // 1 << RANGE_SHIFT = 0x8000000
+
+ /**
+ * Limited range uses values 16/256*2^b to 235/256*2^b for Y, and
+ * 1/16*2^b to 15/16*2^b for Cb, Cr, R, G and B, where b is the bit depth of
+ * the color format.
+ *
+ * E.g. For 8-bit-depth formats:
+ * Luma (Y) samples should range from 16 to 235, inclusive
+ * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive
+ *
+ * For 10-bit-depth formats:
+ * Luma (Y) samples should range from 64 to 940, inclusive
+ * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive
+ */
+ RANGE_LIMITED = 2 << 27, // 2 << RANGE_SHIFT = 0x10000000
+
+ /**
+ * Extended range is used for scRGB. Intended for use with
+ * floating point pixel formats. [0.0 - 1.0] is the standard
+ * sRGB space. Values outside the range 0.0 - 1.0 can encode
+ * color outside the sRGB gamut.
+ * Used to blend / merge multiple dataspaces on a single display.
+ */
+ RANGE_EXTENDED = 3 << 27, // 3 << RANGE_SHIFT = 0x18000000
+
+ /**
+ * sRGB linear encoding:
+ *
+ * The red, green, and blue components are stored in sRGB space, but
+ * are linear, not gamma-encoded.
+ * The RGB primaries and the white point are the same as BT.709.
+ *
+ * The values are encoded using the full range ([0,255] for 8-bit) for all
+ * components.
+ */
+ SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // deprecated, use V0_SRGB_LINEAR
+
+ V0_SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
+
+
+ /**
+ * scRGB linear encoding:
+ *
+ * The red, green, and blue components are stored in extended sRGB space,
+ * but are linear, not gamma-encoded.
+ * The RGB primaries and the white point are the same as BT.709.
+ *
+ * The values are floating point.
+ * A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits.
+ * Values beyond the range [0.0 - 1.0] would correspond to other colors
+ * spaces and/or HDR content.
+ */
+ V0_SCRGB_LINEAR = 1 << 16 | 1 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED
+
+
+ /**
+ * sRGB gamma encoding:
+ *
+ * The red, green and blue components are stored in sRGB space, and
+ * converted to linear space when read, using the SRGB transfer function
+ * for each of the R, G and B components. When written, the inverse
+ * transformation is performed.
+ *
+ * The alpha component, if present, is always stored in linear space and
+ * is left unmodified when read or written.
+ *
+ * Use full range and BT.709 standard.
+ */
+ SRGB = 1 << 16 | 2 << 22 | 1 << 27, // deprecated, use V0_SRGB
+
+ V0_SRGB = 1 << 16 | 2 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL
+
+
+ /**
+ * scRGB:
+ *
+ * The red, green, and blue components are stored in extended sRGB space,
+ * but are linear, not gamma-encoded.
+ * The RGB primaries and the white point are the same as BT.709.
+ *
+ * The values are floating point.
+ * A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits.
+ * Values beyond the range [0.0 - 1.0] would correspond to other colors
+ * spaces and/or HDR content.
+ */
+ V0_SCRGB = 1 << 16 | 2 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED
+
+ /**
+ * YCbCr Colorspaces
+ * -----------------
+ *
+ * Primaries are given using (x,y) coordinates in the CIE 1931 definition
+ * of x and y specified by ISO 11664-1.
+ *
+ * Transfer characteristics are the opto-electronic transfer characteristic
+ * at the source as a function of linear optical intensity (luminance).
+ */
+
+ /**
+ * JPEG File Interchange Format (JFIF)
+ *
+ * Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255
+ *
+ * Use full range, BT.601 transfer and BT.601_625 standard.
+ */
+ JFIF = 2 << 16 | 3 << 22 | 1 << 27, // deprecated, use V0_JFIF
+
+ V0_JFIF = 2 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_FULL
+
+ /**
+ * ITU-R Recommendation 601 (BT.601) - 625-line
+ *
+ * Standard-definition television, 625 Lines (PAL)
+ *
+ * Use limited range, BT.601 transfer and BT.601_625 standard.
+ */
+ BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // deprecated, use V0_BT601_625
+
+ V0_BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+
+
+ /**
+ * ITU-R Recommendation 601 (BT.601) - 525-line
+ *
+ * Standard-definition television, 525 Lines (NTSC)
+ *
+ * Use limited range, BT.601 transfer and BT.601_525 standard.
+ */
+ BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // deprecated, use V0_BT601_525
+
+ V0_BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+
+ /**
+ * ITU-R Recommendation 709 (BT.709)
+ *
+ * High-definition television
+ *
+ * Use limited range, BT.709 transfer and BT.709 standard.
+ */
+ BT709 = 1 << 16 | 3 << 22 | 2 << 27, // deprecated, use V0_BT709
+
+ V0_BT709 = 1 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+
+
+ /**
+ * SMPTE EG 432-1 and SMPTE RP 431-2.
+ *
+ * Digital Cinema DCI-P3
+ *
+ * Use full range, linear transfer and D65 DCI-P3 standard
+ */
+ DCI_P3_LINEAR = 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
+
+
+ /**
+ * SMPTE EG 432-1 and SMPTE RP 431-2.
+ *
+ * Digital Cinema DCI-P3
+ *
+ * Use full range, gamma 2.6 transfer and D65 DCI-P3 standard
+ * Note: Application is responsible for gamma encoding the data as
+ * a 2.6 gamma encoding is not supported in HW.
+ */
+ DCI_P3 = 10 << 16 | 5 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL
+
+
+ /**
+ * Display P3
+ *
+ * Display P3 uses same primaries and white-point as DCI-P3
+ * linear transfer function makes this the same as DCI_P3_LINEAR.
+ */
+ DISPLAY_P3_LINEAR = 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
+
+
+ /**
+ * Display P3
+ *
+ * Use same primaries and white-point as DCI-P3
+ * but sRGB transfer function.
+ */
+ DISPLAY_P3 = 10 << 16 | 2 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_FULL
+
+
+ /**
+ * Adobe RGB
+ *
+ * Use full range, gamma 2.2 transfer and Adobe RGB primaries
+ * Note: Application is responsible for gamma encoding the data as
+ * a 2.2 gamma encoding is not supported in HW.
+ */
+ ADOBE_RGB = 11 << 16 | 4 << 22 | 1 << 27, // STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL
+
+
+ /**
+ * ITU-R Recommendation 2020 (BT.2020)
+ *
+ * Ultra High-definition television
+ *
+ * Use full range, linear transfer and BT2020 standard
+ */
+ BT2020_LINEAR = 6 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_LINEAR | RANGE_FULL
+
+
+ /**
+ * ITU-R Recommendation 2020 (BT.2020)
+ *
+ * Ultra High-definition television
+ *
+ * Use full range, BT.709 transfer and BT2020 standard
+ */
+ BT2020 = 6 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL
+
+ /**
+ * ITU-R Recommendation 2020 (BT.2020)
+ *
+ * Ultra High-definition television
+ *
+ * Use full range, SMPTE 2084 (PQ) transfer and BT2020 standard
+ */
+ BT2020_PQ = 6 << 16 | 7 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL
+
+
+ /**
+ * Data spaces for non-color formats
+ */
+
+ /**
+ * The buffer contains depth ranging measurements from a depth camera.
+ * This value is valid with formats:
+ * HAL_PIXEL_FORMAT_Y16: 16-bit samples, consisting of a depth measurement
+ * and an associated confidence value. The 3 MSBs of the sample make
+ * up the confidence value, and the low 13 LSBs of the sample make up
+ * the depth measurement.
+ * For the confidence section, 0 means 100% confidence, 1 means 0%
+ * confidence. The mapping to a linear float confidence value between
+ * 0.f and 1.f can be obtained with
+ * float confidence = (((depthSample >> 13) - 1) & 0x7) / 7.0f;
+ * The depth measurement can be extracted simply with
+ * uint16_t range = (depthSample & 0x1FFF);
+ * HAL_PIXEL_FORMAT_BLOB: A depth point cloud, as
+ * a variable-length float (x,y,z, confidence) coordinate point list.
+ * The point cloud will be represented with the android_depth_points
+ * structure.
+ */
+ DEPTH = 0x1000,
+
+ /**
+ * The buffer contains sensor events from sensor direct report.
+ * This value is valid with formats:
+ * HAL_PIXEL_FORMAT_BLOB: an array of sensor event structure that forms
+ * a lock free queue. Format of sensor event structure is specified
+ * in Sensors HAL.
+ */
+ SENSOR = 0x1001,
+
+ /**
+ * ITU-R Recommendation 2020 (BT.2020)
+ *
+ * Ultra High-definition television
+ *
+ * Use limited range, BT.709 transfer and BT2020 standard
+ */
+ BT2020_ITU = 6 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+
+ /**
+ * ITU-R Recommendation 2100 (BT.2100)
+ *
+ * High dynamic range television
+ *
+ * Use limited/full range, PQ/HLG transfer, and BT2020 standard
+ * limited range is the preferred / normative definition for BT.2100
+ */
+ BT2020_ITU_PQ = 6 << 16 | 7 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED
+ BT2020_ITU_HLG = 6 << 16 | 8 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED
+ BT2020_HLG = 6 << 16 | 8 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL
+
+ /**
+ * ITU-R Recommendation 2020 (BT.2020)
+ *
+ * Ultra High-definition television
+ *
+ * Use full range, sRGB transfer and BT2020 standard
+ */
+ DISPLAY_BT2020 = 6 << 16 | 2 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_SRGB | RANGE_FULL
+
+ /**
+ * ISO 16684-1:2011(E)
+ *
+ * Embedded depth metadata following the dynamic depth specification.
+ */
+ DYNAMIC_DEPTH = 0x1002,
+
+ /**
+ * JPEG APP segments format as specified by JEIDA spec
+ *
+ * The buffer must only contain APP1 (Application Marker) segment followed
+ * by zero or more APPn segments, as is specified by JEITA CP-3451C section 4.5.4.
+ * The APP1 segment optionally contains a thumbnail. The buffer will not
+ * contain main compressed image.
+ *
+ * This value is valid with formats:
+ * HAL_PIXEL_FORMAT_BLOB: JPEG APP segments optionally containing thumbnail image
+ * in APP1. BLOB buffer with this dataspace is output by HAL, and used by
+ * camera framework to encode into a HEIC image.
+ */
+ JPEG_APP_SEGMENTS = 0x1003,
+
+ /**
+ * ISO/IEC 23008-12
+ *
+ * High Efficiency Image File Format (HEIF)
+ *
+ * This value is valid with formats:
+ * HAL_PIXEL_FORMAT_BLOB: A HEIC image encoded by HEIC or HEVC encoder
+ * according to ISO/IEC 23008-12.
+ */
+ HEIF = 0x1004,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/ExtendableType.aidl b/graphics/common/aidl/android/hardware/graphics/common/ExtendableType.aidl
new file mode 100644
index 0000000..495693c
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/ExtendableType.aidl
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * This struct is used for types that are commonly extended by vendors. For example, buffer
+ * compression is typically SoC specific. It is not possible for Android to define every possible
+ * proprietary vendor compression strategy. Instead, compression is represented using this
+ * ExtendableType that can support standard compression strategies while still allowing
+ * every vendor to easily add their own non-standard definitions.
+ */
+@VintfStability
+parcelable ExtendableType {
+ /**
+ * Name of the stable aidl interface whose value is stored in this structure.
+ *
+ * For standard types, the "name" field will be set to the stable aidl name of the type such as
+ * "android.hardware.graphics.common.Compression".
+ *
+ * For custom vendor types, the "name" field will be set to the name of the custom
+ * @VendorStability vendor AIDL interface such as
+ * "vendor.mycompanyname.graphics.common.Compression". The name of the vendor extension should
+ * contain the name of the owner of the extension. Including the company
+ * name in the "name" field prevents type collisions between different vendors.
+ */
+ @utf8InCpp String name;
+
+ /**
+ * Enum value of the from the stable aidl interface
+ *
+ * For standard types, the "value" field will be set to an enum value from that stable aidl
+ * type such as "NONE".
+ *
+ * For vendor types, the "value" field should be set to the enum value from the custom
+ * @VendorStability vendor AIDL interface extended type such as "MY_COMPRESSION_TYPE1".
+ */
+ long value = 0;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Interlaced.aidl b/graphics/common/aidl/android/hardware/graphics/common/Interlaced.aidl
new file mode 100644
index 0000000..a3f1baa
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/Interlaced.aidl
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe standard interlaced strategies
+ */
+@VintfStability
+@Backing(type="long")
+enum Interlaced {
+ /* The buffer is not interlaced. */
+ NONE = 0,
+
+ /* The buffer's planes are interlaced horizontally. The height of each interlaced plane is
+ * 1/2 the height of the buffer's height. */
+ TOP_BOTTOM = 1,
+
+ /* The buffer's planes are interlaced vertically. The width of each interlaced plane is
+ * 1/2 the width of the buffer's width. */
+ RIGHT_LEFT = 2,
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayout.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayout.aidl
new file mode 100644
index 0000000..168028d
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayout.aidl
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+import android.hardware.graphics.common.PlaneLayoutComponent;
+import android.hardware.graphics.common.Rect;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe the plane layout of a buffer.
+ *
+ * PlaneLayout uses the following definitions:
+ *
+ * - Component - a component is one channel of a pixel. For example, an RGBA format has
+ * four components: R, G, B and A.
+ * - Sample - a sample is comprised of all the components in a given plane. For example,
+ * a buffer with one Y plane and one CbCr plane has one plane with a sample of Y
+ * and one plane with a sample of CbCr.
+ * - Pixel - a pixel is comprised of all the (non-metadata/raw) components in buffer across
+ * all planes. For example, a buffer with a plane of Y and a plane of CbCr has a pixel
+ * of YCbCr.
+ */
+
+@VintfStability
+parcelable PlaneLayout {
+ /**
+ * An list of plane layout components. This list of components should include
+ * every component in this plane. For example, a CbCr plane should return a
+ * vector of size two with one PlaneLayoutComponent for Cb and one for Cr.
+ */
+ PlaneLayoutComponent[] components;
+
+ /**
+ * Offset to the first byte of the plane (in bytes), from the start of the allocation.
+ */
+ long offsetInBytes;
+
+ /**
+ * Bits per sample increment (aka column increment): describes the distance
+ * in bits from one sample to the next sample (to the right) on the same row for the
+ * the component plane.
+ *
+ * The default value is 0. Return the default value if the increment is undefined, unknown,
+ * or variable.
+ *
+ * This can be negative. A negative increment indicates that the samples are read from
+ * right to left.
+ */
+ long sampleIncrementInBits;
+
+ /**
+ * Horizontal stride: number of bytes between two vertically adjacent
+ * samples in given plane. This can be mathematically described by:
+ *
+ * strideInBytes = ALIGN(widthInSamples * bps / 8, alignment)
+ *
+ * where,
+ *
+ * bps: average bits per sample
+ * alignment (in bytes): dependent upon pixel format and usage
+ *
+ * strideInBytes can contain additional padding beyond the widthInSamples.
+ *
+ * The default value is 0. Return the default value if the stride is undefined, unknown,
+ * or variable.
+ *
+ * This can be negative. A negative stride indicates that the rows are read from
+ * bottom to top.
+ */
+ long strideInBytes;
+
+ /**
+ * Dimensions of plane (in samples).
+ *
+ * This is the number of samples in the plane, even if subsampled.
+ *
+ * See 'strideInBytes' for relationship between strideInBytes and widthInSamples.
+ */
+ long widthInSamples;
+ long heightInSamples;
+
+ /**
+ * Can be used to get the total size in bytes of any memory used by the plane
+ * including extra padding. This should not include any extra metadata used to describe the
+ * plane.
+ */
+ long totalSizeInBytes;
+
+ /**
+ * Horizontal and vertical subsampling. Must be a positive power of 2.
+ *
+ * These fields indicate the number of horizontally or vertically adjacent pixels that use
+ * the same pixel data. A value of 1 indicates no subsampling.
+ */
+ long horizontalSubsampling;
+ long verticalSubsampling;
+
+ /**
+ * Some buffer producers require extra padding to their output buffer; therefore the
+ * physical size of the native buffer will be larger than its logical size.
+ * The crop rectangle determines the offset and logical size of the buffer that should be
+ * read by consumers.
+ *
+ * The crop rectangle is measured in samples and is relative to the offset of the
+ * plane. Valid crop rectangles are within the boundaries of the plane:
+ * [0, 0, widthInSamples, heightInSamples].
+ *
+ * The default crop rectangle is a rectangle the same size as the plane:
+ * [0, 0, widthInSamples, heightInSamples].
+ */
+ Rect crop;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
new file mode 100644
index 0000000..3fca53b
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponent.aidl
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+import android.hardware.graphics.common.ExtendableType;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe the type and location of a component in a
+ * buffer's plane.
+ *
+ * PlaneLayoutComponent uses the following definitions:
+ *
+ * - Component - a component is one channel of a pixel. For example, an RGBA format has
+ * four components: R, G, B and A.
+ * - Sample - a sample is comprised of all the components in a given plane. For example,
+ * a buffer with one Y plane and one CbCr plane has one plane with a sample of Y
+ * and one plane with a sample of CbCr.
+ * - Pixel - a pixel is comprised of all the (non-metadata/raw) components in buffer across
+ * all planes. For example, a buffer with a plane of Y and a plane of CbCr has a pixel
+ * of YCbCr.
+ */
+
+@VintfStability
+parcelable PlaneLayoutComponent {
+ /**
+ * The type of this plane layout component.
+ *
+ * android.hardware.graphics.common.PlaneLayoutComponent defines the standard
+ * plane layout component types. Vendors may extend this type to include any
+ * non-standard plane layout component types. For instructions on how to
+ * create a vendor extension, refer to ExtendableType.aidl.
+ */
+ ExtendableType type;
+
+ /**
+ * Offset in bits to the first instance of this component in the plane.
+ * This is relative to the plane's offset (PlaneLayout::offset).
+ *
+ * If the offset cannot be described using a int64_t, this should be set to -1.
+ * For example, if the plane is compressed and the offset is not defined or
+ * relevant, return -1.
+ */
+ long offsetInBits;
+
+ /**
+ * The number of bits used per component in the plane.
+ *
+ * If the plane layout component cannot be described using componentSizeInBits, this
+ * should be set to -1. For example, if the component varies in size throughout
+ * the plane, return -1.
+ */
+ long sizeInBits;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
new file mode 100644
index 0000000..18c4a2e
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe standard plane layout component types
+ *
+ * The enum values have been taken directly from gralloc1's android_flex_component for compatiblity
+ * reasons. However, unlike gralloc1's android_flex_component, this field is NOT a bit field.
+ * A plane's components should NOT be expressed by bitwise OR-ing different
+ * PlaneLayoutComponentTypes together.
+ */
+@VintfStability
+@Backing(type="long")
+enum PlaneLayoutComponentType {
+ /* Luma */
+ Y = 1 << 0,
+ /* Chroma blue */
+ CB = 1 << 1,
+ /* Chroma red */
+ CR = 1 << 2,
+
+ /* Red */
+ R = 1 << 10,
+ /* Green */
+ G = 1 << 11,
+ /* Blue */
+ B = 1 << 12,
+
+ /* Alpha */
+ A = 1 << 30,
+}
diff --git a/vibrator/1.4/types.hal b/graphics/common/aidl/android/hardware/graphics/common/Rect.aidl
similarity index 62%
copy from vibrator/1.4/types.hal
copy to graphics/common/aidl/android/hardware/graphics/common/Rect.aidl
index acc49b1..1a3bc11 100644
--- a/vibrator/1.4/types.hal
+++ b/graphics/common/aidl/android/hardware/graphics/common/Rect.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
+/**
+ * Copyright (c) 2019, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,9 +14,16 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+package android.hardware.graphics.common;
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+/**
+ * General purpose definition of a rectangle.
+ */
+
+@VintfStability
+parcelable Rect {
+ int left;
+ int top;
+ int right;
+ int bottom;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
new file mode 100644
index 0000000..060d12c
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -0,0 +1,282 @@
+/**
+ * Copyright (c) 2019,libgralloctypes_helper 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.graphics.common;
+
+/**
+ * Used by IAllocator/IMapper (gralloc) to describe standard metadata types.
+ *
+ * This is an enum that defines the common types of gralloc 4 buffer metadata. The comments for
+ * each enum include a description of the metadata that is associated with the type.
+ *
+ * IMapper@4.x must support getting the following standard buffer metadata types. IMapper@4.x may
+ * support setting these standard buffer metadata types as well.
+ */
+@VintfStability
+@Backing(type="long")
+enum StandardMetadataType {
+ INVALID = 0,
+
+ /**
+ * Can be used to get the random ID of the buffer. This ID should be psuedorandom with
+ * sufficient entropy.
+ *
+ * This ID should only be used for debugging purposes. It cannot be used as a basis for any
+ * control flows.
+ *
+ * The buffer ID is determined at allocation time and should not change during the lifetime
+ * of the buffer.
+ *
+ * The buffer ID is a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ BUFFER_ID = 1,
+
+ /**
+ * Can be used to get the name passed in by the client at allocation time in the
+ * BufferDescriptorInfo.
+ *
+ * The buffer name is determined at allocation time and should not change during the lifetime
+ * of the buffer.
+ *
+ * The buffer name is a string.
+ *
+ * When it is encoded into a byte stream, the length of the string is written using 8 bytes in
+ * little endian. It is followed by a char array of the string's
+ * characters. The array is not null-terminated.
+ */
+ NAME = 2,
+
+ /**
+ * Can be used to get the number of elements per buffer row requested at allocation time in
+ * the BufferDescriptorInfo.
+ *
+ * The width is determined at allocation time and should not change during the lifetime
+ * of the buffer.
+ *
+ * The width is a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ WIDTH = 3,
+
+ /**
+ * Can be used to get the number of elements per buffer column requested at allocation time in
+ * the BufferDescriptorInfo.
+ *
+ * The height is determined at allocation time and should not change during the lifetime
+ * of the buffer.
+ *
+ * The height is a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ HEIGHT = 4,
+
+ /**
+ * Can be used to get the number of layers requested at allocation time in the
+ * BufferDescriptorInfo.
+ *
+ * The layer count is determined at allocation time and should not change during the lifetime
+ * of the buffer.
+ *
+ * The layer count is a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ LAYER_COUNT = 5,
+
+ /**
+ * Can be used to get the buffer format requested at allocation time in the
+ * BufferDescriptorInfo.
+ *
+ * The requested pixel format is determined at allocation time and should not change during
+ * the lifetime of the buffer.
+ *
+ * The requested pixel format is a android.hardware.graphics.common@1.2::PixelFormat.
+ *
+ * When it is encoded into a byte stream, it is first cast to a int32_t and then represented in
+ * the byte stream by 4 bytes written in little endian.
+ */
+ PIXEL_FORMAT_REQUESTED = 6,
+
+ /**
+ * Can be used to get the fourcc code for the format. Fourcc codes are standard across all
+ * devices of the same kernel version. Fourcc codes must follow the Linux definition of a
+ * fourcc format found in: include/uapi/drm/drm_fourcc.h.
+ *
+ * The pixel format fourcc code is represented by a uint32_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 4 bytes written in little endian.
+ */
+ PIXEL_FORMAT_FOURCC = 7,
+
+ /**
+ * Can be used to get the modifier for the format. Together fourcc and modifier describe the
+ * real pixel format. Each fourcc and modifier pair is unique and must fully define the format
+ * and layout of the buffer. Modifiers can change any property of the buffer. Modifiers must
+ * follow the Linux definition of a modifier found in: include/uapi/drm/drm_fourcc.h.
+ *
+ * The pixel format modifier is represented by a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ PIXEL_FORMAT_MODIFIER = 8,
+
+ /**
+ * Can be used to get the usage requested at allocation time in the BufferDescriptorInfo.
+ *
+ * The usage is determined at allocation time and should not change during the lifetime
+ * of the buffer.
+ *
+ * The usage is a uint64_t bit field of android.hardware.graphics.common@1.2::BufferUsage's.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ USAGE = 9,
+
+ /**
+ * Can be used to get the total size in bytes of any memory used by the buffer including its
+ * metadata and extra padding. This is the total number of bytes used by the buffer allocation.
+ *
+ * The allocation size is a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ ALLOCATION_SIZE = 10,
+
+ /**
+ * Can be used to get if a buffer has protected content. If the buffer does not have protected
+ * content, this should return 0. If a buffer has protected content, this should return 1.
+ *
+ * In future versions, this field will be extended to expose more information about the type
+ * of protected content in the buffer.
+ *
+ * The protected content is a uint64_t.
+ *
+ * When it is encoded into a byte stream, it is represented by 8 bytes written in little endian.
+ */
+ PROTECTED_CONTENT = 11,
+
+ /**
+ * Can be used to get the compression strategy of the buffer. If the device has more than one
+ * compression strategy, it should have different unique values for each compression
+ * strategy.
+ *
+ * Compression is a stable aidl android.hardware.graphics.common.ExtendableType.
+ *
+ * android.hardware.graphics.common.Compression defines the standard compression
+ * strategies. Vendors may extend this type to include any compression strategies.
+ *
+ * When it is encoded into a byte stream, the length of the name field string is written using
+ * 8 bytes in little endian. It is followed by a char array of the string's
+ * characters. The array is not null-terminated. Finally the value field is written as 8 bytes
+ * in little endian.
+ */
+ COMPRESSION = 12,
+
+ /**
+ * Can be used to get how the buffer's planes are interlaced.
+ *
+ * Interlaced is a stable aidl android.hardware.graphics.common.ExtendableType.
+ *
+ * android.hardware.graphics.common.Interlaced defines the standard interlaced
+ * strategies. Vendors may extend this type to include any non-standard interlaced
+ * strategies.
+ *
+ * When it is encoded into a byte stream, the length of the name field string is written using
+ * 8 bytes in little endian. It is followed by a char array of the string's
+ * characters. The array is not null-terminated. Finally the value field is written as 8 bytes
+ * in little endian.
+ */
+ INTERLACED = 13,
+
+ /**
+ * Can be used to get the chroma siting of a buffer.
+ *
+ * Chroma siting is a stable aidl android.hardware.graphics.common.ExtendableType.
+ *
+ * android.hardware.graphics.common.ChromaSiting defines the standard chroma
+ * sitings. Vendors may extend this type to include any non-standard chroma sitings.
+ *
+ * When it is encoded into a byte stream, the length of the name field string is written using
+ * 8 bytes in little endian. It is followed by a char array of the string's
+ * characters. The array is not null-terminated. Finally the value field is written as 8 bytes
+ * in little endian.
+ */
+ CHROMA_SITING = 14,
+
+ /**
+ * Can be used to get the PlaneLayout(s) of the buffer. There should be one PlaneLayout per
+ * plane in the buffer. For example if the buffer only has one plane, only one PlaneLayout
+ * should be returned.
+ *
+ * If the buffer has planes interlaced through time, the returned PlaneLayout structs should be
+ * ordered by time. The nth PlaneLayout should be from the same time or earlier than the
+ * n+1 PlaneLayout.
+ *
+ * The plane layout is a list of stable aidl android.hardware.graphics.common.PlaneLayout's.
+ *
+ * When it is encoded into a byte stream, the total number of PlaneLayouts is written using
+ * 8 bytes in little endian. It is followed by each PlaneLayout.
+ *
+ * To encode a PlaneLayout, write the length of its PlaneLayoutComponent[] components
+ * field as 8 bytes in little endian and then encode each of its components. Finally, write the
+ * following fields in this order each as 8 bytes in little endian: offsetInBytes,
+ * sampleIncrementInBits, strideInBytes, widthInSamples, totalSizeInBytes,
+ * horizontalSubsampling, verticalSubsampling.
+ *
+ * To encode a PlaneLayoutComponent, encode its PlaneLayoutComponentType type field. Next
+ * encode offsetInBits followed by sizeInBits each as 8 bytes in little endian.
+ *
+ * To encode a PlaneLayoutComponentType, write the length of the name field string as
+ * 8 bytes in little endian. It is followed by a char array of the string's
+ * characters. The array is not null-terminated. Finally the value field is written as 8 bytes
+ * in little endian.
+ */
+ PLANE_LAYOUTS = 15,
+
+ /**
+ * Can be used to get or set the dataspace of the buffer. The framework may attempt to set
+ * this value.
+ *
+ * The default dataspace is Dataspace::UNKNOWN. If this dataspace is set to any valid value
+ * other than Dataspace::UNKNOWN, this dataspace overrides all other dataspaces. For example,
+ * if the buffer has Dataspace::DISPLAY_P3 and it is being displayed on a composer Layer that
+ * is Dataspace::sRGB, the buffer should be treated as a DISPLAY_P3 buffer.
+ *
+ * The dataspace is a stable aidl android.hardware.graphics.common.Dataspace.
+ *
+ * When it is encoded into a byte stream, it is first cast to a int32_t and then represented in
+ * the byte stream by 4 bytes written in little endian.
+ */
+ DATASPACE = 16,
+
+ /**
+ * Can be used to get or set the BlendMode. The framework may attempt to set this value.
+ *
+ * The default blend mode is INVALID. If the BlendMode is set to any
+ * valid value other than INVALID, this BlendMode overrides all other
+ * dataspaces. For a longer description of this behavior see MetadataType::DATASPACE.
+ *
+ * The blend mode is a stable aidl android.hardware.graphics.common.BlendMode.
+ *
+ * When it is encoded into a byte stream, it is first cast to a int32_t and then represented by
+ * 4 bytes written in little endian.
+ */
+ BLEND_MODE = 17,
+}
diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
index a0745ce..a8e1480 100644
--- a/graphics/composer/2.1/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
@@ -369,10 +369,7 @@
accessRegion.top = accessRegionRect.top;
accessRegion.width = accessRegionRect.width;
accessRegion.height = accessRegionRect.height;
- int32_t bytesPerPixel;
- int32_t bytesPerStride;
- return mGralloc4->lock(bufferHandle, cpuUsage, accessRegion, acquireFence, &bytesPerPixel,
- &bytesPerStride);
+ return mGralloc4->lock(bufferHandle, cpuUsage, accessRegion, acquireFence);
} else if (mGralloc3) {
IMapper3::Rect accessRegion;
accessRegion.left = accessRegionRect.left;
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index 138d700..35162a6 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -93,17 +93,18 @@
}
protected:
- void beginCommand_2_2(IComposerClient::Command command, uint16_t length) {
- V2_1::CommandWriterBase::beginCommand(
- static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(command)), length);
- }
-
void writeFloatColor(const IComposerClient::FloatColor& color) {
writeFloat(color.r);
writeFloat(color.g);
writeFloat(color.b);
writeFloat(color.a);
}
+
+ private:
+ void beginCommand_2_2(IComposerClient::Command command, uint16_t length) {
+ V2_1::CommandWriterBase::beginCommand(
+ static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(command)), length);
+ }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
index 93da0a5..9b3aa90 100644
--- a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
@@ -173,6 +173,14 @@
Error getRenderIntents(Display display, ColorMode mode,
std::vector<RenderIntent>* outIntents) override {
if (!mDispatch.getRenderIntents) {
+ IComposerClient::DisplayType type;
+ if (getDisplayType(display, &type) == Error::BAD_DISPLAY) {
+ return Error::BAD_DISPLAY;
+ }
+ if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_P3) {
+ return Error::BAD_PARAMETER;
+ }
+
*outIntents = std::vector<RenderIntent>({RenderIntent::COLORIMETRIC});
return Error::NONE;
}
@@ -199,6 +207,9 @@
Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
if (!mDispatch.setColorModeWithRenderIntent) {
+ if (intent < RenderIntent::COLORIMETRIC || intent > RenderIntent::TONE_MAP_ENHANCE) {
+ return Error::BAD_PARAMETER;
+ }
if (intent != RenderIntent::COLORIMETRIC) {
return Error::UNSUPPORTED;
}
@@ -282,6 +293,7 @@
private:
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1::getColorModes;
+ using BaseType2_1::getDisplayType;
using BaseType2_1::mDevice;
using BaseType2_1::setColorMode;
using BaseType2_1::createVirtualDisplay;
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 21ba9f3..f987516 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -57,5 +57,6 @@
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
],
- test_suites: ["general-tests"],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 6a6f7de..044bd96 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -16,14 +16,15 @@
#define LOG_TAG "graphics_composer_hidl_hal_readback_tests@2.2"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.2/ComposerVts.h>
#include <composer-vts/2.2/ReadbackVts.h>
#include <composer-vts/2.2/RenderEngineVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
@@ -50,29 +51,12 @@
using V2_1::vts::TestCommandReader;
using vts::Gralloc;
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsComposerHidlEnvironment* Instance() {
- static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
- private:
- GraphicsComposerHidlEnvironment() {}
- GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsCompositionTest : public ::testing::VtsHalHidlTargetTestBase {
+class GraphicsCompositionTestBase : public ::testing::Test {
protected:
using PowerMode = V2_1::IComposerClient::PowerMode;
- void SetUp() override {
- VtsHalHidlTargetTestBase::SetUp();
+ void SetUpBase(const std::string& service_name) {
ASSERT_NO_FATAL_FAILURE(
- mComposer = std::make_unique<Composer>(
- GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ mComposer = std::make_unique<Composer>(IComposer::getService(service_name)));
ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
mComposerClient->registerCallback(mComposerCallback);
@@ -132,7 +116,6 @@
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
}
- VtsHalHidlTargetTestBase::TearDown();
}
void clearCommandReaderState() {
@@ -198,7 +181,13 @@
}
};
-TEST_F(GraphicsCompositionTest, SingleSolidColorLayer) {
+class GraphicsCompositionTest : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::string> {
+ public:
+ void SetUp() override { SetUpBase(GetParam()); }
+};
+
+TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -260,7 +249,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerBuffer) {
+TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -332,7 +321,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerBufferNoEffect) {
+TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -394,7 +383,7 @@
}
}
-TEST_F(GraphicsCompositionTest, ClientComposition) {
+TEST_P(GraphicsCompositionTest, ClientComposition) {
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
@@ -511,7 +500,7 @@
}
}
-TEST_F(GraphicsCompositionTest, DeviceAndClientComposition) {
+TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
ASSERT_NO_FATAL_FAILURE(
mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
@@ -637,7 +626,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerDamage) {
+TEST_P(GraphicsCompositionTest, SetLayerDamage) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -722,7 +711,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerPlaneAlpha) {
+TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -783,7 +772,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerSourceCrop) {
+TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -854,7 +843,7 @@
}
}
-TEST_F(GraphicsCompositionTest, SetLayerZOrder) {
+TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -941,18 +930,17 @@
}
}
-class GraphicsBlendModeCompositionTest : public GraphicsCompositionTest,
- public ::testing::WithParamInterface<float> {
+class GraphicsBlendModeCompositionTest
+ : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::tuple<string, string>> {
public:
void SetUp() override {
- GraphicsCompositionTest::SetUp();
+ SetUpBase(std::get<0>(GetParam()));
mTestColorModes = {ColorMode::SRGB}; // TODO: add more color mode support
mBackgroundColor = BLACK;
mTopLayerColor = RED;
}
- void TearDown() override { GraphicsCompositionTest::TearDown(); }
-
void setBackgroundColor(IComposerClient::Color color) { mBackgroundColor = color; }
void setTopLayerColor(IComposerClient::Color color) { mTopLayerColor = color; }
@@ -977,7 +965,7 @@
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
layer->setBlendMode(blendMode);
- layer->setAlpha(GetParam());
+ layer->setAlpha(std::stof(std::get<1>(GetParam())));
mLayers.push_back(backgroundLayer);
mLayers.push_back(layer);
@@ -1023,7 +1011,8 @@
IComposerClient::Color mTopLayerColor;
};
-TEST_P(GraphicsBlendModeCompositionTest, None) {
+// TODO(b/145557764): Re-enable after the bug is fixed.
+TEST_P(GraphicsBlendModeCompositionTest, DISABLED_None) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1188,9 +1177,6 @@
}
}
-INSTANTIATE_TEST_CASE_P(BlendModeTest, GraphicsBlendModeCompositionTest,
- ::testing::Values(.2, 1.0));
-
class GraphicsTransformCompositionTest : public GraphicsCompositionTest {
protected:
void SetUp() override {
@@ -1229,7 +1215,7 @@
int mSideLength;
};
-TEST_F(GraphicsTransformCompositionTest, FLIP_H) {
+TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1284,7 +1270,7 @@
}
}
-TEST_F(GraphicsTransformCompositionTest, FLIP_V) {
+TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1339,7 +1325,7 @@
}
}
-TEST_F(GraphicsTransformCompositionTest, ROT_180) {
+TEST_P(GraphicsTransformCompositionTest, ROT_180) {
for (ColorMode mode : mTestColorModes) {
std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---"
<< std::endl;
@@ -1395,6 +1381,23 @@
}
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsCompositionTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_CASE_P(
+ BlendModeTest, GraphicsBlendModeCompositionTest,
+ testing::Combine(
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ testing::Values("0.2", "1.0")),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsTransformCompositionTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // anonymous namespace
} // namespace vts
} // namespace V2_2
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 51832f9..95a0f69 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -16,12 +16,14 @@
#define LOG_TAG "graphics_composer_hidl_hal_test@2.2"
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.2/ComposerVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.0/MapperVts.h>
namespace android {
@@ -41,29 +43,11 @@
using common::V1_1::RenderIntent;
using mapper::V2_0::IMapper;
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsComposerHidlEnvironment* Instance() {
- static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
- private:
- GraphicsComposerHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(
- mComposer = std::make_unique<Composer>(
- GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
@@ -188,7 +172,7 @@
/**
* Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
*/
-TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -239,7 +223,7 @@
/**
* Test IComposerClient::getPerFrameMetadataKeys.
*/
-TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
+TEST_P(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
std::vector<IComposerClient::PerFrameMetadataKey> keys;
Error error = Error::NONE;
mComposerClient->getRaw()->getPerFrameMetadataKeys(
@@ -261,7 +245,7 @@
*
* Test that virtual displays can be created and has the correct display type.
*/
-TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
+TEST_P(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
GTEST_SUCCEED() << "no virtual display support";
return;
@@ -286,7 +270,7 @@
* Test that IComposerClient::getClientTargetSupport returns true for the
* required client targets.
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -310,7 +294,7 @@
* Error::BAD_DISPLAY when passed in an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2BadDisplay) {
std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -332,7 +316,7 @@
/**
* Test IComposerClient::setPowerMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2) {
std::vector<IComposerClient::PowerMode> modes;
modes.push_back(IComposerClient::PowerMode::OFF);
modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
@@ -349,7 +333,7 @@
* Test that IComposerClient::setPowerMode_2_2 succeeds for different varations
* of PowerMode
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2Variations) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2Variations) {
std::vector<IComposerClient::PowerMode> modes;
modes.push_back(IComposerClient::PowerMode::OFF);
@@ -404,7 +388,7 @@
* Tests that IComposerClient::setPowerMode_2_2 returns BAD_DISPLAY when passed an
* invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2BadDisplay) {
Error error = mComposerClient->getRaw()->setPowerMode_2_2(mInvalidDisplayId,
IComposerClient::PowerMode::ON);
ASSERT_EQ(Error::BAD_DISPLAY, error);
@@ -416,7 +400,7 @@
* Test that IComposerClient::setPowerMode_2_2 returns BAD_PARAMETER when passed
* an invalid PowerMode
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2BadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2BadParameter) {
Error error = mComposerClient->getRaw()->setPowerMode_2_2(
mPrimaryDisplay, static_cast<IComposerClient::PowerMode>(-1));
ASSERT_EQ(Error::BAD_PARAMETER, error);
@@ -428,7 +412,7 @@
* Test that IComposerClient::setPowerMode_2_2 returns UNSUPPORTED when passed
* DOZE or DOZE_SUPPORT on a device that does not support these modes
*/
-TEST_F(GraphicsComposerHidlTest, SetPowerMode_2_2Unsupported) {
+TEST_P(GraphicsComposerHidlTest, SetPowerMode_2_2Unsupported) {
if (!mComposerClient->getDozeSupport(mPrimaryDisplay)) {
Error error = mComposerClient->getRaw()->setPowerMode_2_2(mPrimaryDisplay,
IComposerClient::PowerMode::DOZE);
@@ -445,7 +429,7 @@
*
* Test IComposerClient::setReadbackBuffer
*/
-TEST_F(GraphicsComposerHidlTest, SetReadbackBuffer) {
+TEST_P(GraphicsComposerHidlTest, SetReadbackBuffer) {
if (!mHasReadbackBuffer) {
return;
}
@@ -469,7 +453,7 @@
* Test that IComposerClient::setReadbackBuffer returns an Error::BAD_DISPLAY
* when passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) {
if (!mHasReadbackBuffer) {
return;
}
@@ -493,7 +477,7 @@
* Test that IComposerClient::setReadbackBuffer returns Error::BAD_PARAMETER
* when passed an invalid buffer handle
*/
-TEST_F(GraphicsComposerHidlTest, SetReadbackBufferBadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadParameter) {
if (!mHasReadbackBuffer) {
return;
}
@@ -502,7 +486,7 @@
ASSERT_EQ(Error::BAD_PARAMETER, error);
}
-TEST_F(GraphicsComposerHidlTest, GetReadbackBufferFenceInactive) {
+TEST_P(GraphicsComposerHidlTest, GetReadbackBufferFenceInactive) {
if (!mHasReadbackBuffer) {
return;
}
@@ -516,7 +500,7 @@
/**
* Test IComposerClient::Command::SET_LAYER_FLOAT_COLOR.
*/
-TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
V2_1::Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -554,7 +538,7 @@
/**
* Test IComposerClient::getDataspaceSaturationMatrix.
*/
-TEST_F(GraphicsComposerHidlTest, GetDataspaceSaturationMatrix) {
+TEST_P(GraphicsComposerHidlTest, GetDataspaceSaturationMatrix) {
auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
// the last row is known
ASSERT_EQ(0.0f, matrix[12]);
@@ -570,7 +554,7 @@
* Error::BAD_PARAMETER when passed a dataspace other than
* Dataspace::SRGB_LINEAR
*/
-TEST_F(GraphicsComposerHidlTest, GetDataspaceSaturationMatrixBadParameter) {
+TEST_P(GraphicsComposerHidlTest, GetDataspaceSaturationMatrixBadParameter) {
mComposerClient->getRaw()->getDataspaceSaturationMatrix(
Dataspace::UNKNOWN,
[&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_PARAMETER, tmpError); });
@@ -579,7 +563,7 @@
/**
* Test IComposerClient::getColorMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2) {
+TEST_P(GraphicsComposerHidlTest, GetColorMode_2_2) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
auto nativeMode = std::find(modes.cbegin(), modes.cend(), ColorMode::NATIVE);
@@ -592,7 +576,7 @@
* Test that IComposerClient::getColorMode returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetColorMode_2_2BadDisplay) {
mComposerClient->getRaw()->getColorModes_2_2(
mInvalidDisplayId,
[&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
@@ -601,7 +585,7 @@
/**
* Test IComposerClient::getRenderIntents.
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -631,7 +615,7 @@
* Test that IComposerClient::getRenderIntent returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntentsBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntentsBadDisplay) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
mComposerClient->getRaw()->getRenderIntents(
@@ -646,7 +630,7 @@
* Test that IComposerClient::getRenderIntents returns Error::BAD_PARAMETER when
* pased either an invalid Color mode or an invalid Render Intent
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntentsBadParameter) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntentsBadParameter) {
mComposerClient->getRaw()->getRenderIntents(
mPrimaryDisplay, static_cast<ColorMode>(-1),
[&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
@@ -655,7 +639,7 @@
/**
* Test IComposerClient::setColorMode_2_2.
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2) {
std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -674,7 +658,7 @@
* Test that IComposerClient::setColorMode_2_2 returns an Error::BAD_DISPLAY
* when passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadDisplay) {
Error error = mComposerClient->getRaw()->setColorMode_2_2(mInvalidDisplayId, ColorMode::NATIVE,
RenderIntent::COLORIMETRIC);
@@ -687,7 +671,7 @@
* Test that IComposerClient::setColorMode_2_2 returns Error::BAD_PARAMETER when
* passed an invalid Color mode or an invalid render intent
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) {
Error colorModeError = mComposerClient->getRaw()->setColorMode_2_2(
mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
@@ -697,6 +681,16 @@
EXPECT_EQ(Error::BAD_PARAMETER, renderIntentError);
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlCommandTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace
} // namespace vts
} // namespace V2_2
@@ -704,12 +698,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::composer::V2_2::vts::GraphicsComposerHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 11863fa..3dfda19 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -79,6 +79,7 @@
void setLayerPerFrameMetadataBlobs(
const hidl_vec<IComposerClient::PerFrameMetadataBlob>& metadata) {
+ // in units of uint32_t's
size_t commandLength = 0;
if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
@@ -86,12 +87,12 @@
return;
}
- // number of blobs
- commandLength += metadata.size();
+ // space for numElements
+ commandLength += 1;
for (auto metadataBlob : metadata) {
- commandLength += sizeof(int32_t); // key of metadata blob
- commandLength += 1; // size information of metadata blob
+ commandLength += 1; // key of metadata blob
+ commandLength += 1; // size information of metadata blob
// metadata content size
size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
@@ -119,17 +120,18 @@
}
protected:
- void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
- V2_2::CommandWriterBase::beginCommand_2_2(
- static_cast<V2_2::IComposerClient::Command>(static_cast<int32_t>(command)), length);
- }
-
void writeBlob(uint32_t length, const unsigned char* blob) {
memcpy(&mData[mDataWritten], blob, length);
uint32_t numElements = length / 4;
mDataWritten += numElements;
mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
}
+
+ private:
+ void beginCommand_2_3(IComposerClient::Command command, uint16_t length) {
+ V2_1::CommandWriterBase::beginCommand(
+ static_cast<V2_1::IComposerClient::Command>(static_cast<int32_t>(command)), length);
+ }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
index 0d4e5b8..e5ac842 100644
--- a/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
+++ b/graphics/composer/2.3/utils/vts/include/composer-vts/2.3/ComposerVts.h
@@ -49,12 +49,10 @@
public:
Composer();
explicit Composer(const std::string& name);
+ explicit Composer(const sp<IComposer>& composer);
std::unique_ptr<ComposerClient> createClient();
- protected:
- explicit Composer(const sp<IComposer>& composer);
-
private:
const sp<IComposer> mComposer;
};
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index b729062..fa4823e 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -49,4 +49,6 @@
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.3-command-buffer",
],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index dafe587..94766af 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -18,13 +18,15 @@
#include <algorithm>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
#include <composer-vts/2.1/GraphicsComposerCallback.h>
#include <composer-vts/2.1/TestCommandReader.h>
#include <composer-vts/2.3/ComposerVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.0/MapperVts.h>
namespace android {
@@ -43,29 +45,11 @@
using mapper::V2_0::IMapper;
using V2_2::vts::Gralloc;
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsComposerHidlEnvironment* Instance() {
- static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
- private:
- GraphicsComposerHidlEnvironment() {}
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(
- mComposer = std::make_unique<Composer>(
- GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+ mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
@@ -175,7 +159,7 @@
*
* TODO: Check that ports are unique for multiple displays.
*/
-TEST_F(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
+TEST_P(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
uint8_t port0;
std::vector<uint8_t> data0;
if (mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) {
@@ -193,7 +177,7 @@
/**
* Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
*/
-TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -244,7 +228,7 @@
/**
* Test IComposerClient::getHdrCapabilities_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetHdrCapabilities_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetHdrCapabilities_2_3) {
float maxLuminance;
float maxAverageLuminance;
float minLuminance;
@@ -256,7 +240,7 @@
/**
* Test IComposerClient::getPerFrameMetadataKeys_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetPerFrameMetadataKeys_2_3) {
std::vector<IComposerClient::PerFrameMetadataKey> keys;
mComposerClient->getRaw()->getPerFrameMetadataKeys_2_3(
mPrimaryDisplay, [&](const auto tmpError, const auto outKeys) {
@@ -270,7 +254,7 @@
/**
* TestIComposerClient::getReadbackBufferAttributes_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetReadbackBufferAttributes_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetReadbackBufferAttributes_2_3) {
Dataspace dataspace;
PixelFormat pixelFormat;
@@ -288,7 +272,7 @@
/**
* Test IComposerClient::getClientTargetSupport_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -311,7 +295,7 @@
* Error::BAD_DISPLAY when passed in an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_3BadDisplay) {
std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
for (auto config : configs) {
int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
@@ -333,7 +317,7 @@
/**
* Test IComposerClient::getRenderIntents_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents_2_3) {
std::vector<ColorMode> modes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
for (auto mode : modes) {
std::vector<RenderIntent> intents =
@@ -363,7 +347,7 @@
* Test that IComposerClient::getRenderIntents_2_3 returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents_2_3BadDisplay) {
std::vector<ColorMode> modes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
for (auto mode : modes) {
mComposerClient->getRaw()->getRenderIntents_2_3(
@@ -378,7 +362,7 @@
* Test that IComposerClient::getRenderIntents_2_3 returns Error::BAD_PARAMETER when
* pased either an invalid Color mode or an invalid Render Intent
*/
-TEST_F(GraphicsComposerHidlTest, GetRenderIntents_2_3BadParameter) {
+TEST_P(GraphicsComposerHidlTest, GetRenderIntents_2_3BadParameter) {
mComposerClient->getRaw()->getRenderIntents_2_3(
mPrimaryDisplay, static_cast<ColorMode>(-1),
[&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::BAD_PARAMETER, tmpError); });
@@ -387,7 +371,7 @@
/**
* IComposerClient::getColorModes_2_3
*/
-TEST_F(GraphicsComposerHidlTest, GetColorModes_2_3) {
+TEST_P(GraphicsComposerHidlTest, GetColorModes_2_3) {
std::vector<ColorMode> colorModes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
@@ -400,7 +384,7 @@
* Test that IComposerClient::getColorModes_2_3 returns Error::BAD_DISPLAY when
* passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, GetColorMode_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, GetColorMode_2_3BadDisplay) {
mComposerClient->getRaw()->getColorModes_2_3(
mInvalidDisplayId,
[&](const auto& tmpError, const auto&) { ASSERT_EQ(Error::BAD_DISPLAY, tmpError); });
@@ -409,7 +393,7 @@
/**
* IComposerClient::setColorMode_2_3
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_3) {
std::vector<ColorMode> colorModes = mComposerClient->getColorModes_2_3(mPrimaryDisplay);
for (auto mode : colorModes) {
std::vector<RenderIntent> intents =
@@ -430,7 +414,7 @@
* Test that IComposerClient::setColorMode_2_3 returns an Error::BAD_DISPLAY
* when passed an invalid display handle
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_3BadDisplay) {
Error error = mComposerClient->getRaw()->setColorMode_2_3(mInvalidDisplayId, ColorMode::NATIVE,
RenderIntent::COLORIMETRIC);
@@ -443,7 +427,7 @@
* Test that IComposerClient::setColorMode_2_3 returns Error::BAD_PARAMETER when
* passed an invalid Color mode or an invalid render intent
*/
-TEST_F(GraphicsComposerHidlTest, SetColorMode_2_3BadParameter) {
+TEST_P(GraphicsComposerHidlTest, SetColorMode_2_3BadParameter) {
Error colorModeError = mComposerClient->getRaw()->setColorMode_2_3(
mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
EXPECT_EQ(Error::BAD_PARAMETER, colorModeError);
@@ -458,7 +442,7 @@
* TODO Add color to the layer, use matrix to keep only red component,
* and check.
*/
-TEST_F(GraphicsComposerHidlTest, SetLayerColorTransform) {
+TEST_P(GraphicsComposerHidlTest, SetLayerColorTransform) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -485,7 +469,7 @@
}
}
-TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
+TEST_P(GraphicsComposerHidlTest, GetDisplayedContentSamplingAttributes) {
int constexpr invalid = -1;
auto format = static_cast<PixelFormat>(invalid);
auto dataspace = static_cast<Dataspace>(invalid);
@@ -505,7 +489,7 @@
static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid));
};
-TEST_F(GraphicsComposerHidlTest, SetDisplayedContentSamplingEnabled) {
+TEST_P(GraphicsComposerHidlTest, SetDisplayedContentSamplingEnabled) {
auto const maxFrames = 10;
auto const enableAllComponents = 0;
auto error = mComposerClient->setDisplayedContentSamplingEnabled(
@@ -523,7 +507,7 @@
EXPECT_EQ(error, Error::NONE);
}
-TEST_F(GraphicsComposerHidlTest, GetDisplayedContentSample) {
+TEST_P(GraphicsComposerHidlTest, GetDisplayedContentSample) {
int constexpr invalid = -1;
auto format = static_cast<PixelFormat>(invalid);
auto dataspace = static_cast<Dataspace>(invalid);
@@ -558,7 +542,7 @@
* getDisplayCapabilities is required in composer 2.3
* Test some constraints.
*/
-TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBasic) {
+TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBasic) {
std::vector<IComposerClient::DisplayCapability> capabilities;
const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
ASSERT_EQ(Error::NONE, error);
@@ -572,13 +556,13 @@
EXPECT_EQ(mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay), hasBrightnessSupport);
}
-TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
std::vector<IComposerClient::DisplayCapability> capabilities;
const auto error = mComposerClient->getDisplayCapabilities(mInvalidDisplayId, &capabilities);
EXPECT_EQ(Error::BAD_DISPLAY, error);
}
-TEST_F(GraphicsComposerHidlTest, SetLayerPerFrameMetadataBlobs) {
+TEST_P(GraphicsComposerHidlTest, SetLayerPerFrameMetadataBlobs) {
Layer layer;
ASSERT_NO_FATAL_FAILURE(layer =
mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -604,7 +588,7 @@
/*
* Test that if brightness operations are supported, setDisplayBrightness works as expected.
*/
-TEST_F(GraphicsComposerHidlTest, setDisplayBrightness) {
+TEST_P(GraphicsComposerHidlTest, setDisplayBrightness) {
std::vector<IComposerClient::DisplayCapability> capabilities;
const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
ASSERT_EQ(Error::NONE, error);
@@ -627,6 +611,16 @@
EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f), Error::BAD_PARAMETER);
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerHidlCommandTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace
} // namespace vts
} // namespace V2_3
@@ -634,12 +628,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::composer::V2_3::vts::GraphicsComposerHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- return status;
-}
diff --git a/graphics/composer/2.4/IComposerCallback.hal b/graphics/composer/2.4/IComposerCallback.hal
index 5c3f8bd..fea24a1 100644
--- a/graphics/composer/2.4/IComposerCallback.hal
+++ b/graphics/composer/2.4/IComposerCallback.hal
@@ -32,4 +32,14 @@
* is expected to be called vsyncPeriodNanos nanoseconds after this call.
*/
oneway onVsync_2_4(Display display, int64_t timestamp, VsyncPeriodNanos vsyncPeriodNanos);
+
+ /**
+ * Notifies the client that the previously reported timing for vsync period change has been
+ * updated. This may occur if the composer missed the deadline for changing the vsync period
+ * or the client submitted a refresh frame too late.
+ *
+ * @param display is the display which vsync period change is in progress
+ * @param updatedTimeline is the new timeline for the vsync period change.
+ */
+ oneway onVsyncPeriodTimingChanged(Display display, VsyncPeriodChangeTimeline updatedTimeline);
};
diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal
index c2102d5..f23536c 100644
--- a/graphics/composer/2.4/IComposerClient.hal
+++ b/graphics/composer/2.4/IComposerClient.hal
@@ -20,10 +20,23 @@
import @2.1::Config;
import @2.1::Display;
import @2.1::Error;
+import @2.1::IComposerClient;
import @2.3::IComposerClient;
interface IComposerClient extends @2.3::IComposerClient {
/**
+ * Display attributes queryable through getDisplayAttribute_2_4.
+ */
+ enum Attribute : @2.1::IComposerClient.Attribute {
+ /**
+ * The configuration group ID (as int32_t) this config is associated to.
+ * Switching between configurations within the same group may be done seamlessly
+ * in some conditions via setActiveConfigWithConstraints.
+ */
+ CONFIG_GROUP = 7,
+ };
+
+ /**
* Required capabilities which are supported by the display. The
* particular set of supported capabilities for a given display may be
* retrieved using getDisplayCapabilities.
@@ -60,6 +73,7 @@
* (i.e., the vsync period must not change before this time).
*/
int64_t desiredTimeNanos;
+
/**
* If true, requires that the vsync period change must happen seamlessly without
* a noticeable visual artifact.
@@ -74,7 +88,6 @@
*
* @param callback is the IComposerCallback object.
*/
- @entry
registerCallback_2_4(IComposerCallback callback);
/**
@@ -99,25 +112,29 @@
getDisplayConnectionType(Display display) generates (Error error, DisplayConnectionType type);
/**
- * Provides a list of the vsync periods supported by the display in the given configuration
+ * Returns a display attribute value for a particular display
+ * configuration.
*
- * @param display is the display for which the vsync periods are queried.
- * @param config is the display configuration for which the vsync periods are queried.
- *
+ * @param display is the display to query.
+ * @param config is the display configuration for which to return
+ * attribute values.
* @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_CONFIG when an invalid config handle was passed in.
- * @return supportedVsyncPeriods is a list of supported vsync periods.
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_CONFIG when config does not name a valid configuration for
+ * this display.
+ * BAD_PARAMETER when attribute is unrecognized.
+ * UNSUPPORTED when attribute cannot be queried for the config.
+ * @return value is the value of the attribute.
*/
- getSupportedDisplayVsyncPeriods(Display display, Config config)
- generates (Error error, vec<VsyncPeriodNanos> supportedVsyncPeriods);
+ getDisplayAttribute_2_4(Display display, Config config, Attribute attribute)
+ generates (Error error, int32_t value);
/**
* Retrieves which vsync period the display is currently using.
*
* If no display configuration is currently active, this function must
* return BAD_CONFIG. If the vsync period is about to change due to a
- * setActiveConfigAndVsyncPeriod call, this function must return the current vsync period
+ * setActiveConfigWithConstraints call, this function must return the current vsync period
* until the change takes place.
*
* @param display is the display for which the vsync period is queried.
@@ -131,7 +148,8 @@
/**
* Sets the active configuration and the refresh rate for this display.
- * If the config is the same as the current config, only the vsync period shall change.
+ * If the new config shares the same config group as the current config,
+ * only the vsync period shall change.
* Upon returning, the given display configuration, except vsync period, must be active and
* remain so until either this function is called again or the display is disconnected.
* When the display starts to refresh at the new vsync period, onVsync_2_4 callback must be
@@ -139,21 +157,19 @@
*
* @param display is the display for which the active config is set.
* @param config is the new display configuration.
- * @param vsyncPeriodNanos is the new display vsync period.
* @param vsyncPeriodChangeConstraints are the constraints required for changing vsync period.
*
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* BAD_CONFIG when the configuration handle passed in is not valid
* for this display.
- * BAD_VSYNC_PERIOD when an invalid vsync period is passed in.
+ * SEAMLESS_NOT_ALLOWED when seamlessRequired was true but config provided doesn't
+ * share the same config group as the current config.
* SEAMLESS_NOT_POSSIBLE when seamlessRequired was true but the display cannot achieve
* the vsync period change without a noticeable visual artifact.
- * @return newVsyncAppliedTime is the time in CLOCK_MONOTONIC when the new display will start to
- * refresh at the new vsync period.
+ * @return timeline is the timeline for the vsync period change.
*/
- setActiveConfigAndVsyncPeriod(Display display, Config config,
- VsyncPeriodNanos vsyncPeriodNanos,
+ setActiveConfigWithConstraints(Display display, Config config,
VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints)
- generates (Error error, int64_t newVsyncAppliedTime);
+ generates (Error error, VsyncPeriodChangeTimeline timeline);
};
diff --git a/graphics/composer/2.4/types.hal b/graphics/composer/2.4/types.hal
index b45d7a6..065f024 100644
--- a/graphics/composer/2.4/types.hal
+++ b/graphics/composer/2.4/types.hal
@@ -20,13 +20,36 @@
enum Error : @2.1::Error {
/**
- * Invalid vsync period
+ * Seamless cannot be required for configurations that don't share a config group
*/
- BAD_VSYNC_PERIOD = 9,
+ SEAMLESS_NOT_ALLOWED = 9,
/**
* Seamless requirements cannot be met
*/
SEAMLESS_NOT_POSSIBLE = 10,
};
+/**
+ * Timing for a vsync period change.
+ */
+struct VsyncPeriodChangeTimeline {
+ /**
+ * The time in CLOCK_MONOTONIC when the new display will start to refresh at
+ * the new vsync period.
+ */
+ int64_t newVsyncAppliedTimeNanos;
+
+ /**
+ * Set to true if the client is required to send a frame to be displayed before
+ * the change can take place.
+ */
+ bool refreshRequired;
+
+ /**
+ * The time in CLOCK_MONOTONIC when the client is expected to send the new frame.
+ * Should be ignored if refreshRequired is false.
+ */
+ int64_t refreshTimeNanos;
+};
+
typedef uint32_t VsyncPeriodNanos;
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index ddf209b..4160ed9 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -76,6 +76,13 @@
ALOGE_IF(!ret.isOk(), "failed to send onVsync_2_4: %s", ret.description().c_str());
}
+ void onVsyncPeriodTimingChanged(Display display,
+ const VsyncPeriodChangeTimeline& updatedTimeline) override {
+ auto ret = mCallback->onVsyncPeriodTimingChanged(display, updatedTimeline);
+ ALOGE_IF(!ret.isOk(), "failed to send onVsyncPeriodTimingChanged: %s",
+ ret.description().c_str());
+ }
+
protected:
const sp<IComposerCallback> mCallback;
V2_1::hal::ComposerResources* const mResources;
@@ -104,13 +111,12 @@
return Void();
}
- Return<void> getSupportedDisplayVsyncPeriods(
- Display display, Config config,
- IComposerClient::getSupportedDisplayVsyncPeriods_cb hidl_cb) override {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
- Error error =
- mHal->getSupportedDisplayVsyncPeriods(display, config, &supportedVsyncPeriods);
- hidl_cb(error, supportedVsyncPeriods);
+ Return<void> getDisplayAttribute_2_4(
+ Display display, Config config, IComposerClient::Attribute attribute,
+ IComposerClient::getDisplayAttribute_2_4_cb hidl_cb) override {
+ int32_t value = 0;
+ Error error = mHal->getDisplayAttribute_2_4(display, config, attribute, &value);
+ hidl_cb(error, value);
return Void();
}
@@ -122,15 +128,14 @@
return Void();
}
- Return<void> setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ Return<void> setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- IComposerClient::setActiveConfigAndVsyncPeriod_cb hidl_cb) override {
- int64_t newVsyncAppliedTime = 0;
- Error error = mHal->setActiveConfigAndVsyncPeriod(display, config, vsyncPeriodNanos,
- vsyncPeriodChangeConstraints,
- &newVsyncAppliedTime);
- hidl_cb(error, newVsyncAppliedTime);
+ IComposerClient::setActiveConfigWithConstraints_cb hidl_cb) override {
+ VsyncPeriodChangeTimeline timeline = {};
+ Error error = mHal->setActiveConfigWithConstraints(display, config,
+ vsyncPeriodChangeConstraints, &timeline);
+ hidl_cb(error, timeline);
return Void();
}
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
index 0739f62..89dbe66 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
@@ -47,6 +47,8 @@
virtual void onVsync(Display display, int64_t timestamp) = 0;
virtual void onVsync_2_4(Display display, int64_t timestamp,
VsyncPeriodNanos vsyncPeriodNanos) = 0;
+ virtual void onVsyncPeriodTimingChanged(Display display,
+ const VsyncPeriodChangeTimeline& timeline) = 0;
};
virtual void registerEventCallback_2_4(EventCallback_2_4* callback) = 0;
@@ -57,13 +59,14 @@
Display display, std::vector<IComposerClient::DisplayCapability>* outCapabilities) = 0;
virtual Error getDisplayConnectionType(Display display,
IComposerClient::DisplayConnectionType* outType) = 0;
- virtual Error getSupportedDisplayVsyncPeriods(
- Display display, Config config, std::vector<VsyncPeriodNanos>* outVsyncPeriod) = 0;
+ virtual Error getDisplayAttribute_2_4(Display display, Config config,
+ IComposerClient::Attribute attribute,
+ int32_t* outValue) = 0;
virtual Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) = 0;
- virtual Error setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ virtual Error setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime) = 0;
+ VsyncPeriodChangeTimeline* timeline) = 0;
};
} // namespace hal
diff --git a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
index 3420c8c..d59d0d5 100644
--- a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
+++ b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
@@ -25,6 +25,7 @@
#include <android/hardware/graphics/composer/2.4/IComposerClient.h>
#include <composer-hal/2.4/ComposerHal.h>
#include <composer-passthrough/2.3/HwcHal.h>
+#include <hardware/hwcomposer_defs.h>
namespace android {
namespace hardware {
@@ -51,14 +52,22 @@
void registerEventCallback_2_4(hal::ComposerHal::EventCallback_2_4* callback) override {
mEventCallback_2_4 = callback;
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
- reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
- reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
- reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this,
- reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_HOTPLUG, this,
+ reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_REFRESH, this,
+ reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_VSYNC, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_VSYNC_2_4, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook));
+
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsyncPeriodTimingChangedHook));
}
void unregisterEventCallback_2_4() override {
@@ -69,10 +78,12 @@
// - will never be called afterward
//
// which is likely incorrect
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr);
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr);
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr);
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED,
+ this, nullptr);
mEventCallback_2_4 = nullptr;
}
@@ -106,26 +117,16 @@
return static_cast<Error>(error);
}
- Error getSupportedDisplayVsyncPeriods(Display display, Config config,
- std::vector<VsyncPeriodNanos>* outVsyncPeriods) override {
- if (!mDispatch.getSupportedDisplayVsyncPeriods) {
- return Error::UNSUPPORTED;
+ Error getDisplayAttribute_2_4(Display display, Config config,
+ IComposerClient::Attribute attribute,
+ int32_t* outValue) override {
+ int32_t err = BaseType2_1::mDispatch.getDisplayAttribute(
+ mDevice, display, config, static_cast<int32_t>(attribute), outValue);
+ if (err != HWC2_ERROR_NONE && *outValue == -1) {
+ // Convert the error from hwcomposer2 to IComposerClient definition
+ return Error::BAD_PARAMETER;
}
-
- uint32_t count = 0;
- int32_t error = mDispatch.getSupportedDisplayVsyncPeriods(mDevice, display, config, &count,
- nullptr);
- if (error != HWC2_ERROR_NONE) {
- return static_cast<Error>(error);
- }
- outVsyncPeriods->resize(count);
- error = mDispatch.getSupportedDisplayVsyncPeriods(mDevice, display, config, &count,
- outVsyncPeriods->data());
- if (error != HWC2_ERROR_NONE) {
- *outVsyncPeriods = std::vector<VsyncPeriodNanos>();
- return static_cast<Error>(error);
- }
- return Error::NONE;
+ return static_cast<Error>(err);
}
Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) override {
@@ -140,11 +141,11 @@
return Error::NONE;
}
- Error setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ Error setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime) override {
- if (!mDispatch.setActiveConfigAndVsyncPeriod) {
+ VsyncPeriodChangeTimeline* timeline) override {
+ if (!mDispatch.setActiveConfigWithConstraints) {
return Error::UNSUPPORTED;
}
@@ -154,12 +155,15 @@
vsync_period_change_constraints.seamlessRequired =
vsyncPeriodChangeConstraints.seamlessRequired;
- int32_t error = mDispatch.setActiveConfigAndVsyncPeriod(
- mDevice, display, config, vsyncPeriodNanos, &vsync_period_change_constraints,
- outNewVsyncAppliedTime);
+ hwc_vsync_period_change_timeline_t out_timeline;
+ int32_t error = mDispatch.setActiveConfigWithConstraints(
+ mDevice, display, config, &vsync_period_change_constraints, &out_timeline);
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
+ timeline->newVsyncAppliedTimeNanos = out_timeline.newVsyncAppliedTimeNanos;
+ timeline->refreshRequired = out_timeline.refreshRequired;
+ timeline->refreshTimeNanos = out_timeline.refreshTimeNanos;
return Error::NONE;
}
@@ -171,13 +175,10 @@
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE,
&mDispatch.getDisplayConnectionType);
- this->initOptionalDispatch(HWC2_FUNCTION_REGISTER_CALLBACK, &mDispatch.registerCallback);
- this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_DISPLAY_VSYNC_PERIODS,
- &mDispatch.getSupportedDisplayVsyncPeriods);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD,
&mDispatch.getDisplayVsyncPeriod);
- this->initOptionalDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_AND_VSYNC_PERIOD,
- &mDispatch.setActiveConfigAndVsyncPeriod);
+ this->initOptionalDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,
+ &mDispatch.setActiveConfigWithConstraints);
return true;
}
@@ -205,13 +206,22 @@
hal->mEventCallback_2_4->onVsync_2_4(display, timestamp, vsyncPeriodNanos);
}
+ static void vsyncPeriodTimingChangedHook(hwc2_callback_data_t callbackData,
+ hwc2_display_t display,
+ hwc_vsync_period_change_timeline_t* updated_timeline) {
+ auto hal = static_cast<HwcHalImpl*>(callbackData);
+ VsyncPeriodChangeTimeline timeline;
+ timeline.newVsyncAppliedTimeNanos = updated_timeline->newVsyncAppliedTimeNanos;
+ timeline.refreshRequired = updated_timeline->refreshRequired;
+ timeline.refreshTimeNanos = updated_timeline->refreshTimeNanos;
+ hal->mEventCallback_2_4->onVsyncPeriodTimingChanged(display, timeline);
+ }
+
private:
struct {
HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE getDisplayConnectionType;
- HWC2_PFN_REGISTER_CALLBACK registerCallback;
- HWC2_PFN_GET_SUPPORTED_DISPLAY_VSYNC_PERIODS getSupportedDisplayVsyncPeriods;
HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD getDisplayVsyncPeriod;
- HWC2_PFN_SET_ACTIVE_CONFIG_AND_VSYNC_PERIOD setActiveConfigAndVsyncPeriod;
+ HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS setActiveConfigWithConstraints;
} mDispatch = {};
hal::ComposerHal::EventCallback_2_4* mEventCallback_2_4 = nullptr;
diff --git a/graphics/composer/2.4/utils/vts/ComposerVts.cpp b/graphics/composer/2.4/utils/vts/ComposerVts.cpp
index b02a59a..35ac23f 100644
--- a/graphics/composer/2.4/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.4/utils/vts/ComposerVts.cpp
@@ -70,15 +70,18 @@
return error;
}
-Error ComposerClient::getSupportedDisplayVsyncPeriods(
- Display display, Config config, std::vector<VsyncPeriodNanos>* outSupportedVsyncPeriods) {
- Error error = Error::NONE;
- mClient->getSupportedDisplayVsyncPeriods(
- display, config, [&](const auto& tmpError, const auto& tmpSupportedVsyncPeriods) {
- error = tmpError;
- *outSupportedVsyncPeriods = tmpSupportedVsyncPeriods;
+int32_t ComposerClient::getDisplayAttribute_2_4(
+ android::hardware::graphics::composer::V2_1::Display display,
+ android::hardware::graphics::composer::V2_1::Config config,
+ IComposerClient::Attribute attribute) {
+ int32_t value = 0;
+ mClient->getDisplayAttribute_2_4(
+ display, config, attribute, [&](const auto& tmpError, const auto& tmpValue) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get display attribute";
+ value = tmpValue;
});
- return error;
+
+ return value;
}
Error ComposerClient::getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) {
@@ -90,17 +93,16 @@
return error;
}
-Error ComposerClient::setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+Error ComposerClient::setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime) {
+ VsyncPeriodChangeTimeline* timeline) {
Error error = Error::NONE;
- mClient->setActiveConfigAndVsyncPeriod(
- display, config, vsyncPeriodNanos, vsyncPeriodChangeConstraints,
- [&](const auto& tmpError, const auto& tmpNewVsyncAppliedTime) {
- error = tmpError;
- *outNewVsyncAppliedTime = tmpNewVsyncAppliedTime;
- });
+ mClient->setActiveConfigWithConstraints(display, config, vsyncPeriodChangeConstraints,
+ [&](const auto& tmpError, const auto& tmpTimeline) {
+ error = tmpError;
+ *timeline = tmpTimeline;
+ });
return error;
}
diff --git a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
index 5db3e16..83e74ed 100644
--- a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
+++ b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
@@ -74,15 +74,15 @@
Error getDisplayConnectionType(Display display,
IComposerClient::DisplayConnectionType* outType);
- Error getSupportedDisplayVsyncPeriods(Display display, Config config,
- std::vector<VsyncPeriodNanos>* outSupportedVsyncPeriods);
+ int32_t getDisplayAttribute_2_4(Display display, Config config,
+ IComposerClient::Attribute attribute);
Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriods);
- Error setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ Error setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime);
+ VsyncPeriodChangeTimeline* timeline);
private:
const sp<IComposerClient> mClient;
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index 2c87666..f038f55 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -114,7 +114,7 @@
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
- void Test_setActiveConfigAndVsyncPeriod(
+ void Test_setActiveConfigWithConstraints(
const IComposerClient::VsyncPeriodChangeConstraints& constraints);
std::unique_ptr<Composer> mComposer;
@@ -194,42 +194,28 @@
}
}
-TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadDisplay) {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
- EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->getSupportedDisplayVsyncPeriods(
- mInvalidDisplayId, Config(0), &supportedVsyncPeriods));
-}
+TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute_2_4) {
+ std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
+ for (auto config : configs) {
+ const std::array<IComposerClient::Attribute, 4> requiredAttributes = {{
+ IComposerClient::Attribute::WIDTH,
+ IComposerClient::Attribute::HEIGHT,
+ IComposerClient::Attribute::VSYNC_PERIOD,
+ IComposerClient::Attribute::CONFIG_GROUP,
+ }};
+ for (auto attribute : requiredAttributes) {
+ mComposerClient->getDisplayAttribute_2_4(mPrimaryDisplay, config, attribute);
+ }
-TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadConfig) {
- for (Display display : mComposerCallback->getDisplays()) {
- Config invalidConfigId = GetInvalidConfigId(display);
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
- EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->getSupportedDisplayVsyncPeriods(
- display, invalidConfigId, &supportedVsyncPeriods));
- }
-}
-
-TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods) {
- for (Display display : mComposerCallback->getDisplays()) {
- for (Config config : mComposerClient->getDisplayConfigs(display)) {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
-
- // Get the default vsync period from the config
- VsyncPeriodNanos defaultVsyncPeiord = mComposerClient->getDisplayAttribute(
- display, config, IComposerClient::Attribute::VSYNC_PERIOD);
- // Get all supported vsync periods for this config
- EXPECT_EQ(Error::NONE, mComposerClient->getSupportedDisplayVsyncPeriods(
- display, config, &supportedVsyncPeriods));
- // Default vsync period must be present in the list
- EXPECT_NE(std::find(supportedVsyncPeriods.begin(), supportedVsyncPeriods.end(),
- defaultVsyncPeiord),
- supportedVsyncPeriods.end());
-
- // Each vsync period must be unique
- std::unordered_set<VsyncPeriodNanos> vsyncPeriodSet;
- for (VsyncPeriodNanos vsyncPeriodNanos : supportedVsyncPeriods) {
- EXPECT_TRUE(vsyncPeriodSet.insert(vsyncPeriodNanos).second);
- }
+ const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
+ IComposerClient::Attribute::DPI_X,
+ IComposerClient::Attribute::DPI_Y,
+ }};
+ for (auto attribute : optionalAttributes) {
+ mComposerClient->getRaw()->getDisplayAttribute_2_4(
+ mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) {
+ EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
+ });
}
}
}
@@ -240,20 +226,40 @@
mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadDisplay) {
- int64_t newVsyncAppliedTime;
+TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
+ for (Display display : mComposerCallback->getDisplays()) {
+ for (Config config : mComposerClient->getDisplayConfigs(display)) {
+ mComposerClient->setActiveConfig(display, config);
+
+ VsyncPeriodNanos vsyncPeriodNanos;
+ VsyncPeriodNanos expectedvsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
+ display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ int retryCount = 100;
+ do {
+ std::this_thread::sleep_for(10ms);
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ --retryCount;
+ } while (retryCount > 0);
+
+ EXPECT_EQ(vsyncPeriodNanos, expectedvsyncPeriodNanos);
+ }
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadDisplay) {
+ VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime();
- EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setActiveConfigAndVsyncPeriod(
- mInvalidDisplayId, Config(0), VsyncPeriodNanos(0),
- constraints, &newVsyncAppliedTime));
+ EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setActiveConfigWithConstraints(
+ mInvalidDisplayId, Config(0), constraints, &timeline));
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadConfig) {
- int64_t newVsyncAppliedTime;
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) {
+ VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = false;
@@ -261,93 +267,114 @@
for (Display display : mComposerCallback->getDisplays()) {
Config invalidConfigId = GetInvalidConfigId(display);
- EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigAndVsyncPeriod(
- display, invalidConfigId, VsyncPeriodNanos(0),
- constraints, &newVsyncAppliedTime));
+ EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigWithConstraints(
+ display, invalidConfigId, constraints, &timeline));
}
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadVsyncPeriod) {
- int64_t newVsyncAppliedTime;
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+ VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
- constraints.seamlessRequired = false;
+ constraints.seamlessRequired = true;
constraints.desiredTimeNanos = systemTime();
for (Display display : mComposerCallback->getDisplays()) {
for (Config config : mComposerClient->getDisplayConfigs(display)) {
- EXPECT_EQ(Error::BAD_VSYNC_PERIOD, mComposerClient->setActiveConfigAndVsyncPeriod(
- display, config, VsyncPeriodNanos(0),
- constraints, &newVsyncAppliedTime));
- }
- }
-}
+ int32_t configGroup = mComposerClient->getDisplayAttribute_2_4(
+ display, config, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
-void GraphicsComposerHidlTest::Test_setActiveConfigAndVsyncPeriod(
- const IComposerClient::VsyncPeriodChangeConstraints& constraints) {
- int64_t newVsyncAppliedTime;
-
- for (Display display : mComposerCallback->getDisplays()) {
- for (Config config : mComposerClient->getDisplayConfigs(display)) {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
-
- EXPECT_EQ(Error::NONE, mComposerClient->getSupportedDisplayVsyncPeriods(
- display, config, &supportedVsyncPeriods));
- for (VsyncPeriodNanos newVsyncPeriod : supportedVsyncPeriods) {
- VsyncPeriodNanos vsyncPeriodNanos;
- EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
-
- if (vsyncPeriodNanos == newVsyncPeriod) {
- continue;
+ for (Config otherConfig : mComposerClient->getDisplayConfigs(display)) {
+ int32_t otherConfigGroup = mComposerClient->getDisplayAttribute_2_4(
+ display, otherConfig,
+ IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
+ if (configGroup != otherConfigGroup) {
+ mComposerClient->setActiveConfig(display, config);
+ EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
+ mComposerClient->setActiveConfigWithConstraints(
+ display, otherConfig, constraints, &timeline));
}
-
- EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigAndVsyncPeriod(
- display, config, newVsyncPeriod, constraints,
- &newVsyncAppliedTime));
-
- EXPECT_TRUE(newVsyncAppliedTime >= constraints.desiredTimeNanos);
-
- // Refresh rate should change within a reasonable time
- constexpr nsecs_t kReasonableTimeForChange = 1'000'000'000; // 1 second
- EXPECT_TRUE(newVsyncAppliedTime - constraints.desiredTimeNanos <=
- kReasonableTimeForChange);
-
- while (systemTime() <= newVsyncAppliedTime) {
- EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
- if (systemTime() <= constraints.desiredTimeNanos) {
- EXPECT_NE(vsyncPeriodNanos, newVsyncPeriod);
- }
-
- if (vsyncPeriodNanos == newVsyncPeriod) {
- break;
- }
- std::this_thread::sleep_for(10ms);
- }
- EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
- EXPECT_EQ(vsyncPeriodNanos, newVsyncPeriod);
}
}
}
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod) {
+void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(
+ const IComposerClient::VsyncPeriodChangeConstraints& constraints) {
+ VsyncPeriodChangeTimeline timeline = {};
+
+ for (Display display : mComposerCallback->getDisplays()) {
+ for (Config config : mComposerClient->getDisplayConfigs(display)) {
+ mComposerClient->setActiveConfig(display, config);
+
+ int32_t configVsyncPeriod = mComposerClient->getDisplayAttribute_2_4(
+ display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ for (Config otherConfig : mComposerClient->getDisplayConfigs(display)) {
+ if (config == otherConfig) {
+ continue;
+ }
+
+ int32_t otherVsyncPeriod = mComposerClient->getDisplayAttribute_2_4(
+ display, otherConfig,
+ IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+
+ if (configVsyncPeriod == otherVsyncPeriod) {
+ continue;
+ }
+
+ EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
+ display, otherConfig, constraints, &timeline));
+
+ if (timeline.refreshRequired) {
+ // TODO(b/143775556): handle this case;
+ continue;
+ }
+
+ EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
+
+ // Refresh rate should change within a reasonable time
+ constexpr nsecs_t kReasonableTimeForChange = 1'000'000'000; // 1 second
+ EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
+ kReasonableTimeForChange);
+
+ while (systemTime() <= timeline.newVsyncAppliedTimeNanos) {
+ VsyncPeriodNanos vsyncPeriodNanos;
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+
+ if (systemTime() <= constraints.desiredTimeNanos) {
+ EXPECT_NE(vsyncPeriodNanos, otherVsyncPeriod);
+ }
+
+ if (vsyncPeriodNanos == otherVsyncPeriod) {
+ break;
+ }
+ std::this_thread::sleep_for(10ms);
+ }
+ VsyncPeriodNanos vsyncPeriodNanos;
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ EXPECT_EQ(vsyncPeriodNanos, otherVsyncPeriod);
+ }
+ }
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints) {
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime();
- Test_setActiveConfigAndVsyncPeriod(constraints);
+ Test_setActiveConfigWithConstraints(constraints);
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_delayed) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_delayed) {
IComposerClient::VsyncPeriodChangeConstraints constraints;
constexpr auto kDelayForChange = 300ms;
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime() + kDelayForChange.count();
- Test_setActiveConfigAndVsyncPeriod(constraints);
+ Test_setActiveConfigWithConstraints(constraints);
}
INSTANTIATE_TEST_SUITE_P(
diff --git a/graphics/mapper/2.0/utils/vts/MapperVts.cpp b/graphics/mapper/2.0/utils/vts/MapperVts.cpp
index d08ac56..d4e4dde 100644
--- a/graphics/mapper/2.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/2.0/utils/vts/MapperVts.cpp
@@ -16,8 +16,6 @@
#include <mapper-vts/2.0/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -30,10 +28,10 @@
}
void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
diff --git a/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h b/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h
index 6c2c9a6..fc8a102 100644
--- a/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h
+++ b/graphics/mapper/2.0/utils/vts/include/mapper-vts/2.0/MapperVts.h
@@ -22,6 +22,7 @@
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
namespace android {
diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp
index 853c2a3..a055b61 100644
--- a/graphics/mapper/2.0/vts/functional/Android.bp
+++ b/graphics/mapper/2.0/vts/functional/Android.bp
@@ -24,5 +24,5 @@
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.0-vts",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
index 5ec0af2..b079a4b 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
@@ -20,8 +20,10 @@
#include <thread>
#include <vector>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.0/MapperVts.h>
namespace android {
@@ -35,28 +37,12 @@
using android::hardware::graphics::common::V1_0::BufferUsage;
using android::hardware::graphics::common::V1_0::PixelFormat;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
mDummyDescriptorInfo.width = 64;
mDummyDescriptorInfo.height = 64;
@@ -75,14 +61,14 @@
/**
* Test IAllocator::dumpDebugInfo by calling it.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+TEST_P(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
mGralloc->dumpDebugInfo();
}
/**
* Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -105,7 +91,7 @@
/**
* Test IAllocator::allocate with invalid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
// this assumes any valid descriptor is non-empty
BufferDescriptor descriptor;
mGralloc->getAllocator()->allocate(descriptor, 1,
@@ -117,7 +103,7 @@
/**
* Test IAllocator::allocate does not leak.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -131,7 +117,7 @@
/**
* Test that IAllocator::allocate is thread-safe.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -161,14 +147,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorBasic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorNegative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
@@ -179,7 +165,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
const native_handle_t* bufferHandle;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
@@ -188,7 +174,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferClone) {
const native_handle_t* clonedBufferHandle;
ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -206,7 +192,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
const native_handle_t* rawHandle;
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -218,10 +204,8 @@
// free the imported handle with another mapper
std::unique_ptr<Gralloc> anotherGralloc;
- ASSERT_NO_FATAL_FAILURE(
- anotherGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
ASSERT_EQ(Error::NONE, error);
@@ -231,7 +215,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -245,7 +229,7 @@
/**
* Test IMapper::importBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, ImportBufferNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -263,7 +247,7 @@
/**
* Test IMapper::freeBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, FreeBufferNegative) {
native_handle_t* invalidHandle = nullptr;
Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
@@ -286,7 +270,7 @@
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -332,7 +316,7 @@
* Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
* write to and read from it.
*/
-TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+TEST_P(GraphicsMapperHidlTest, LockYCbCrBasic) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
@@ -391,7 +375,7 @@
/**
* Test IMapper::unlock with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+TEST_P(GraphicsMapperHidlTest, UnlockNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -426,6 +410,14 @@
#endif
}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V2_0
@@ -433,13 +425,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V2_0::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/graphics/mapper/2.1/utils/vts/Android.bp b/graphics/mapper/2.1/utils/vts/Android.bp
index ca02aad..abbe50a 100644
--- a/graphics/mapper/2.1/utils/vts/Android.bp
+++ b/graphics/mapper/2.1/utils/vts/Android.bp
@@ -16,14 +16,13 @@
cc_library_static {
name: "android.hardware.graphics.mapper@2.1-vts",
- defaults: ["hidl_defaults"],
+ defaults: ["hidl_defaults", "VtsHalTargetTestDefaults"],
srcs: ["MapperVts.cpp"],
cflags: [
"-O0",
"-g",
],
static_libs: [
- "VtsHalHidlTargetTestBase",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.0-vts",
diff --git a/graphics/mapper/2.1/utils/vts/MapperVts.cpp b/graphics/mapper/2.1/utils/vts/MapperVts.cpp
index 36f9cbb..239de74 100644
--- a/graphics/mapper/2.1/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/2.1/utils/vts/MapperVts.cpp
@@ -16,8 +16,6 @@
#include <mapper-vts/2.1/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
diff --git a/graphics/mapper/2.1/vts/functional/Android.bp b/graphics/mapper/2.1/vts/functional/Android.bp
index afd8e7f..bb76c74 100644
--- a/graphics/mapper/2.1/vts/functional/Android.bp
+++ b/graphics/mapper/2.1/vts/functional/Android.bp
@@ -26,5 +26,5 @@
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@2.1-vts",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
index 5e7cf93..1185945 100644
--- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
+++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
@@ -16,9 +16,11 @@
#define LOG_TAG "VtsHalGraphicsMapperV2_1TargetTest"
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
#include <android/hardware/graphics/mapper/2.1/IMapper.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/2.1/MapperVts.h>
namespace android {
@@ -34,28 +36,12 @@
using android::hardware::graphics::common::V1_1::PixelFormat;
using V2_0::Error;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
mDummyDescriptorInfo.width = 64;
mDummyDescriptorInfo.height = 64;
@@ -74,7 +60,7 @@
/**
* Test that IMapper::validateBufferSize works.
*/
-TEST_F(GraphicsMapperHidlTest, ValidateBufferSizeBasic) {
+TEST_P(GraphicsMapperHidlTest, ValidateBufferSizeBasic) {
const native_handle_t* bufferHandle;
uint32_t stride;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true, &stride));
@@ -87,7 +73,7 @@
/**
* Test IMapper::validateBufferSize with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ValidateBufferSizeBadBuffer) {
+TEST_P(GraphicsMapperHidlTest, ValidateBufferSizeBadBuffer) {
native_handle_t* invalidHandle = nullptr;
Error ret = mGralloc->getMapper()->validateBufferSize(invalidHandle, mDummyDescriptorInfo,
mDummyDescriptorInfo.width);
@@ -114,7 +100,7 @@
/**
* Test IMapper::validateBufferSize with invalid descriptor and/or stride.
*/
-TEST_F(GraphicsMapperHidlTest, ValidateBufferSizeBadValue) {
+TEST_P(GraphicsMapperHidlTest, ValidateBufferSizeBadValue) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -161,7 +147,7 @@
/**
* Test IMapper::getTransportSize.
*/
-TEST_F(GraphicsMapperHidlTest, GetTransportSizeBasic) {
+TEST_P(GraphicsMapperHidlTest, GetTransportSizeBasic) {
const native_handle_t* bufferHandle;
uint32_t numFds;
uint32_t numInts;
@@ -173,7 +159,7 @@
/**
* Test IMapper::getTransportSize with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, GetTransportSizeBadBuffer) {
+TEST_P(GraphicsMapperHidlTest, GetTransportSizeBadBuffer) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->getTransportSize(
invalidHandle, [&](const auto& tmpError, const auto&, const auto&) {
@@ -203,14 +189,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptor_2_1Basic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptor_2_1Basic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor_2_1(info, [&](const auto& tmpError, const auto&) {
@@ -218,22 +204,18 @@
});
}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V2_1
} // namespace mapper
} // namespace graphics
} // namespace hardware
-} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V2_1::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
-
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
-
- return status;
-}
+} // namespace android
\ No newline at end of file
diff --git a/graphics/mapper/3.0/utils/vts/MapperVts.cpp b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
index c94e8db..de886a9 100644
--- a/graphics/mapper/3.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
@@ -16,8 +16,6 @@
#include <mapper-vts/3.0/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -35,19 +33,19 @@
}
void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
void Gralloc::initNoErr(const std::string& allocatorServiceName,
const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
if (mMapper.get()) {
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
diff --git a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
index 1141a88..b2fbebb1 100644
--- a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
+++ b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
@@ -22,6 +22,7 @@
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
namespace android {
diff --git a/graphics/mapper/3.0/vts/functional/Android.bp b/graphics/mapper/3.0/vts/functional/Android.bp
index 77075a5..f01670e 100644
--- a/graphics/mapper/3.0/vts/functional/Android.bp
+++ b/graphics/mapper/3.0/vts/functional/Android.bp
@@ -26,5 +26,5 @@
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.mapper@3.0-vts",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
index ff73ecf..92b5994 100644
--- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
+++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
@@ -20,8 +20,10 @@
#include <thread>
#include <vector>
-#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/3.0/MapperVts.h>
namespace android {
@@ -35,28 +37,12 @@
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::common::V1_2::PixelFormat;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
mDummyDescriptorInfo.width = 64;
mDummyDescriptorInfo.height = 64;
@@ -75,14 +61,14 @@
/**
* Test IAllocator::dumpDebugInfo by calling it.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+TEST_P(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
mGralloc->dumpDebugInfo();
}
/**
* Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -105,7 +91,7 @@
/**
* Test IAllocator::allocate with invalid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
// this assumes any valid descriptor is non-empty
BufferDescriptor descriptor;
mGralloc->getAllocator()->allocate(descriptor, 1,
@@ -117,7 +103,7 @@
/**
* Test IAllocator::allocate does not leak.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -131,7 +117,7 @@
/**
* Test that IAllocator::allocate is thread-safe.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -161,14 +147,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorBasic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorNegative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
@@ -179,7 +165,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
const native_handle_t* bufferHandle;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
@@ -188,7 +174,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferClone) {
const native_handle_t* clonedBufferHandle;
ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -206,7 +192,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
const native_handle_t* rawHandle;
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -218,10 +204,8 @@
// free the imported handle with another mapper
std::unique_ptr<Gralloc> anotherGralloc;
- ASSERT_NO_FATAL_FAILURE(
- anotherGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
ASSERT_EQ(Error::NONE, error);
@@ -231,7 +215,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -245,7 +229,7 @@
/**
* Test IMapper::importBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, ImportBufferNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -263,7 +247,7 @@
/**
* Test IMapper::freeBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, FreeBufferNegative) {
native_handle_t* invalidHandle = nullptr;
Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
@@ -286,7 +270,7 @@
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -346,7 +330,7 @@
* Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
* write to and read from it.
*/
-TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+TEST_P(GraphicsMapperHidlTest, LockYCbCrBasic) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
@@ -405,7 +389,7 @@
/**
* Test IMapper::unlock with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+TEST_P(GraphicsMapperHidlTest, UnlockNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -443,7 +427,7 @@
/**
* Test IMapper::isSupported with required format RGBA_8888
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
const auto& info = mDummyDescriptorInfo;
bool supported = false;
@@ -454,7 +438,7 @@
/**
* Test IMapper::isSupported with required format YV12
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedYV12) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedYV12) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
bool supported = false;
@@ -466,7 +450,7 @@
/**
* Test IMapper::isSupported with optional format Y16
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedY16) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedY16) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::Y16;
bool supported = false;
@@ -474,6 +458,14 @@
ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
}
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V3_0
@@ -481,13 +473,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V3_0::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/graphics/mapper/4.0/IMapper.hal b/graphics/mapper/4.0/IMapper.hal
index 640539f..03dfef1 100644
--- a/graphics/mapper/4.0/IMapper.hal
+++ b/graphics/mapper/4.0/IMapper.hal
@@ -35,18 +35,20 @@
*/
uint32_t width;
- /**
- * The height specifies how many rows of pixels must be in the
- * allocated buffer.
- */
+ /**
+ * The height specifies how many rows of pixels must be in the
+ * allocated buffer.
+ */
uint32_t height;
- /**
- * The number of image layers that must be in the allocated buffer.
- */
+ /**
+ * The number of image layers that must be in the allocated buffer.
+ */
uint32_t layerCount;
- /** Buffer pixel format. */
+ /**
+ * Buffer pixel format.
+ */
PixelFormat format;
/**
@@ -54,6 +56,12 @@
* BufferUsage.
*/
bitfield<BufferUsage> usage;
+
+ /**
+ * The size in bytes of the reserved region associated with the buffer.
+ * See getReservedRegion for more information.
+ */
+ uint64_t reservedSize;
};
struct Rect {
@@ -69,9 +77,10 @@
*
* Since the buffer descriptor fully describes a buffer, any device
* dependent or device independent checks must be performed here whenever
- * possible. Specifically, when layered buffers are not supported, this
- * function must return `UNSUPPORTED` if `description.layers` is great than
- * 1.
+ * possible. When layered buffers are not supported, this function must
+ * return `UNSUPPORTED` if `description.layers` is great than 1. This
+ * function may return `UNSUPPORTED` if `description.reservedSize` is
+ * larger than a page.
*
* @param description Attributes of the descriptor.
* @return error Error status of the call, which may be
@@ -197,16 +206,20 @@
* outside of @p accessRegion is undefined, except that it must not cause
* process termination.
*
+ * This function can lock both single-planar and multi-planar formats. The caller
+ * should use get() to get information about the buffer they are locking.
+ * get() can be used to get information about the planes, offsets, stride,
+ * etc.
+ *
+ * This function must also work on buffers with
+ * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
+ * as with any other formats requested by multimedia codecs when they are
+ * configured with a flexible-YUV-compatible color format.
+ *
* On success, @p data must be filled with a pointer to the locked buffer
* memory. This address will represent the top-left corner of the entire
* buffer, even if @p accessRegion does not begin at the top-left corner.
*
- * On success, bytesPerPixel must contain the number of bytes per pixel in
- * the buffer. If the bytesPerPixel is unknown or variable, a value of -1
- * should be returned. bytesPerStride must contain the bytes per stride of
- * the buffer. If the bytesPerStride is unknown or variable, a value of -1
- * should be returned.
- *
* The locked buffer must adhere to the format requested at allocation time
* in the BufferDescriptorInfo.
*
@@ -229,55 +242,13 @@
* - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
* that locking may succeed at a later time.
* @return data CPU-accessible pointer to the buffer data.
- * @return bytesPerPixel the number of bytes per pixel in the buffer
- * @return bytesPerStride the number of bytes per stride of the buffer
*/
lock(pointer buffer,
uint64_t cpuUsage,
Rect accessRegion,
handle acquireFence)
generates (Error error,
- pointer data,
- int32_t bytesPerPixel,
- int32_t bytesPerStride);
-
- /**
- * Locks a YCbCr buffer for the specified CPU usage.
- *
- * This is largely the same as lock(), except that instead of returning a
- * pointer directly to the buffer data, it returns a `YCbCrLayout` struct
- * describing how to access the data planes.
- *
- * This function must work on buffers with
- * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
- * as with any other formats requested by multimedia codecs when they are
- * configured with a flexible-YUV-compatible color format.
- *
- * @param buffer Buffer to lock.
- * @param cpuUsage CPU usage flags to request. See +ndk
- * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
- * @param accessRegion Portion of the buffer that the client intends to
- * access.
- * @param acquireFence Handle containing a file descriptor referring to a
- * sync fence object, which will be signaled when it is safe for the
- * mapper to lock the buffer. @p acquireFence may be empty if it is
- * already safe to lock.
- * @return error Error status of the call, which may be
- * - `NONE` upon success.
- * - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
- * function.
- * - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
- * is incompatible with the buffer.
- * - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
- * that locking may succeed at a later time.
- * @return layout Data layout of the locked buffer.
- */
- lockYCbCr(pointer buffer,
- uint64_t cpuUsage,
- Rect accessRegion,
- handle acquireFence)
- generates (Error error,
- YCbCrLayout layout);
+ pointer data);
/**
* Unlocks a buffer to indicate all CPU accesses to the buffer have
@@ -295,6 +266,50 @@
unlock(pointer buffer) generates (Error error, handle releaseFence);
/**
+ * Flushes the contents of a locked buffer.
+ *
+ * This function flushes the CPUs caches for the range of all the buffer's
+ * planes and metadata. This should behave similarly to unlock() except the
+ * buffer should remain mapped to the CPU.
+ *
+ * The client is still responsible for calling unlock() when it is done
+ * with all CPU accesses to the buffer.
+ *
+ * If non-CPU blocks are simultaneously writing the buffer, the locked
+ * copy should still be flushed but what happens is undefined except that
+ * it should not cause any crashes.
+ *
+ * @param buffer Buffer to flush.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ * @return releaseFence Handle containing a file descriptor referring to a
+ * sync fence object. The sync fence object will be signaled when the
+ * mapper has completed any pending work. @p releaseFence may be an
+ * empty fence.
+ */
+ flushLockedBuffer(pointer buffer) generates (Error error, handle releaseFence);
+
+ /**
+ * Rereads the contents of a locked buffer.
+ *
+ * This should fetch the most recent copy of the locked buffer.
+ *
+ * It may reread locked copies of the buffer in other processes.
+ *
+ * The client is still responsible for calling unlock() when it is done
+ * with all CPU accesses to the buffer.
+ *
+ * @param buffer Buffer to reread.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ * - `NO_RESOURCES` if the buffer cannot be reread at this time. Note
+ * that rereading may succeed at a later time.
+ */
+ rereadLockedBuffer(pointer buffer) generates(Error error);
+
+ /**
* Test whether the given BufferDescriptorInfo is allocatable.
*
* If this function returns true, it means that a buffer with the given
@@ -309,5 +324,322 @@
generates (Error error,
bool supported);
+
+ /**
+ * Description for get(...), set(...) and getFromBufferDescriptorInfo(...)
+ *
+ * ------------ Overview -----------------------------------
+ * Gralloc 4 adds support for getting and setting buffer metadata on a buffer.
+ *
+ * To get buffer metadata, the client passes in a buffer handle and a token that
+ * represents the type of buffer metadata they would like to get. IMapper returns
+ * a byte stream that contains the buffer metadata. To set the buffer metadata, the
+ * client passes in a buffer handle and a token that represents the type of buffer
+ * metadata they would like to set and a byte stream that contains the buffer metadata
+ * they are setting.
+ *
+ * Buffer metadata is global for a buffer. When the metadata is set on the buffer
+ * in a process, the updated metadata should be available to all other processes.
+ * Please see "Storing and Propagating Metadata" below for more details.
+ *
+ * The getter and setter functions have been optimized for easy vendor extension.
+ * They do not require a formal HIDL extension to add support for getting and setting
+ * vendor defined buffer metadata. In order to allow easy extension, the types used
+ * here are not typical HIDL types. See "Buffer Metadata Token" and
+ * "Buffer Metadata Stream" below for more details.
+ *
+ * ------------ Storing and Propagating Metadata -----------
+ * Buffer metadata must be global. Any changes to the metadata must be propagated
+ * to all other processes immediately. Vendors may chose how they would like support
+ * this functionality.
+ *
+ * We recommend supporting this functionality by allocating an extra page of shared
+ * memory and storing it in the buffer's native_handle_t. The buffer metadata can
+ * be stored in the extra page of shared memory. Set operations are automatically
+ * propagated to all other processes.
+ *
+ * ------------ Buffer Metadata Synchronization ------------
+ * There are no explicit buffer metadata synchronization primitives. Many devices
+ * before gralloc 4 already support getting and setting of global buffer metadata
+ * with no explicit synchronization primitives. Adding synchronization primitives
+ * would just add unnecessary complexity.
+ *
+ * The general rule is if a process has permission to write to a buffer, they
+ * have permission to write to the buffer's metadata. If a process has permission
+ * to read from a buffer, they have permission to read the buffer's metadata.
+ *
+ * There is one exception to this rule. Fences CANNOT be used to protect a buffer's
+ * metadata. A process should finish writing to a buffer's metadata before
+ * sending the buffer to another process that will read or write to the buffer.
+ * This exception is needed because sometimes userspace needs to read the
+ * buffer's metadata before the buffer's contents are ready.
+ *
+ * As a simple example: an app renders to a buffer and then displays the buffer.
+ * In this example when the app renders to the buffer, both the buffer and its
+ * metadata need to be updated. The app's process queues up its work on the GPU
+ * and gets back an acquire fence. The app's process must update the buffer's
+ * metadata before enqueuing the buffer to SurfaceFlinger. The app process CANNOT
+ * update the buffer's metadata after enqueuing the buffer. When HardwareComposer
+ * receives the buffer, it is immediately safe to read the buffer's metadata
+ * and use it to program the display driver. To read the buffer's contents,
+ * display driver must still wait on the acquire fence.
+ *
+ * ------------ Buffer Metadata Token ----------------------
+ * In order to allow arbitrary vendor defined metadata, we could not use a
+ * HIDL enum as the buffer metadata token. Extending a HIDL enum requires a full
+ * HIDL extension. We also could not use a simple non-HIDL enum because vendor
+ * defined enums from different vendors could collide. Instead we have defined
+ * a struct that has a string representing the enum type and an int that
+ * represents the enum value. The string protects different enum values from
+ * colliding.
+ *
+ * The token struct (MetadataType) is defined as a HIDL struct since it
+ * is passed into a HIDL function. The standard buffer metadata types are NOT
+ * defined as a HIDL enum because it would have required a new IMapper version
+ * just to add future standard buffer metadata types. By putting the enum in the
+ * stable AIDL (hardware/interfaces/graphics/common/aidl/android/hardware/
+ * graphics/common/StandardMetadataType.aidl), vendors will be able to optionally
+ * choose to support future standard buffer metadata types without upgrading
+ * HIDL versions. For more information see the description of "struct MetadataType".
+ *
+ * ------------ Buffer Metadata Stream ---------------------
+ * The buffer metadata is get and set as a byte stream (vec<uint8_t>). By getting
+ * and setting buffer metadata as a byte stream, vendors can use the standard
+ * getters and setter functions defined here. Vendors do NOT need to add their own
+ * getters and setter functions for each new type of buffer metadata.
+ *
+ * Converting buffer metadata into a byte stream can be non-trivial. For the standard
+ * buffer metadata types defined in StandardMetadataType.aidl, there are also
+ * support functions that will encode the buffer metadata into a byte stream
+ * and decode the buffer metadata from a byte stream. We STRONGLY recommend using
+ * these support functions. The framework will use them when getting and setting
+ * metadata. The support functions are defined in
+ * frameworks/native/libs/gralloc/types/include/gralloctypes/Gralloc4.h.
+ */
+
+ /**
+ * MetadataType represents the different types of buffer metadata that could be
+ * associated with a buffer. It is used by IMapper to help get and set buffer metadata
+ * on the buffer's native handle.
+ *
+ * Standard buffer metadata will have the name field set to
+ * "android.hardware.graphics.common.StandardMetadataType" and will contain values
+ * from StandardMetadataType.aidl.
+ *
+ * This struct should be "extended" by devices that use a proprietary or non-standard
+ * buffer metadata. To extend the struct, first create a custom @VendorStability vendor
+ * AIDL interface that defines the new type(s) you would like to support. Set the
+ * struct's name field to the custom aidl interface's name
+ * (eg. "vendor.mycompanyname.graphics.common.MetadataType"). Set the struct's value
+ * field to the custom @VendorStabilty vendor AIDL interface.
+ *
+ * Each company should create their own StandardMetadataType.aidl extension. The name
+ * field prevents values from different companies from colliding.
+ */
+ struct MetadataType {
+ string name;
+ int64_t value;
+ };
+
+ /**
+ * Gets the buffer metadata for a given MetadataType.
+ *
+ * Buffer metadata can be changed after allocation so clients should avoid "caching"
+ * the buffer metadata. For example, if the video resolution changes and the buffers
+ * are not reallocated, several buffer metadata values may change without warning.
+ * Clients should not expect the values to be constant. They should requery them every
+ * frame. The only exception is buffer metadata that is determined at allocation
+ * time. For StandardMetadataType values, only BUFFER_ID, NAME, WIDTH,
+ * HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and USAGE are safe to cache because
+ * they are determined at allocation time.
+ *
+ * @param buffer Buffer containing desired metadata
+ * @param metadataType MetadataType for the metadata value being queried
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported.
+ * IMapper must support getting all StandardMetadataType.aidl values defined
+ * at the time the device first launches.
+ * @return metadata Vector of bytes representing the buffer metadata associated with
+ * the MetadataType.
+ */
+ get(pointer buffer, MetadataType metadataType)
+ generates (Error error,
+ vec<uint8_t> metadata);
+
+ /**
+ * Sets the global value for a given MetadataType.
+ *
+ * Metadata fields are not required to be settable. This function can
+ * return Error::UNSUPPORTED whenever it doesn't support setting a
+ * particular Metadata field.
+ *
+ * The framework may attempt to set the following StandardMetadataType
+ * values: DATASPACE, PER_FRAME_METADATA, PER_FRAME_METADATA_BLOB and BLEND_MODE.
+ * We strongly encourage everyone to support setting as many of those fields as
+ * possible. If a device's Composer implementation supports a field, it should be
+ * supported here. Over time these metadata fields will be moved out of
+ * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
+ * If a device's IMapper doesn't support setting those Metadata fields,
+ * eventually the device may not longer be able to support these fields.
+ *
+ * @param buffer Buffer receiving desired metadata
+ * @param metadataType MetadataType for the metadata value being set
+ * @param metadata Vector of bytes representing the value associated with
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `BAD_VALUE` when the field is constant and can never be set (such as
+ * BUFFER_ID, NAME, WIDTH, HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and
+ * USAGE)
+ * - `NO_RESOURCES` if the set cannot be fullfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported or setting
+ * it is unsupported. Unsupported should also be returned if the metadata
+ * is malformed.
+ */
+ set(pointer buffer, MetadataType metadataType, vec<uint8_t> metadata)
+ generates (Error error);
+
+ /**
+ * Given a BufferDescriptorInfo, gets the starting value of a given
+ * MetadataType. This can be used to query basic information about a buffer
+ * before the buffer is allocated.
+ *
+ * @param description Attributes of the descriptor.
+ * @param metadataType MetadataType for the metadata value being queried
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_VALUE` if any of the specified BufferDescriptorInfo attributes
+ * are invalid.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when any of the description attributes are unsupported or
+ * if the metadataType is unknown/unsupported. This should also be
+ * returned if the requested metadata is not defined until a buffer has been
+ * allocated.
+ * @return metadata Vector of bytes representing the value associated with
+ * the MetadataType value.
+ */
+ getFromBufferDescriptorInfo(BufferDescriptorInfo description,
+ MetadataType metadataType)
+ generates (Error error,
+ vec<uint8_t> metadata);
+
+ struct MetadataTypeDescription {
+ MetadataType metadataType;
+ /**
+ * description should contain a string representation of the MetadataType.
+ *
+ * For example: "MyExampleMetadataType is a 64-bit timestamp in nanoseconds
+ * that indicates when a buffer is decoded. It is set by the media HAL after
+ * a buffer is decoded. It is used by the display HAL for hardware
+ * synchronization".
+ *
+ * This field is required for any non-StandardMetadataTypes.
+ */
+ string description;
+ /**
+ * isGettable represents if the MetadataType can be get.
+ */
+ bool isGettable;
+ /**
+ * isSettable represents if the MetadataType can be set.
+ */
+ bool isSettable;
+ };
+
+ /**
+ * Lists all the MetadataTypes supported by IMapper as well as a description
+ * of each supported MetadataType. For StandardMetadataTypes, the description
+ * string can be left empty.
+ *
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * @return descriptions Vector of MetadataTypeDescriptions that represent the
+ * MetadataTypes supported by the device.
+ */
+ listSupportedMetadataTypes()
+ generates (Error error, vec<MetadataTypeDescription> descriptions);
+
+ struct MetadataDump {
+ /**
+ * The type of metadata being dumped.
+ */
+ MetadataType metadataType;
+ /**
+ * The byte stream representation of the metadata. If the metadata is not
+ * gettable, the vector must be empty.
+ */
+ vec<uint8_t> metadata;
+ };
+
+ struct BufferDump {
+ /**
+ * A vector of all the metadata that is being dumped for a particular buffer.
+ */
+ vec<MetadataDump> metadataDump;
+ };
+
+ /**
+ * Dumps a buffer's metadata.
+ *
+ * @param buffer Buffer that is being dumped
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * @return bufferDump Struct representing the metadata being dumped
+ */
+ dumpBuffer(pointer buffer)
+ generates (Error error, BufferDump bufferDump);
+
+ /**
+ * Dumps the metadata for all the buffers in the current process.
+ *
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * @return bufferDumps Vector of structs representing the buffers being dumped
+ */
+ dumpBuffers()
+ generates (Error error, vec<BufferDump> bufferDumps);
+
+ /**
+ * Returns the region of shared memory associated with the buffer that is
+ * reserved for client use.
+ *
+ * The shared memory may be allocated from any shared memory allocator.
+ * The shared memory must be CPU-accessible and virtually contiguous. The
+ * starting address must be word-aligned.
+ *
+ * This function may only be called after importBuffer() has been called by the
+ * client. The reserved region must remain accessible until freeBuffer() has
+ * been called. After freeBuffer() has been called, the client must not access
+ * the reserved region.
+ *
+ * This reserved memory may be used in future versions of Android to
+ * help clients implement backwards compatible features without requiring
+ * IAllocator/IMapper updates.
+ *
+ * @param buffer Imported buffer handle.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ * @return reservedRegion CPU-accessible pointer to the reserved region
+ * @return reservedSize the size of the reservedRegion that was requested
+ * in the BufferDescriptorInfo.
+ */
+ getReservedRegion(pointer buffer)
+ generates (Error error,
+ pointer reservedRegion,
+ uint64_t reservedSize);
};
diff --git a/graphics/mapper/4.0/types.hal b/graphics/mapper/4.0/types.hal
index 2fdfa65..00b6607 100644
--- a/graphics/mapper/4.0/types.hal
+++ b/graphics/mapper/4.0/types.hal
@@ -53,32 +53,3 @@
*/
typedef vec<uint8_t> BufferDescriptor;
-/**
- * Structure for describing YCbCr formats for consumption by applications.
- * This is used with PixelFormat::YCBCR_*_888.
- *
- * Buffer chroma subsampling is defined in the format.
- * e.g. PixelFormat::YCBCR_420_888 has subsampling 4:2:0.
- *
- * Buffers must have a 8 bit depth.
- *
- * y, cb, and cr point to the first byte of their respective planes.
- *
- * Stride describes the distance in bytes from the first value of one row of
- * the image to the first value of the next row. It includes the width of the
- * image plus padding.
- * yStride is the stride of the luma plane.
- * cStride is the stride of the chroma planes.
- *
- * chromaStep is the distance in bytes from one chroma pixel value to the
- * next. This is 2 bytes for semiplanar (because chroma values are interleaved
- * and each chroma value is one byte) and 1 for planar.
- */
-struct YCbCrLayout {
- pointer y;
- pointer cb;
- pointer cr;
- uint32_t yStride;
- uint32_t cStride;
- uint32_t chromaStep;
-};
diff --git a/graphics/mapper/4.0/utils/vts/Android.bp b/graphics/mapper/4.0/utils/vts/Android.bp
index e451584..56ff116 100644
--- a/graphics/mapper/4.0/utils/vts/Android.bp
+++ b/graphics/mapper/4.0/utils/vts/Android.bp
@@ -26,6 +26,9 @@
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.mapper@4.0",
],
+ shared_libs: [
+ "libgralloctypes",
+ ],
export_static_lib_headers: [
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.mapper@4.0",
diff --git a/graphics/mapper/4.0/utils/vts/MapperVts.cpp b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
index 056b7c9..8a5f54e 100644
--- a/graphics/mapper/4.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
@@ -14,10 +14,9 @@
* limitations under the License.
*/
+#include <gralloctypes/Gralloc4.h>
#include <mapper-vts/4.0/MapperVts.h>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace android {
namespace hardware {
namespace graphics {
@@ -35,19 +34,19 @@
}
void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
void Gralloc::initNoErr(const std::string& allocatorServiceName,
const std::string& mapperServiceName) {
- mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ mAllocator = IAllocator::getService(allocatorServiceName);
- mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ mMapper = IMapper::getService(mapperServiceName);
if (mMapper.get()) {
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
@@ -92,28 +91,39 @@
std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
uint32_t count, bool import,
- uint32_t* outStride) {
+ bool allowFailure, uint32_t* outStride) {
std::vector<const native_handle_t*> bufferHandles;
bufferHandles.reserve(count);
- mAllocator->allocate(descriptor, count,
- [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
- ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
+ mAllocator->allocate(
+ descriptor, count,
+ [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
+ ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
- for (uint32_t i = 0; i < count; i++) {
- if (import) {
- ASSERT_NO_FATAL_FAILURE(
- bufferHandles.push_back(importBuffer(tmpBuffers[i])));
- } else {
- ASSERT_NO_FATAL_FAILURE(
- bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
- }
- }
+ for (uint32_t i = 0; i < count; i++) {
+ const native_handle_t* bufferHandle = nullptr;
+ if (import) {
+ if (allowFailure) {
+ bufferHandle = importBuffer(tmpBuffers[i]);
+ } else {
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(tmpBuffers[i]));
+ }
+ } else {
+ if (allowFailure) {
+ bufferHandle = cloneBuffer(tmpBuffers[i]);
+ } else {
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(tmpBuffers[i]));
+ }
+ }
+ if (bufferHandle) {
+ bufferHandles.push_back(bufferHandle);
+ }
+ }
- if (outStride) {
- *outStride = tmpStride;
- }
- });
+ if (outStride) {
+ *outStride = tmpStride;
+ }
+ });
if (::testing::Test::HasFatalFailure()) {
bufferHandles.clear();
@@ -123,17 +133,20 @@
}
const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
- bool import, uint32_t* outStride) {
+ bool import, bool allowFailure, uint32_t* outStride) {
BufferDescriptor descriptor = createDescriptor(descriptorInfo);
if (::testing::Test::HasFatalFailure()) {
return nullptr;
}
- auto buffers = allocate(descriptor, 1, import, outStride);
+ auto buffers = allocate(descriptor, 1, import, allowFailure, outStride);
if (::testing::Test::HasFatalFailure()) {
return nullptr;
}
+ if (buffers.size() != 1) {
+ return nullptr;
+ }
return buffers[0];
}
@@ -167,6 +180,10 @@
}
void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
+ if (bufferHandle == nullptr) {
+ return;
+ }
+
auto buffer = const_cast<native_handle_t*>(bufferHandle);
if (mImportedBuffers.erase(bufferHandle)) {
@@ -180,8 +197,7 @@
}
void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
- int32_t* outBytesPerStride) {
+ const IMapper::Rect& accessRegion, int acquireFence) {
auto buffer = const_cast<native_handle_t*>(bufferHandle);
NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
@@ -192,17 +208,11 @@
acquireFenceHandle = h;
}
- *outBytesPerPixel = -1;
- *outBytesPerStride = -1;
-
void* data = nullptr;
mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpData, int32_t tmpBytesPerPixel,
- int32_t tmpBytesPerStride) {
+ [&](const auto& tmpError, const auto& tmpData) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
data = tmpData;
- *outBytesPerPixel = tmpBytesPerPixel;
- *outBytesPerStride = tmpBytesPerStride;
});
if (acquireFence >= 0) {
@@ -212,33 +222,6 @@
return data;
}
-YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence) {
- auto buffer = const_cast<native_handle_t*>(bufferHandle);
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- hidl_handle acquireFenceHandle;
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- YCbCrLayout layout = {};
- mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpLayout) {
- ASSERT_EQ(Error::NONE, tmpError)
- << "failed to lockYCbCr buffer " << buffer;
- layout = tmpLayout;
- });
-
- if (acquireFence >= 0) {
- close(acquireFence);
- }
-
- return layout;
-}
-
int Gralloc::unlock(const native_handle_t* bufferHandle) {
auto buffer = const_cast<native_handle_t*>(bufferHandle);
@@ -261,6 +244,34 @@
return releaseFence;
}
+int Gralloc::flushLockedBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ mMapper->flushLockedBuffer(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to flush locked buffer " << buffer;
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle) {
+ ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
+ if (fenceHandle->numFds == 1) {
+ releaseFence = dup(fenceHandle->data[0]);
+ ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
+ } else {
+ ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
+ }
+ }
+ });
+
+ return releaseFence;
+}
+
+void Gralloc::rereadLockedBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ ASSERT_EQ(Error::NONE, mMapper->rereadLockedBuffer(buffer));
+}
+
bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
const IMapper::BufferDescriptorInfo& descriptorInfo,
uint32_t stride) {
@@ -296,6 +307,48 @@
return supported;
}
+Error Gralloc::get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec) {
+ Error err;
+ mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
+ [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
+ err = tmpError;
+ *outVec = tmpVec;
+ });
+ return err;
+}
+
+Error Gralloc::set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ const hidl_vec<uint8_t>& vec) {
+ return mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, vec);
+}
+
+Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec) {
+ Error err;
+ mMapper->getFromBufferDescriptorInfo(
+ descriptorInfo, metadataType,
+ [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
+ err = tmpError;
+ *outVec = tmpVec;
+ });
+ return err;
+}
+
+Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
+ uint64_t* outReservedSize) {
+ Error err;
+ mMapper->getReservedRegion(
+ const_cast<native_handle_t*>(bufferHandle),
+ [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
+ err = tmpError;
+ *outReservedRegion = tmpReservedRegion;
+ *outReservedSize = tmpReservedSize;
+ });
+ return err;
+}
+
} // namespace vts
} // namespace V4_0
} // namespace mapper
diff --git a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
index 03ce764..1c635c4 100644
--- a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
+++ b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
@@ -22,6 +22,7 @@
#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <gtest/gtest.h>
#include <utils/StrongPointer.h>
namespace android {
@@ -51,9 +52,11 @@
//
// Either case, the returned buffers must be freed with freeBuffer.
std::vector<const native_handle_t*> allocate(const BufferDescriptor& descriptor, uint32_t count,
- bool import = true, uint32_t* outStride = nullptr);
+ bool import = true, bool allowFailure = false,
+ uint32_t* outStride = nullptr);
const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
- bool import = true, uint32_t* outStride = nullptr);
+ bool import = true, bool allowFailure = false,
+ uint32_t* outStride = nullptr);
// IMapper methods
@@ -68,12 +71,12 @@
// in and out of the mapper. The ownership of the fd is always transferred
// with each of these functions.
void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
- int32_t* outBytesPerStride);
- YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion, int acquireFence);
+ const IMapper::Rect& accessRegion, int acquireFence);
int unlock(const native_handle_t* bufferHandle);
+ int flushLockedBuffer(const native_handle_t* bufferHandle);
+ void rereadLockedBuffer(const native_handle_t* bufferHandle);
+
bool validateBufferSize(const native_handle_t* bufferHandle,
const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t stride);
void getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
@@ -81,6 +84,19 @@
bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo);
+ Error get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec);
+
+ Error set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ const hidl_vec<uint8_t>& vec);
+
+ Error getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec);
+
+ Error getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
+ uint64_t* outReservedSize);
+
private:
void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index a90ee0c..926cf31 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -19,12 +19,20 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
static_libs: [
+ "android.hardware.graphics.mapper@4.0-vts",
+ "libgralloctypes",
+ "libsync",
+ "vintf-graphics-common-ndk_platform",
+ ],
+ shared_libs: [
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@4.0",
- "android.hardware.graphics.mapper@4.0-vts",
],
- test_suites: ["general-tests"],
+ header_libs: [
+ "libsystem_headers",
+ ],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 62ff613..4ca5e7e 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -16,13 +16,21 @@
#define LOG_TAG "VtsHalGraphicsMapperV4_0TargetTest"
+#include <unistd.h>
#include <chrono>
#include <thread>
#include <vector>
-#include <VtsHalHidlTargetTestBase.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
+
#include <android-base/logging.h>
+#include <android/sync.h>
+#include <gralloctypes/Gralloc4.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <mapper-vts/4.0/MapperVts.h>
+#include <system/graphics.h>
namespace android {
namespace hardware {
@@ -34,29 +42,26 @@
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::common::V1_2::PixelFormat;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::ExtendableType;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::StandardMetadataType;
-// Test environment for graphics.mapper.
-class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static GraphicsMapperHidlEnvironment* Instance() {
- static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
- return instance;
- }
+using DecodeFunction = std::function<void(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const hidl_vec<uint8_t>& vec)>;
- virtual void registerTestServices() override {
- registerTestService<IAllocator>();
- registerTestService<IMapper>();
- }
-};
-
-class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class GraphicsMapperHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
protected:
void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(
- mGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
+ ASSERT_NE(nullptr, mGralloc->getAllocator().get());
+ ASSERT_NE(nullptr, mGralloc->getMapper().get());
mDummyDescriptorInfo.name = "dummy";
mDummyDescriptorInfo.width = 64;
@@ -65,33 +70,260 @@
mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
mDummyDescriptorInfo.usage =
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+ mDummyDescriptorInfo.reservedSize = 0;
}
void TearDown() override {}
+ void testGet(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const MetadataType& metadataType, DecodeFunction decode) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(descriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &vec));
+
+ ASSERT_NO_FATAL_FAILURE(decode(descriptorInfo, vec));
+ }
+
+ void testSet(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const MetadataType& metadataType, const hidl_vec<uint8_t>& metadata,
+ DecodeFunction decode) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(descriptorInfo, true));
+
+ Error err = mGralloc->set(bufferHandle, metadataType, metadata);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &vec));
+
+ ASSERT_NO_FATAL_FAILURE(decode(descriptorInfo, vec));
+ }
+
+ void verifyDummyDescriptorInfoPlaneLayouts(const std::vector<PlaneLayout>& planeLayouts) {
+ ASSERT_EQ(1, planeLayouts.size());
+
+ const auto& planeLayout = planeLayouts.front();
+
+ ASSERT_EQ(4, planeLayout.components.size());
+
+ int64_t offsetInBitsR = -1;
+ int64_t offsetInBitsG = -1;
+ int64_t offsetInBitsB = -1;
+ int64_t offsetInBitsA = -1;
+
+ for (const auto& component : planeLayout.components) {
+ EXPECT_EQ(GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, component.type.name);
+ EXPECT_EQ(8, component.sizeInBits);
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_R.value) {
+ offsetInBitsR = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_G.value) {
+ offsetInBitsG = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_B.value) {
+ offsetInBitsB = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_A.value) {
+ offsetInBitsA = component.offsetInBits;
+ }
+ }
+
+ EXPECT_EQ(0, offsetInBitsR);
+ EXPECT_EQ(8, offsetInBitsG);
+ EXPECT_EQ(16, offsetInBitsB);
+ EXPECT_EQ(24, offsetInBitsA);
+
+ EXPECT_EQ(0, planeLayout.offsetInBytes);
+ EXPECT_EQ(8, planeLayout.sampleIncrementInBits);
+ // Skip testing stride because any stride is valid
+ EXPECT_EQ(mDummyDescriptorInfo.width, planeLayout.widthInSamples);
+ EXPECT_EQ(mDummyDescriptorInfo.height, planeLayout.heightInSamples);
+ EXPECT_LE(planeLayout.widthInSamples * planeLayout.heightInSamples * 4,
+ planeLayout.totalSizeInBytes);
+ EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+ EXPECT_EQ(1, planeLayout.verticalSubsampling);
+
+ EXPECT_EQ(0, planeLayout.crop.left);
+ EXPECT_EQ(0, planeLayout.crop.top);
+ EXPECT_EQ(planeLayout.widthInSamples, planeLayout.crop.right);
+ EXPECT_EQ(planeLayout.heightInSamples, planeLayout.crop.bottom);
+ }
+
+ void verifyBufferDump(const IMapper::BufferDump& bufferDump,
+ const native_handle_t* bufferHandle = nullptr) {
+ std::set<StandardMetadataType> foundMetadataTypes;
+
+ const std::vector<IMapper::MetadataDump> metadataDump = bufferDump.metadataDump;
+
+ for (const auto& dump : metadataDump) {
+ const auto& metadataType = dump.metadataType;
+ const auto& metadata = dump.metadata;
+
+ if (!gralloc4::isStandardMetadataType(metadataType)) {
+ continue;
+ }
+
+ StandardMetadataType type = gralloc4::getStandardMetadataTypeValue(metadataType);
+
+ if (sRequiredMetadataTypes.find(type) == sRequiredMetadataTypes.end()) {
+ continue;
+ }
+
+ ASSERT_EQ(foundMetadataTypes.find(type), foundMetadataTypes.end());
+ foundMetadataTypes.insert(type);
+
+ if (!bufferHandle) {
+ continue;
+ }
+
+ hidl_vec<uint8_t> metadataFromGet;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &metadataFromGet));
+
+ ASSERT_EQ(metadataFromGet, metadata);
+ }
+
+ EXPECT_EQ(sRequiredMetadataTypes, foundMetadataTypes);
+ }
+
+ void getAndroidYCbCr(const native_handle_t* bufferHandle, uint8_t* data,
+ android_ycbcr* outYCbCr) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
+ std::vector<PlaneLayout> planeLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
+
+ outYCbCr->y = nullptr;
+ outYCbCr->cb = nullptr;
+ outYCbCr->cr = nullptr;
+ outYCbCr->ystride = 0;
+ outYCbCr->cstride = 0;
+ outYCbCr->chroma_step = 0;
+
+ for (const auto& planeLayout : planeLayouts) {
+ for (const auto& planeLayoutComponent : planeLayout.components) {
+ std::string componentTypeName = planeLayoutComponent.type.name;
+ if (!std::strncmp(componentTypeName.c_str(), GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE,
+ componentTypeName.size())) {
+ continue;
+ }
+ ASSERT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+
+ uint8_t* tmpData =
+ data + planeLayout.offsetInBytes + (planeLayoutComponent.offsetInBits / 8);
+ uint64_t sampleIncrementInBytes;
+
+ auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+ switch (type) {
+ case PlaneLayoutComponentType::Y:
+ ASSERT_EQ(nullptr, outYCbCr->y);
+ ASSERT_EQ(8, planeLayoutComponent.sizeInBits);
+ ASSERT_EQ(8, planeLayout.sampleIncrementInBits);
+ outYCbCr->y = tmpData;
+ outYCbCr->ystride = planeLayout.strideInBytes;
+ break;
+
+ case PlaneLayoutComponentType::CB:
+ case PlaneLayoutComponentType::CR:
+ ASSERT_EQ(0, planeLayout.sampleIncrementInBits % 8);
+
+ sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
+ ASSERT_TRUE(sampleIncrementInBytes == 1 || sampleIncrementInBytes == 2);
+
+ if (outYCbCr->cstride == 0 && outYCbCr->chroma_step == 0) {
+ outYCbCr->cstride = planeLayout.strideInBytes;
+ outYCbCr->chroma_step = sampleIncrementInBytes;
+ } else {
+ ASSERT_EQ(outYCbCr->cstride, planeLayout.strideInBytes);
+ ASSERT_EQ(outYCbCr->chroma_step, sampleIncrementInBytes);
+ }
+
+ if (type == PlaneLayoutComponentType::CB) {
+ ASSERT_EQ(nullptr, outYCbCr->cb);
+ outYCbCr->cb = tmpData;
+ } else {
+ ASSERT_EQ(nullptr, outYCbCr->cr);
+ outYCbCr->cr = tmpData;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ ASSERT_NE(nullptr, outYCbCr->y);
+ ASSERT_NE(nullptr, outYCbCr->cb);
+ ASSERT_NE(nullptr, outYCbCr->cr);
+ }
+
+ void fillRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes,
+ uint32_t seed = 0) {
+ for (uint32_t y = 0; y < height; y++) {
+ memset(data, y + seed, widthInBytes);
+ data += strideInBytes;
+ }
+ }
+
+ void verifyRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes,
+ uint32_t seed = 0) {
+ for (uint32_t y = 0; y < height; y++) {
+ for (size_t i = 0; i < widthInBytes; i++) {
+ EXPECT_EQ(static_cast<uint8_t>(y + seed), data[i]);
+ }
+ data += strideInBytes;
+ }
+ }
+
std::unique_ptr<Gralloc> mGralloc;
IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
+ static const std::set<StandardMetadataType> sRequiredMetadataTypes;
+};
+
+const std::set<StandardMetadataType> GraphicsMapperHidlTest::sRequiredMetadataTypes{
+ StandardMetadataType::BUFFER_ID,
+ StandardMetadataType::NAME,
+ StandardMetadataType::WIDTH,
+ StandardMetadataType::HEIGHT,
+ StandardMetadataType::LAYER_COUNT,
+ StandardMetadataType::PIXEL_FORMAT_REQUESTED,
+ StandardMetadataType::PIXEL_FORMAT_FOURCC,
+ StandardMetadataType::PIXEL_FORMAT_MODIFIER,
+ StandardMetadataType::USAGE,
+ StandardMetadataType::ALLOCATION_SIZE,
+ StandardMetadataType::PROTECTED_CONTENT,
+ StandardMetadataType::COMPRESSION,
+ StandardMetadataType::INTERLACED,
+ StandardMetadataType::CHROMA_SITING,
+ StandardMetadataType::PLANE_LAYOUTS,
+ StandardMetadataType::DATASPACE,
+ StandardMetadataType::BLEND_MODE,
};
/**
* Test IAllocator::dumpDebugInfo by calling it.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+TEST_P(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
mGralloc->dumpDebugInfo();
}
/**
* Test IAllocator::allocate with valid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
for (uint32_t count = 0; count < 5; count++) {
std::vector<const native_handle_t*> bufferHandles;
uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(bufferHandles =
- mGralloc->allocate(descriptor, count, false, &stride));
+ ASSERT_NO_FATAL_FAILURE(
+ bufferHandles = mGralloc->allocate(descriptor, count, false, false, &stride));
if (count >= 1) {
EXPECT_LE(mDummyDescriptorInfo.width, stride) << "invalid buffer stride";
@@ -106,7 +338,7 @@
/**
* Test IAllocator::allocate with invalid buffer descriptors.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
// this assumes any valid descriptor is non-empty
BufferDescriptor descriptor;
mGralloc->getAllocator()->allocate(descriptor, 1,
@@ -118,7 +350,7 @@
/**
* Test IAllocator::allocate does not leak.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -132,7 +364,7 @@
/**
* Test that IAllocator::allocate is thread-safe.
*/
-TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+TEST_P(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
BufferDescriptor descriptor;
ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
@@ -163,14 +395,14 @@
/**
* Test IMapper::createDescriptor with valid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorBasic) {
ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
}
/**
* Test IMapper::createDescriptor with invalid descriptor info.
*/
-TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+TEST_P(GraphicsMapperHidlTest, CreateDescriptorNegative) {
auto info = mDummyDescriptorInfo;
info.width = 0;
mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
@@ -181,7 +413,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
const native_handle_t* bufferHandle;
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
@@ -190,7 +422,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferClone) {
const native_handle_t* clonedBufferHandle;
ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -208,7 +440,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
const native_handle_t* rawHandle;
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
@@ -220,10 +452,8 @@
// free the imported handle with another mapper
std::unique_ptr<Gralloc> anotherGralloc;
- ASSERT_NO_FATAL_FAILURE(
- anotherGralloc = std::make_unique<Gralloc>(
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
- GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
ASSERT_EQ(Error::NONE, error);
@@ -233,7 +463,7 @@
/**
* Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
*/
-TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+TEST_P(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
auto info = mDummyDescriptorInfo;
info.width = 1024;
info.height = 1024;
@@ -247,7 +477,7 @@
/**
* Test IMapper::importBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, ImportBufferNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -265,7 +495,7 @@
/**
* Test IMapper::freeBuffer with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+TEST_P(GraphicsMapperHidlTest, FreeBufferNegative) {
native_handle_t* invalidHandle = nullptr;
Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
@@ -288,55 +518,30 @@
/**
* Test IMapper::lock and IMapper::unlock.
*/
-TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, false, &stride));
// lock buffer for writing
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
static_cast<int32_t>(info.height)};
int fence = -1;
uint8_t* data;
- int32_t bytesPerPixel = -1;
- int32_t bytesPerStride = -1;
ASSERT_NO_FATAL_FAILURE(
- data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence,
- &bytesPerPixel, &bytesPerStride)));
-
- // Valid return values are -1 for unsupported or the number bytes for supported which is >=0
- EXPECT_GT(bytesPerPixel, -1);
- EXPECT_GT(bytesPerStride, -1);
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
// RGBA_8888
- size_t strideInBytes = stride * 4;
- size_t writeInBytes = info.width * 4;
-
- for (uint32_t y = 0; y < info.height; y++) {
- memset(data, y, writeInBytes);
- data += strideInBytes;
- }
+ fillRGBA8888(data, info.height, stride * 4, info.width * 4);
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
- bytesPerPixel = -1;
- bytesPerStride = -1;
-
// lock again for reading
ASSERT_NO_FATAL_FAILURE(
- data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence,
- &bytesPerPixel, &bytesPerStride)));
- for (uint32_t y = 0; y < info.height; y++) {
- for (size_t i = 0; i < writeInBytes; i++) {
- EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
- }
- data += strideInBytes;
- }
-
- EXPECT_GT(bytesPerPixel, -1);
- EXPECT_GT(bytesPerStride, -1);
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+ ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(data, info.height, stride * 4, info.width * 4));
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
if (fence >= 0) {
@@ -344,36 +549,42 @@
}
}
-/**
- * Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
- * write to and read from it.
- */
-TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_420_888) {
auto info = mDummyDescriptorInfo;
- info.format = PixelFormat::YV12;
+ info.format = PixelFormat::YCBCR_420_888;
const native_handle_t* bufferHandle;
uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, false, &stride));
// lock buffer for writing
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
static_cast<int32_t>(info.height)};
int fence = -1;
- YCbCrLayout layout;
- ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
+ uint8_t* data;
- auto yData = static_cast<uint8_t*>(layout.y);
- auto cbData = static_cast<uint8_t*>(layout.cb);
- auto crData = static_cast<uint8_t*>(layout.cr);
+ ASSERT_NO_FATAL_FAILURE(
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+
+ android_ycbcr yCbCr;
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(bufferHandle, data, &yCbCr));
+
+ auto yData = static_cast<uint8_t*>(yCbCr.y);
+ auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+ auto crData = static_cast<uint8_t*>(yCbCr.cr);
+ auto yStride = yCbCr.ystride;
+ auto cStride = yCbCr.cstride;
+ auto chromaStep = yCbCr.chroma_step;
+
for (uint32_t y = 0; y < info.height; y++) {
for (uint32_t x = 0; x < info.width; x++) {
auto val = static_cast<uint8_t>(info.height * y + x);
- yData[layout.yStride * y + x] = val;
- if (y % 2 == 0 && x % 2 == 0) {
- cbData[layout.cStride * y / 2 + x / 2] = val;
- crData[layout.cStride * y / 2 + x / 2] = val;
+ yData[yStride * y + x] = val;
+
+ if (y % chromaStep && x % chromaStep == 0) {
+ cbData[cStride * y / chromaStep + x / chromaStep] = val;
+ crData[cStride * y / chromaStep + x / chromaStep] = val;
}
}
}
@@ -381,19 +592,23 @@
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
// lock again for reading
- ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
+ ASSERT_NO_FATAL_FAILURE(
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
- yData = static_cast<uint8_t*>(layout.y);
- cbData = static_cast<uint8_t*>(layout.cb);
- crData = static_cast<uint8_t*>(layout.cr);
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(bufferHandle, data, &yCbCr));
+
+ yData = static_cast<uint8_t*>(yCbCr.y);
+ cbData = static_cast<uint8_t*>(yCbCr.cb);
+ crData = static_cast<uint8_t*>(yCbCr.cr);
for (uint32_t y = 0; y < info.height; y++) {
for (uint32_t x = 0; x < info.width; x++) {
auto val = static_cast<uint8_t>(info.height * y + x);
- EXPECT_EQ(val, yData[layout.yStride * y + x]);
- if (y % 2 == 0 && x % 2 == 0) {
- EXPECT_EQ(val, cbData[layout.cStride * y / 2 + x / 2]);
- EXPECT_EQ(val, crData[layout.cStride * y / 2 + x / 2]);
+ EXPECT_EQ(val, yData[yStride * y + x]);
+
+ if (y % chromaStep == 0 && x % chromaStep == 0) {
+ EXPECT_EQ(val, cbData[cStride * y / chromaStep + x / chromaStep]);
+ EXPECT_EQ(val, crData[cStride * y / chromaStep + x / chromaStep]);
}
}
}
@@ -407,7 +622,7 @@
/**
* Test IMapper::unlock with bad access region
*/
-TEST_F(GraphicsMapperHidlTest, LockBadAccessRegion) {
+TEST_P(GraphicsMapperHidlTest, LockBadAccessRegion) {
const auto& info = mDummyDescriptorInfo;
const native_handle_t* bufferHandle;
@@ -427,8 +642,7 @@
auto buffer = const_cast<native_handle_t*>(bufferHandle);
mGralloc->getMapper()->lock(buffer, info.usage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& /*tmpData*/,
- int32_t /*tmpBytesPerPixel*/, int32_t /*tmpBytesPerStride*/) {
+ [&](const auto& tmpError, const auto& /*tmpData*/) {
EXPECT_EQ(Error::BAD_VALUE, tmpError)
<< "locking with a bad access region should fail";
});
@@ -450,7 +664,7 @@
/**
* Test IMapper::unlock with invalid buffers.
*/
-TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+TEST_P(GraphicsMapperHidlTest, UnlockNegative) {
native_handle_t* invalidHandle = nullptr;
mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
EXPECT_EQ(Error::BAD_BUFFER, tmpError)
@@ -486,9 +700,78 @@
}
/**
+ * Test IMapper::flush and IMapper::reread.
+ */
+TEST_P(GraphicsMapperHidlTest, FlushRereadBasic) {
+ const auto& info = mDummyDescriptorInfo;
+
+ const native_handle_t* rawHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(
+ rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false, false, &stride));
+
+ const native_handle_t* writeBufferHandle;
+ const native_handle_t* readBufferHandle;
+ ASSERT_NO_FATAL_FAILURE(writeBufferHandle = mGralloc->importBuffer(rawHandle));
+ ASSERT_NO_FATAL_FAILURE(readBufferHandle = mGralloc->importBuffer(rawHandle));
+
+ // lock buffer for writing
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+ uint8_t* writeData;
+ ASSERT_NO_FATAL_FAILURE(
+ writeData = static_cast<uint8_t*>(mGralloc->lock(
+ writeBufferHandle, static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN), region,
+ -1)));
+
+ uint8_t* readData;
+ ASSERT_NO_FATAL_FAILURE(
+ readData = static_cast<uint8_t*>(mGralloc->lock(
+ readBufferHandle, static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN), region,
+ -1)));
+
+ fillRGBA8888(writeData, info.height, stride * 4, info.width * 4);
+
+ int fence;
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->flushLockedBuffer(writeBufferHandle));
+ ASSERT_EQ(0, sync_wait(fence, 3500));
+ close(fence);
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc->rereadLockedBuffer(readBufferHandle));
+
+ ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(readData, info.height, stride * 4, info.width * 4));
+
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(readBufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(writeBufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
+}
+
+/**
+ * Test IMapper::flushLockedBuffer with bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, FlushLockedBufferBadBuffer) {
+ ASSERT_NO_FATAL_FAILURE(mGralloc->getMapper()->flushLockedBuffer(
+ nullptr, [&](const auto& tmpError, const auto& /*tmpReleaseFence*/) {
+ ASSERT_EQ(Error::BAD_BUFFER, tmpError);
+ }));
+}
+
+/**
+ * Test IMapper::rereadLockedBuffer with bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, RereadLockedBufferBadBuffer) {
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->getMapper()->rereadLockedBuffer(nullptr));
+}
+
+/**
* Test IMapper::isSupported with required format RGBA_8888
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
const auto& info = mDummyDescriptorInfo;
bool supported = false;
@@ -499,7 +782,7 @@
/**
* Test IMapper::isSupported with required format YV12
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedYV12) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedYV12) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YV12;
bool supported = false;
@@ -511,7 +794,7 @@
/**
* Test IMapper::isSupported with optional format Y16
*/
-TEST_F(GraphicsMapperHidlTest, IsSupportedY16) {
+TEST_P(GraphicsMapperHidlTest, IsSupportedY16) {
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::Y16;
bool supported = false;
@@ -519,6 +802,1212 @@
ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
}
+/**
+ * Test IMapper::get(BufferId)
+ */
+TEST_P(GraphicsMapperHidlTest, GetBufferId) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_BufferId,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t bufferId = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBufferId(vec, &bufferId));
+ });
+}
+
+/**
+ * Test IMapper::get(Name)
+ */
+TEST_P(GraphicsMapperHidlTest, GetName) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Name,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ std::string name;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeName(vec, &name));
+ EXPECT_EQ(info.name, name);
+ });
+}
+
+/**
+ * Test IMapper::get(Width)
+ */
+TEST_P(GraphicsMapperHidlTest, GetWidth) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Width,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t width = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeWidth(vec, &width));
+ EXPECT_EQ(info.width, width);
+ });
+}
+
+/**
+ * Test IMapper::get(Height)
+ */
+TEST_P(GraphicsMapperHidlTest, GetHeight) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Height,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t height = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeHeight(vec, &height));
+ EXPECT_EQ(info.height, height);
+ });
+}
+
+/**
+ * Test IMapper::get(LayerCount)
+ */
+TEST_P(GraphicsMapperHidlTest, GetLayerCount) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_LayerCount,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t layerCount = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeLayerCount(vec, &layerCount));
+ EXPECT_EQ(info.layerCount, layerCount);
+ });
+}
+
+/**
+ * Test IMapper::get(PixelFormatRequested)
+ */
+TEST_P(GraphicsMapperHidlTest, GetPixelFormatRequested) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatRequested,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ PixelFormat pixelFormatRequested = PixelFormat::BLOB;
+ ASSERT_EQ(NO_ERROR,
+ gralloc4::decodePixelFormatRequested(vec, &pixelFormatRequested));
+ EXPECT_EQ(info.format, pixelFormatRequested);
+ });
+}
+
+/**
+ * Test IMapper::get(PixelFormatFourCC)
+ */
+TEST_P(GraphicsMapperHidlTest, GetPixelFormatFourCC) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint32_t pixelFormatFourCC = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatFourCC(vec, &pixelFormatFourCC));
+ });
+}
+
+/**
+ * Test IMapper::get(PixelFormatModifier)
+ */
+TEST_P(GraphicsMapperHidlTest, GetPixelFormatModifier) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t pixelFormatModifier = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatModifier(vec, &pixelFormatModifier));
+ });
+}
+
+/**
+ * Test IMapper::get(Usage)
+ */
+TEST_P(GraphicsMapperHidlTest, GetUsage) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t usage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &usage));
+ EXPECT_EQ(info.usage, usage);
+ });
+}
+
+/**
+ * Test IMapper::get(AllocationSize)
+ */
+TEST_P(GraphicsMapperHidlTest, GetAllocationSize) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_AllocationSize,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t allocationSize = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeAllocationSize(vec, &allocationSize));
+ });
+}
+
+/**
+ * Test IMapper::get(ProtectedContent)
+ */
+TEST_P(GraphicsMapperHidlTest, GetProtectedContent) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ const native_handle_t* bufferHandle = nullptr;
+ bufferHandle = mGralloc->allocate(info, true, true);
+ if (bufferHandle) {
+ GTEST_SUCCEED() << "unable to allocate protected content";
+ }
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ProtectedContent, &vec));
+
+ uint64_t protectedContent = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeProtectedContent(vec, &protectedContent));
+ EXPECT_EQ(1, protectedContent);
+}
+
+/**
+ * Test IMapper::get(Compression)
+ */
+TEST_P(GraphicsMapperHidlTest, GetCompression) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ testGet(info, gralloc4::MetadataType_Compression,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType compression = gralloc4::Compression_DisplayStreamCompression;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeCompression(vec, &compression));
+
+ EXPECT_EQ(gralloc4::Compression_None.name, compression.name);
+ EXPECT_EQ(gralloc4::Compression_None.value, compression.value);
+ });
+}
+
+/**
+ * Test IMapper::get(Interlaced)
+ */
+TEST_P(GraphicsMapperHidlTest, GetInterlaced) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType interlaced = gralloc4::Interlaced_TopBottom;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeInterlaced(vec, &interlaced));
+
+ EXPECT_EQ(gralloc4::Interlaced_None.name, interlaced.name);
+ EXPECT_EQ(gralloc4::Interlaced_None.value, interlaced.value);
+ });
+}
+
+/**
+ * Test IMapper::get(ChromaSiting)
+ */
+TEST_P(GraphicsMapperHidlTest, GetChromaSiting) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_ChromaSiting,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType chromaSiting = gralloc4::ChromaSiting_Unknown;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeChromaSiting(vec, &chromaSiting));
+
+ EXPECT_EQ(gralloc4::ChromaSiting_None.name, chromaSiting.name);
+ EXPECT_EQ(gralloc4::ChromaSiting_None.value, chromaSiting.value);
+ });
+}
+
+/**
+ * Test IMapper::get(PlaneLayouts)
+ */
+TEST_P(GraphicsMapperHidlTest, GetPlaneLayouts) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
+
+ std::vector<PlaneLayout> planeLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
+
+ ASSERT_NO_FATAL_FAILURE(verifyDummyDescriptorInfoPlaneLayouts(planeLayouts));
+}
+
+/**
+ * Test IMapper::get(Dataspace)
+ */
+TEST_P(GraphicsMapperHidlTest, GetDataspace) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ Dataspace dataspace = Dataspace::DISPLAY_P3;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeDataspace(vec, &dataspace));
+ EXPECT_EQ(Dataspace::UNKNOWN, dataspace);
+ });
+}
+
+/**
+ * Test IMapper::get(BlendMode)
+ */
+TEST_P(GraphicsMapperHidlTest, GetBlendMode) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ BlendMode blendMode = BlendMode::NONE;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBlendMode(vec, &blendMode));
+ EXPECT_EQ(BlendMode::INVALID, blendMode);
+ });
+}
+
+/**
+ * Test IMapper::get(metadata) with a bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, GetMetadataBadValue) {
+ const native_handle_t* bufferHandle = nullptr;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_BufferId, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Name, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Width, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Height, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_LayerCount, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Usage, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_AllocationSize, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ProtectedContent, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_Compression, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_Interlaced, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ChromaSiting, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_Dataspace, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_BlendMode, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::get(metadata) for unsupported metadata
+ */
+TEST_P(GraphicsMapperHidlTest, GetUnsupportedMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ MetadataType metadataTypeFake = {"FAKE", 1};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->get(bufferHandle, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::get(metadata) for unsupported standard metadata
+ */
+TEST_P(GraphicsMapperHidlTest, GetUnsupportedStandardMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ MetadataType metadataTypeFake = {GRALLOC4_STANDARD_METADATA_TYPE, 9999};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->get(bufferHandle, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::set(PixelFormatFourCC)
+ */
+TEST_P(GraphicsMapperHidlTest, SetPixelFormatFourCC) {
+ uint32_t pixelFormatFourCC = 0x34324142; // DRM_FORMAT_BGRA8888
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatFourCC(pixelFormatFourCC, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint32_t realPixelFormatFourCC = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatFourCC(vec, &realPixelFormatFourCC));
+ EXPECT_EQ(pixelFormatFourCC, realPixelFormatFourCC);
+ });
+}
+
+/**
+ * Test IMapper::set(PixelFormatModifier)
+ */
+TEST_P(GraphicsMapperHidlTest, SetPixelFormatModifier) {
+ uint64_t pixelFormatModifier = 10;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatModifier(pixelFormatModifier, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realPixelFormatModifier = 0;
+ ASSERT_EQ(NO_ERROR,
+ gralloc4::decodePixelFormatModifier(vec, &realPixelFormatModifier));
+ EXPECT_EQ(pixelFormatModifier, realPixelFormatModifier);
+ });
+}
+
+/**
+ * Test IMapper::set(Usage) remove flag
+ */
+TEST_P(GraphicsMapperHidlTest, SetUsageRemoveBit) {
+ uint64_t usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN);
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realUsage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &realUsage));
+ EXPECT_EQ(usage, realUsage);
+ });
+}
+/**
+ * Test IMapper::set(Usage) add flag
+ */
+TEST_P(GraphicsMapperHidlTest, SetUsageAddBit) {
+ uint64_t usage = mDummyDescriptorInfo.usage | static_cast<uint64_t>(BufferUsage::GPU_TEXTURE);
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realUsage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &realUsage));
+ EXPECT_EQ(usage, realUsage);
+ });
+}
+
+/**
+ * Test IMapper::set(Usage) to test protected content
+ */
+TEST_P(GraphicsMapperHidlTest, SetUsageProtected) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ bufferHandle = mGralloc->allocate(info, true, true);
+ if (bufferHandle) {
+ GTEST_SUCCEED() << "unable to allocate protected content";
+ }
+
+ uint64_t usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY);
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
+
+ Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec);
+ ASSERT_EQ(err, Error::UNSUPPORTED);
+ vec.resize(0);
+
+ uint64_t realUsage = 0;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_Usage, &vec));
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &realUsage));
+ EXPECT_EQ(info.usage, realUsage);
+}
+
+/**
+ * Test IMapper::set(AllocationSize)
+ */
+TEST_P(GraphicsMapperHidlTest, SetAllocationSize) {
+ uint64_t allocationSize = 1000000;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeAllocationSize(allocationSize, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_AllocationSize, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realAllocationSize = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeAllocationSize(vec, &realAllocationSize));
+ EXPECT_EQ(allocationSize, realAllocationSize);
+ });
+}
+
+/**
+ * Test IMapper::set(ProtectedContent)
+ */
+TEST_P(GraphicsMapperHidlTest, SetProtectedContent) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ bufferHandle = mGralloc->allocate(info, true, true);
+ if (bufferHandle) {
+ GTEST_SUCCEED() << "unable to allocate protected content";
+ }
+
+ uint64_t protectedContent = 0;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeProtectedContent(protectedContent, &vec));
+
+ Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_ProtectedContent, vec);
+ ASSERT_EQ(err, Error::UNSUPPORTED);
+ vec.resize(0);
+
+ uint64_t realProtectedContent = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ProtectedContent, &vec));
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeProtectedContent(vec, &realProtectedContent));
+ EXPECT_EQ(1, realProtectedContent);
+}
+
+/**
+ * Test IMapper::set(Compression)
+ */
+TEST_P(GraphicsMapperHidlTest, SetCompression) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ ExtendableType compression = gralloc4::Compression_DisplayStreamCompression;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeCompression(compression, &vec));
+
+ testSet(info, gralloc4::MetadataType_Compression, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType realCompression = gralloc4::Compression_None;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeCompression(vec, &realCompression));
+
+ EXPECT_EQ(compression.name, realCompression.name);
+ EXPECT_EQ(compression.value, realCompression.value);
+ });
+}
+
+/**
+ * Test IMapper::set(Interlaced)
+ */
+TEST_P(GraphicsMapperHidlTest, SetInterlaced) {
+ ExtendableType interlaced = gralloc4::Interlaced_RightLeft;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeInterlaced(interlaced, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType realInterlaced = gralloc4::Interlaced_None;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeInterlaced(vec, &realInterlaced));
+
+ EXPECT_EQ(interlaced.name, realInterlaced.name);
+ EXPECT_EQ(interlaced.value, realInterlaced.value);
+ });
+}
+
+/**
+ * Test IMapper::set(ChromaSiting)
+ */
+TEST_P(GraphicsMapperHidlTest, SetChromaSiting) {
+ ExtendableType chromaSiting = gralloc4::ChromaSiting_SitedInterstitial;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeChromaSiting(chromaSiting, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_ChromaSiting, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType realChromaSiting = gralloc4::ChromaSiting_None;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeChromaSiting(vec, &realChromaSiting));
+
+ EXPECT_EQ(chromaSiting.name, realChromaSiting.name);
+ EXPECT_EQ(chromaSiting.value, realChromaSiting.value);
+ });
+}
+
+/**
+ * Test IMapper::set(PlaneLayouts)
+ */
+TEST_P(GraphicsMapperHidlTest, SetPlaneLayouts) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+ std::vector<PlaneLayout> planeLayouts;
+ PlaneLayout planeLayoutA;
+ PlaneLayout planeLayoutRGB;
+ PlaneLayoutComponent component;
+
+ planeLayoutA.offsetInBytes = 0;
+ planeLayoutA.sampleIncrementInBits = 8;
+ planeLayoutA.strideInBytes = info.width + 20;
+ planeLayoutA.widthInSamples = info.width;
+ planeLayoutA.heightInSamples = info.height;
+ planeLayoutA.totalSizeInBytes = planeLayoutA.strideInBytes * info.height;
+ planeLayoutA.horizontalSubsampling = 1;
+ planeLayoutA.verticalSubsampling = 1;
+ planeLayoutA.crop.left = 0;
+ planeLayoutA.crop.top = 0;
+ planeLayoutA.crop.right = info.width;
+ planeLayoutA.crop.bottom = info.height;
+
+ component.type = gralloc4::PlaneLayoutComponentType_A;
+ component.offsetInBits = 0;
+ component.sizeInBits = 8;
+ planeLayoutA.components.push_back(component);
+
+ planeLayouts.push_back(planeLayoutA);
+
+ planeLayoutRGB.offsetInBytes = 0;
+ planeLayoutRGB.sampleIncrementInBits = 32;
+ planeLayoutRGB.strideInBytes = info.width + 20;
+ planeLayoutRGB.widthInSamples = info.width;
+ planeLayoutRGB.heightInSamples = info.height;
+ planeLayoutRGB.totalSizeInBytes = planeLayoutRGB.strideInBytes * info.height;
+ planeLayoutRGB.horizontalSubsampling = 1;
+ planeLayoutRGB.verticalSubsampling = 1;
+ planeLayoutRGB.crop.left = 0;
+ planeLayoutRGB.crop.top = 0;
+ planeLayoutRGB.crop.right = info.width;
+ planeLayoutRGB.crop.bottom = info.height;
+
+ component.type = gralloc4::PlaneLayoutComponentType_R;
+ planeLayoutRGB.components.push_back(component);
+ component.type = gralloc4::PlaneLayoutComponentType_G;
+ planeLayoutRGB.components.push_back(component);
+ component.type = gralloc4::PlaneLayoutComponentType_B;
+ planeLayoutRGB.components.push_back(component);
+
+ planeLayouts.push_back(planeLayoutRGB);
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodePlaneLayouts(planeLayouts, &vec));
+
+ Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_PlaneLayouts, vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ std::vector<PlaneLayout> realPlaneLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &realPlaneLayouts));
+
+ ASSERT_EQ(planeLayouts.size(), realPlaneLayouts.size());
+
+ for (int i = 0; i < realPlaneLayouts.size(); i++) {
+ const auto& planeLayout = planeLayouts[i];
+ const auto& realPlaneLayout = realPlaneLayouts[i];
+
+ EXPECT_EQ(planeLayout.offsetInBytes, realPlaneLayout.offsetInBytes);
+ EXPECT_EQ(planeLayout.sampleIncrementInBits, realPlaneLayout.sampleIncrementInBits);
+ EXPECT_EQ(planeLayout.strideInBytes, realPlaneLayout.strideInBytes);
+ EXPECT_EQ(planeLayout.widthInSamples, realPlaneLayout.widthInSamples);
+ EXPECT_EQ(planeLayout.heightInSamples, realPlaneLayout.heightInSamples);
+ EXPECT_LE(planeLayout.totalSizeInBytes, realPlaneLayout.totalSizeInBytes);
+ EXPECT_EQ(planeLayout.horizontalSubsampling, realPlaneLayout.horizontalSubsampling);
+ EXPECT_EQ(planeLayout.verticalSubsampling, realPlaneLayout.verticalSubsampling);
+
+ EXPECT_EQ(planeLayout.crop.left, realPlaneLayout.crop.left);
+ EXPECT_EQ(planeLayout.crop.top, realPlaneLayout.crop.top);
+ EXPECT_EQ(planeLayout.crop.right, realPlaneLayout.crop.right);
+ EXPECT_EQ(planeLayout.crop.bottom, realPlaneLayout.crop.bottom);
+
+ ASSERT_EQ(planeLayout.components.size(), realPlaneLayout.components.size());
+
+ for (int j = 0; j < realPlaneLayout.components.size(); j++) {
+ const auto& component = planeLayout.components[j];
+ const auto& realComponent = realPlaneLayout.components[j];
+
+ EXPECT_EQ(component.type.name, realComponent.type.name);
+ EXPECT_EQ(component.type.value, realComponent.type.value);
+ EXPECT_EQ(component.sizeInBits, realComponent.sizeInBits);
+ EXPECT_EQ(component.offsetInBits, realComponent.offsetInBits);
+ }
+ }
+}
+
+/**
+ * Test IMapper::set(Dataspace)
+ */
+TEST_P(GraphicsMapperHidlTest, SetDataspace) {
+ Dataspace dataspace = Dataspace::V0_SRGB_LINEAR;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(dataspace, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ Dataspace realDataspace = Dataspace::UNKNOWN;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeDataspace(vec, &realDataspace));
+ EXPECT_EQ(dataspace, realDataspace);
+ });
+}
+
+/**
+ * Test IMapper::set(BlendMode)
+ */
+TEST_P(GraphicsMapperHidlTest, SetBlendMode) {
+ BlendMode blendMode = BlendMode::PREMULTIPLIED;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeBlendMode(blendMode, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ BlendMode realBlendMode = BlendMode::INVALID;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBlendMode(vec, &realBlendMode));
+ EXPECT_EQ(blendMode, realBlendMode);
+ });
+}
+
+/**
+ * Test IMapper::set(metadata) with a bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, SetMetadataNullBuffer) {
+ const native_handle_t* bufferHandle = nullptr;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Name, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Width, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Height, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_LayerCount, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatModifier, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_AllocationSize, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ProtectedContent, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Compression, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Interlaced, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ChromaSiting, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PlaneLayouts, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+}
+
+/**
+ * Test IMapper::set(metadata) for constant metadata
+ */
+TEST_P(GraphicsMapperHidlTest, SetConstantMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Name, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Width, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Height, vec));
+ ASSERT_EQ(Error::BAD_VALUE,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_LayerCount, vec));
+ ASSERT_EQ(Error::BAD_VALUE,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec));
+}
+
+/**
+ * Test IMapper::set(metadata) for bad metadata
+ */
+TEST_P(GraphicsMapperHidlTest, SetBadMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Name, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Width, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Height, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_LayerCount, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatModifier, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_AllocationSize, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ProtectedContent, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Compression, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Interlaced, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ChromaSiting, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PlaneLayouts, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(BufferId)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBufferId) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_BufferId, &vec));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Name)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoName) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Name, &vec));
+
+ std::string name;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeName(vec, &name));
+ EXPECT_EQ(mDummyDescriptorInfo.name, name);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Width)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoWidth) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Width, &vec));
+
+ uint64_t width = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeWidth(vec, &width));
+ EXPECT_EQ(mDummyDescriptorInfo.width, width);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Height)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoHeight) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Height, &vec));
+
+ uint64_t height = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeHeight(vec, &height));
+ EXPECT_EQ(mDummyDescriptorInfo.height, height);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PixelFormatRequested)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatRequested) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatRequested, &vec));
+
+ PixelFormat pixelFormatRequested = PixelFormat::BLOB;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatRequested(vec, &pixelFormatRequested));
+ EXPECT_EQ(mDummyDescriptorInfo.format, pixelFormatRequested);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PixelFormatFourCC)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatFourCC) {
+ hidl_vec<uint8_t> vec;
+ Error err = mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC, &vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ uint32_t pixelFormatFourCC = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatFourCC(vec, &pixelFormatFourCC));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PixelFormatModifier)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatModifier) {
+ hidl_vec<uint8_t> vec;
+ Error err = mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier, &vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ uint64_t pixelFormatModifier = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatModifier(vec, &pixelFormatModifier));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Usage)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUsage) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Usage, &vec));
+
+ uint64_t usage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &usage));
+ EXPECT_EQ(mDummyDescriptorInfo.usage, usage);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(AllocationSize)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoAllocationSize) {
+ hidl_vec<uint8_t> vec;
+ Error err = mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_AllocationSize, &vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ uint64_t allocationSize = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeAllocationSize(vec, &allocationSize));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(ProtectedContent)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoProtectedContent) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ info, gralloc4::MetadataType_ProtectedContent, &vec));
+
+ uint64_t protectedContent = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeProtectedContent(vec, &protectedContent));
+ EXPECT_EQ(1, protectedContent);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Compression)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoCompression) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ info, gralloc4::MetadataType_Compression, &vec));
+
+ ExtendableType compression = gralloc4::Compression_DisplayStreamCompression;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeCompression(vec, &compression));
+
+ EXPECT_EQ(gralloc4::Compression_None.name, compression.name);
+ EXPECT_EQ(gralloc4::Compression_None.value, compression.value);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Interlaced)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoInterlaced) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced, &vec));
+
+ ExtendableType interlaced = gralloc4::Interlaced_TopBottom;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeInterlaced(vec, &interlaced));
+
+ EXPECT_EQ(gralloc4::Interlaced_None.name, interlaced.name);
+ EXPECT_EQ(gralloc4::Interlaced_None.value, interlaced.value);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(ChromaSiting)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoChromaSiting) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_ChromaSiting, &vec));
+
+ ExtendableType chromaSiting = gralloc4::ChromaSiting_CositedHorizontal;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeChromaSiting(vec, &chromaSiting));
+
+ EXPECT_EQ(gralloc4::ChromaSiting_None.name, chromaSiting.name);
+ EXPECT_EQ(gralloc4::ChromaSiting_None.value, chromaSiting.value);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PlaneLayouts)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPlaneLayouts) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_PlaneLayouts, &vec));
+
+ std::vector<PlaneLayout> planeLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
+ ASSERT_NO_FATAL_FAILURE(verifyDummyDescriptorInfoPlaneLayouts(planeLayouts));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Dataspace)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoDataspace) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace, &vec));
+
+ Dataspace dataspace = Dataspace::DISPLAY_P3;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeDataspace(vec, &dataspace));
+ EXPECT_EQ(Dataspace::UNKNOWN, dataspace);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(BlendMode)
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBlendMode) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode, &vec));
+
+ BlendMode blendMode = BlendMode::COVERAGE;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBlendMode(vec, &blendMode));
+ EXPECT_EQ(BlendMode::INVALID, blendMode);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported metadata
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedMetadata) {
+ MetadataType metadataTypeFake = {"FAKE", 1};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported standard metadata
+ */
+TEST_P(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedStandardMetadata) {
+ MetadataType metadataTypeFake = {GRALLOC4_STANDARD_METADATA_TYPE, 9999};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::listSupportedMetadataTypes()
+ */
+TEST_P(GraphicsMapperHidlTest, ListSupportedMetadataTypes) {
+ hidl_vec<IMapper::MetadataTypeDescription> descriptions;
+ mGralloc->getMapper()->listSupportedMetadataTypes(
+ [&](const auto& tmpError, const auto& tmpDescriptions) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ descriptions = tmpDescriptions;
+ });
+
+ std::set<StandardMetadataType> foundMetadataTypes;
+
+ std::set<StandardMetadataType> notSettableMetadataTypes{
+ StandardMetadataType::BUFFER_ID, StandardMetadataType::NAME,
+ StandardMetadataType::WIDTH, StandardMetadataType::HEIGHT,
+ StandardMetadataType::LAYER_COUNT, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
+ StandardMetadataType::USAGE};
+
+ ASSERT_LE(sRequiredMetadataTypes.size(), descriptions.size());
+
+ for (const auto& description : descriptions) {
+ const auto& metadataType = description.metadataType;
+
+ if (!gralloc4::isStandardMetadataType(metadataType)) {
+ EXPECT_GT(0, description.description.size());
+ continue;
+ }
+
+ StandardMetadataType type = gralloc4::getStandardMetadataTypeValue(metadataType);
+
+ if (sRequiredMetadataTypes.find(type) == sRequiredMetadataTypes.end()) {
+ continue;
+ }
+
+ ASSERT_EQ(foundMetadataTypes.find(type), foundMetadataTypes.end());
+ foundMetadataTypes.insert(type);
+
+ ASSERT_TRUE(description.isGettable);
+
+ if (notSettableMetadataTypes.find(type) != notSettableMetadataTypes.end()) {
+ ASSERT_FALSE(description.isSettable);
+ }
+ }
+
+ ASSERT_EQ(sRequiredMetadataTypes, foundMetadataTypes);
+}
+
+/**
+ * Test IMapper::dumpBuffer()
+ */
+TEST_P(GraphicsMapperHidlTest, DumpBuffer) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ IMapper::BufferDump bufferDump;
+ mGralloc->getMapper()->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ bufferDump = tmpBufferDump;
+ });
+
+ ASSERT_NO_FATAL_FAILURE(verifyBufferDump(bufferDump, buffer));
+}
+
+/**
+ * Test IMapper::dumpBuffer() with an invalid buffer
+ */
+TEST_P(GraphicsMapperHidlTest, DumpBufferNullBuffer) {
+ native_handle_t* bufferHandle = nullptr;
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ mGralloc->getMapper()->dumpBuffer(buffer,
+ [&](const auto& tmpError, const auto& /*tmpBufferDump*/) {
+ ASSERT_EQ(Error::BAD_BUFFER, tmpError);
+ });
+}
+
+/**
+ * Test IMapper::dumpBuffer() multiple
+ */
+TEST_P(GraphicsMapperHidlTest, DumpBuffers) {
+ size_t bufferCount = 10;
+
+ for (int i = 0; i < bufferCount; i++) {
+ ASSERT_NO_FATAL_FAILURE(mGralloc->allocate(mDummyDescriptorInfo, true));
+ }
+
+ hidl_vec<IMapper::BufferDump> bufferDump;
+ mGralloc->getMapper()->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ bufferDump = tmpBufferDump;
+ });
+
+ ASSERT_EQ(bufferCount, bufferDump.size());
+
+ for (const auto& dump : bufferDump) {
+ ASSERT_NO_FATAL_FAILURE(verifyBufferDump(dump));
+ }
+}
+
+/**
+ * Test IMapper::getReservedRegion()
+ */
+TEST_P(GraphicsMapperHidlTest, GetReservedRegion) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+
+ const int pageSize = getpagesize();
+ ASSERT_GE(0, pageSize);
+ std::vector<uint64_t> requestedReservedSizes{1, 10, 333, static_cast<uint64_t>(pageSize) / 2,
+ static_cast<uint64_t>(pageSize)};
+
+ for (auto requestedReservedSize : requestedReservedSizes) {
+ info.reservedSize = requestedReservedSize;
+
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+ void* reservedRegion = nullptr;
+ uint64_t reservedSize = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize));
+ ASSERT_NE(nullptr, reservedRegion);
+ ASSERT_EQ(requestedReservedSize, reservedSize);
+
+ uint8_t testValue = 1;
+ memset(reservedRegion, testValue, reservedSize);
+ for (uint64_t i = 0; i < reservedSize; i++) {
+ ASSERT_EQ(testValue, static_cast<uint8_t*>(reservedRegion)[i]);
+ }
+ }
+}
+
+/**
+ * Test IMapper::getReservedRegion() request over a page
+ */
+TEST_P(GraphicsMapperHidlTest, GetLargeReservedRegion) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+
+ const int pageSize = getpagesize();
+ ASSERT_GE(0, pageSize);
+ std::vector<uint64_t> requestedReservedSizes{static_cast<uint64_t>(pageSize) * 2,
+ static_cast<uint64_t>(pageSize) * 10,
+ static_cast<uint64_t>(pageSize) * 1000};
+
+ for (auto requestedReservedSize : requestedReservedSizes) {
+ info.reservedSize = requestedReservedSize;
+
+ BufferDescriptor descriptor;
+ ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(info));
+
+ Error err;
+ mGralloc->getAllocator()->allocate(
+ descriptor, 1,
+ [&](const auto& tmpError, const auto&, const auto&) { err = tmpError; });
+ if (err == Error::UNSUPPORTED) {
+ continue;
+ }
+ ASSERT_EQ(Error::NONE, err);
+
+ void* reservedRegion = nullptr;
+ uint64_t reservedSize = 0;
+ err = mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize);
+
+ ASSERT_EQ(Error::NONE, err);
+ ASSERT_NE(nullptr, reservedRegion);
+ ASSERT_EQ(requestedReservedSize, reservedSize);
+ }
+}
+
+/**
+ * Test IMapper::getReservedRegion() across multiple mappers
+ */
+TEST_P(GraphicsMapperHidlTest, GetReservedRegionMultiple) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+
+ const int pageSize = getpagesize();
+ ASSERT_GE(0, pageSize);
+ info.reservedSize = pageSize;
+
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+ void* reservedRegion1 = nullptr;
+ uint64_t reservedSize1 = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion1, &reservedSize1));
+ ASSERT_NE(nullptr, reservedRegion1);
+ ASSERT_EQ(info.reservedSize, reservedSize1);
+
+ std::unique_ptr<Gralloc> anotherGralloc;
+ ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
+ std::get<1>(GetParam())));
+
+ void* reservedRegion2 = nullptr;
+ uint64_t reservedSize2 = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion2, &reservedSize2));
+ ASSERT_EQ(reservedRegion1, reservedRegion2);
+ ASSERT_EQ(reservedSize1, reservedSize2);
+}
+
+/**
+ * Test IMapper::getReservedRegion() with a bad buffer
+ */
+TEST_P(GraphicsMapperHidlTest, GetReservedRegionBadBuffer) {
+ const native_handle_t* bufferHandle = nullptr;
+
+ void* reservedRegion = nullptr;
+ uint64_t reservedSize = 0;
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize));
+ ASSERT_EQ(nullptr, reservedRegion);
+ ASSERT_EQ(0, reservedSize);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, GraphicsMapperHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
+
} // namespace
} // namespace vts
} // namespace V4_0
@@ -526,13 +2015,3 @@
} // namespace graphics
} // namespace hardware
} // namespace android
-
-int main(int argc, char** argv) {
- using android::hardware::graphics::mapper::V4_0::vts::GraphicsMapperHidlEnvironment;
- ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp
index 049e393..7581335 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -18,3 +18,55 @@
}
+cc_library_static {
+ name: "android.hardware.health@1.0-impl-helper",
+ vendor: true,
+ srcs: ["Health.cpp"],
+
+ header_libs: [
+ "libbase_headers",
+ "libhealthd_headers",
+ ],
+
+ shared_libs: [
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "android.hardware.health@1.0",
+ ],
+
+ static_libs: [
+ "android.hardware.health@1.0-convert",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.health@1.0-impl",
+ vendor: true,
+ relative_install_path: "hw",
+
+ static_libs: [
+ "android.hardware.health@1.0-impl-helper",
+ "android.hardware.health@1.0-convert",
+ "libhealthd.default",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.health@1.0-service",
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.health@1.0-service.rc"],
+ srcs: ["HealthService.cpp"],
+
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libdl",
+ "libbase",
+ "libutils",
+ "libhidlbase",
+ "android.hardware.health@1.0",
+ ],
+}
diff --git a/health/1.0/default/Android.mk b/health/1.0/default/Android.mk
deleted file mode 100644
index bbf37af..0000000
--- a/health/1.0/default/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.health@1.0-impl
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_C_INCLUDES := system/core/base/include
-LOCAL_SRC_FILES := \
- Health.cpp \
-
-LOCAL_HEADER_LIBRARIES := libhealthd_headers
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libhidlbase \
- liblog \
- libutils \
- android.hardware.health@1.0 \
-
-LOCAL_STATIC_LIBRARIES := android.hardware.health@1.0-convert
-
-LOCAL_HAL_STATIC_LIBRARIES := libhealthd
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_MODULE := android.hardware.health@1.0-service
-LOCAL_INIT_RC := android.hardware.health@1.0-service.rc
-LOCAL_SRC_FILES := \
- HealthService.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libdl \
- libbase \
- libutils \
- libhidlbase \
- android.hardware.health@1.0 \
-
-include $(BUILD_EXECUTABLE)
-
-include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/health/1.0/default/README.md b/health/1.0/default/README.md
new file mode 100644
index 0000000..1ded7de
--- /dev/null
+++ b/health/1.0/default/README.md
@@ -0,0 +1,66 @@
+# Implement the 2.1 HAL instead!
+
+It is strongly recommended that you implement the 2.1 HAL directly. See
+`hardware/interfaces/health/2.1/README.md` for more details.
+
+# Implement Health 1.0 HAL
+
+1. Install common binderized service. The binderized service `dlopen()`s
+ passthrough implementations on the device, so there is no need to write
+ your own.
+
+ ```mk
+ # Install default binderized implementation to vendor.
+ PRODUCT_PACKAGES += android.hardware.health@1.0-service
+ ```
+
+1. Add proper VINTF manifest entry to your device manifest. Example:
+
+ ```xml
+ <hal format="hidl">
+ <name>android.hardware.health</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IHealth</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ ```
+
+1. Install the proper passthrough implemetation.
+
+ 1. If you want to use the default implementation (with default `libhealthd`),
+ add the following to `device.mk`:
+
+ ```mk
+ PRODUCT_PACKAGES += \
+ android.hardware.health@1.0-impl
+ ```
+
+ 1. Otherwise, if you have a customized `libhealthd.<board>`:
+
+ 1. Define your passthrough implementation. Example (replace `<device>`
+ and `<board>` accordingly):
+
+ ```bp
+ cc_library_shared {
+ name: "android.hardware.health@1.0-impl-<device>",
+ vendor: true,
+ relative_install_path: "hw",
+
+ static_libs: [
+ "android.hardware.health@1.0-impl-helper",
+ "android.hardware.health@1.0-convert",
+ "libhealthd.<board>",
+ ],
+ }
+ ```
+
+ 1. Add to `device.mk`.
+
+ ```
+ PRODUCT_PACKAGES += android.hardware.health@1.0-impl-<device>
+ ```
+
+ 1. Define appropriate SELinux permissions.
diff --git a/health/2.0/default/healthd_common_adapter.cpp b/health/2.0/default/healthd_common_adapter.cpp
index 8fc689d..0b5d869 100644
--- a/health/2.0/default/healthd_common_adapter.cpp
+++ b/health/2.0/default/healthd_common_adapter.cpp
@@ -49,11 +49,14 @@
static std::unique_ptr<HealthLoopAdapter> health_loop;
int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
+ if (!health_loop) return -1;
+
auto wrapped_handler = [handler](auto*, uint32_t epevents) { handler(epevents); };
return health_loop->RegisterEvent(fd, wrapped_handler, wakeup);
}
void healthd_battery_update_internal(bool charger_online) {
+ if (!health_loop) return;
health_loop->AdjustWakealarmPeriods(charger_online);
}
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index a7cbb36..4409bde 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -527,9 +527,9 @@
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 3)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE),
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
&key_blob, &key_characteristics));
ASSERT_GT(key_blob.size(), 0U);
@@ -579,11 +579,12 @@
for (auto key_size : InvalidKeySizes(Algorithm::RSA)) {
HidlBuf key_blob;
KeyCharacteristics key_characteristics;
- ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 3)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE),
- &key_blob, &key_characteristics));
+ ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE),
+ &key_blob, &key_characteristics));
}
}
@@ -4338,25 +4339,29 @@
* to specify how many following bytes will be used to encode the length.
*/
TEST_F(AttestationTest, AttestationApplicationIDLengthProperlyEncoded) {
- auto creation_time = std::chrono::system_clock::now();
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .EcdsaSigningKey(EcCurve::P_256)
- .Digest(Digest::SHA_2_256)));
+ std::vector<uint32_t> app_id_lengths{143, 258};
+ for (uint32_t length : app_id_lengths) {
+ auto creation_time = std::chrono::system_clock::now();
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::SHA_2_256)));
- hidl_vec<hidl_vec<uint8_t>> cert_chain;
- const string app_id(143, 'a');
- ASSERT_EQ(ErrorCode::OK,
- AttestKey(AuthorizationSetBuilder()
- .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
- .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf(app_id)),
- &cert_chain));
- EXPECT_GE(cert_chain.size(), 2U);
+ hidl_vec<hidl_vec<uint8_t>> cert_chain;
+ const string app_id(length, 'a');
+ ASSERT_EQ(ErrorCode::OK,
+ AttestKey(AuthorizationSetBuilder()
+ .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+ .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf(app_id)),
+ &cert_chain));
+ EXPECT_GE(cert_chain.size(), 2U);
- EXPECT_TRUE(verify_attestation_record("challenge", app_id, //
- key_characteristics_.softwareEnforced, //
- key_characteristics_.hardwareEnforced, //
- SecLevel(), cert_chain[0], creation_time));
+ EXPECT_TRUE(verify_attestation_record("challenge", app_id, //
+ key_characteristics_.softwareEnforced, //
+ key_characteristics_.hardwareEnforced, //
+ SecLevel(), cert_chain[0], creation_time));
+ CheckedDeleteKey();
+ }
}
/*
* AttestationTest.AesAttestation
@@ -4600,6 +4605,57 @@
}
}
+typedef KeymasterHidlTest TransportLimitTest;
+
+/*
+ * TransportLimitTest.LargeFinishInput
+ *
+ * Verifies that passing large input data to finish either succeeds or fails as expected.
+ */
+TEST_F(TransportLimitTest, LargeFinishInput) {
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(128)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::NONE)));
+
+ for (int msg_size = 10 /*1KB*/; msg_size <= 17 /*128KB*/; msg_size++) {
+ auto cipher_params =
+ AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE);
+
+ AuthorizationSet out_params;
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, cipher_params, &out_params));
+
+ string plain_message = std::string(1 << msg_size, 'x');
+ string encrypted_message;
+ auto rc = Finish(plain_message, &encrypted_message);
+
+ if (rc == ErrorCode::OK) {
+ EXPECT_EQ(plain_message.size(), encrypted_message.size())
+ << "Encrypt finish returned OK, but did not consume all of the given input";
+ } else {
+ EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, rc)
+ << "Encrypt finish failed in an unexpected way when given a large input";
+ continue;
+ }
+ cipher_params.push_back(out_params);
+
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, cipher_params));
+
+ string decrypted_message;
+ rc = Finish(encrypted_message, &decrypted_message);
+
+ if (rc == ErrorCode::OK) {
+ EXPECT_EQ(plain_message.size(), decrypted_message.size())
+ << "Decrypt finish returned OK, did not consume all of the given input";
+ } else {
+ EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, rc)
+ << "Encrypt finish failed in an unexpected way when given a large input";
+ }
+ }
+
+ CheckedDeleteKey();
+}
} // namespace test
} // namespace V4_0
diff --git a/vibrator/1.4/vts/functional/Android.bp b/keymaster/4.0/vts/performance/Android.bp
similarity index 65%
copy from vibrator/1.4/vts/functional/Android.bp
copy to keymaster/4.0/vts/performance/Android.bp
index 202a824..9434bc9 100644
--- a/vibrator/1.4/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/performance/Android.bp
@@ -14,20 +14,16 @@
// limitations under the License.
//
-cc_test {
- name: "VtsHalVibratorV1_4TargetTest",
+cc_benchmark {
+ name: "keymaster_benchmark",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["VtsHalVibratorV1_4TargetTest.cpp"],
- static_libs: [
- "android.hardware.vibrator@1.0",
- "android.hardware.vibrator@1.1",
- "android.hardware.vibrator@1.2",
- "android.hardware.vibrator@1.3",
- "android.hardware.vibrator@1.4",
+ srcs: [
+ "Benchmark.cpp",
],
- test_suites: [
- "general-tests",
- "vts-core",
+ static_libs: [
+ "android.hardware.keymaster@4.0",
+ "libkeymaster4support",
+ "libsoftkeymasterdevice",
+ "libchrome"
],
}
-
diff --git a/keymaster/4.0/vts/performance/Benchmark.cpp b/keymaster/4.0/vts/performance/Benchmark.cpp
new file mode 100644
index 0000000..96ef5bf
--- /dev/null
+++ b/keymaster/4.0/vts/performance/Benchmark.cpp
@@ -0,0 +1,717 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "keymaster_benchmark"
+
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+#include <android/hardware/keymaster/4.0/types.h>
+#include <keymaster/keymaster_configuration.h>
+#include <keymasterV4_0/authorization_set.h>
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <binder/IServiceManager.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include <log/log.h>
+#include <utils/StrongPointer.h>
+
+#include <benchmark/benchmark.h>
+#include <hidl/Status.h>
+
+#include <base/command_line.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace test {
+
+// libutils:
+using android::OK;
+using android::sp;
+using android::status_t;
+
+// libhidl:
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+// IKeymaster:
+using android::IServiceManager;
+using android::hardware::hidl_string;
+using android::hardware::keymaster::V4_0::AuthorizationSet;
+using android::hardware::keymaster::V4_0::AuthorizationSetBuilder;
+using android::hardware::keymaster::V4_0::BlockMode;
+using android::hardware::keymaster::V4_0::ErrorCode;
+using android::hardware::keymaster::V4_0::IKeymasterDevice;
+using android::hardware::keymaster::V4_0::KeyCharacteristics;
+using android::hardware::keymaster::V4_0::SecurityLevel;
+
+// Standard library:
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::optional;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+class HidlBuf : public hidl_vec<uint8_t> {
+ typedef hidl_vec<uint8_t> super;
+
+ public:
+ HidlBuf() {}
+ HidlBuf(const super& other) : super(other) {}
+ HidlBuf(super&& other) : super(std::move(other)) {}
+ explicit HidlBuf(const std::string& other) : HidlBuf() { *this = other; }
+
+ HidlBuf& operator=(const super& other) {
+ super::operator=(other);
+ return *this;
+ }
+
+ HidlBuf& operator=(super&& other) {
+ super::operator=(std::move(other));
+ return *this;
+ }
+
+ HidlBuf& operator=(const string& other) {
+ resize(other.size());
+ std::copy(other.begin(), other.end(), begin());
+ return *this;
+ }
+
+ string to_string() const { return string(reinterpret_cast<const char*>(data()), size()); }
+};
+
+#define SMALL_MESSAGE_SIZE 64
+#define MEDIUM_MESSAGE_SIZE 1024
+#define LARGE_MESSAGE_SIZE 131072
+
+class KeymasterWrapper {
+ private:
+ sp<IKeymasterDevice> keymaster_;
+ SecurityLevel securityLevel_;
+ hidl_string name_;
+ hidl_string author_;
+ HidlBuf key_blob_;
+ KeyCharacteristics key_characteristics_;
+ ErrorCode error_;
+ string key_transform_;
+ string keymaster_name_;
+ uint32_t os_version_;
+ uint32_t os_patch_level_;
+ std::vector<string> message_cache_;
+
+ bool GenerateKey(const AuthorizationSet& authSet) {
+ return (keymaster_
+ ->generateKey(
+ authSet.hidl_data(),
+ [&](ErrorCode hidl_error, const hidl_vec<uint8_t>& hidl_key_blob,
+ const KeyCharacteristics& hidl_key_characteristics) {
+ error_ = hidl_error;
+ key_blob_ = hidl_key_blob;
+ key_characteristics_ = std::move(hidl_key_characteristics);
+ })
+ .isOk() &&
+ error_ == ErrorCode::OK);
+ }
+
+ bool GenerateKey(Algorithm algorithm, int keySize, Digest digest = Digest::NONE,
+ PaddingMode padding = PaddingMode::NONE, optional<BlockMode> blockMode = {}) {
+ AuthorizationSetBuilder authSet = AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT)
+ .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT)
+ .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
+ .Authorization(TAG_PURPOSE, KeyPurpose::VERIFY)
+ .Authorization(TAG_KEY_SIZE, keySize)
+ .Authorization(TAG_ALGORITHM, algorithm)
+ .Digest(digest)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Padding(padding);
+ if (blockMode) {
+ authSet.BlockMode(*blockMode);
+ }
+ if (algorithm == Algorithm::RSA) {
+ authSet.Authorization(TAG_RSA_PUBLIC_EXPONENT, 65537U);
+ }
+ return GenerateKey(authSet);
+ }
+
+ KeymasterWrapper(const sp<IKeymasterDevice> keymaster) {
+ os_version_ = ::keymaster::GetOsVersion();
+ os_patch_level_ = ::keymaster::GetOsPatchlevel();
+ keymaster_ = keymaster;
+ keymaster_->getHardwareInfo([&](SecurityLevel securityLevel, const hidl_string& name,
+ const hidl_string& author) {
+ securityLevel_ = securityLevel;
+ name_ = name;
+ author_ = author;
+ });
+
+ message_cache_.push_back(string(SMALL_MESSAGE_SIZE, 'x'));
+ message_cache_.push_back(string(MEDIUM_MESSAGE_SIZE, 'x'));
+ message_cache_.push_back(string(LARGE_MESSAGE_SIZE, 'x'));
+ }
+
+ public:
+ static KeymasterWrapper* newInstance(const std::string& keymaster_name) {
+ auto keymaster = IKeymasterDevice::getService(keymaster_name);
+ if (!keymaster) {
+ std::cerr << "Error: unable to find keymaster service named " << keymaster_name
+ << std::endl;
+ return nullptr;
+ }
+ return new KeymasterWrapper(keymaster);
+ }
+
+ bool GenerateKey(string transform, int keySize, bool sign = false) {
+ if (transform == key_transform_) {
+ return true;
+ } else if (key_transform_ != "") {
+ // Deleting old key first
+ if (!DeleteKey()) {
+ return false;
+ }
+ }
+ optional<Algorithm> algorithm = getAlgorithm(transform);
+ if (!algorithm) {
+ cerr << "Error: invalid algorithm " << transform << endl;
+ return false;
+ }
+ key_transform_ = transform;
+ return GenerateKey(*algorithm, keySize, getDigest(transform), getPadding(transform, sign),
+ getBlockMode(transform));
+ }
+
+ bool DeleteKey() {
+ key_blob_ = HidlBuf();
+ key_transform_ = "";
+ return keymaster_->deleteKey(key_blob_).isOk();
+ }
+
+ AuthorizationSet getOperationParams(string transform, bool sign = false) {
+ AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+ .Padding(getPadding(transform, sign))
+ .Authorization(TAG_MAC_LENGTH, 128)
+ .Digest(getDigest(transform));
+ optional<BlockMode> blockMode = getBlockMode(transform);
+ if (blockMode) {
+ builder.BlockMode(*blockMode);
+ }
+ return std::move(builder);
+ }
+
+ optional<OperationHandle> EncryptBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::ENCRYPT, in_params, out_params);
+ }
+
+ optional<OperationHandle> DecryptBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::DECRYPT, in_params, out_params);
+ }
+
+ optional<OperationHandle> SignBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::SIGN, in_params, out_params);
+ }
+
+ optional<OperationHandle> VerifyBegin(AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet) {
+ return Begin(KeyPurpose::VERIFY, in_params, out_params);
+ }
+
+ optional<OperationHandle> Begin(KeyPurpose operation, const AuthorizationSet& in_params,
+ AuthorizationSet* out_params) {
+ OperationHandle op_handle;
+ if (!keymaster_
+ ->begin(operation, key_blob_, in_params.hidl_data(), HardwareAuthToken(),
+ [&](ErrorCode hidl_error,
+ const hidl_vec<KeyParameter>& hidl_out_params,
+ uint64_t hidl_op_handle) {
+ error_ = hidl_error;
+ out_params->push_back(AuthorizationSet(hidl_out_params));
+ op_handle = hidl_op_handle;
+ })
+ .isOk() ||
+ error_ != ErrorCode::OK) {
+ keymaster_->abort(op_handle);
+ return {};
+ }
+ return op_handle;
+ }
+
+ optional<string> ProcessMessage(const OperationHandle& op_handle, const string& message,
+ const AuthorizationSet& in_params,
+ AuthorizationSet* out_params = new AuthorizationSet,
+ const string& signature = "") {
+ static const int HIDL_BUFFER_LIMIT = 1 << 14; // 16KB
+
+ string output;
+ size_t input_consumed = 0;
+ while (message.length() - input_consumed > 0) {
+ if (!keymaster_
+ ->update(op_handle, in_params.hidl_data(),
+ HidlBuf(message.substr(input_consumed, HIDL_BUFFER_LIMIT)),
+ HardwareAuthToken(), VerificationToken(),
+ [&](ErrorCode hidl_error, uint32_t hidl_input_consumed,
+ const hidl_vec<KeyParameter>& hidl_out_params,
+ const HidlBuf& hidl_output) {
+ error_ = hidl_error;
+ out_params->push_back(AuthorizationSet(hidl_out_params));
+ output.append(hidl_output.to_string());
+ input_consumed += hidl_input_consumed;
+ })
+ .isOk() ||
+ error_ != ErrorCode::OK) {
+ keymaster_->abort(op_handle);
+ return {};
+ }
+ }
+
+ if (!keymaster_
+ ->finish(op_handle, in_params.hidl_data(),
+ HidlBuf(message.substr(input_consumed)), HidlBuf(signature),
+ HardwareAuthToken(), VerificationToken(),
+ [&](ErrorCode hidl_error,
+ const hidl_vec<KeyParameter>& hidl_out_params,
+ const HidlBuf& hidl_output) {
+ error_ = hidl_error;
+ out_params->push_back(AuthorizationSet(hidl_out_params));
+ output.append(hidl_output.to_string());
+ })
+ .isOk() ||
+ error_ != ErrorCode::OK) {
+ keymaster_->abort(op_handle);
+ return {};
+ }
+
+ return output;
+ }
+
+ int getError() { return static_cast<int>(error_); }
+
+ const string getHardwareName() { return name_; }
+
+ SecurityLevel getSecurityLevel() { return securityLevel_; }
+
+ const string& GenerateMessage(int size) {
+ for (const string& message : message_cache_) {
+ if (message.size() == size) {
+ return message;
+ }
+ }
+ string message = string(size, 'x');
+ message_cache_.push_back(message);
+ return std::move(message);
+ }
+
+ optional<BlockMode> getBlockMode(string transform) {
+ if (transform.find("/ECB") != string::npos) {
+ return BlockMode::ECB;
+ } else if (transform.find("/CBC") != string::npos) {
+ return BlockMode::CBC;
+ } else if (transform.find("/CTR") != string::npos) {
+ return BlockMode::CTR;
+ } else if (transform.find("/GCM") != string::npos) {
+ return BlockMode::GCM;
+ }
+ return {};
+ }
+
+ PaddingMode getPadding(string transform, bool sign) {
+ if (transform.find("/PKCS7") != string::npos) {
+ return PaddingMode::PKCS7;
+ } else if (transform.find("/PSS") != string::npos) {
+ return PaddingMode::RSA_PSS;
+ } else if (transform.find("/OAEP") != string::npos) {
+ return PaddingMode::RSA_OAEP;
+ } else if (transform.find("/PKCS1") != string::npos) {
+ return sign ? PaddingMode::RSA_PKCS1_1_5_SIGN : PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
+ } else if (sign && transform.find("RSA") != string::npos) {
+ // RSA defaults to PKCS1 for sign
+ return PaddingMode::RSA_PKCS1_1_5_SIGN;
+ }
+ return PaddingMode::NONE;
+ }
+
+ optional<Algorithm> getAlgorithm(string transform) {
+ if (transform.find("AES") != string::npos) {
+ return Algorithm::AES;
+ } else if (transform.find("Hmac") != string::npos) {
+ return Algorithm::HMAC;
+ } else if (transform.find("DESede") != string::npos) {
+ return Algorithm::TRIPLE_DES;
+ } else if (transform.find("RSA") != string::npos) {
+ return Algorithm::RSA;
+ } else if (transform.find("EC") != string::npos) {
+ return Algorithm::EC;
+ }
+ cerr << "Can't find algorithm for " << transform << endl;
+ return {};
+ }
+
+ Digest getDigest(string transform) {
+ if (transform.find("MD5") != string::npos) {
+ return Digest::MD5;
+ } else if (transform.find("SHA1") != string::npos ||
+ transform.find("SHA-1") != string::npos) {
+ return Digest::SHA1;
+ } else if (transform.find("SHA224") != string::npos) {
+ return Digest::SHA_2_224;
+ } else if (transform.find("SHA256") != string::npos) {
+ return Digest::SHA_2_256;
+ } else if (transform.find("SHA384") != string::npos) {
+ return Digest::SHA_2_384;
+ } else if (transform.find("SHA512") != string::npos) {
+ return Digest::SHA_2_512;
+ } else if (transform.find("RSA") != string::npos &&
+ transform.find("OAEP") != string::npos) {
+ return Digest::SHA1;
+ }
+ return Digest::NONE;
+ }
+};
+
+KeymasterWrapper* keymaster;
+
+static void settings(benchmark::internal::Benchmark* benchmark) {
+ benchmark->Unit(benchmark::kMillisecond);
+}
+
+static void addDefaultLabel(benchmark::State& state) {
+ string secLevel;
+ switch (keymaster->getSecurityLevel()) {
+ case SecurityLevel::STRONGBOX:
+ secLevel = "STRONGBOX";
+ break;
+ case SecurityLevel::SOFTWARE:
+ secLevel = "SOFTWARE";
+ break;
+ case SecurityLevel::TRUSTED_ENVIRONMENT:
+ secLevel = "TEE";
+ break;
+ }
+ state.SetLabel("hardware_name:" + keymaster->getHardwareName() + " sec_level:" + secLevel);
+}
+
+// clang-format off
+#define BENCHMARK_KM(func, transform, keySize) \
+ BENCHMARK_CAPTURE(func, transform/keySize, #transform "/" #keySize, keySize)->Apply(settings);
+#define BENCHMARK_KM_MSG(func, transform, keySize, msgSize) \
+ BENCHMARK_CAPTURE(func, transform/keySize/msgSize, #transform "/" #keySize "/" #msgSize, \
+ keySize, msgSize) \
+ ->Apply(settings);
+
+#define BENCHMARK_KM_ALL_MSGS(func, transform, keySize) \
+ BENCHMARK_KM_MSG(func, transform, keySize, SMALL_MESSAGE_SIZE) \
+ BENCHMARK_KM_MSG(func, transform, keySize, MEDIUM_MESSAGE_SIZE) \
+ BENCHMARK_KM_MSG(func, transform, keySize, LARGE_MESSAGE_SIZE)
+
+#define BENCHMARK_KM_CIPHER(transform, keySize, msgSize) \
+ BENCHMARK_KM_MSG(encrypt, transform, keySize, msgSize) \
+ BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
+
+#define BENCHMARK_KM_CIPHER_ALL_MSGS(transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(encrypt, transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(decrypt, transform, keySize)
+
+#define BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(sign, transform, keySize) \
+ BENCHMARK_KM_ALL_MSGS(verify, transform, keySize)
+// clang-format on
+
+/*
+ * ============= KeyGen TESTS ==================
+ */
+static void keygen(benchmark::State& state, string transform, int keySize) {
+ addDefaultLabel(state);
+ for (auto _ : state) {
+ keymaster->GenerateKey(transform, keySize);
+ state.PauseTiming();
+ keymaster->DeleteKey();
+ state.ResumeTiming();
+ }
+}
+
+BENCHMARK_KM(keygen, AES, 128);
+BENCHMARK_KM(keygen, AES, 256);
+
+BENCHMARK_KM(keygen, RSA, 2048);
+BENCHMARK_KM(keygen, RSA, 3072);
+BENCHMARK_KM(keygen, RSA, 4096);
+
+BENCHMARK_KM(keygen, EC, 224);
+BENCHMARK_KM(keygen, EC, 256);
+BENCHMARK_KM(keygen, EC, 384);
+BENCHMARK_KM(keygen, EC, 521);
+
+BENCHMARK_KM(keygen, DESede, 168);
+
+BENCHMARK_KM(keygen, Hmac, 64);
+BENCHMARK_KM(keygen, Hmac, 128);
+BENCHMARK_KM(keygen, Hmac, 256);
+BENCHMARK_KM(keygen, Hmac, 512);
+BENCHMARK_KM(keygen, Hmac, 1024);
+BENCHMARK_KM(keygen, Hmac, 2048);
+BENCHMARK_KM(keygen, Hmac, 4096);
+BENCHMARK_KM(keygen, Hmac, 8192);
+
+/*
+ * ============= SIGNATURE TESTS ==================
+ */
+
+static void sign(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize, true)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ auto params = keymaster->getOperationParams(transform, true);
+ string message = keymaster->GenerateMessage(msgSize);
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ auto opHandle = keymaster->SignBegin(params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, message, params)) {
+ state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+static void verify(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize, true)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ AuthorizationSet out_params;
+ AuthorizationSet in_params = keymaster->getOperationParams(transform, true);
+ string message = keymaster->GenerateMessage(msgSize);
+ auto opHandle = keymaster->SignBegin(in_params, &out_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ optional<string> signature =
+ keymaster->ProcessMessage(*opHandle, message, in_params, &out_params);
+ if (!signature) {
+ state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ in_params.push_back(out_params);
+ for (auto _ : state) {
+ state.PauseTiming();
+ opHandle = keymaster->VerifyBegin(in_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Verify begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, message, in_params, &out_params, *signature)) {
+ state.SkipWithError(("Verify error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+// clang-format off
+#define BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(transform) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 64) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 128) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 512) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 1024) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2024) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 8192)
+
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA1)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA224)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA384)
+BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA512)
+
+#define BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(transform) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 224) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 384) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 521)
+
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(NONEwithECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA1withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA224withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA256withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA384withECDSA);
+BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA512withECDSA);
+
+#define BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(transform) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2048) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 3072) \
+ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096)
+
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA);
+
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA/PSS);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA/PSS);
+// clang-format on
+
+/*
+ * ============= CIPHER TESTS ==================
+ */
+
+static void encrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ auto params = keymaster->getOperationParams(transform);
+ string message = keymaster->GenerateMessage(msgSize);
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ auto opHandle = keymaster->EncryptBegin(params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, message, params)) {
+ state.SkipWithError(
+ ("Encryption error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+static void decrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+ addDefaultLabel(state);
+ if (!keymaster->GenerateKey(transform, keySize)) {
+ state.SkipWithError(
+ ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ AuthorizationSet out_params;
+ AuthorizationSet in_params = keymaster->getOperationParams(transform);
+ string message = keymaster->GenerateMessage(msgSize);
+ auto opHandle = keymaster->EncryptBegin(in_params, &out_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ auto encryptedMessage = keymaster->ProcessMessage(*opHandle, message, in_params, &out_params);
+ if (!encryptedMessage) {
+ state.SkipWithError(("Encryption error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ in_params.push_back(out_params);
+ for (auto _ : state) {
+ state.PauseTiming();
+ opHandle = keymaster->DecryptBegin(in_params);
+ if (!opHandle) {
+ state.SkipWithError(
+ ("Decryption begin error, " + std::to_string(keymaster->getError())).c_str());
+ return;
+ }
+ state.ResumeTiming();
+ if (!keymaster->ProcessMessage(*opHandle, *encryptedMessage, in_params)) {
+ state.SkipWithError(
+ ("Decryption error, " + std::to_string(keymaster->getError())).c_str());
+ break;
+ }
+ }
+}
+
+// clang-format off
+// AES
+#define BENCHMARK_KM_CIPHER_ALL_AES_KEYS(transform) \
+ BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 128) \
+ BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 256)
+
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/NoPadding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/PKCS7Padding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CTR/NoPadding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/NoPadding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/PKCS7Padding);
+BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/GCM/NoPadding);
+
+// Triple DES
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/NoPadding, 168);
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/PKCS7Padding, 168);
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/NoPadding, 168);
+BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/PKCS7Padding, 168);
+
+#define BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(transform, msgSize) \
+ BENCHMARK_KM_CIPHER(transform, 2048, msgSize) \
+ BENCHMARK_KM_CIPHER(transform, 3072, msgSize) \
+ BENCHMARK_KM_CIPHER(transform, 4096, msgSize)
+
+BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/NoPadding, SMALL_MESSAGE_SIZE);
+BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/PKCS1Padding, SMALL_MESSAGE_SIZE);
+BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/OAEPPadding, SMALL_MESSAGE_SIZE);
+// clang-format on
+
+} // namespace test
+} // namespace V4_0
+} // namespace keymaster
+} // namespace hardware
+} // namespace android
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ base::CommandLine::Init(argc, argv);
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ auto service_name = command_line->GetSwitchValueASCII("service_name");
+ if (service_name.empty()) {
+ service_name = "default";
+ }
+ android::hardware::keymaster::V4_0::test::keymaster =
+ android::hardware::keymaster::V4_0::test::KeymasterWrapper::newInstance(service_name);
+ if (!android::hardware::keymaster::V4_0::test::keymaster) {
+ return 1;
+ }
+ ::benchmark::RunSpecifiedBenchmarks();
+}
\ No newline at end of file
diff --git a/keymaster/4.0/vts/performance/README b/keymaster/4.0/vts/performance/README
new file mode 100644
index 0000000..57d984a
--- /dev/null
+++ b/keymaster/4.0/vts/performance/README
@@ -0,0 +1,19 @@
+# Keymaster Benchmark
+
+The Keymaster Benchmark is a standalone tool for measuring the performance of keymaster implementations.
+
+## Building
+
+Build:
+`m keymaster_benchmark`
+
+Transfer to device/emulator:
+`adb sync data`
+
+The benchmark executable should will be located at `data/benchmarktest/keymaster_benchmark/keymaster_benchmark` on the device.
+
+## Usage
+
+Keymaster Benchmark is built on [Google microbenchmark library](https://github.com/google/benchmark).
+All of the commandline arguments provided by the microbenchmark library are valid, such as `--benchmark_filter=<regex>` or `benchmark_out_format={json|console|csv}`.
+In addition to the command line arguments provided by microbenchmark, `--service_name=<service_name>` is provided allow specification of the keymaster service name, e.g. specify `--service_name=strongbox` to benchmark strongbox.
diff --git a/keymaster/4.1/Android.bp b/keymaster/4.1/Android.bp
new file mode 100644
index 0000000..3b505d8
--- /dev/null
+++ b/keymaster/4.1/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.keymaster@4.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IKeymasterDevice.hal",
+ "IOperation.hal",
+ ],
+ interfaces: [
+ "android.hardware.keymaster@3.0",
+ "android.hardware.keymaster@4.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/keymaster/4.1/IKeymasterDevice.hal b/keymaster/4.1/IKeymasterDevice.hal
new file mode 100644
index 0000000..64d2c9f
--- /dev/null
+++ b/keymaster/4.1/IKeymasterDevice.hal
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.keymaster@4.1;
+
+import @4.0::ErrorCode;
+import @4.0::HardwareAuthToken;
+import @4.0::IKeymasterDevice;
+import @4.0::KeyParameter;
+import @4.0::KeyPurpose;
+import @4.0::OperationHandle;
+import IOperation;
+
+/**
+ * @4.1::IKeymasterDevice is a minor extension to @4.0::IKeymasterDevice. It adds support for
+ *
+ * - Partial hardware enforcment of UNLOCKED_DEVICE_REQUIRED keys;
+ * - Device-unique attestaion;
+ * - Early boot only keys;
+ * - Better cleanup of operations when clients die without completing or aborting them.
+ */
+interface IKeymasterDevice extends @4.0::IKeymasterDevice {
+ /**
+ * Called by client to notify the IKeymasterDevice that the device is now locked, and keys with
+ * the UNLOCKED_DEVICE_REQUIRED tag should no longer be usable. When this function is called,
+ * the IKeymasterDevice should note the current timestamp, and attempts to use
+ * UNLOCKED_DEVICE_REQUIRED keys must be rejected with Error::DEVICE_LOCKED until an
+ * authentication token with a later timestamp is presented. If the `passwordOnly' argument is
+ * set to true the sufficiently-recent authentication token must indicate that the user
+ * authenticated with a password, not a biometric.
+ *
+ * @param passwordOnly specifies whether the device must be unlocked with a password, rather
+ * than a biometric, before UNLOCKED_DEVICE_REQUIRED keys can be used.
+ */
+ deviceLocked(bool passwordOnly) generates (ErrorCode error);
+
+ /**
+ * Called by client to notify the IKeymasterDevice that the device has left the early boot
+ * state, and that keys with the EARLY_BOOT_ONLY tag may no longer be used. All attempts to use
+ * an EARLY_BOOT_ONLY key after this method is called must fail with Error::INVALID_KEY_BLOB.
+ */
+ earlyBootEnded() generates (ErrorCode error);
+
+ /**
+ * Begins a cryptographic operation. beginOp() is a variation on begin(). beginOp() has
+ * identical functionality to begin, but instead of an OperationHandle it returns an IOperation
+ * object. An IKeymasterDevice HAL service must call linkToDeath() on the Operation before
+ * returning it, and the provided hidl_death_recipient, if called, must abort() the operation.
+ * This is to ensure that in the event a client crashes while an operation is in progress, the
+ * operation slot is freed and available for use by other clients.
+ *
+ * @4.1::IKeymasterDevices must implement both beginOp() and begin().
+ */
+ beginOp(KeyPurpose purpose, vec<uint8_t> keyBlob, vec<KeyParameter> inParams,
+ HardwareAuthToken authToken)
+ generates (ErrorCode error, vec<KeyParameter> outParam, IOperation operation);
+};
diff --git a/keymaster/4.1/IOperation.hal b/keymaster/4.1/IOperation.hal
new file mode 100644
index 0000000..7103e9e
--- /dev/null
+++ b/keymaster/4.1/IOperation.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.keymaster@4.1;
+
+import @4.0::ErrorCode;
+import @4.0::OperationHandle;
+
+/**
+ * IOperation represents an in-progress IKeymasterDevice operation. It is returned by
+ * IKeymasterDevice.beginOp().
+ */
+interface IOperation {
+ /**
+ * Returns the operation handle to be used as an authentication challenge.
+ */
+ getOperationChallenge() generates (ErrorCode error, OperationHandle operation);
+};
diff --git a/keymaster/4.1/default/Android.bp b/keymaster/4.1/default/Android.bp
new file mode 100644
index 0000000..b06878b
--- /dev/null
+++ b/keymaster/4.1/default/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_binary {
+ name: "android.hardware.keymaster@4.1-service",
+ defaults: ["hidl_defaults"],
+ relative_install_path: "hw",
+ vendor: true,
+ init_rc: ["android.hardware.keymaster@4.1-service.rc"],
+ srcs: ["service.cpp"],
+
+ shared_libs: [
+ "android.hardware.keymaster@4.0",
+ "android.hardware.keymaster@4.1",
+ "libbase",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libkeymaster4",
+ "libkeymaster41",
+ "liblog",
+ "libutils",
+ ],
+
+}
diff --git a/keymaster/4.1/default/OWNERS b/keymaster/4.1/default/OWNERS
new file mode 100644
index 0000000..335660d
--- /dev/null
+++ b/keymaster/4.1/default/OWNERS
@@ -0,0 +1,2 @@
+jdanis@google.com
+swillden@google.com
diff --git a/keymaster/4.1/default/android.hardware.keymaster@4.1-service.rc b/keymaster/4.1/default/android.hardware.keymaster@4.1-service.rc
new file mode 100644
index 0000000..740b3c2
--- /dev/null
+++ b/keymaster/4.1/default/android.hardware.keymaster@4.1-service.rc
@@ -0,0 +1,6 @@
+service vendor.keymaster-4-1 /vendor/bin/hw/android.hardware.keymaster@4.1-service
+ interface android.hardware.keymaster@4.0::IKeymasterDevice default
+ interface android.hardware.keymaster@4.1::IKeymasterDevice default
+ class early_hal
+ user system
+ group system drmrpc
diff --git a/keymaster/4.1/default/service.cpp b/keymaster/4.1/default/service.cpp
new file mode 100644
index 0000000..d79a291
--- /dev/null
+++ b/keymaster/4.1/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <android-base/logging.h>
+#include <android/hardware/keymaster/4.1/IKeymasterDevice.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include <AndroidKeymaster41Device.h>
+
+using android::hardware::keymaster::V4_0::SecurityLevel;
+
+int main() {
+ ::android::hardware::configureRpcThreadpool(1, true /* willJoinThreadpool */);
+ auto keymaster = ::keymaster::V4_1::CreateKeymasterDevice(SecurityLevel::SOFTWARE);
+ auto status = keymaster->registerAsService();
+ if (status != android::OK) {
+ LOG(FATAL) << "Could not register service for Keymaster 4.1 (" << status << ")";
+ }
+
+ android::hardware::joinRpcThreadpool();
+ return -1; // Should never get here.
+}
diff --git a/keymaster/4.1/support/Android.bp b/keymaster/4.1/support/Android.bp
new file mode 100644
index 0000000..34b6108
--- /dev/null
+++ b/keymaster/4.1/support/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library {
+ name: "libkeymaster4_1support",
+ vendor_available: true,
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "android.hardware.keymaster@3.0",
+ "android.hardware.keymaster@4.0",
+ "android.hardware.keymaster@4.1",
+ "libkeymaster4support",
+ ]
+}
diff --git a/keymaster/4.1/support/include/keymasterV4_1/authorization_set.h b/keymaster/4.1/support/include/keymasterV4_1/authorization_set.h
new file mode 100644
index 0000000..afc0eaf
--- /dev/null
+++ b/keymaster/4.1/support/include/keymasterV4_1/authorization_set.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_V4_1_SUPPORT_INCLUDE_AUTHORIZATION_SET_H_
+#define HARDWARE_INTERFACES_KEYMASTER_V4_1_SUPPORT_INCLUDE_AUTHORIZATION_SET_H_
+
+#include <keymasterV4_0/authorization_set.h>
+
+#include <keymasterV4_1/keymaster_tags.h>
+
+namespace android::hardware::keymaster::V4_1 {
+
+using V4_0::AuthorizationSet;
+using V4_0::AuthorizationSetBuilder;
+using V4_0::KeyParameter;
+
+} // namespace android::hardware::keymaster::V4_1
+
+#endif // HARDWARE_INTERFACES_KEYMASTER_V4_1_SUPPORT_INCLUDE_AUTHORIZATION_SET_H_
diff --git a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
new file mode 100644
index 0000000..6ffe8e1
--- /dev/null
+++ b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_V4_1_SUPPORT_INCLUDE_KEYMASTER_TAGS_H_
+#define HARDWARE_INTERFACES_KEYMASTER_V4_1_SUPPORT_INCLUDE_KEYMASTER_TAGS_H_
+
+#include <android/hardware/keymaster/4.1/types.h>
+
+#include <keymasterV4_0/keymaster_tags.h>
+
+namespace android::hardware::keymaster::V4_1 {
+
+using V4_0::BlockMode;
+using V4_0::Digest;
+using V4_0::EcCurve;
+using V4_0::ErrorCode;
+using V4_0::HardwareAuthToken;
+using V4_0::KeyParameter;
+using V4_0::PaddingMode;
+using V4_0::TagType;
+using V4_0::VerificationToken;
+
+using V4_0::TypedTag;
+
+using V4_0::TAG_ACTIVE_DATETIME;
+using V4_0::TAG_ALGORITHM;
+using V4_0::TAG_ALLOW_WHILE_ON_BODY;
+using V4_0::TAG_APPLICATION_DATA;
+using V4_0::TAG_APPLICATION_ID;
+using V4_0::TAG_ASSOCIATED_DATA;
+using V4_0::TAG_ATTESTATION_APPLICATION_ID;
+using V4_0::TAG_ATTESTATION_CHALLENGE;
+using V4_0::TAG_AUTH_TIMEOUT;
+using V4_0::TAG_BLOB_USAGE_REQUIREMENTS;
+using V4_0::TAG_BLOCK_MODE;
+using V4_0::TAG_BOOT_PATCHLEVEL;
+using V4_0::TAG_BOOTLOADER_ONLY;
+using V4_0::TAG_CALLER_NONCE;
+using V4_0::TAG_CONFIRMATION_TOKEN;
+using V4_0::TAG_CREATION_DATETIME;
+using V4_0::TAG_DIGEST;
+using V4_0::TAG_EC_CURVE;
+using V4_0::TAG_HARDWARE_TYPE;
+using V4_0::TAG_INCLUDE_UNIQUE_ID;
+using V4_0::TAG_INVALID;
+using V4_0::TAG_KEY_SIZE;
+using V4_0::TAG_MAC_LENGTH;
+using V4_0::TAG_MAX_USES_PER_BOOT;
+using V4_0::TAG_MIN_MAC_LENGTH;
+using V4_0::TAG_MIN_SECONDS_BETWEEN_OPS;
+using V4_0::TAG_NO_AUTH_REQUIRED;
+using V4_0::TAG_NONCE;
+using V4_0::TAG_ORIGIN;
+using V4_0::TAG_ORIGINATION_EXPIRE_DATETIME;
+using V4_0::TAG_OS_PATCHLEVEL;
+using V4_0::TAG_OS_VERSION;
+using V4_0::TAG_PADDING;
+using V4_0::TAG_PURPOSE;
+using V4_0::TAG_RESET_SINCE_ID_ROTATION;
+using V4_0::TAG_ROLLBACK_RESISTANCE;
+using V4_0::TAG_ROOT_OF_TRUST;
+using V4_0::TAG_RSA_PUBLIC_EXPONENT;
+using V4_0::TAG_TRUSTED_CONFIRMATION_REQUIRED;
+using V4_0::TAG_TRUSTED_USER_PRESENCE_REQUIRED;
+using V4_0::TAG_UNIQUE_ID;
+using V4_0::TAG_UNLOCKED_DEVICE_REQUIRED;
+using V4_0::TAG_USAGE_EXPIRE_DATETIME;
+using V4_0::TAG_USER_AUTH_TYPE;
+using V4_0::TAG_USER_ID;
+using V4_0::TAG_USER_SECURE_ID;
+using V4_0::TAG_VENDOR_PATCHLEVEL;
+
+#define DECLARE_KM_4_1_TYPED_TAG(name) \
+ typedef typename V4_0::Tag2TypedTag<(static_cast<V4_0::Tag>(V4_1::Tag::name))>::type \
+ TAG_##name##_t; \
+ static TAG_##name##_t TAG_##name;
+
+DECLARE_KM_4_1_TYPED_TAG(EARLY_BOOT_ONLY);
+DECLARE_KM_4_1_TYPED_TAG(DEVICE_UNIQUE_ATTESTATION);
+
+} // namespace android::hardware::keymaster::V4_1
+
+#endif // HARDWARE_INTERFACES_KEYMASTER_V4_1_SUPPORT_INCLUDE_KEYMASTER_TAGS_H_
diff --git a/keymaster/4.1/types.hal b/keymaster/4.1/types.hal
new file mode 100644
index 0000000..bdf1731
--- /dev/null
+++ b/keymaster/4.1/types.hal
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.keymaster@4.1;
+
+import @4.0::ErrorCode;
+import @4.0::Tag;
+import @4.0::TagType;
+
+enum Tag : @4.0::Tag {
+ /**
+ * Keys tagged with EARLY_BOOT_ONLY may only be used, or created, during early boot, until
+ * IKeymasterDevice::earlyBootEnded() is called.
+ */
+ EARLY_BOOT_ONLY = TagType:BOOL | 305,
+ /**
+ * DEVICE_UNIQUE_ATTESTATION is an argument to IKeymasterDevice::attestKey(). It indicates that
+ * attestation using a device-unique key is requested, rather than a batch key. Only
+ * SecurityLevel::STRONGBOX IKeymasterDevices may support device-unique attestations.
+ * SecurityLevel::TRUSTED_ENVIRONMENT IKeymasterDevices must return ErrorCode::INVALID_ARGUMENT
+ * if they receive DEVICE_UNIQUE_ATTESTATION. SecurityLevel::STRONGBOX IKeymasterDevices need
+ * not support DEVICE_UNIQUE_ATTESTATION, and return ErrorCode::CANNOT_ATTEST_IDS if they do not
+ * support it.
+ *
+ * IKeymasterDevice implementations that support device-unique attestation MUST add the
+ * DEVICE_UNIQUE_ATTESTATION tag to device-unique attestations.
+ */
+ DEVICE_UNIQUE_ATTESTATION = TagType:BOOL | 720,
+};
diff --git a/keymaster/4.1/vts/OWNERS b/keymaster/4.1/vts/OWNERS
new file mode 100644
index 0000000..335660d
--- /dev/null
+++ b/keymaster/4.1/vts/OWNERS
@@ -0,0 +1,2 @@
+jdanis@google.com
+swillden@google.com
diff --git a/vibrator/1.4/vts/functional/Android.bp b/keymaster/4.1/vts/functional/Android.bp
similarity index 66%
rename from vibrator/1.4/vts/functional/Android.bp
rename to keymaster/4.1/vts/functional/Android.bp
index 202a824..f5a0c9c 100644
--- a/vibrator/1.4/vts/functional/Android.bp
+++ b/keymaster/4.1/vts/functional/Android.bp
@@ -15,19 +15,16 @@
//
cc_test {
- name: "VtsHalVibratorV1_4TargetTest",
+ name: "VtsHalKeymasterV4_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["VtsHalVibratorV1_4TargetTest.cpp"],
+ srcs: [
+ "EarlyBootKeyTest.cpp",
+ ],
static_libs: [
- "android.hardware.vibrator@1.0",
- "android.hardware.vibrator@1.1",
- "android.hardware.vibrator@1.2",
- "android.hardware.vibrator@1.3",
- "android.hardware.vibrator@1.4",
+ "android.hardware.keymaster@4.0",
+ "android.hardware.keymaster@4.1",
+ "libkeymaster4support",
+ "libkeymaster4_1support",
],
- test_suites: [
- "general-tests",
- "vts-core",
- ],
+ test_suites: ["vts-core"],
}
-
diff --git a/vibrator/1.4/IVibratorCallback.hal b/keymaster/4.1/vts/functional/EarlyBootKeyTest.cpp
similarity index 80%
copy from vibrator/1.4/IVibratorCallback.hal
copy to keymaster/4.1/vts/functional/EarlyBootKeyTest.cpp
index 76281bc..4a19010 100644
--- a/vibrator/1.4/IVibratorCallback.hal
+++ b/keymaster/4.1/vts/functional/EarlyBootKeyTest.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+namespace android::hardware::keymaster::V4_1::test {
-interface IVibratorCallback {
- oneway onComplete();
-};
+// TODO(swillden): Put tests here.
+
+} // namespace android::hardware::keymaster::V4_1::test
diff --git a/media/c2/1.1/Android.bp b/media/c2/1.1/Android.bp
new file mode 100644
index 0000000..c3e30b2
--- /dev/null
+++ b/media/c2/1.1/Android.bp
@@ -0,0 +1,27 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.media.c2@1.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IComponent.hal",
+ "IComponentStore.hal",
+ ],
+ interfaces: [
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.media.bufferpool@2.0",
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.omx@1.0",
+ "android.hardware.media@1.0",
+ "android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/media/c2/1.1/IComponent.hal b/media/c2/1.1/IComponent.hal
new file mode 100644
index 0000000..97382dd
--- /dev/null
+++ b/media/c2/1.1/IComponent.hal
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2@1.1;
+
+import android.hardware.media.c2@1.0::IComponent;
+import android.hardware.media.c2@1.0::Status;
+
+/**
+ * Interface for a Codec2 component corresponding to API level 1.0 or below.
+ * Components have two states: stopped and running. The running state has three
+ * sub-states: executing, tripped and error.
+ *
+ * All methods in `IComponent` must not block. If a method call cannot be
+ * completed in a timely manner, it must return `TIMED_OUT` in the return
+ * status.
+ *
+ * @note This is an extension of version 1.0 of `IComponent`. The purpose of the
+ * extension is to add support for tunneling.
+ */
+interface IComponent extends @1.0::IComponent {
+ /**
+ * Configures a component for a tunneled playback mode.
+ *
+ * A successful call to this method puts the component in the *tunneled*
+ * mode. In this mode, the output `Worklet`s returned in
+ * IComponentListener::onWorkDone() may not contain any buffers. The output
+ * buffers are passed directly to the consumer end of a buffer queue whose
+ * producer side is configured with the returned @p sidebandStream passed
+ * to IGraphicBufferProducer::setSidebandStream().
+ *
+ * The component is initially in the non-tunneled mode by default. The
+ * tunneled mode can be toggled on only before the component starts
+ * processing. Once the component is put into the tunneled mode, it shall
+ * stay in the tunneled mode until and only until reset() is called.
+ *
+ * @param avSyncHwId A resource ID for hardware sync. The generator of sync
+ * IDs must ensure that this number is unique among all services at any
+ * given time. For example, if both the audio HAL and the tuner HAL
+ * support this feature, sync IDs from the audio HAL must not clash
+ * with sync IDs from the tuner HAL.
+ * @return status Status of the call, which may be
+ * - `OK` - The operation completed successfully. In this case,
+ * @p sidebandHandle shall not be a null handle.
+ * - `OMITTED` - The component does not support video tunneling.
+ * - `BAD_STATE` - The component is already running.
+ * - `TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `CORRUPTED` - Some unknown error occurred.
+ * @return sidebandHandle Codec-allocated sideband stream handle. This can
+ * be passed to IGraphicBufferProducer::setSidebandStream() to
+ * establish a direct channel to the consumer.
+ */
+ configureVideoTunnel(
+ uint32_t avSyncHwId
+ ) generates (
+ Status status,
+ handle sidebandHandle
+ );
+};
diff --git a/media/c2/1.1/IComponentStore.hal b/media/c2/1.1/IComponentStore.hal
new file mode 100644
index 0000000..38e0fc6
--- /dev/null
+++ b/media/c2/1.1/IComponentStore.hal
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2@1.1;
+
+import android.hardware.media.bufferpool@2.0::IClientManager;
+import android.hardware.media.c2@1.0::IComponentListener;
+import android.hardware.media.c2@1.0::IComponentStore;
+import android.hardware.media.c2@1.0::Status;
+
+import IComponent;
+
+/**
+ * Entry point for Codec2 HAL.
+ *
+ * All methods in `IComponentStore` must not block. If a method call cannot be
+ * completed in a timely manner, it must return `TIMED_OUT` in the return
+ * status. The only exceptions are getPoolClientManager() and getConfigurable(),
+ * which must always return immediately.
+ *
+ * @note This is an extension of version 1.0 of `IComponentStore`. The purpose
+ * of the extension is to add support for tunneling.
+ */
+interface IComponentStore extends @1.0::IComponentStore {
+ /**
+ * Creates a component by name.
+ *
+ * @param name Name of the component to create. This must match one of the
+ * names returned by listComponents().
+ * @param listener Callback receiver.
+ * @param pool `IClientManager` object of the BufferPool in the client
+ * process. This may be null if the client does not own a BufferPool.
+ * @return status Status of the call, which may be
+ * - `OK` - The component was created successfully.
+ * - `NOT_FOUND` - There is no component with the given name.
+ * - `NO_MEMORY` - Not enough memory to create the component.
+ * - `TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `CORRUPTED` - Some unknown error occurred.
+ * @return comp The created component if @p status is `OK`.
+ *
+ * @sa IComponentListener.
+ */
+ createComponent_1_1(
+ string name,
+ IComponentListener listener,
+ IClientManager pool
+ ) generates (
+ Status status,
+ IComponent comp
+ );
+};
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index 3d78fb6..da7ba78 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -125,7 +125,7 @@
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
* For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
- * the scale and zeroPoint must be same as input0.
+ * the scale and zeroPoint must be the same as input0.
*/
MEAN = 31,
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 837ced5..b111d96 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1954,7 +1954,7 @@
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
* For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
- * the scale and zeroPoint must be same as input0.
+ * the scale and zeroPoint must be the same as input0.
*/
MEAN = @1.1::OperationType:MEAN,
@@ -2448,15 +2448,17 @@
* then clipping is disabled.
* If all the input tensors have type {@link OperandType::TENSOR_FLOAT32},
* this scalar must be of the type {@link OperandType::FLOAT32},
- * otherwise if all the input tensors have the type {@link OperandType::TENSOR_FLOAT16},
- * this scalar must be of type {@link OperandType::FLOAT16}.
+ * otherwise if all the input tensors have the type
+ * {@link OperandType::TENSOR_FLOAT16}, this scalar must be
+ * of type {@link OperandType::FLOAT16}.
* * 50: The clipping threshold for the output from the
* projection layer, such that values are bound within
* [-proj_clip, proj_clip]. If set to 0.0 then clipping is disabled.
* If all the input tensors have type {@link OperandType::TENSOR_FLOAT32},
* this scalar must be of the type {@link OperandType::FLOAT32},
- * otherwise if all the input tensors have the type {@link OperandType::TENSOR_FLOAT16},
- * this scalar must be of type {@link OperandType::FLOAT16}.
+ * otherwise if all the input tensors have the type
+ * {@link OperandType::TENSOR_FLOAT16}, this scalar must be
+ * of type {@link OperandType::FLOAT16}.
* * 51: merge_outputs
* An {@link OperandType::BOOL} scalar specifying if the outputs
* from forward and backward cells should be merged.
@@ -4124,7 +4126,6 @@
* * 0: A tensor of the same type and shape as input1 and input2.
* For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
* the scale and zeroPoint can be different from inputs' scale and zeroPoint.
- *
*/
SELECT = 84,
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index bdca0e9..fc727b7 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -71,5 +71,5 @@
header_libs: [
"libneuralnetworks_headers",
],
- test_suites: ["general-tests", "vts-core"],
+ test_suites: ["general-tests"],
}
diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
index aacb385..4909214 100644
--- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp
@@ -29,13 +29,14 @@
#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <gtest/gtest.h>
#include <hidlmemory/mapping.h>
-#include <gtest/gtest.h>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <numeric>
+#include <vector>
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
@@ -58,8 +59,20 @@
using V1_1::ExecutionPreference;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+namespace {
+
+enum class Executor { ASYNC, SYNC, BURST };
+
enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
+struct TestConfig {
+ Executor executor;
+ MeasureTiming measureTiming;
+ OutputType outputType;
+};
+
+} // namespace
+
Model createModel(const TestModel& testModel) {
// Model operands.
hidl_vec<Operand> operands(testModel.operands.size());
@@ -194,31 +207,31 @@
return android::nn::ExecutionBurstController::create(preparedModel,
std::chrono::microseconds{0});
}
-enum class Executor { ASYNC, SYNC, BURST };
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel,
- Executor executor, MeasureTiming measure, OutputType outputType) {
+ const TestConfig& testConfig) {
// If output0 does not have size larger than one byte, we can not test with insufficient buffer.
- if (outputType == OutputType::INSUFFICIENT && !isOutputSizeGreaterThanOne(testModel, 0)) {
+ if (testConfig.outputType == OutputType::INSUFFICIENT &&
+ !isOutputSizeGreaterThanOne(testModel, 0)) {
return;
}
Request request = createRequest(testModel);
- if (outputType == OutputType::INSUFFICIENT) {
+ if (testConfig.outputType == OutputType::INSUFFICIENT) {
makeOutputInsufficientSize(/*outputIndex=*/0, &request);
}
ErrorStatus executionStatus;
hidl_vec<OutputShape> outputShapes;
Timing timing;
- switch (executor) {
+ switch (testConfig.executor) {
case Executor::ASYNC: {
SCOPED_TRACE("asynchronous");
// launch execution
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- Return<ErrorStatus> executionLaunchStatus =
- ExecutePreparedModel(preparedModel, request, measure, executionCallback);
+ Return<ErrorStatus> executionLaunchStatus = ExecutePreparedModel(
+ preparedModel, request, testConfig.measureTiming, executionCallback);
ASSERT_TRUE(executionLaunchStatus.isOk());
EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
@@ -234,8 +247,8 @@
SCOPED_TRACE("synchronous");
// execute
- Return<ErrorStatus> executionReturnStatus =
- ExecutePreparedModel(preparedModel, request, measure, &outputShapes, &timing);
+ Return<ErrorStatus> executionReturnStatus = ExecutePreparedModel(
+ preparedModel, request, testConfig.measureTiming, &outputShapes, &timing);
ASSERT_TRUE(executionReturnStatus.isOk());
executionStatus = static_cast<ErrorStatus>(executionReturnStatus);
@@ -258,14 +271,14 @@
// execute burst
int n;
std::tie(n, outputShapes, timing, std::ignore) =
- controller->compute(request, measure, keys);
+ controller->compute(request, testConfig.measureTiming, keys);
executionStatus = nn::convertResultCodeToErrorStatus(n);
break;
}
}
- if (outputType != OutputType::FULLY_SPECIFIED &&
+ if (testConfig.outputType != OutputType::FULLY_SPECIFIED &&
executionStatus == ErrorStatus::GENERAL_FAILURE) {
LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
"execute model that it does not support.";
@@ -274,7 +287,7 @@
<< std::endl;
GTEST_SKIP();
}
- if (measure == MeasureTiming::NO) {
+ if (testConfig.measureTiming == MeasureTiming::NO) {
EXPECT_EQ(UINT64_MAX, timing.timeOnDevice);
EXPECT_EQ(UINT64_MAX, timing.timeInDriver);
} else {
@@ -283,7 +296,7 @@
}
}
- switch (outputType) {
+ switch (testConfig.outputType) {
case OutputType::FULLY_SPECIFIED:
// If the model output operands are fully specified, outputShapes must be either
// either empty, or have the same number of elements as the number of outputs.
@@ -321,44 +334,29 @@
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel,
bool testDynamicOutputShape) {
+ std::vector<OutputType> outputTypesList;
+ std::vector<MeasureTiming> measureTimingList;
+ std::vector<Executor> executorList;
+
if (testDynamicOutputShape) {
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::NO,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::NO,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::NO,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::YES,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::YES,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::YES,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::NO,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::NO,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::NO,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::YES,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::YES,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::YES,
- OutputType::INSUFFICIENT);
+ outputTypesList = {OutputType::UNSPECIFIED, OutputType::INSUFFICIENT};
+ measureTimingList = {MeasureTiming::NO, MeasureTiming::YES};
+ executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST};
} else {
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::NO,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::NO,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::NO,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::YES,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::YES,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::YES,
- OutputType::FULLY_SPECIFIED);
+ outputTypesList = {OutputType::FULLY_SPECIFIED};
+ measureTimingList = {MeasureTiming::NO, MeasureTiming::YES};
+ executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST};
+ }
+
+ for (const OutputType outputType : outputTypesList) {
+ for (const MeasureTiming measureTiming : measureTimingList) {
+ for (const Executor executor : executorList) {
+ const TestConfig testConfig = {.executor = executor,
+ .measureTiming = measureTiming,
+ .outputType = outputType};
+ EvaluatePreparedModel(preparedModel, testModel, testConfig);
+ }
+ }
}
}
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index 7df14b1..84c4813 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -109,6 +109,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -116,7 +117,8 @@
* * 0: A tensor.
* * 1: A tensor of the same {@link OperandType}, and compatible dimensions
* as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scales and zeroPoint can be different from input0 scale and zeroPoint.
* * 2: An {@link OperandType::INT32} scalar, and has to be one of the
* {@link FusedActivationFunc} values. Specifies the activation to
@@ -124,7 +126,8 @@
*
* Outputs:
* * 0: The sum, a tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
* the scale and zeroPoint can be different from inputs' scale and zeroPoint.
*/
ADD = @1.2::OperationType:ADD,
@@ -146,6 +149,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
* With the default data layout NHWC, the data is stored in the order of:
@@ -207,7 +211,8 @@
* Outputs:
* * 0: The output 4-D tensor, of shape
* [batches, out_height, out_width, depth].
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
AVERAGE_POOL_2D = @1.2::OperationType:AVERAGE_POOL_2D,
@@ -223,6 +228,7 @@
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
* (full support since HAL version 1.2, see the input section)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -232,6 +238,9 @@
* Before HAL version 1.2, all input tensors of
* {@link OperandType::TENSOR_QUANT8_ASYMM}
* must have the same scale and zeroPoint as the output tensor.
+ * Input tensors of
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+ * are allowed to have different scale and zeroPoint.
* Since HAL version 1.2, zero-sized tensors are supported.
* * n: An {@link OperandType::INT32} scalar, specifying the
* concatenation axis.
@@ -242,6 +251,8 @@
* Since HAL version 1.2, for a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
* the scale and zeroPoint values can be different from
* input tensors. Before HAL version 1.2 they have to be the same as for the input tensors.
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint values can be different from input tensors.
*/
CONCATENATION = @1.2::OperationType:CONCATENATION,
@@ -951,6 +962,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -962,6 +974,8 @@
* * 0: The output tensor of same shape as input0.
* For {@link OperandType::TENSOR_QUANT8_ASYMM},
* the scale must be 1.f / 256 and the zeroPoint must be 0.
+ * For {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED},
+ * the scale must be 1.f / 256 and the zeroPoint must be -128.
*/
LOGISTIC = @1.2::OperationType:LOGISTIC,
@@ -1256,6 +1270,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
* With the default data layout NHWC, the data is stored in the order of:
@@ -1317,7 +1332,8 @@
* Outputs:
* * 0: The output 4-D tensor, of shape
* [batches, out_height, out_width, depth].
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
MAX_POOL_2D = @1.2::OperationType:MAX_POOL_2D,
@@ -1345,6 +1361,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -1358,7 +1375,8 @@
*
* Outputs:
* * 0: The product, a tensor of the same {@link OperandType} as input0.
- * For output tensor of {@link OperandType::TENSOR_QUANT8_ASYMM},
+ * For output tensor of {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * and {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED},
* the following condition must be satisfied:
* output_scale > input1_scale * input2_scale.
*/
@@ -1375,6 +1393,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1384,7 +1403,8 @@
*
* Outputs:
* * 0: The output tensor of same shape as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RELU = @1.2::OperationType:RELU,
@@ -1400,6 +1420,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1409,7 +1430,8 @@
*
* Outputs:
* * 0: The output tensor of the same shape as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RELU1 = @1.2::OperationType:RELU1,
@@ -1425,6 +1447,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1434,7 +1457,8 @@
*
* Outputs:
* * 0: The output tensor of same shape as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RELU6 = @1.2::OperationType:RELU6,
@@ -1449,6 +1473,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1465,7 +1490,8 @@
*
* Outputs:
* * 0: The output tensor, of shape specified by the input shape.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
RESHAPE = @1.2::OperationType:RESHAPE,
@@ -1755,6 +1781,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM} (since HAL version 1.2)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4.
*
@@ -1766,6 +1793,8 @@
* * 0: The output tensor of same shape as input0.
* For {@link OperandType::TENSOR_QUANT8_ASYMM},
* the scale must be 1.f / 128 and the zeroPoint must be 128.
+ * For {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED},
+ * the scale must be 1.f / 128 and the zeroPoint must be 0.
*/
TANH = @1.2::OperationType:TANH,
@@ -1861,6 +1890,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -1880,8 +1910,9 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
- * the scale and zeroPoint must be same as input0.
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint must be the same as input0.
*/
MEAN = @1.2::OperationType:MEAN,
@@ -1988,6 +2019,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -2003,7 +2035,8 @@
* * 0: A tensor of the same {@link OperandType} as input0. Contains the
* same data as input, but has one or more dimensions of size 1
* removed.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
SQUEEZE = @1.2::OperationType:SQUEEZE,
@@ -2021,6 +2054,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -2050,7 +2084,8 @@
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0 and rank (n - k),
* where k is the number of bits set in shrink_axis_mask.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
STRIDED_SLICE = @1.2::OperationType:STRIDED_SLICE,
@@ -2083,6 +2118,7 @@
* * {@link OperandType::TENSOR_FLOAT16} (since HAL version 1.2)
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM} (since HAL version 1.2)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -2096,7 +2132,8 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint can be different from inputs' scale and zeroPoint.
*/
SUB = @1.2::OperationType:SUB,
@@ -2375,15 +2412,17 @@
* then clipping is disabled.
* If all the input tensors have type {@link OperandType::TENSOR_FLOAT32},
* this scalar must be of the type {@link OperandType::FLOAT32},
- * otherwise if all the input tensors have the type {@link OperandType::TENSOR_FLOAT16},
- * this scalar must be of type {@link OperandType::FLOAT16}.
+ * otherwise if all the input tensors have the type
+ * {@link OperandType::TENSOR_FLOAT16}, this scalar must be
+ * of type {@link OperandType::FLOAT16}.
* * 50: The clipping threshold for the output from the
* projection layer, such that values are bound within
* [-proj_clip, proj_clip]. If set to 0.0 then clipping is disabled.
* If all the input tensors have type {@link OperandType::TENSOR_FLOAT32},
* this scalar must be of the type {@link OperandType::FLOAT32},
- * otherwise if all the input tensors have the type {@link OperandType::TENSOR_FLOAT16},
- * this scalar must be of type {@link OperandType::FLOAT16}.
+ * otherwise if all the input tensors have the type
+ * {@link OperandType::TENSOR_FLOAT16}, this scalar must be
+ * of type {@link OperandType::FLOAT16}.
* * 51: merge_outputs
* An {@link OperandType::BOOL} scalar specifying if the outputs
* from forward and backward cells should be merged.
@@ -3799,6 +3838,7 @@
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -3811,7 +3851,8 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
REDUCE_MAX = @1.2::OperationType:REDUCE_MAX,
@@ -3828,6 +3869,7 @@
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: up to 4
*
@@ -3840,7 +3882,8 @@
*
* Outputs:
* * 0: A tensor of the same {@link OperandType} as input0.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scale and zeroPoint must be the same as input0.
*/
REDUCE_MIN = @1.2::OperationType:REDUCE_MIN,
@@ -4034,6 +4077,7 @@
* * {@link OperandType::TENSOR_FLOAT32}
* * {@link OperandType::TENSOR_INT32}
* * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since HAL version 1.3)
*
* Supported tensor rank: from 1
*
@@ -4044,14 +4088,14 @@
* true) or input2 (if false).
* * 1: An input tensor of the same shape as input0.
* * 2: An input tensor of the same shape and type as input1.
- * For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * and {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
* the scales and zeroPoint can be different from input1 scale and zeroPoint.
*
* Outputs:
* * 0: A tensor of the same type and shape as input1 and input2.
* For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
* the scale and zeroPoint can be different from inputs' scale and zeroPoint.
- *
*/
SELECT = @1.2::OperationType:SELECT,
diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
index d8a7534..60992d5 100644
--- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
@@ -456,8 +456,7 @@
}
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
}
TEST_P(CompilationCachingTest, CacheSavingAndRetrievalNonZeroOffset) {
@@ -519,8 +518,7 @@
}
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
}
TEST_P(CompilationCachingTest, SaveToCacheInvalidNumCache) {
@@ -541,8 +539,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -566,8 +563,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -590,8 +586,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -615,8 +610,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -727,8 +721,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -752,8 +745,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -776,8 +768,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -801,8 +792,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -914,8 +904,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -937,8 +926,7 @@
saveModelToCache(model, modelCache, dataCache, &preparedModel);
ASSERT_NE(preparedModel, nullptr);
// Execute and verify results.
- EvaluatePreparedModel(preparedModel, testModel,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
// Check if prepareModelFromCache fails.
preparedModel = nullptr;
ErrorStatus status;
@@ -1082,8 +1070,7 @@
ASSERT_EQ(preparedModel, nullptr);
} else {
ASSERT_NE(preparedModel, nullptr);
- EvaluatePreparedModel(preparedModel, testModelAdd,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModelAdd, /*testKind=*/TestKind::GENERAL);
}
}
}
@@ -1144,8 +1131,7 @@
ASSERT_EQ(preparedModel, nullptr);
} else {
ASSERT_NE(preparedModel, nullptr);
- EvaluatePreparedModel(preparedModel, testModelAdd,
- /*testDynamicOutputShape=*/false);
+ EvaluatePreparedModel(preparedModel, testModelAdd, /*testKind=*/TestKind::GENERAL);
}
}
}
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
index 1059bde..be894f2 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
@@ -34,13 +34,14 @@
#include <android/hardware/neuralnetworks/1.3/types.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <gtest/gtest.h>
#include <hidlmemory/mapping.h>
-#include <gtest/gtest.h>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <numeric>
+#include <vector>
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
@@ -69,8 +70,35 @@
using V1_2::implementation::ExecutionCallback;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+namespace {
+
+enum class Executor { ASYNC, SYNC, BURST };
+
enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
+struct TestConfig {
+ Executor executor;
+ MeasureTiming measureTiming;
+ OutputType outputType;
+ // `reportSkipping` indicates if a test should print an info message in case
+ // it is skipped. The field is set to true by default and is set to false in
+ // quantization coupling tests to suppress skipping a test
+ bool reportSkipping;
+ TestConfig(Executor executor, MeasureTiming measureTiming, OutputType outputType)
+ : executor(executor),
+ measureTiming(measureTiming),
+ outputType(outputType),
+ reportSkipping(true) {}
+ TestConfig(Executor executor, MeasureTiming measureTiming, OutputType outputType,
+ bool reportSkipping)
+ : executor(executor),
+ measureTiming(measureTiming),
+ outputType(outputType),
+ reportSkipping(reportSkipping) {}
+};
+
+} // namespace
+
Model createModel(const TestModel& testModel) {
// Model operands.
hidl_vec<Operand> operands(testModel.operands.size());
@@ -205,31 +233,34 @@
return android::nn::ExecutionBurstController::create(preparedModel,
std::chrono::microseconds{0});
}
-enum class Executor { ASYNC, SYNC, BURST };
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel,
- Executor executor, MeasureTiming measure, OutputType outputType) {
+ const TestConfig& testConfig, bool* skipped = nullptr) {
+ if (skipped != nullptr) {
+ *skipped = false;
+ }
// If output0 does not have size larger than one byte, we can not test with insufficient buffer.
- if (outputType == OutputType::INSUFFICIENT && !isOutputSizeGreaterThanOne(testModel, 0)) {
+ if (testConfig.outputType == OutputType::INSUFFICIENT &&
+ !isOutputSizeGreaterThanOne(testModel, 0)) {
return;
}
Request request = createRequest(testModel);
- if (outputType == OutputType::INSUFFICIENT) {
+ if (testConfig.outputType == OutputType::INSUFFICIENT) {
makeOutputInsufficientSize(/*outputIndex=*/0, &request);
}
ErrorStatus executionStatus;
hidl_vec<OutputShape> outputShapes;
Timing timing;
- switch (executor) {
+ switch (testConfig.executor) {
case Executor::ASYNC: {
SCOPED_TRACE("asynchronous");
// launch execution
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
- Return<ErrorStatus> executionLaunchStatus =
- ExecutePreparedModel(preparedModel, request, measure, executionCallback);
+ Return<ErrorStatus> executionLaunchStatus = ExecutePreparedModel(
+ preparedModel, request, testConfig.measureTiming, executionCallback);
ASSERT_TRUE(executionLaunchStatus.isOk());
EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionLaunchStatus));
@@ -245,8 +276,8 @@
SCOPED_TRACE("synchronous");
// execute
- Return<ErrorStatus> executionReturnStatus =
- ExecutePreparedModel(preparedModel, request, measure, &outputShapes, &timing);
+ Return<ErrorStatus> executionReturnStatus = ExecutePreparedModel(
+ preparedModel, request, testConfig.measureTiming, &outputShapes, &timing);
ASSERT_TRUE(executionReturnStatus.isOk());
executionStatus = static_cast<ErrorStatus>(executionReturnStatus);
@@ -269,15 +300,21 @@
// execute burst
int n;
std::tie(n, outputShapes, timing, std::ignore) =
- controller->compute(request, measure, keys);
+ controller->compute(request, testConfig.measureTiming, keys);
executionStatus = nn::convertResultCodeToErrorStatus(n);
break;
}
}
- if (outputType != OutputType::FULLY_SPECIFIED &&
+ if (testConfig.outputType != OutputType::FULLY_SPECIFIED &&
executionStatus == ErrorStatus::GENERAL_FAILURE) {
+ if (skipped != nullptr) {
+ *skipped = true;
+ }
+ if (!testConfig.reportSkipping) {
+ return;
+ }
LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
"execute model that it does not support.";
std::cout << "[ ] Early termination of test because vendor service cannot "
@@ -285,7 +322,7 @@
<< std::endl;
GTEST_SKIP();
}
- if (measure == MeasureTiming::NO) {
+ if (testConfig.measureTiming == MeasureTiming::NO) {
EXPECT_EQ(UINT64_MAX, timing.timeOnDevice);
EXPECT_EQ(UINT64_MAX, timing.timeInDriver);
} else {
@@ -294,7 +331,7 @@
}
}
- switch (outputType) {
+ switch (testConfig.outputType) {
case OutputType::FULLY_SPECIFIED:
// If the model output operands are fully specified, outputShapes must be either
// either empty, or have the same number of elements as the number of outputs.
@@ -331,59 +368,115 @@
}
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel, const TestModel& testModel,
- bool testDynamicOutputShape) {
- if (testDynamicOutputShape) {
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::NO,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::NO,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::NO,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::YES,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::YES,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::YES,
- OutputType::UNSPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::NO,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::NO,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::NO,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::YES,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::YES,
- OutputType::INSUFFICIENT);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::YES,
- OutputType::INSUFFICIENT);
- } else {
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::NO,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::NO,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::NO,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::ASYNC, MeasureTiming::YES,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::SYNC, MeasureTiming::YES,
- OutputType::FULLY_SPECIFIED);
- EvaluatePreparedModel(preparedModel, testModel, Executor::BURST, MeasureTiming::YES,
- OutputType::FULLY_SPECIFIED);
+ TestKind testKind) {
+ std::vector<OutputType> outputTypesList;
+ std::vector<MeasureTiming> measureTimingList;
+ std::vector<Executor> executorList;
+
+ switch (testKind) {
+ case TestKind::GENERAL: {
+ outputTypesList = {OutputType::FULLY_SPECIFIED};
+ measureTimingList = {MeasureTiming::NO, MeasureTiming::YES};
+ executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST};
+ } break;
+ case TestKind::DYNAMIC_SHAPE: {
+ outputTypesList = {OutputType::UNSPECIFIED, OutputType::INSUFFICIENT};
+ measureTimingList = {MeasureTiming::NO, MeasureTiming::YES};
+ executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST};
+ } break;
+ case TestKind::QUANTIZATION_COUPLING: {
+ LOG(FATAL) << "Wrong TestKind for EvaluatePreparedModel";
+ return;
+ } break;
+ }
+
+ for (const OutputType outputType : outputTypesList) {
+ for (const MeasureTiming measureTiming : measureTimingList) {
+ for (const Executor executor : executorList) {
+ const TestConfig testConfig(executor, measureTiming, outputType);
+ EvaluatePreparedModel(preparedModel, testModel, testConfig);
+ }
+ }
}
}
-void Execute(const sp<IDevice>& device, const TestModel& testModel, bool testDynamicOutputShape) {
+void EvaluatePreparedCoupledModels(const sp<IPreparedModel>& preparedModel,
+ const TestModel& testModel,
+ const sp<IPreparedModel>& preparedCoupledModel,
+ const TestModel& coupledModel) {
+ const std::vector<OutputType> outputTypesList = {OutputType::FULLY_SPECIFIED};
+ const std::vector<MeasureTiming> measureTimingList = {MeasureTiming::NO, MeasureTiming::YES};
+ const std::vector<Executor> executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST};
+
+ for (const OutputType outputType : outputTypesList) {
+ for (const MeasureTiming measureTiming : measureTimingList) {
+ for (const Executor executor : executorList) {
+ const TestConfig testConfig(executor, measureTiming, outputType,
+ /*reportSkipping=*/false);
+ bool baseSkipped = false;
+ EvaluatePreparedModel(preparedModel, testModel, testConfig, &baseSkipped);
+ bool coupledSkipped = false;
+ EvaluatePreparedModel(preparedCoupledModel, coupledModel, testConfig,
+ &coupledSkipped);
+ ASSERT_EQ(baseSkipped, coupledSkipped);
+ if (baseSkipped) {
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+ "execute model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service "
+ "cannot "
+ "execute model that it does not support."
+ << std::endl;
+ GTEST_SKIP();
+ }
+ }
+ }
+ }
+}
+
+void Execute(const sp<IDevice>& device, const TestModel& testModel, TestKind testKind) {
Model model = createModel(testModel);
- if (testDynamicOutputShape) {
+ if (testKind == TestKind::DYNAMIC_SHAPE) {
makeOutputDimensionsUnspecified(&model);
}
sp<IPreparedModel> preparedModel;
- createPreparedModel(device, model, &preparedModel);
- if (preparedModel == nullptr) return;
-
- EvaluatePreparedModel(preparedModel, testModel, testDynamicOutputShape);
+ switch (testKind) {
+ case TestKind::GENERAL: {
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
+ EvaluatePreparedModel(preparedModel, testModel, TestKind::GENERAL);
+ } break;
+ case TestKind::DYNAMIC_SHAPE: {
+ createPreparedModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) return;
+ EvaluatePreparedModel(preparedModel, testModel, TestKind::DYNAMIC_SHAPE);
+ } break;
+ case TestKind::QUANTIZATION_COUPLING: {
+ ASSERT_TRUE(testModel.hasQuant8AsymmOperands());
+ createPreparedModel(device, model, &preparedModel, /*reportSkipping*/ false);
+ TestModel signedQuantizedModel = convertQuant8AsymmOperandsToSigned(testModel);
+ sp<IPreparedModel> preparedCoupledModel;
+ createPreparedModel(device, createModel(signedQuantizedModel), &preparedCoupledModel,
+ /*reportSkipping*/ false);
+ // If we couldn't prepare a model with unsigned quantization, we must
+ // fail to prepare a model with signed quantization as well.
+ if (preparedModel == nullptr) {
+ ASSERT_EQ(preparedCoupledModel, nullptr);
+ // If we failed to prepare both of the models, we can safely skip
+ // the test.
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+ "prepare model that it does not support.";
+ std::cout
+ << "[ ] Early termination of test because vendor service cannot "
+ "prepare model that it does not support."
+ << std::endl;
+ GTEST_SKIP();
+ }
+ ASSERT_NE(preparedCoupledModel, nullptr);
+ EvaluatePreparedCoupledModels(preparedModel, testModel, preparedCoupledModel,
+ signedQuantizedModel);
+ } break;
+ }
}
void GeneratedTestBase::SetUp() {
@@ -406,12 +499,19 @@
// Tag for the dynamic output shape tests
class DynamicOutputShapeTest : public GeneratedTest {};
+// Tag for the dynamic output shape tests
+class DISABLED_QuantizationCouplingTest : public GeneratedTest {};
+
TEST_P(GeneratedTest, Test) {
- Execute(kDevice, kTestModel, /*testDynamicOutputShape=*/false);
+ Execute(kDevice, kTestModel, /*testKind=*/TestKind::GENERAL);
}
TEST_P(DynamicOutputShapeTest, Test) {
- Execute(kDevice, kTestModel, /*testDynamicOutputShape=*/true);
+ Execute(kDevice, kTestModel, /*testKind=*/TestKind::DYNAMIC_SHAPE);
+}
+
+TEST_P(DISABLED_QuantizationCouplingTest, Test) {
+ Execute(kDevice, kTestModel, /*testKind=*/TestKind::QUANTIZATION_COUPLING);
}
INSTANTIATE_GENERATED_TEST(GeneratedTest,
@@ -420,4 +520,8 @@
INSTANTIATE_GENERATED_TEST(DynamicOutputShapeTest,
[](const TestModel& testModel) { return !testModel.expectFailure; });
+INSTANTIATE_GENERATED_TEST(DISABLED_QuantizationCouplingTest, [](const TestModel& testModel) {
+ return testModel.hasQuant8AsymmOperands() && testModel.operations.size() == 1;
+});
+
} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
index 45cff5b..ad6323f 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
@@ -57,8 +57,19 @@
void PrepareModel(const sp<IDevice>& device, const Model& model, sp<IPreparedModel>* preparedModel);
+enum class TestKind {
+ // Runs a test model and compares the results to a golden data
+ GENERAL,
+ // Same as GENERAL but sets dimensions for the output tensors to zeros
+ DYNAMIC_SHAPE,
+ // Tests if quantized model with TENSOR_QUANT8_ASYMM produces the same result
+ // (OK/SKIPPED/FAILED) as the model with all such tensors converted to
+ // TENSOR_QUANT8_ASYMM_SIGNED.
+ QUANTIZATION_COUPLING
+};
+
void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel,
- const test_helper::TestModel& testModel, bool testDynamicOutputShape);
+ const test_helper::TestModel& testModel, TestKind testKind);
} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
index 46bbd3f..6fd5407 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
@@ -340,11 +340,22 @@
case OperationType::ARGMAX:
case OperationType::ARGMIN: {
if (type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32 ||
- type == OperandType::TENSOR_INT32 || type == OperandType::TENSOR_QUANT8_ASYMM) {
+ type == OperandType::TENSOR_INT32 || type == OperandType::TENSOR_QUANT8_ASYMM ||
+ type == OperandType::TENSOR_QUANT8_ASYMM_SIGNED) {
return true;
}
} break;
- case OperationType::QUANTIZE:
+ case OperationType::QUANTIZE: {
+ if (operand == operation.inputs[0] &&
+ (type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32)) {
+ return true;
+ }
+ if (operand == operation.outputs[0] &&
+ (type == OperandType::TENSOR_QUANT8_ASYMM ||
+ type == OperandType::TENSOR_QUANT8_ASYMM_SIGNED)) {
+ return true;
+ }
+ } break;
case OperationType::RANDOM_MULTINOMIAL: {
if (operand == operation.inputs[0] &&
(type == OperandType::TENSOR_FLOAT16 || type == OperandType::TENSOR_FLOAT32)) {
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
index 625913d..92d8fa7 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
@@ -37,7 +37,7 @@
// internal helper function
void createPreparedModel(const sp<IDevice>& device, const Model& model,
- sp<IPreparedModel>* preparedModel) {
+ sp<IPreparedModel>* preparedModel, bool reportSkipping) {
ASSERT_NE(nullptr, preparedModel);
*preparedModel = nullptr;
@@ -74,6 +74,9 @@
// can continue.
if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
ASSERT_EQ(nullptr, preparedModel->get());
+ if (!reportSkipping) {
+ return;
+ }
LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot prepare "
"model that it does not support.";
std::cout << "[ ] Early termination of test because vendor service cannot "
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
index 8cb42d4..4e51052 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
@@ -47,7 +47,7 @@
// Create an IPreparedModel object. If the model cannot be prepared,
// "preparedModel" will be nullptr instead.
void createPreparedModel(const sp<IDevice>& device, const Model& model,
- sp<IPreparedModel>* preparedModel);
+ sp<IPreparedModel>* preparedModel, bool reportSkipping = true);
// Utility function to get PreparedModel from callback and downcast to V1_2.
sp<IPreparedModel> getPreparedModel_1_3(const sp<implementation::PreparedModelCallback>& callback);
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 9dec2f2..2351d90 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -33,7 +33,8 @@
static_libs: [
"android.hardware.radio@1.0",
],
- test_suites: ["general-tests"],
+ test_config: "vts_hal_radio_target_test.xml",
+ test_suites: ["general-tests", "vts-core"],
}
cc_test {
@@ -47,7 +48,8 @@
static_libs: [
"android.hardware.radio@1.0",
],
- test_suites: ["general-tests"],
+ test_config: "vts_hal_sap_target_test.xml",
+ test_suites: ["general-tests", "vts-core"],
}
cc_library_static {
diff --git a/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp b/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
index d53c062..9d61b52 100644
--- a/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
+++ b/radio/1.0/vts/functional/VtsHalRadioV1_0TargetTest.cpp
@@ -14,12 +14,18 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_0.h>
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_0::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
// setup seed for rand function
int seedSrand = time(NULL);
diff --git a/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp b/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp
index 859e6fb..b80b971 100644
--- a/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp
+++ b/radio/1.0/vts/functional/VtsHalSapV1_0TargetTest.cpp
@@ -14,12 +14,18 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <sap_hidl_hal_utils.h>
+INSTANTIATE_TEST_SUITE_P(PerInstance, SapHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_0::ISap::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(SapHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- SapHidlEnvironment::Instance()->init(&argc, argv);
// setup seed for rand function
int seedSrand = time(NULL);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
index 2c1eb60..125ea0c 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.setGsmBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, setGsmBroadcastConfig) {
+TEST_P(RadioHidlTest, setGsmBroadcastConfig) {
serial = GetRandomSerialNumber();
// Create GsmBroadcastSmsConfigInfo #1
@@ -84,7 +84,7 @@
/*
* Test IRadio.getGsmBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, getGsmBroadcastConfig) {
+TEST_P(RadioHidlTest, getGsmBroadcastConfig) {
serial = GetRandomSerialNumber();
radio->getGsmBroadcastConfig(serial);
@@ -104,7 +104,7 @@
/*
* Test IRadio.setCdmaBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaBroadcastConfig) {
+TEST_P(RadioHidlTest, setCdmaBroadcastConfig) {
serial = GetRandomSerialNumber();
CdmaBroadcastSmsConfigInfo cbSmsConfig;
@@ -131,7 +131,7 @@
/*
* Test IRadio.getCdmaBroadcastConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, getCdmaBroadcastConfig) {
+TEST_P(RadioHidlTest, getCdmaBroadcastConfig) {
serial = GetRandomSerialNumber();
radio->getCdmaBroadcastConfig(serial);
@@ -149,7 +149,7 @@
/*
* Test IRadio.setCdmaBroadcastActivation() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaBroadcastActivation) {
+TEST_P(RadioHidlTest, setCdmaBroadcastActivation) {
serial = GetRandomSerialNumber();
bool activate = false;
@@ -169,7 +169,7 @@
/*
* Test IRadio.setGsmBroadcastActivation() for the response returned.
*/
-TEST_F(RadioHidlTest, setGsmBroadcastActivation) {
+TEST_P(RadioHidlTest, setGsmBroadcastActivation) {
serial = GetRandomSerialNumber();
bool activate = false;
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 eaef3ed..d937d74 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.getDataRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest, getDataRegistrationState) {
+TEST_P(RadioHidlTest, getDataRegistrationState) {
serial = GetRandomSerialNumber();
radio->getDataRegistrationState(serial);
@@ -99,7 +99,7 @@
/*
* Test IRadio.setupDataCall() for the response returned.
*/
-TEST_F(RadioHidlTest, setupDataCall) {
+TEST_P(RadioHidlTest, setupDataCall) {
serial = GetRandomSerialNumber();
RadioTechnology radioTechnology = RadioTechnology::LTE;
@@ -147,7 +147,7 @@
/*
* Test IRadio.deactivateDataCall() for the response returned.
*/
-TEST_F(RadioHidlTest, deactivateDataCall) {
+TEST_P(RadioHidlTest, deactivateDataCall) {
serial = GetRandomSerialNumber();
int cid = 1;
bool reasonRadioShutDown = false;
@@ -169,7 +169,7 @@
/*
* Test IRadio.getDataCallList() for the response returned.
*/
-TEST_F(RadioHidlTest, getDataCallList) {
+TEST_P(RadioHidlTest, getDataCallList) {
serial = GetRandomSerialNumber();
radio->getDataCallList(serial);
@@ -188,7 +188,7 @@
/*
* Test IRadio.setInitialAttachApn() for the response returned.
*/
-TEST_F(RadioHidlTest, setInitialAttachApn) {
+TEST_P(RadioHidlTest, setInitialAttachApn) {
serial = GetRandomSerialNumber();
DataProfileInfo dataProfileInfo;
@@ -231,7 +231,7 @@
/*
* Test IRadio.setDataAllowed() for the response returned.
*/
-TEST_F(RadioHidlTest, setDataAllowed) {
+TEST_P(RadioHidlTest, setDataAllowed) {
serial = GetRandomSerialNumber();
bool allow = true;
@@ -249,7 +249,7 @@
/*
* Test IRadio.setDataProfile() for the response returned.
*/
-TEST_F(RadioHidlTest, setDataProfile) {
+TEST_P(RadioHidlTest, setDataProfile) {
serial = GetRandomSerialNumber();
// Create a dataProfileInfo
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
index 2670d96..60cb2fe 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
@@ -19,7 +19,7 @@
/*
* Test IRadio.getIccCardStatus() for the response returned.
*/
-TEST_F(RadioHidlTest, getIccCardStatus) {
+TEST_P(RadioHidlTest, getIccCardStatus) {
EXPECT_LE(cardStatus.applications.size(), (unsigned int)RadioConst::CARD_MAX_APPS);
EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, (int)RadioConst::CARD_MAX_APPS);
@@ -29,7 +29,7 @@
/*
* Test IRadio.supplyIccPinForApp() for the response returned
*/
-TEST_F(RadioHidlTest, supplyIccPinForApp) {
+TEST_P(RadioHidlTest, supplyIccPinForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -54,7 +54,7 @@
/*
* Test IRadio.supplyIccPukForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyIccPukForApp) {
+TEST_P(RadioHidlTest, supplyIccPukForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -78,7 +78,7 @@
/*
* Test IRadio.supplyIccPin2ForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyIccPin2ForApp) {
+TEST_P(RadioHidlTest, supplyIccPin2ForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -104,7 +104,7 @@
/*
* Test IRadio.supplyIccPuk2ForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyIccPuk2ForApp) {
+TEST_P(RadioHidlTest, supplyIccPuk2ForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -128,7 +128,7 @@
/*
* Test IRadio.changeIccPinForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, changeIccPinForApp) {
+TEST_P(RadioHidlTest, changeIccPinForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -153,7 +153,7 @@
/*
* Test IRadio.changeIccPin2ForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, changeIccPin2ForApp) {
+TEST_P(RadioHidlTest, changeIccPin2ForApp) {
serial = GetRandomSerialNumber();
// Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -179,7 +179,7 @@
/*
* Test IRadio.getImsiForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, getImsiForApp) {
+TEST_P(RadioHidlTest, getImsiForApp) {
serial = GetRandomSerialNumber();
// Check success returned while getting imsi for 3GPP and 3GPP2 apps only
@@ -208,7 +208,7 @@
/*
* Test IRadio.iccIOForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, iccIOForApp) {
+TEST_P(RadioHidlTest, iccIOForApp) {
serial = GetRandomSerialNumber();
for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
@@ -233,7 +233,7 @@
/*
* Test IRadio.iccTransmitApduBasicChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccTransmitApduBasicChannel) {
+TEST_P(RadioHidlTest, iccTransmitApduBasicChannel) {
serial = GetRandomSerialNumber();
SimApdu msg;
memset(&msg, 0, sizeof(msg));
@@ -250,7 +250,7 @@
/*
* Test IRadio.iccOpenLogicalChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccOpenLogicalChannel) {
+TEST_P(RadioHidlTest, iccOpenLogicalChannel) {
serial = GetRandomSerialNumber();
int p2 = 0x04;
// Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
@@ -265,7 +265,7 @@
/*
* Test IRadio.iccCloseLogicalChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccCloseLogicalChannel) {
+TEST_P(RadioHidlTest, iccCloseLogicalChannel) {
serial = GetRandomSerialNumber();
// Try closing invalid channel and check INVALID_ARGUMENTS returned as error
radio->iccCloseLogicalChannel(serial, 0);
@@ -279,7 +279,7 @@
/*
* Test IRadio.iccTransmitApduLogicalChannel() for the response returned.
*/
-TEST_F(RadioHidlTest, iccTransmitApduLogicalChannel) {
+TEST_P(RadioHidlTest, iccTransmitApduLogicalChannel) {
serial = GetRandomSerialNumber();
SimApdu msg;
memset(&msg, 0, sizeof(msg));
@@ -296,7 +296,7 @@
/*
* Test IRadio.requestIccSimAuthentication() for the response returned.
*/
-TEST_F(RadioHidlTest, requestIccSimAuthentication) {
+TEST_P(RadioHidlTest, requestIccSimAuthentication) {
serial = GetRandomSerialNumber();
// Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
@@ -315,7 +315,7 @@
/*
* Test IRadio.supplyNetworkDepersonalization() for the response returned.
*/
-TEST_F(RadioHidlTest, supplyNetworkDepersonalization) {
+TEST_P(RadioHidlTest, supplyNetworkDepersonalization) {
serial = GetRandomSerialNumber();
radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
index 4331c06..e253dcf 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.getClir() for the response returned.
*/
-TEST_F(RadioHidlTest, getClir) {
+TEST_P(RadioHidlTest, getClir) {
serial = GetRandomSerialNumber();
radio->getClir(serial);
@@ -39,7 +39,7 @@
/*
* Test IRadio.setClir() for the response returned.
*/
-TEST_F(RadioHidlTest, setClir) {
+TEST_P(RadioHidlTest, setClir) {
serial = GetRandomSerialNumber();
int32_t status = 1;
@@ -57,7 +57,7 @@
/*
* Test IRadio.getFacilityLockForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, getFacilityLockForApp) {
+TEST_P(RadioHidlTest, getFacilityLockForApp) {
serial = GetRandomSerialNumber();
std::string facility = "";
std::string password = "";
@@ -80,7 +80,7 @@
/*
* Test IRadio.setFacilityLockForApp() for the response returned.
*/
-TEST_F(RadioHidlTest, setFacilityLockForApp) {
+TEST_P(RadioHidlTest, setFacilityLockForApp) {
serial = GetRandomSerialNumber();
std::string facility = "";
bool lockState = false;
@@ -104,7 +104,7 @@
/*
* Test IRadio.setBarringPassword() for the response returned.
*/
-TEST_F(RadioHidlTest, setBarringPassword) {
+TEST_P(RadioHidlTest, setBarringPassword) {
serial = GetRandomSerialNumber();
std::string facility = "";
std::string oldPassword = "";
@@ -127,7 +127,7 @@
/*
* Test IRadio.getClip() for the response returned.
*/
-TEST_F(RadioHidlTest, getClip) {
+TEST_P(RadioHidlTest, getClip) {
serial = GetRandomSerialNumber();
radio->getClip(serial);
@@ -145,7 +145,7 @@
/*
* Test IRadio.setSuppServiceNotifications() for the response returned.
*/
-TEST_F(RadioHidlTest, setSuppServiceNotifications) {
+TEST_P(RadioHidlTest, setSuppServiceNotifications) {
serial = GetRandomSerialNumber();
bool enable = false;
@@ -164,7 +164,7 @@
/*
* Test IRadio.requestIsimAuthentication() for the response returned.
*/
-TEST_F(RadioHidlTest, requestIsimAuthentication) {
+TEST_P(RadioHidlTest, requestIsimAuthentication) {
serial = GetRandomSerialNumber();
std::string challenge = "";
@@ -186,7 +186,7 @@
/*
* Test IRadio.getImsRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest, getImsRegistrationState) {
+TEST_P(RadioHidlTest, getImsRegistrationState) {
serial = GetRandomSerialNumber();
radio->getImsRegistrationState(serial);
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 3499762..d04cb36 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -19,7 +19,7 @@
/*
* Test IRadio.getSignalStrength() for the response returned.
*/
-TEST_F(RadioHidlTest, getSignalStrength) {
+TEST_P(RadioHidlTest, getSignalStrength) {
serial = GetRandomSerialNumber();
radio->getSignalStrength(serial);
@@ -35,7 +35,7 @@
/*
* Test IRadio.getVoiceRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest, getVoiceRegistrationState) {
+TEST_P(RadioHidlTest, getVoiceRegistrationState) {
serial = GetRandomSerialNumber();
radio->getVoiceRegistrationState(serial);
@@ -51,7 +51,7 @@
/*
* Test IRadio.getOperator() for the response returned.
*/
-TEST_F(RadioHidlTest, getOperator) {
+TEST_P(RadioHidlTest, getOperator) {
serial = GetRandomSerialNumber();
radio->getOperator(serial);
@@ -67,7 +67,7 @@
/*
* Test IRadio.setRadioPower() for the response returned.
*/
-TEST_F(RadioHidlTest, setRadioPower) {
+TEST_P(RadioHidlTest, setRadioPower) {
serial = GetRandomSerialNumber();
radio->setRadioPower(serial, 1);
@@ -83,7 +83,7 @@
/*
* Test IRadio.getNetworkSelectionMode() for the response returned.
*/
-TEST_F(RadioHidlTest, getNetworkSelectionMode) {
+TEST_P(RadioHidlTest, getNetworkSelectionMode) {
serial = GetRandomSerialNumber();
radio->getNetworkSelectionMode(serial);
@@ -99,7 +99,7 @@
/*
* Test IRadio.setNetworkSelectionModeAutomatic() for the response returned.
*/
-TEST_F(RadioHidlTest, setNetworkSelectionModeAutomatic) {
+TEST_P(RadioHidlTest, setNetworkSelectionModeAutomatic) {
serial = GetRandomSerialNumber();
radio->setNetworkSelectionModeAutomatic(serial);
@@ -118,7 +118,7 @@
/*
* Test IRadio.setNetworkSelectionModeManual() for the response returned.
*/
-TEST_F(RadioHidlTest, setNetworkSelectionModeManual) {
+TEST_P(RadioHidlTest, setNetworkSelectionModeManual) {
serial = GetRandomSerialNumber();
radio->setNetworkSelectionModeManual(serial, "123456");
@@ -137,7 +137,7 @@
/*
* Test IRadio.getAvailableNetworks() for the response returned.
*/
-TEST_F(RadioHidlTest, getAvailableNetworks) {
+TEST_P(RadioHidlTest, getAvailableNetworks) {
serial = GetRandomSerialNumber();
radio->getAvailableNetworks(serial);
@@ -158,7 +158,7 @@
/*
* Test IRadio.getBasebandVersion() for the response returned.
*/
-TEST_F(RadioHidlTest, getBasebandVersion) {
+TEST_P(RadioHidlTest, getBasebandVersion) {
serial = GetRandomSerialNumber();
radio->getBasebandVersion(serial);
@@ -174,7 +174,7 @@
/*
* Test IRadio.setBandMode() for the response returned.
*/
-TEST_F(RadioHidlTest, setBandMode) {
+TEST_P(RadioHidlTest, setBandMode) {
serial = GetRandomSerialNumber();
radio->setBandMode(serial, RadioBandMode::BAND_MODE_USA);
@@ -191,7 +191,7 @@
/*
* Test IRadio.getAvailableBandModes() for the response returned.
*/
-TEST_F(RadioHidlTest, getAvailableBandModes) {
+TEST_P(RadioHidlTest, getAvailableBandModes) {
serial = GetRandomSerialNumber();
radio->getAvailableBandModes(serial);
@@ -207,7 +207,7 @@
/*
* Test IRadio.setPreferredNetworkType() for the response returned.
*/
-TEST_F(RadioHidlTest, setPreferredNetworkType) {
+TEST_P(RadioHidlTest, setPreferredNetworkType) {
serial = GetRandomSerialNumber();
radio->setPreferredNetworkType(serial, PreferredNetworkType::GSM_ONLY);
@@ -224,7 +224,7 @@
/*
* Test IRadio.getPreferredNetworkType() for the response returned.
*/
-TEST_F(RadioHidlTest, getPreferredNetworkType) {
+TEST_P(RadioHidlTest, getPreferredNetworkType) {
serial = GetRandomSerialNumber();
radio->getPreferredNetworkType(serial);
@@ -240,7 +240,7 @@
/*
* Test IRadio.getNeighboringCids() for the response returned.
*/
-TEST_F(RadioHidlTest, getNeighboringCids) {
+TEST_P(RadioHidlTest, getNeighboringCids) {
serial = GetRandomSerialNumber();
radio->getNeighboringCids(serial);
@@ -258,7 +258,7 @@
/*
* Test IRadio.setLocationUpdates() for the response returned.
*/
-TEST_F(RadioHidlTest, setLocationUpdates) {
+TEST_P(RadioHidlTest, setLocationUpdates) {
serial = GetRandomSerialNumber();
radio->setLocationUpdates(serial, true);
@@ -275,7 +275,7 @@
/*
* Test IRadio.setCdmaRoamingPreference() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaRoamingPreference) {
+TEST_P(RadioHidlTest, setCdmaRoamingPreference) {
serial = GetRandomSerialNumber();
radio->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
@@ -293,7 +293,7 @@
/*
* Test IRadio.getCdmaRoamingPreference() for the response returned.
*/
-TEST_F(RadioHidlTest, getCdmaRoamingPreference) {
+TEST_P(RadioHidlTest, getCdmaRoamingPreference) {
serial = GetRandomSerialNumber();
radio->getCdmaRoamingPreference(serial);
@@ -312,7 +312,7 @@
/*
* Test IRadio.getTTYMode() for the response returned.
*/
-TEST_F(RadioHidlTest, getTTYMode) {
+TEST_P(RadioHidlTest, getTTYMode) {
serial = GetRandomSerialNumber();
radio->getTTYMode(serial);
@@ -328,7 +328,7 @@
/*
* Test IRadio.setTTYMode() for the response returned.
*/
-TEST_F(RadioHidlTest, setTTYMode) {
+TEST_P(RadioHidlTest, setTTYMode) {
serial = GetRandomSerialNumber();
radio->setTTYMode(serial, TtyMode::OFF);
@@ -344,7 +344,7 @@
/*
* Test IRadio.setPreferredVoicePrivacy() for the response returned.
*/
-TEST_F(RadioHidlTest, setPreferredVoicePrivacy) {
+TEST_P(RadioHidlTest, setPreferredVoicePrivacy) {
serial = GetRandomSerialNumber();
radio->setPreferredVoicePrivacy(serial, true);
@@ -361,7 +361,7 @@
/*
* Test IRadio.getPreferredVoicePrivacy() for the response returned.
*/
-TEST_F(RadioHidlTest, getPreferredVoicePrivacy) {
+TEST_P(RadioHidlTest, getPreferredVoicePrivacy) {
serial = GetRandomSerialNumber();
radio->getPreferredVoicePrivacy(serial);
@@ -378,7 +378,7 @@
/*
* Test IRadio.getCDMASubscription() for the response returned.
*/
-TEST_F(RadioHidlTest, getCDMASubscription) {
+TEST_P(RadioHidlTest, getCDMASubscription) {
serial = GetRandomSerialNumber();
radio->getCDMASubscription(serial);
@@ -396,7 +396,7 @@
/*
* Test IRadio.getDeviceIdentity() for the response returned.
*/
-TEST_F(RadioHidlTest, getDeviceIdentity) {
+TEST_P(RadioHidlTest, getDeviceIdentity) {
serial = GetRandomSerialNumber();
radio->getDeviceIdentity(serial);
@@ -413,7 +413,7 @@
/*
* Test IRadio.exitEmergencyCallbackMode() for the response returned.
*/
-TEST_F(RadioHidlTest, exitEmergencyCallbackMode) {
+TEST_P(RadioHidlTest, exitEmergencyCallbackMode) {
serial = GetRandomSerialNumber();
radio->exitEmergencyCallbackMode(serial);
@@ -431,7 +431,7 @@
/*
* Test IRadio.getCdmaSubscriptionSource() for the response returned.
*/
-TEST_F(RadioHidlTest, getCdmaSubscriptionSource) {
+TEST_P(RadioHidlTest, getCdmaSubscriptionSource) {
serial = GetRandomSerialNumber();
radio->getCdmaSubscriptionSource(serial);
@@ -449,7 +449,7 @@
/*
* Test IRadio.setCdmaSubscriptionSource() for the response returned.
*/
-TEST_F(RadioHidlTest, setCdmaSubscriptionSource) {
+TEST_P(RadioHidlTest, setCdmaSubscriptionSource) {
serial = GetRandomSerialNumber();
radio->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
@@ -468,7 +468,7 @@
/*
* Test IRadio.getVoiceRadioTechnology() for the response returned.
*/
-TEST_F(RadioHidlTest, getVoiceRadioTechnology) {
+TEST_P(RadioHidlTest, getVoiceRadioTechnology) {
serial = GetRandomSerialNumber();
radio->getVoiceRadioTechnology(serial);
@@ -484,7 +484,7 @@
/*
* Test IRadio.getCellInfoList() for the response returned.
*/
-TEST_F(RadioHidlTest, getCellInfoList) {
+TEST_P(RadioHidlTest, getCellInfoList) {
serial = GetRandomSerialNumber();
radio->getCellInfoList(serial);
@@ -502,7 +502,7 @@
/*
* Test IRadio.setCellInfoListRate() for the response returned.
*/
-TEST_F(RadioHidlTest, setCellInfoListRate) {
+TEST_P(RadioHidlTest, setCellInfoListRate) {
serial = GetRandomSerialNumber();
// TODO(sanketpadawe): RIL crashes with value of rate = 10
@@ -520,7 +520,7 @@
/*
* Test IRadio.nvReadItem() for the response returned.
*/
-TEST_F(RadioHidlTest, nvReadItem) {
+TEST_P(RadioHidlTest, nvReadItem) {
serial = GetRandomSerialNumber();
radio->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
@@ -537,7 +537,7 @@
/*
* Test IRadio.nvWriteItem() for the response returned.
*/
-TEST_F(RadioHidlTest, nvWriteItem) {
+TEST_P(RadioHidlTest, nvWriteItem) {
serial = GetRandomSerialNumber();
NvWriteItem item;
memset(&item, 0, sizeof(item));
@@ -557,7 +557,7 @@
/*
* Test IRadio.nvWriteCdmaPrl() for the response returned.
*/
-TEST_F(RadioHidlTest, nvWriteCdmaPrl) {
+TEST_P(RadioHidlTest, nvWriteCdmaPrl) {
serial = GetRandomSerialNumber();
std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
@@ -575,7 +575,7 @@
/*
* Test IRadio.nvResetConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, nvResetConfig) {
+TEST_P(RadioHidlTest, nvResetConfig) {
serial = GetRandomSerialNumber();
radio->nvResetConfig(serial, ResetNvType::ERASE);
@@ -592,7 +592,7 @@
/*
* Test IRadio.setUiccSubscription() for the response returned.
*/
-TEST_F(RadioHidlTest, setUiccSubscription) {
+TEST_P(RadioHidlTest, setUiccSubscription) {
serial = GetRandomSerialNumber();
SelectUiccSub item;
memset(&item, 0, sizeof(item));
@@ -614,7 +614,7 @@
/*
* Test IRadio.getHardwareConfig() for the response returned.
*/
-TEST_F(RadioHidlTest, getHardwareConfig) {
+TEST_P(RadioHidlTest, getHardwareConfig) {
serial = GetRandomSerialNumber();
radio->getHardwareConfig(serial);
@@ -631,7 +631,7 @@
/*
* Test IRadio.requestShutdown() for the response returned.
*/
-TEST_F(RadioHidlTest, requestShutdown) {
+TEST_P(RadioHidlTest, requestShutdown) {
serial = GetRandomSerialNumber();
radio->requestShutdown(serial);
@@ -648,7 +648,7 @@
/*
* Test IRadio.getRadioCapability() for the response returned.
*/
-TEST_F(RadioHidlTest, getRadioCapability) {
+TEST_P(RadioHidlTest, getRadioCapability) {
serial = GetRandomSerialNumber();
radio->getRadioCapability(serial);
@@ -664,7 +664,7 @@
/*
* Test IRadio.setRadioCapability() for the response returned.
*/
-TEST_F(RadioHidlTest, setRadioCapability) {
+TEST_P(RadioHidlTest, setRadioCapability) {
serial = GetRandomSerialNumber();
RadioCapability rc;
memset(&rc, 0, sizeof(rc));
@@ -685,7 +685,7 @@
/*
* Test IRadio.startLceService() for the response returned.
*/
-TEST_F(RadioHidlTest, startLceService) {
+TEST_P(RadioHidlTest, startLceService) {
serial = GetRandomSerialNumber();
radio->startLceService(serial, 5, true);
@@ -704,7 +704,7 @@
/*
* Test IRadio.stopLceService() for the response returned.
*/
-TEST_F(RadioHidlTest, stopLceService) {
+TEST_P(RadioHidlTest, stopLceService) {
serial = GetRandomSerialNumber();
radio->stopLceService(serial);
@@ -722,7 +722,7 @@
/*
* Test IRadio.pullLceData() for the response returned.
*/
-TEST_F(RadioHidlTest, pullLceData) {
+TEST_P(RadioHidlTest, pullLceData) {
serial = GetRandomSerialNumber();
radio->pullLceData(serial);
@@ -741,7 +741,7 @@
/*
* Test IRadio.getModemActivityInfo() for the response returned.
*/
-TEST_F(RadioHidlTest, getModemActivityInfo) {
+TEST_P(RadioHidlTest, getModemActivityInfo) {
serial = GetRandomSerialNumber();
radio->getModemActivityInfo(serial);
@@ -758,7 +758,7 @@
/*
* Test IRadio.setAllowedCarriers() for the response returned.
*/
-TEST_F(RadioHidlTest, setAllowedCarriers) {
+TEST_P(RadioHidlTest, setAllowedCarriers) {
serial = GetRandomSerialNumber();
CarrierRestrictions carriers;
memset(&carriers, 0, sizeof(carriers));
@@ -835,7 +835,7 @@
/*
* Test IRadio.getAllowedCarriers() for the response returned.
*/
-TEST_F(RadioHidlTest, getAllowedCarriers) {
+TEST_P(RadioHidlTest, getAllowedCarriers) {
serial = GetRandomSerialNumber();
radio->getAllowedCarriers(serial);
@@ -852,7 +852,7 @@
/*
* Test IRadio.sendDeviceState() for the response returned.
*/
-TEST_F(RadioHidlTest, sendDeviceState) {
+TEST_P(RadioHidlTest, sendDeviceState) {
serial = GetRandomSerialNumber();
radio->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true);
@@ -871,7 +871,7 @@
/*
* Test IRadio.setIndicationFilter() for the response returned.
*/
-TEST_F(RadioHidlTest, setIndicationFilter) {
+TEST_P(RadioHidlTest, setIndicationFilter) {
serial = GetRandomSerialNumber();
radio->setIndicationFilter(serial, 1);
@@ -890,7 +890,7 @@
/*
* Test IRadio.setSimCardPower() for the response returned.
*/
-TEST_F(RadioHidlTest, setSimCardPower) {
+TEST_P(RadioHidlTest, setSimCardPower) {
serial = GetRandomSerialNumber();
radio->setSimCardPower(serial, true);
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
index 9e41429..58c3bbd 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.sendSms() for the response returned.
*/
-TEST_F(RadioHidlTest, sendSms) {
+TEST_P(RadioHidlTest, sendSms) {
serial = GetRandomSerialNumber();
GsmSmsMessage msg;
msg.smscPdu = "";
@@ -45,7 +45,7 @@
/*
* Test IRadio.sendSMSExpectMore() for the response returned.
*/
-TEST_F(RadioHidlTest, sendSMSExpectMore) {
+TEST_P(RadioHidlTest, sendSMSExpectMore) {
serial = GetRandomSerialNumber();
GsmSmsMessage msg;
msg.smscPdu = "";
@@ -71,7 +71,7 @@
/*
* Test IRadio.acknowledgeLastIncomingGsmSms() for the response returned.
*/
-TEST_F(RadioHidlTest, acknowledgeLastIncomingGsmSms) {
+TEST_P(RadioHidlTest, acknowledgeLastIncomingGsmSms) {
serial = GetRandomSerialNumber();
bool success = true;
@@ -92,7 +92,7 @@
/*
* Test IRadio.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
*/
-TEST_F(RadioHidlTest, acknowledgeIncomingGsmSmsWithPdu) {
+TEST_P(RadioHidlTest, acknowledgeIncomingGsmSmsWithPdu) {
serial = GetRandomSerialNumber();
bool success = true;
std::string ackPdu = "";
@@ -111,7 +111,7 @@
/*
* Test IRadio.sendCdmaSms() for the response returned.
*/
-TEST_F(RadioHidlTest, sendCdmaSms) {
+TEST_P(RadioHidlTest, sendCdmaSms) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAddress
@@ -155,7 +155,7 @@
/*
* Test IRadio.acknowledgeLastIncomingCdmaSms() for the response returned.
*/
-TEST_F(RadioHidlTest, acknowledgeLastIncomingCdmaSms) {
+TEST_P(RadioHidlTest, acknowledgeLastIncomingCdmaSms) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAck
@@ -179,7 +179,7 @@
/*
* Test IRadio.sendImsSms() for the response returned.
*/
-TEST_F(RadioHidlTest, sendImsSms) {
+TEST_P(RadioHidlTest, sendImsSms) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAddress
@@ -229,7 +229,7 @@
/*
* Test IRadio.getSmscAddress() for the response returned.
*/
-TEST_F(RadioHidlTest, getSmscAddress) {
+TEST_P(RadioHidlTest, getSmscAddress) {
serial = GetRandomSerialNumber();
radio->getSmscAddress(serial);
@@ -249,7 +249,7 @@
/*
* Test IRadio.setSmscAddress() for the response returned.
*/
-TEST_F(RadioHidlTest, setSmscAddress) {
+TEST_P(RadioHidlTest, setSmscAddress) {
serial = GetRandomSerialNumber();
hidl_string address = hidl_string("smscAddress");
@@ -270,7 +270,7 @@
/*
* Test IRadio.writeSmsToSim() for the response returned.
*/
-TEST_F(RadioHidlTest, writeSmsToSim) {
+TEST_P(RadioHidlTest, writeSmsToSim) {
serial = GetRandomSerialNumber();
SmsWriteArgs smsWriteArgs;
smsWriteArgs.status = SmsWriteArgsStatus::REC_UNREAD;
@@ -296,7 +296,7 @@
/*
* Test IRadio.deleteSmsOnSim() for the response returned.
*/
-TEST_F(RadioHidlTest, deleteSmsOnSim) {
+TEST_P(RadioHidlTest, deleteSmsOnSim) {
serial = GetRandomSerialNumber();
int index = 1;
@@ -319,7 +319,7 @@
/*
* Test IRadio.writeSmsToRuim() for the response returned.
*/
-TEST_F(RadioHidlTest, writeSmsToRuim) {
+TEST_P(RadioHidlTest, writeSmsToRuim) {
serial = GetRandomSerialNumber();
// Create a CdmaSmsAddress
@@ -370,7 +370,7 @@
/*
* Test IRadio.deleteSmsOnRuim() for the response returned.
*/
-TEST_F(RadioHidlTest, deleteSmsOnRuim) {
+TEST_P(RadioHidlTest, deleteSmsOnRuim) {
serial = GetRandomSerialNumber();
int index = 1;
@@ -421,7 +421,7 @@
/*
* Test IRadio.reportSmsMemoryStatus() for the response returned.
*/
-TEST_F(RadioHidlTest, reportSmsMemoryStatus) {
+TEST_P(RadioHidlTest, reportSmsMemoryStatus) {
serial = GetRandomSerialNumber();
bool available = true;
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 a3b5029..1170111 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.sendEnvelope() for the response returned.
*/
-TEST_F(RadioHidlTest, sendEnvelope) {
+TEST_P(RadioHidlTest, sendEnvelope) {
serial = GetRandomSerialNumber();
// Test with sending empty string
@@ -44,7 +44,7 @@
/*
* Test IRadio.sendTerminalResponseToSim() for the response returned.
*/
-TEST_F(RadioHidlTest, sendTerminalResponseToSim) {
+TEST_P(RadioHidlTest, sendTerminalResponseToSim) {
serial = GetRandomSerialNumber();
// Test with sending empty string
@@ -67,7 +67,7 @@
/*
* Test IRadio.handleStkCallSetupRequestFromSim() for the response returned.
*/
-TEST_F(RadioHidlTest, handleStkCallSetupRequestFromSim) {
+TEST_P(RadioHidlTest, handleStkCallSetupRequestFromSim) {
serial = GetRandomSerialNumber();
bool accept = false;
@@ -88,7 +88,7 @@
/*
* Test IRadio.reportStkServiceIsRunning() for the response returned.
*/
-TEST_F(RadioHidlTest, reportStkServiceIsRunning) {
+TEST_P(RadioHidlTest, reportStkServiceIsRunning) {
serial = GetRandomSerialNumber();
radio->reportStkServiceIsRunning(serial);
@@ -107,7 +107,7 @@
* Test IRadio.sendEnvelopeWithStatus() for the response returned with empty
* string.
*/
-TEST_F(RadioHidlTest, sendEnvelopeWithStatus) {
+TEST_P(RadioHidlTest, sendEnvelopeWithStatus) {
serial = GetRandomSerialNumber();
// Test with sending empty string
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
index 96719d6..3c833c0 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_test.cpp
@@ -17,13 +17,10 @@
#include <radio_hidl_hal_utils_v1_0.h>
void RadioHidlTest::SetUp() {
- radio = ::testing::VtsHalHidlTargetTestBase::getService<IRadio>(
- RadioHidlEnvironment::Instance()->getServiceName<IRadio>(hidl_string(RADIO_SERVICE_NAME)));
+ radio = IRadio::getService(GetParam());
if (radio == NULL) {
sleep(60);
- radio = ::testing::VtsHalHidlTargetTestBase::getService<IRadio>(
- RadioHidlEnvironment::Instance()->getServiceName<IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio = IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio.get());
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
index 23bc434..8a551f7 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
@@ -16,8 +16,6 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -26,6 +24,7 @@
#include <android/hardware/radio/1.0/IRadioIndication.h>
#include <android/hardware/radio/1.0/IRadioResponse.h>
#include <android/hardware/radio/1.0/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -515,23 +514,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<IRadio>(); }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx;
std::condition_variable cv;
int count;
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp b/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
index 1fce470..a192a33 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_voice.cpp
@@ -19,7 +19,7 @@
/*
* Test IRadio.getCurrentCalls() for the response returned.
*/
-TEST_F(RadioHidlTest, getCurrentCalls) {
+TEST_P(RadioHidlTest, getCurrentCalls) {
serial = GetRandomSerialNumber();
radio->getCurrentCalls(serial);
@@ -35,7 +35,7 @@
/*
* Test IRadio.dial() for the response returned.
*/
-TEST_F(RadioHidlTest, dial) {
+TEST_P(RadioHidlTest, dial) {
serial = GetRandomSerialNumber();
Dial dialInfo;
@@ -62,7 +62,7 @@
/*
* Test IRadio.hangup() for the response returned.
*/
-TEST_F(RadioHidlTest, hangup) {
+TEST_P(RadioHidlTest, hangup) {
serial = GetRandomSerialNumber();
radio->hangup(serial, 1);
@@ -81,7 +81,7 @@
/*
* Test IRadio.hangupWaitingOrBackground() for the response returned.
*/
-TEST_F(RadioHidlTest, hangupWaitingOrBackground) {
+TEST_P(RadioHidlTest, hangupWaitingOrBackground) {
serial = GetRandomSerialNumber();
radio->hangupWaitingOrBackground(serial);
@@ -99,7 +99,7 @@
/*
* Test IRadio.hangupForegroundResumeBackground() for the response returned.
*/
-TEST_F(RadioHidlTest, hangupForegroundResumeBackground) {
+TEST_P(RadioHidlTest, hangupForegroundResumeBackground) {
serial = GetRandomSerialNumber();
radio->hangupForegroundResumeBackground(serial);
@@ -117,7 +117,7 @@
/*
* Test IRadio.switchWaitingOrHoldingAndActive() for the response returned.
*/
-TEST_F(RadioHidlTest, switchWaitingOrHoldingAndActive) {
+TEST_P(RadioHidlTest, switchWaitingOrHoldingAndActive) {
serial = GetRandomSerialNumber();
radio->switchWaitingOrHoldingAndActive(serial);
@@ -135,7 +135,7 @@
/*
* Test IRadio.conference() for the response returned.
*/
-TEST_F(RadioHidlTest, conference) {
+TEST_P(RadioHidlTest, conference) {
serial = GetRandomSerialNumber();
radio->conference(serial);
@@ -153,7 +153,7 @@
/*
* Test IRadio.rejectCall() for the response returned.
*/
-TEST_F(RadioHidlTest, rejectCall) {
+TEST_P(RadioHidlTest, rejectCall) {
serial = GetRandomSerialNumber();
radio->rejectCall(serial);
@@ -171,7 +171,7 @@
/*
* Test IRadio.getLastCallFailCause() for the response returned.
*/
-TEST_F(RadioHidlTest, getLastCallFailCause) {
+TEST_P(RadioHidlTest, getLastCallFailCause) {
serial = GetRandomSerialNumber();
radio->getLastCallFailCause(serial);
@@ -188,7 +188,7 @@
/*
* Test IRadio.sendUssd() for the response returned.
*/
-TEST_F(RadioHidlTest, sendUssd) {
+TEST_P(RadioHidlTest, sendUssd) {
serial = GetRandomSerialNumber();
radio->sendUssd(serial, hidl_string("test"));
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -206,7 +206,7 @@
/*
* Test IRadio.cancelPendingUssd() for the response returned.
*/
-TEST_F(RadioHidlTest, cancelPendingUssd) {
+TEST_P(RadioHidlTest, cancelPendingUssd) {
serial = GetRandomSerialNumber();
radio->cancelPendingUssd(serial);
@@ -225,7 +225,7 @@
/*
* Test IRadio.getCallForwardStatus() for the response returned.
*/
-TEST_F(RadioHidlTest, getCallForwardStatus) {
+TEST_P(RadioHidlTest, getCallForwardStatus) {
serial = GetRandomSerialNumber();
CallForwardInfo callInfo;
memset(&callInfo, 0, sizeof(callInfo));
@@ -247,7 +247,7 @@
/*
* Test IRadio.setCallForward() for the response returned.
*/
-TEST_F(RadioHidlTest, setCallForward) {
+TEST_P(RadioHidlTest, setCallForward) {
serial = GetRandomSerialNumber();
CallForwardInfo callInfo;
memset(&callInfo, 0, sizeof(callInfo));
@@ -269,7 +269,7 @@
/*
* Test IRadio.getCallWaiting() for the response returned.
*/
-TEST_F(RadioHidlTest, getCallWaiting) {
+TEST_P(RadioHidlTest, getCallWaiting) {
serial = GetRandomSerialNumber();
radio->getCallWaiting(serial, 1);
@@ -288,7 +288,7 @@
/*
* Test IRadio.setCallWaiting() for the response returned.
*/
-TEST_F(RadioHidlTest, setCallWaiting) {
+TEST_P(RadioHidlTest, setCallWaiting) {
serial = GetRandomSerialNumber();
radio->setCallWaiting(serial, true, 1);
@@ -307,7 +307,7 @@
/*
* Test IRadio.acceptCall() for the response returned.
*/
-TEST_F(RadioHidlTest, acceptCall) {
+TEST_P(RadioHidlTest, acceptCall) {
serial = GetRandomSerialNumber();
radio->acceptCall(serial);
@@ -325,7 +325,7 @@
/*
* Test IRadio.separateConnection() for the response returned.
*/
-TEST_F(RadioHidlTest, separateConnection) {
+TEST_P(RadioHidlTest, separateConnection) {
serial = GetRandomSerialNumber();
radio->separateConnection(serial, 1);
@@ -344,7 +344,7 @@
/*
* Test IRadio.explicitCallTransfer() for the response returned.
*/
-TEST_F(RadioHidlTest, explicitCallTransfer) {
+TEST_P(RadioHidlTest, explicitCallTransfer) {
serial = GetRandomSerialNumber();
radio->explicitCallTransfer(serial);
@@ -362,7 +362,7 @@
/*
* Test IRadio.sendCDMAFeatureCode() for the response returned.
*/
-TEST_F(RadioHidlTest, sendCDMAFeatureCode) {
+TEST_P(RadioHidlTest, sendCDMAFeatureCode) {
serial = GetRandomSerialNumber();
radio->sendCDMAFeatureCode(serial, hidl_string());
@@ -382,7 +382,7 @@
/*
* Test IRadio.sendDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, sendDtmf) {
+TEST_P(RadioHidlTest, sendDtmf) {
serial = GetRandomSerialNumber();
radio->sendDtmf(serial, "1");
@@ -402,7 +402,7 @@
/*
* Test IRadio.startDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, startDtmf) {
+TEST_P(RadioHidlTest, startDtmf) {
serial = GetRandomSerialNumber();
radio->startDtmf(serial, "1");
@@ -422,7 +422,7 @@
/*
* Test IRadio.stopDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, stopDtmf) {
+TEST_P(RadioHidlTest, stopDtmf) {
serial = GetRandomSerialNumber();
radio->stopDtmf(serial);
@@ -441,7 +441,7 @@
/*
* Test IRadio.setMute() for the response returned.
*/
-TEST_F(RadioHidlTest, setMute) {
+TEST_P(RadioHidlTest, setMute) {
serial = GetRandomSerialNumber();
radio->setMute(serial, true);
@@ -459,7 +459,7 @@
/*
* Test IRadio.getMute() for the response returned.
*/
-TEST_F(RadioHidlTest, getMute) {
+TEST_P(RadioHidlTest, getMute) {
serial = GetRandomSerialNumber();
radio->getMute(serial);
@@ -475,7 +475,7 @@
/*
* Test IRadio.sendBurstDtmf() for the response returned.
*/
-TEST_F(RadioHidlTest, sendBurstDtmf) {
+TEST_P(RadioHidlTest, sendBurstDtmf) {
serial = GetRandomSerialNumber();
radio->sendBurstDtmf(serial, "1", 0, 0);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
index 1d79ff6..6bd2c88 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp
@@ -19,7 +19,7 @@
/*
* Test ISap.connectReq() for the response returned.
*/
-TEST_F(SapHidlTest, connectReq) {
+TEST_P(SapHidlTest, connectReq) {
token = GetRandomSerialNumber();
int32_t maxMsgSize = 100;
@@ -35,7 +35,7 @@
/*
* Test IRadio.disconnectReq() for the response returned
*/
-TEST_F(SapHidlTest, disconnectReq) {
+TEST_P(SapHidlTest, disconnectReq) {
token = GetRandomSerialNumber();
sap->disconnectReq(token);
@@ -46,7 +46,7 @@
/*
* Test IRadio.apduReq() for the response returned.
*/
-TEST_F(SapHidlTest, apduReq) {
+TEST_P(SapHidlTest, apduReq) {
token = GetRandomSerialNumber();
SapApduType sapApduType = SapApduType::APDU;
android::hardware::hidl_vec<uint8_t> command = {};
@@ -64,7 +64,7 @@
/*
* Test IRadio.transferAtrReq() for the response returned.
*/
-TEST_F(SapHidlTest, transferAtrReq) {
+TEST_P(SapHidlTest, transferAtrReq) {
token = GetRandomSerialNumber();
sap->transferAtrReq(token);
@@ -80,7 +80,7 @@
/*
* Test IRadio.powerReq() for the response returned.
*/
-TEST_F(SapHidlTest, powerReq) {
+TEST_P(SapHidlTest, powerReq) {
token = GetRandomSerialNumber();
bool state = true;
@@ -97,7 +97,7 @@
/*
* Test IRadio.resetSimReq() for the response returned.
*/
-TEST_F(SapHidlTest, resetSimReq) {
+TEST_P(SapHidlTest, resetSimReq) {
token = GetRandomSerialNumber();
sap->resetSimReq(token);
@@ -113,7 +113,7 @@
/*
* Test IRadio.transferCardReaderStatusReq() for the response returned.
*/
-TEST_F(SapHidlTest, transferCardReaderStatusReq) {
+TEST_P(SapHidlTest, transferCardReaderStatusReq) {
token = GetRandomSerialNumber();
sap->transferCardReaderStatusReq(token);
@@ -127,7 +127,7 @@
/*
* Test IRadio.setTransferProtocolReq() for the response returned.
*/
-TEST_F(SapHidlTest, setTransferProtocolReq) {
+TEST_P(SapHidlTest, setTransferProtocolReq) {
token = GetRandomSerialNumber();
SapTransferProtocol sapTransferProtocol = SapTransferProtocol::T0;
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
index 65b344b..fe10587 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
@@ -17,8 +17,7 @@
#include <sap_hidl_hal_utils.h>
void SapHidlTest::SetUp() {
- sap = ::testing::VtsHalHidlTargetTestBase::getService<ISap>(
- SapHidlEnvironment::Instance()->getServiceName<ISap>(hidl_string(SAP_SERVICE_NAME)));
+ sap = ISap::getService(GetParam());
ASSERT_NE(sap, nullptr);
sapCb = new SapCallback(*this);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_utils.h b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
index f432932..2fc9ae3 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
@@ -16,8 +16,6 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -25,6 +23,7 @@
#include <android/hardware/radio/1.0/ISap.h>
#include <android/hardware/radio/1.0/ISapCallback.h>
#include <android/hardware/radio/1.0/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -80,23 +79,9 @@
Return<void> transferProtocolResponse(int32_t token, SapResultCode resultCode);
};
-// Test environment for Sap HIDL HAL.
-class SapHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static SapHidlEnvironment* Instance() {
- static SapHidlEnvironment* instance = new SapHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<ISap>(); }
-
- private:
- SapHidlEnvironment() {}
-};
-
// The main test class for Sap HIDL.
-class SapHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- private:
+class SapHidlTest : public ::testing::TestWithParam<std::string> {
+ private:
std::mutex mtx;
std::condition_variable cv;
int count;
diff --git a/radio/1.0/vts/functional/vts_hal_radio_target_test.xml b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
new file mode 100644
index 0000000..5e4a1cd
--- /dev/null
+++ b/radio/1.0/vts/functional/vts_hal_radio_target_test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_0TargetTest->/data/local/tmp/VtsHalRadioV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_0TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.0/vts/functional/vts_hal_sap_target_test.xml b/radio/1.0/vts/functional/vts_hal_sap_target_test.xml
new file mode 100644
index 0000000..457d700
--- /dev/null
+++ b/radio/1.0/vts/functional/vts_hal_sap_target_test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalSapV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalSapV1_0TargetTest->/data/local/tmp/VtsHalSapV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalSapV1_0TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index 826f0de..05b47c9 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -16,9 +16,8 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-
#include <android/hardware/radio/1.0/types.h>
+#include <gtest/gtest.h>
using ::android::hardware::radio::V1_0::RadioError;
using ::android::hardware::radio::V1_0::SapResultCode;
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
index 5695c6b..58aa67e 100644
--- a/radio/1.1/vts/functional/Android.bp
+++ b/radio/1.1/vts/functional/Android.bp
@@ -30,5 +30,5 @@
header_libs: [
"radio.util.header@1.0",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/radio/1.1/vts/functional/AndroidTest.xml b/radio/1.1/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5badadd
--- /dev/null
+++ b/radio/1.1/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_1TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_1TargetTest->/data/local/tmp/VtsHalRadioV1_1TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_1TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp b/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
index 83564ee..98dbf62 100644
--- a/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
+++ b/radio/1.1/vts/functional/VtsHalRadioV1_1TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_1.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_1,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_1::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
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 33347c5..75abbbf 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -20,7 +20,7 @@
/*
* Test IRadio.setSimCardPower() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, setSimCardPower_1_1) {
+TEST_P(RadioHidlTest_v1_1, setSimCardPower_1_1) {
/* Record the sim card state for the testing environment */
CardState cardStateForTest = cardStatus.cardState;
@@ -81,7 +81,7 @@
/*
* Test IRadio.startNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_1, startNetworkScan) {
serial = GetRandomSerialNumber();
NetworkScanRequest request;
@@ -115,7 +115,7 @@
/*
* Test IRadio.startNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_1, startNetworkScan_InvalidArgument) {
serial = GetRandomSerialNumber();
NetworkScanRequest request;
@@ -139,7 +139,7 @@
/*
* Test IRadio.stopNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, stopNetworkScan) {
+TEST_P(RadioHidlTest_v1_1, stopNetworkScan) {
serial = GetRandomSerialNumber();
radio_v1_1->stopNetworkScan(serial);
@@ -158,7 +158,7 @@
/*
* Test IRadio.setCarrierInfoForImsiEncryption() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
+TEST_P(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
serial = GetRandomSerialNumber();
ImsiEncryptionInfo imsiInfo;
imsiInfo.mcc = "310";
@@ -181,7 +181,7 @@
/*
* Test IRadio.startKeepalive() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, startKeepalive) {
+TEST_P(RadioHidlTest_v1_1, startKeepalive) {
std::vector<KeepaliveRequest> requests = {
{
// Invalid IPv4 source address
@@ -279,7 +279,7 @@
/*
* Test IRadio.stopKeepalive() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_1, stopKeepalive) {
+TEST_P(RadioHidlTest_v1_1, stopKeepalive) {
serial = GetRandomSerialNumber();
radio_v1_1->stopKeepalive(serial, 0xBAD);
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_test.cpp b/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
index 2f657b4..020168e 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,10 @@
#include <radio_hidl_hal_utils_v1_1.h>
void RadioHidlTest_v1_1::SetUp() {
- radio_v1_1 =
- ::testing::VtsHalHidlTargetTestBase::getService<::android::hardware::radio::V1_1::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_1 = ::android::hardware::radio::V1_1::IRadio::getService(GetParam());
if (radio_v1_1 == NULL) {
sleep(60);
- radio_v1_1 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_1::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_1::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_1 = ::android::hardware::radio::V1_1::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_1.get());
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 925f4fc..b81ee13 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
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -26,6 +25,7 @@
#include <android/hardware/radio/1.1/IRadioIndication.h>
#include <android/hardware/radio/1.1/IRadioResponse.h>
#include <android/hardware/radio/1.1/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -535,25 +535,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_1::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_1 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_1 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx;
std::condition_variable cv;
int count;
diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp
index c5838a8..f7189a8 100644
--- a/radio/1.2/vts/functional/Android.bp
+++ b/radio/1.2/vts/functional/Android.bp
@@ -34,5 +34,5 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/radio/1.2/vts/functional/AndroidTest.xml b/radio/1.2/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5d92248
--- /dev/null
+++ b/radio/1.2/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_2TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_2TargetTest->/data/local/tmp/VtsHalRadioV1_2TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_2TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp b/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp
index c1a2f3d..400e394 100644
--- a/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp
+++ b/radio/1.2/vts/functional/VtsHalRadioV1_2TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_2.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_2,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_2::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index a98f22a..7464307 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -31,7 +31,7 @@
/*
* Test IRadio.startNetworkScan() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan) {
serial = GetRandomSerialNumber();
if (radioConfig != NULL && DDS_LOGICAL_SLOT_INDEX != logicalSlotId) {
@@ -82,7 +82,7 @@
/*
* Test IRadio.startNetworkScan() with invalid specifier.
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidArgument) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
@@ -109,7 +109,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -141,7 +141,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidInterval2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -173,7 +173,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -205,7 +205,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidMaxSearchTime2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -237,7 +237,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -269,7 +269,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_InvalidPeriodicity2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -301,7 +301,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_GoodRequest1) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_GoodRequest1) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -335,7 +335,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity and plmns
*/
-TEST_F(RadioHidlTest_v1_2, startNetworkScan_GoodRequest2) {
+TEST_P(RadioHidlTest_v1_2, startNetworkScan_GoodRequest2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {
@@ -370,7 +370,7 @@
/*
* Test IRadio.setIndicationFilter_1_2()
*/
-TEST_F(RadioHidlTest_v1_2, setIndicationFilter_1_2) {
+TEST_P(RadioHidlTest_v1_2, setIndicationFilter_1_2) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setIndicationFilter_1_2(
@@ -388,7 +388,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() with invalid hysteresisDb
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -408,7 +408,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() with empty parameters
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_EmptyParams) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_EmptyParams) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -426,7 +426,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for GERAN
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Geran) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Geran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -445,7 +445,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for UTRAN
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Utran) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Utran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -464,7 +464,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for EUTRAN
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Eutran) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Eutran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -483,7 +483,7 @@
/*
* Test IRadio.setSignalStrengthReportingCriteria() for CDMA2000
*/
-TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Cdma2000) {
+TEST_P(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Cdma2000) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
@@ -502,7 +502,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -527,7 +527,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() invalid hysteresisUlKbps
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -552,7 +552,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() empty params
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_emptyParams) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_emptyParams) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -573,7 +573,7 @@
/*
* Test IRadio.setLinkCapacityReportingCriteria() GERAN
*/
-TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_Geran) {
+TEST_P(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_Geran) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
@@ -595,7 +595,7 @@
/*
* Test IRadio.setupDataCall_1_2() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, setupDataCall_1_2) {
+TEST_P(RadioHidlTest_v1_2, setupDataCall_1_2) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::AccessNetwork accessNetwork =
@@ -655,7 +655,7 @@
/*
* Test IRadio.deactivateDataCall_1_2() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, deactivateDataCall_1_2) {
+TEST_P(RadioHidlTest_v1_2, deactivateDataCall_1_2) {
serial = GetRandomSerialNumber();
int cid = 1;
::android::hardware::radio::V1_2::DataRequestReason reason =
@@ -686,7 +686,7 @@
/*
* Test IRadio.getCellInfoList() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getCellInfoList_1_2) {
+TEST_P(RadioHidlTest_v1_2, getCellInfoList_1_2) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getCellInfoList(serial);
@@ -704,7 +704,7 @@
/*
* Test IRadio.getVoiceRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getVoiceRegistrationState) {
+TEST_P(RadioHidlTest_v1_2, getVoiceRegistrationState) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getVoiceRegistrationState(serial);
@@ -722,7 +722,7 @@
/*
* Test IRadio.getDataRegistrationState() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getDataRegistrationState) {
+TEST_P(RadioHidlTest_v1_2, getDataRegistrationState) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getDataRegistrationState(serial);
@@ -797,7 +797,7 @@
/*
* Test IRadio.getAvailableBandModes() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_2, getAvailableBandModes) {
+TEST_P(RadioHidlTest_v1_2, getAvailableBandModes) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_2->getAvailableBandModes(serial);
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
index 21caddb..4845c7f 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,10 @@
#include <radio_hidl_hal_utils_v1_2.h>
void RadioHidlTest_v1_2::SetUp() {
- radio_v1_2 =
- ::testing::VtsHalHidlTargetTestBase::getService<::android::hardware::radio::V1_2::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_2::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_2 = ::android::hardware::radio::V1_2::IRadio::getService(GetParam());
if (radio_v1_2 == NULL) {
sleep(60);
- radio_v1_2 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_2::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_2::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_2 = ::android::hardware::radio::V1_2::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_2.get());
@@ -51,8 +43,7 @@
/* Enforce Vts Testing with Sim Status Present only. */
EXPECT_EQ(CardState::PRESENT, cardStatus.base.cardState);
- radioConfig = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::config::V1_1::IRadioConfig>();
+ radioConfig = ::android::hardware::radio::config::V1_1::IRadioConfig::getService();
/* Enforce Vts tesing with RadioConfig for network scan excemption. */
// Some devices can only perform network scan on logical modem that currently used for packet
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index 2db1cac..479340c 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -30,6 +29,7 @@
#include <android/hardware/radio/1.2/IRadioIndication.h>
#include <android/hardware/radio/1.2/IRadioResponse.h>
#include <android/hardware/radio/1.2/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -631,25 +631,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_2::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_2 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_2 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
diff --git a/radio/1.3/vts/functional/Android.bp b/radio/1.3/vts/functional/Android.bp
index 67aff6e..2301732 100644
--- a/radio/1.3/vts/functional/Android.bp
+++ b/radio/1.3/vts/functional/Android.bp
@@ -32,5 +32,5 @@
"android.hardware.radio@1.0",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/radio/1.3/vts/functional/AndroidTest.xml b/radio/1.3/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..c910047
--- /dev/null
+++ b/radio/1.3/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_3TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_3TargetTest->/data/local/tmp/VtsHalRadioV1_3TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_3TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp b/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp
index 7d2623e..2622bbc 100644
--- a/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp
+++ b/radio/1.3/vts/functional/VtsHalRadioV1_3TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_3.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_3,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_3::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_api.cpp b/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
index 813dd13..4e48141 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.3/vts/functional/radio_hidl_hal_api.cpp
@@ -22,7 +22,7 @@
/*
* Test IRadio.enableMddem() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_3, enableModem) {
+TEST_P(RadioHidlTest_v1_3, enableModem) {
serial = GetRandomSerialNumber();
bool responseToggle = radioRsp_v1_3->enableModemResponseToggle;
@@ -61,7 +61,7 @@
/*
* Test IRadio.getModemStackStatus() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_3, getModemStackStatus) {
+TEST_P(RadioHidlTest_v1_3, getModemStackStatus) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_3->getModemStackStatus(serial);
@@ -81,7 +81,7 @@
*
* This test is excluded from manifest, due to non-implementation in Q. Tracked by b/130254624.
*/
-TEST_F(RadioHidlTest_v1_3, setSystemSelectionChannels) {
+TEST_P(RadioHidlTest_v1_3, setSystemSelectionChannels) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_test.cpp b/radio/1.3/vts/functional/radio_hidl_hal_test.cpp
index a876b1a..4581350 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.3/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,10 @@
#include <radio_hidl_hal_utils_v1_3.h>
void RadioHidlTest_v1_3::SetUp() {
- radio_v1_3 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_3::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_3::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_3 = ::android::hardware::radio::V1_3::IRadio::getService(GetParam());
if (radio_v1_3 == NULL) {
sleep(60);
- radio_v1_3 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_3::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_3::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_3 = ::android::hardware::radio::V1_3::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_3.get());
diff --git a/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h b/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h
index 1d03a99..893eac5 100644
--- a/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h
+++ b/radio/1.3/vts/functional/radio_hidl_hal_utils_v1_3.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -609,25 +608,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_3::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_3 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_3 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp
index 6827132..8284404 100644
--- a/radio/1.4/vts/functional/Android.bp
+++ b/radio/1.4/vts/functional/Android.bp
@@ -35,5 +35,5 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests"]
+ test_suites: ["general-tests", "vts-core"]
}
diff --git a/radio/1.4/vts/functional/AndroidTest.xml b/radio/1.4/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..c910047
--- /dev/null
+++ b/radio/1.4/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_3TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalRadioV1_3TargetTest->/data/local/tmp/VtsHalRadioV1_3TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalRadioV1_3TargetTest" />
+ </test>
+</configuration>
diff --git a/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp b/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp
index d6330e6..23ec011 100644
--- a/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp
+++ b/radio/1.4/vts/functional/VtsHalRadioV1_4TargetTest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <radio_hidl_hal_utils_v1_4.h>
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- RadioHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
\ No newline at end of file
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_4,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::V1_4::IRadio::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index a4953d7..95136bb 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -21,7 +21,7 @@
/*
* Test IRadio.emergencyDial() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, emergencyDial) {
+TEST_P(RadioHidlTest_v1_4, emergencyDial) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
@@ -52,7 +52,7 @@
/*
* Test IRadio.emergencyDial() with specified service and its response returned.
*/
-TEST_F(RadioHidlTest_v1_4, emergencyDial_withServices) {
+TEST_P(RadioHidlTest_v1_4, emergencyDial_withServices) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
@@ -84,7 +84,7 @@
/*
* Test IRadio.emergencyDial() with known emergency call routing and its response returned.
*/
-TEST_F(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
+TEST_P(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
@@ -116,7 +116,7 @@
/*
* Test IRadio.getPreferredNetworkTypeBitmap() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getPreferredNetworkTypeBitmap) {
+TEST_P(RadioHidlTest_v1_4, getPreferredNetworkTypeBitmap) {
serial = GetRandomSerialNumber();
Return<void> res = radio_v1_4->getPreferredNetworkTypeBitmap(serial);
@@ -130,7 +130,7 @@
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
}
-TEST_F(RadioHidlTest_v1_4, setPreferredNetworkTypeBitmap) {
+TEST_P(RadioHidlTest_v1_4, setPreferredNetworkTypeBitmap) {
serial = GetRandomSerialNumber();
::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily>
network_type_bitmap{};
@@ -175,7 +175,7 @@
* REQUEST_NOT_SUPPORTED will be disallowed for all tests. Modems have "GSM" rat scan need to
* support scanning requests combined with some parameters.
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -218,7 +218,7 @@
/*
* Test IRadio.startNetworkScan() with invalid specifier.
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
@@ -246,7 +246,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -283,7 +283,7 @@
/*
* Test IRadio.startNetworkScan() with invalid interval (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -319,7 +319,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -355,7 +355,7 @@
/*
* Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -391,7 +391,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -427,7 +427,7 @@
/*
* Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -463,7 +463,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -502,7 +502,7 @@
/*
* Test IRadio.startNetworkScan() with valid periodicity and plmns
*/
-TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
+TEST_P(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
serial = GetRandomSerialNumber();
RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
@@ -543,7 +543,7 @@
/*
* Test IRadio.getSignalStrength_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getSignalStrength_1_4) {
+TEST_P(RadioHidlTest_v1_4, getSignalStrength_1_4) {
serial = GetRandomSerialNumber();
radio_v1_4->getSignalStrength_1_4(serial);
@@ -562,7 +562,7 @@
/*
* Test IRadio.setupDataCall_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, setupDataCall_1_4) {
+TEST_P(RadioHidlTest_v1_4, setupDataCall_1_4) {
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_4::AccessNetwork accessNetwork =
@@ -617,7 +617,7 @@
/*
* Test IRadio.getAllowedCarriers_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getAllowedCarriers_1_4) {
+TEST_P(RadioHidlTest_v1_4, getAllowedCarriers_1_4) {
serial = GetRandomSerialNumber();
radio_v1_4->getAllowedCarriers_1_4(serial);
@@ -632,7 +632,7 @@
/**
* Test IRadio.setAllowedCarriers_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, setAllowedCarriers_1_4) {
+TEST_P(RadioHidlTest_v1_4, setAllowedCarriers_1_4) {
serial = GetRandomSerialNumber();
CarrierRestrictionsWithPriority carrierRestrictions;
memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
@@ -727,7 +727,7 @@
}
}
-TEST_F(RadioHidlTest_v1_4, setDataProfile_1_4) {
+TEST_P(RadioHidlTest_v1_4, setDataProfile_1_4) {
serial = GetRandomSerialNumber();
// Create a dataProfileInfo
@@ -770,7 +770,7 @@
}
}
-TEST_F(RadioHidlTest_v1_4, setInitialAttachApn_1_4) {
+TEST_P(RadioHidlTest_v1_4, setInitialAttachApn_1_4) {
serial = GetRandomSerialNumber();
// Create a dataProfileInfo
@@ -812,7 +812,7 @@
/*
* Test IRadio.getDataRegistrationStateResponse_1_4() for the response returned.
*/
-TEST_F(RadioHidlTest_v1_4, getDataRegistrationState_1_4) {
+TEST_P(RadioHidlTest_v1_4, getDataRegistrationState_1_4) {
int rat;
serial = GetRandomSerialNumber();
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
index f27749b..15a0b24 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_test.cpp
@@ -17,18 +17,11 @@
#include <radio_hidl_hal_utils_v1_4.h>
void RadioHidlTest_v1_4::SetUp() {
- radio_v1_4 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_4::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_4::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_4 = ::android::hardware::radio::V1_4::IRadio::getService(GetParam());
+
if (radio_v1_4 == NULL) {
sleep(60);
- radio_v1_4 = ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::V1_4::IRadio>(
- RadioHidlEnvironment::Instance()
- ->getServiceName<::android::hardware::radio::V1_4::IRadio>(
- hidl_string(RADIO_SERVICE_NAME)));
+ radio_v1_4 = ::android::hardware::radio::V1_4::IRadio::getService(GetParam());
}
ASSERT_NE(nullptr, radio_v1_4.get());
@@ -48,8 +41,7 @@
EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
- ::testing::VtsHalHidlTargetTestBase::getService<
- ::android::hardware::radio::config::V1_1::IRadioConfig>();
+ ::android::hardware::radio::config::V1_1::IRadioConfig::getService();
/* Enforce Vts tesing with RadioConfig is existed. */
ASSERT_NE(nullptr, radioConfig.get());
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
index b07f9c3..31b7e13 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
+++ b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
@@ -16,8 +16,7 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <log/log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -28,6 +27,7 @@
#include <android/hardware/radio/1.4/IRadioIndication.h>
#include <android/hardware/radio/1.4/IRadioResponse.h>
#include <android/hardware/radio/1.4/types.h>
+#include <gtest/gtest.h>
#include "vts_test_util.h"
@@ -705,25 +705,9 @@
const ::android::hardware::hidl_string& reason);
};
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioHidlEnvironment* Instance() {
- static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::radio::V1_4::IRadio>();
- }
-
- private:
- RadioHidlEnvironment() {}
-};
-
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_4 : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+class RadioHidlTest_v1_4 : public ::testing::TestWithParam<std::string> {
+ protected:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
diff --git a/radio/1.5/Android.bp b/radio/1.5/Android.bp
index de9ec6e..06a2a6e 100644
--- a/radio/1.5/Android.bp
+++ b/radio/1.5/Android.bp
@@ -19,6 +19,7 @@
"android.hardware.radio@1.3",
"android.hardware.radio@1.4",
"android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
],
gen_java: true,
}
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
index 74ec56d..aa93ef3 100644
--- a/radio/1.5/IRadio.hal
+++ b/radio/1.5/IRadio.hal
@@ -18,6 +18,8 @@
import @1.4::IRadio;
import @1.5::AccessNetwork;
+import @1.5::NetworkScanRequest;
+import @1.5::RadioAccessSpecifier;
import @1.5::SignalThresholdInfo;
/**
@@ -29,7 +31,6 @@
* setResponseFunctions must work with @1.5::IRadioResponse and @1.5::IRadioIndication.
*/
interface IRadio extends @1.4::IRadio {
-
/**
* Sets the signal strength reporting criteria.
*
@@ -41,18 +42,91 @@
* -EUTRAN - RSRP/RSRQ/RSSNR
* -NGRAN - SSRSRP/SSRSRQ/SSSINR
*
- * Note: Reporting criteria must be individually set for each RAN. For any unset reporting
- * criteria, the value is implementation-defined.
+ * Note: Reporting criteria must be individually set for each RAN. For each RAN, if none of
+ * reporting criteria of any measurement is set enabled
+ * (see @1.5::SignalThresholdInfo.isEnabled), the reporting criteria for this RAN is
+ * implementation-defined. For each RAN, if any of reporting criteria of any measure is set
+ * enabled, the reporting criteria of the other measures in this RAN are set disabled
+ * (see @1.5::SignalThresholdInfo.isEnabled) until they are set enabled.
*
* Response callback is
* IRadioResponse.setSignalStrengthReportingCriteriaResponse_1_5()
*
* @param serial Serial number of request.
* @param signalThresholdInfo Signal threshold info including the threshold values,
- * hysteresisDb, and hysteresisMs. See @1.5::SignalThresholdInfo
- * for details.
+ * hysteresisDb, hysteresisMs and isEnabled.
+ * See @1.5::SignalThresholdInfo for details.
* @param accessNetwork The type of network for which to apply these thresholds.
*/
oneway setSignalStrengthReportingCriteria_1_5(int32_t serial,
SignalThresholdInfo signalThresholdInfo, AccessNetwork accessNetwork);
+
+ /**
+ * Enable or disable UiccApplications on the SIM. If disabled:
+ * - Modem will not register on any network.
+ * - SIM must be PRESENT, and the IccId of the SIM must still be accessible.
+ * - The corresponding modem stack is still functional, e.g. able to make emergency calls or
+ * do network scan.
+ * By default if this API is not called, the uiccApplications must be enabled automatically.
+ * It must work for both single SIM and DSDS cases for UX consistency.
+ * The preference is per SIM, and must be remembered over power cycle, modem reboot, or SIM
+ * insertion / unplug.
+ *
+ * @param serial: Serial number of request.
+ * @param enable: true if to enable uiccApplications, false to disable.
+
+ * Response callback is IRadioResponse.enableUiccApplicationsResponse()
+ */
+ oneway enableUiccApplications(int32_t serial, bool enable);
+
+ /**
+ * Whether uiccApplications are enabled, or disabled.
+ *
+ * By default uiccApplications must be enabled, unless enableUiccApplications() with enable
+ * being false is called.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response callback is IRadioResponse.areUiccApplicationsEnabledResponse()
+ */
+ oneway areUiccApplicationsEnabled(int32_t serial);
+
+ /**
+ * Query whether disabling and enabling UiccApplications functionality is supported. If not,
+ * calling enableUiccApplications with a different value will return
+ * RadioError:REQUEST_NOT_SUPPORTED.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response callback is IRadioResponse.canToggleUiccApplicationsEnablementResponse()
+ */
+ oneway canToggleUiccApplicationsEnablement(int32_t serial);
+
+ /**
+ * Specify which bands modem's background scan must act on.
+ * If specifyChannels is true, it only scans bands specified in specifiers.
+ * If specifyChannels is false, it scans all bands.
+ *
+ * For example, CBRS is only on LTE band 48. By specifying this band,
+ * modem saves more power.
+ *
+ * @param serial Serial number of request.
+ * @param specifyChannels whether to scan bands defined in specifiers.
+ * @param specifiers which bands to scan. Only used if specifyChannels is true.
+ *
+ * Response callback is IRadioResponse.setSystemSelectionChannelsResponse()
+ */
+ oneway setSystemSelectionChannels_1_5(int32_t serial, bool specifyChannels,
+ vec<RadioAccessSpecifier> specifiers);
+
+ /**
+ * Starts a network scan
+ *
+ * @param serial Serial number of request.
+ * @param request Defines the radio networks/bands/channels which need to be scanned.
+ *
+ * Same API as @1.4::IRadio.startNetworkScan_1_4, except using
+ * 1.5 version of NetworkScanRequest
+ */
+ oneway startNetworkScan_1_5(int32_t serial, NetworkScanRequest request);
};
diff --git a/radio/1.5/IRadioIndication.hal b/radio/1.5/IRadioIndication.hal
index d488404..81452ab 100644
--- a/radio/1.5/IRadioIndication.hal
+++ b/radio/1.5/IRadioIndication.hal
@@ -23,4 +23,11 @@
* Interface declaring unsolicited radio indications.
*/
interface IRadioIndication extends @1.4::IRadioIndication {
+ /**
+ * Report change of whether uiccApplications are enabled, or disabled.
+ *
+ * @param type Type of radio indication
+ * @param enabled whether uiccApplications are enabled, or disabled
+ */
+ oneway uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
};
diff --git a/radio/1.5/IRadioResponse.hal b/radio/1.5/IRadioResponse.hal
index 91dc1e0..e7a3852 100644
--- a/radio/1.5/IRadioResponse.hal
+++ b/radio/1.5/IRadioResponse.hal
@@ -32,4 +32,65 @@
* RadioError:RADIO_NOT_AVAILABLE
*/
oneway setSignalStrengthReportingCriteriaResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:SIM_ABSENT
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:BUSY
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ oneway enableUiccApplicationsResponse(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param enabled whether Uicc applications are enabled.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:SIM_ABSENT
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ oneway areUiccApplicationsEnabledResponse(RadioResponseInfo info, bool enabled);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param canToggle whether toggling UiccApplications functionality is supported.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway canToggleUiccApplicationsEnablementResponse(RadioResponseInfo info, bool canToggle);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway setSystemSelectionChannelsResponse_1_5(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:DEVICE_IN_USE
+ * RadioError:INTERNAL_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway startNetworkScanResponse_1_5(RadioResponseInfo info);
};
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index 216ca1f..04a9bcf 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -16,6 +16,13 @@
package android.hardware.radio@1.5;
+import @1.1::EutranBands;
+import @1.1::GeranBands;
+import @1.1::RadioAccessNetworks;
+import @1.1::RadioAccessSpecifier;
+import @1.1::ScanType;
+import @1.1::UtranBands;
+import @1.2::NetworkScanRequest;
import @1.4::AccessNetwork;
/**
@@ -52,9 +59,11 @@
RSRQ = 4,
/**
* Reference Signal Signal to Noise Ratio
- * Range: -20 dB to -30 dB;
+ * Range: -20 dB to 30 dB;
* Used RAN: EUTRAN
- * Reference: 3GPP TS 36.101 8.1.1
+ * Note: this field is optional; how to support it can be decided by the
+ * corresponding vendor. Though the response code is not enforced,
+ * vendor's implementation must ensure this interface not crashing.
*/
RSSNR = 5,
/**
@@ -104,6 +113,15 @@
* A vector size of 0 disables the use of thresholds for reporting.
*/
vec<int32_t> thresholds;
+
+ /**
+ * Indicates whether the reporting criteria of the corresponding measurement is enabled
+ * (isEnabled==true) or disabled (isEnabled==false).
+ *
+ * If enabled, modem must trigger the report based on the criteria.
+ * If disabled, modem must not trigger the report based on the criteria.
+ */
+ bool isEnabled;
};
enum AccessNetwork : @1.4::AccessNetwork {
@@ -111,4 +129,142 @@
* Next-Generation Radio Access Network (NGRAN)
*/
NGRAN = 6,
-};
\ No newline at end of file
+};
+
+enum RadioAccessNetworks : @1.1::RadioAccessNetworks {
+ NGRAN = 4,
+};
+
+/**
+ * Overwritten from @1.1::RadioAccessSpecifier to add NGRAN and NgranBands
+ */
+struct RadioAccessSpecifier {
+ /**
+ * The type of network to scan.
+ */
+ RadioAccessNetworks radioAccessNetwork;
+
+ /**
+ * The frequency bands to scan.
+ * Maximum length of the vector is 8.
+ */
+ safe_union Bands {
+ /** Valid only if radioAccessNetwork = GERAN. */
+ vec<GeranBands> geranBands;
+ /** Valid only if radioAccessNetwork = UTRAN. */
+ vec<UtranBands> utranBands;
+ /** Valid only if radioAccessNetwork = EUTRAN. */
+ vec<EutranBands> eutranBands;
+ /** Valid only if radioAccessNetwork = NGRAN. */
+ vec<NgranBands> ngranBands;
+ } bands;
+
+ /**
+ * The radio channels to scan as defined in 3GPP TS 25.101 and 36.101.
+ * Maximum length of the vector is 32.
+ */
+ vec<int32_t> channels;
+};
+
+enum NgranBands : int32_t {
+ /** 3GPP TS 38.101-1, Table 5.2-1: FR1 bands */
+ BAND_1 = 1,
+ BAND_2 = 2,
+ BAND_3 = 3,
+ BAND_5 = 5,
+ BAND_7 = 7,
+ BAND_8 = 8,
+ BAND_12 = 12,
+ BAND_14 = 14,
+ BAND_18 = 18,
+ BAND_20 = 20,
+ BAND_25 = 25,
+ BAND_28 = 28,
+ BAND_29 = 29,
+ BAND_30 = 30,
+ BAND_34 = 34,
+ BAND_38 = 38,
+ BAND_39 = 39,
+ BAND_40 = 40,
+ BAND_41 = 41,
+ BAND_48 = 48,
+ BAND_50 = 50,
+ BAND_51 = 51,
+ BAND_65 = 65,
+ BAND_66 = 66,
+ BAND_70 = 70,
+ BAND_71 = 71,
+ BAND_74 = 74,
+ BAND_75 = 75,
+ BAND_76 = 76,
+ BAND_77 = 77,
+ BAND_78 = 78,
+ BAND_79 = 79,
+ BAND_80 = 80,
+ BAND_81 = 81,
+ BAND_82 = 82,
+ BAND_83 = 83,
+ BAND_84 = 84,
+ BAND_86 = 86,
+ BAND_90 = 90,
+ /** 3GPP TS 38.101-2, Table 5.2-1: FR2 bands */
+ BAND_257 = 257,
+ BAND_258 = 258,
+ BAND_260 = 260,
+ BAND_261 = 261,
+};
+
+/**
+ * Overwritten from @1.2::NetworkScanRequest to update
+ * RadioAccessSpecifier to 1.5 version
+ */
+struct NetworkScanRequest {
+ ScanType type;
+
+ /**
+ * Time interval in seconds between the completion of one scan and the start of
+ * a subsequent scan.
+ * Implementations may ignore this field unless the 'type' is 'PERIODIC'.
+ * Range: ScanIntervalRange:MIN to ScanIntervalRange:MAX
+ */
+ int32_t interval;
+
+ /**
+ * Networks with bands/channels to scan
+ * Maximum length of the vector is RadioConst:RADIO_ACCESS_SPECIFIER_MAX_SIZE
+ */
+ vec<RadioAccessSpecifier> specifiers;
+
+ /**
+ * Maximum duration of the periodic search (in seconds).
+ * If the search lasts maxSearchTime, it must be terminated.
+ * Range: MaxSearchTimeRange:MIN to MaxSearchTimeRange:MAX
+ */
+ int32_t maxSearchTime;
+
+ /**
+ * Indicates whether the modem must report incremental results of the network scan
+ * to the client.
+ * FALSE – Incremental results must not be reported.
+ * TRUE – Incremental must be reported.
+ */
+ bool incrementalResults;
+
+ /**
+ * Indicates the periodicity with which the modem must report incremental results to
+ * the client (in seconds).
+ * Implementations may ignore this value if the incremental results are not requested.
+ * This value must be less than or equal to maxSearchTime.
+ * Range: IncrementalResultsPeriodicityRange:MIN to IncrementalResultsPeriodicityRange:MAX
+ */
+ int32_t incrementalResultsPeriodicity;
+
+ /**
+ * Describes the List of PLMN ids (MCC-MNC)
+ * If any PLMN of this list is found, search must end at that point and results with all
+ * PLMN found until that point should be sent as response.
+ * If the list is not sent, search to be completed until end and all PLMNs found to be
+ * reported.
+ */
+ vec<string> mccMncs;
+};
diff --git a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
index b72febd..5f11d19 100644
--- a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
+++ b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
@@ -23,4 +23,4 @@
int status = RUN_ALL_TESTS();
LOG(INFO) << "Test result = " << status;
return status;
-}
\ No newline at end of file
+}
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 650ede4..6bf8170 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -29,6 +29,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 10; // hysteresisDb too large given threshold list deltas
signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::GERAN);
@@ -52,6 +53,7 @@
signalThresholdInfo.signalMeasurement = SignalMeasurementType::RSSI;
signalThresholdInfo.hysteresisMs = 0;
signalThresholdInfo.hysteresisDb = 0;
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::GERAN);
@@ -76,6 +78,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-109, -103, -97, -89};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::GERAN);
@@ -100,6 +103,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-110, -97, -73, -49, -25};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::UTRAN);
@@ -124,6 +128,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-128, -108, -88, -68};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
@@ -148,6 +153,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-27, -20, -13, -6};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
@@ -172,6 +178,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
@@ -179,10 +186,6 @@
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
-
- ALOGI("setSignalStrengthReportingCriteria_1_5_Eutran, rspInfo.error = %s\n",
- toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
}
/*
@@ -196,6 +199,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 2;
signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::CDMA2000);
@@ -220,6 +224,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 0;
signalThresholdInfo.thresholds = {-105, -90, -75, -65};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::NGRAN);
@@ -244,6 +249,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 0;
signalThresholdInfo.thresholds = {-15, -10, -5, -4};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::NGRAN);
@@ -258,6 +264,27 @@
}
/*
+ * Test IRadio.setSignalStrengthReportingCriteria_1_5() for EUTRAN
+ */
+TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Disable_RSSNR) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalMeasurementType::RSSNR;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-10, 0, 10, 20};
+ signalThresholdInfo.isEnabled = false;
+
+ Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
+ serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+}
+
+/*
* Test IRadio.setSignalStrengthReportingCriteria_1_5() for NGRAN_SSSINR
*/
TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR) {
@@ -268,6 +295,7 @@
signalThresholdInfo.hysteresisMs = 5000;
signalThresholdInfo.hysteresisDb = 0;
signalThresholdInfo.thresholds = {-10, 3, 16, 18};
+ signalThresholdInfo.isEnabled = true;
Return<void> res = radio_v1_5->setSignalStrengthReportingCriteria_1_5(
serial, signalThresholdInfo, ::android::hardware::radio::V1_5::AccessNetwork::NGRAN);
@@ -279,4 +307,593 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.enableUiccApplications() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsNotSupported) {
+ serial = GetRandomSerialNumber();
+
+ radio_v1_5->canToggleUiccApplicationsEnablement(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // No error should happen.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Supported case will be tested by other test cases.
+ if (radioRsp_v1_5->canToggleUiccApplicationsEnablement) return;
+
+ // Enabling UiccApplications should still work as it should be enabled by default.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Disabling UiccApplications should return REQUEST_NOT_SUPPORTED error.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::REQUEST_NOT_SUPPORTED, radioRsp_v1_5->rspInfo.error);
+
+ // Query areUiccApplicationsEnabled should return true.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ ASSERT_TRUE(radioRsp_v1_5->areUiccApplicationsEnabled);
+}
+
+/*
+ * Test IRadio.enableUiccApplications() for the response returned.
+ * For SIM ABSENT case.
+ */
+TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsSupportedSimAbsent) {
+ serial = GetRandomSerialNumber();
+
+ radio_v1_5->canToggleUiccApplicationsEnablement(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // No error should happen.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ // Not supported case will be tested by togglingUiccApplicationsNotSupported test case.
+ if (!radioRsp_v1_5->canToggleUiccApplicationsEnablement) return;
+
+ // This test case only test SIM ABSENT case.
+ if (cardStatus.base.base.cardState != CardState::ABSENT) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_v1_5->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is absent, RadioError::SIM_ABSENT should be thrown.
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_v1_5->rspInfo.error);
+}
+
+/*
+ * Test IRadio.enableUiccApplications() for the response returned.
+ * For SIM PRESENT case.
+ */
+TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsSupportedSimPresent) {
+ serial = GetRandomSerialNumber();
+
+ radio_v1_5->canToggleUiccApplicationsEnablement(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // No error should happen.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ // Not supported case will be tested by disablingUiccApplicationsNotSupported test case.
+ if (!radioRsp_v1_5->canToggleUiccApplicationsEnablement) return;
+
+ // This test case only test SIM ABSENT case.
+ if (cardStatus.base.base.cardState != CardState::PRESENT) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ ASSERT_FALSE(radioRsp_v1_5->areUiccApplicationsEnabled);
+
+ // Enable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->enableUiccApplications(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Query Uicc application enablement.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // As SIM is present, there shouldn't be error.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ ASSERT_TRUE(radioRsp_v1_5->areUiccApplicationsEnabled);
+}
+
+/*
+ * Test IRadio.areUiccApplicationsEnabled() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, areUiccApplicationsEnabled) {
+ serial = GetRandomSerialNumber();
+
+ radio_v1_5->canToggleUiccApplicationsEnablement(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ // No error should happen.
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ // Not supported case will be tested by togglingUiccApplicationsNotSupported test case.
+ if (!radioRsp_v1_5->canToggleUiccApplicationsEnablement) return;
+
+ // Disable Uicc applications.
+ serial = GetRandomSerialNumber();
+ radio_v1_5->areUiccApplicationsEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+
+ // If SIM is absent, RadioError::SIM_ABSENT should be thrown. Otherwise there shouldn't be any
+ // error.
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::SIM_ABSENT, radioRsp_v1_5->rspInfo.error);
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setSystemSelectionChannels_1_5() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(serial, true, {specifier});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
+
+ if (radioRsp_v1_5->rspInfo.error == RadioError::NONE) {
+ serial = GetRandomSerialNumber();
+ Return<void> res = radio_v1_5->setSystemSelectionChannels_1_5(serial, false, {specifier});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("setSystemSelectionChannels, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan, rspInfo.error = %s\n", toString(radioRsp_v1_5->rspInfo.error).c_str());
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do
+ // not support the required manual GSM search functionality. This is
+ // tracked in b/112206766. Modems have "GSM" rat scan need to
+ // support scanning requests combined with some parameters.
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid specifier.
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidArgument) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
+ .interval = 60};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid interval (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 4,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid interval (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 301,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid max search time (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 59,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid max search time (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 3601,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid periodicity (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = true,
+ .incrementalResultsPeriodicity = 0};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with invalid periodicity (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = true,
+ .incrementalResultsPeriodicity = 11};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_5->rspInfo.error,
+ {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with valid periodicity
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 360,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan_1_5() with valid periodicity and plmns
+ */
+TEST_F(RadioHidlTest_v1_5, startNetworkScan_GoodRequest2) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
+ rasBands.geranBands() = {GeranBands::BAND_450, GeranBands::BAND_480};
+
+ ::android::hardware::radio::V1_5::RadioAccessSpecifier specifier = {
+ .radioAccessNetwork = ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN,
+ .bands = rasBands,
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_5::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 360,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10,
+ .mccMncs = {"310410"}};
+
+ Return<void> res = radio_v1_5->startNetworkScan_1_5(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_5->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index 683fdfc..01bda69 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -53,7 +53,7 @@
class RadioHidlTest_v1_5;
extern ::android::hardware::radio::V1_4::CardStatus cardStatus;
-/* Callback class for radio respons v1_5 */
+/* Callback class for radio response v1_5 */
class RadioResponse_v1_5 : public ::android::hardware::radio::V1_5::IRadioResponse {
protected:
RadioHidlTest_v1_5& parent_v1_5;
@@ -80,6 +80,12 @@
::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp;
::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicyResp;
+ // Whether toggling uicc applications operation is supported.
+ bool canToggleUiccApplicationsEnablement;
+
+ // Whether Uicc applications are enabled or not.
+ bool areUiccApplicationsEnabled;
+
RadioResponse_v1_5(RadioHidlTest_v1_5& parent_v1_5);
virtual ~RadioResponse_v1_5() = default;
@@ -524,6 +530,17 @@
/* 1.5 Api */
Return<void> setSignalStrengthReportingCriteriaResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> enableUiccApplicationsResponse(const RadioResponseInfo& info);
+
+ Return<void> areUiccApplicationsEnabledResponse(const RadioResponseInfo& info, bool enabled);
+
+ Return<void> canToggleUiccApplicationsEnablementResponse(const RadioResponseInfo& info,
+ bool canToggle);
+
+ Return<void> setSystemSelectionChannelsResponse_1_5(const RadioResponseInfo& info);
+
+ Return<void> startNetworkScanResponse_1_5(const RadioResponseInfo& info);
};
/* Callback class for radio indication */
@@ -535,6 +552,9 @@
RadioIndication_v1_5(RadioHidlTest_v1_5& parent_v1_5);
virtual ~RadioIndication_v1_5() = default;
+ /* 1.5 Api */
+ Return<void> uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
+
/* 1.4 Api */
Return<void> currentEmergencyNumberList(
RadioIndicationType type,
diff --git a/radio/1.5/vts/functional/radio_indication.cpp b/radio/1.5/vts/functional/radio_indication.cpp
index b63b745..acffbbe 100644
--- a/radio/1.5/vts/functional/radio_indication.cpp
+++ b/radio/1.5/vts/functional/radio_indication.cpp
@@ -328,3 +328,8 @@
const ::android::hardware::hidl_string& /*reason*/) {
return Void();
}
+
+Return<void> RadioIndication_v1_5::uiccApplicationsEnablementChanged(RadioIndicationType /*type*/,
+ bool /*enabled*/) {
+ return Void();
+}
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 29a9250..5964c96 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -892,4 +892,39 @@
rspInfo = info;
parent_v1_5.notify(info.serial);
return Void();
-}
\ No newline at end of file
+}
+
+Return<void> RadioResponse_v1_5::enableUiccApplicationsResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::areUiccApplicationsEnabledResponse(const RadioResponseInfo& info,
+ bool enabled) {
+ rspInfo = info;
+ areUiccApplicationsEnabled = enabled;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::canToggleUiccApplicationsEnablementResponse(
+ const RadioResponseInfo& info, bool canToggle) {
+ rspInfo = info;
+ canToggleUiccApplicationsEnablement = canToggle;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setSystemSelectionChannelsResponse_1_5(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startNetworkScanResponse_1_5(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
diff --git a/radio/config/1.0/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.0/vts/functional/radio_config_hidl_hal_utils.h
index 6bc1b65..2722afe 100644
--- a/radio/config/1.0/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.0/vts/functional/radio_config_hidl_hal_utils.h
@@ -27,6 +27,7 @@
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
+#include <log/log.h>
#include "vts_test_util.h"
diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h
index e9951dc..4cdeb06 100644
--- a/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h
@@ -26,6 +26,7 @@
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
+#include <log/log.h>
#include "vts_test_util.h"
diff --git a/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h
index e9cbcbd..ba3f02e 100644
--- a/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h
@@ -28,6 +28,7 @@
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
+#include <log/log.h>
#include "vts_test_util.h"
@@ -98,20 +99,6 @@
const ::android::hardware::hidl_vec<SimSlotStatus>& slotStatus);
};
-// Test environment for Radio HIDL HAL.
-class RadioConfigHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static RadioConfigHidlEnvironment* Instance() {
- static RadioConfigHidlEnvironment* instance = new RadioConfigHidlEnvironment;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<IRadioConfig>(); }
-
- private:
- RadioConfigHidlEnvironment() {}
-};
-
// The main test class for Radio config HIDL.
class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
protected:
diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp
new file mode 100644
index 0000000..88de666
--- /dev/null
+++ b/radio/config/1.3/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.radio.config@1.3",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IRadioConfig.hal",
+ "IRadioConfigIndication.hal",
+ "IRadioConfigResponse.hal",
+ ],
+ interfaces: [
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/radio/config/1.3/IRadioConfig.hal b/radio/config/1.3/IRadioConfig.hal
new file mode 100644
index 0000000..a0ce6e0
--- /dev/null
+++ b/radio/config/1.3/IRadioConfig.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.config@1.3;
+
+import @1.1::IRadioConfig;
+
+/**
+ * This interface is used by telephony and telecom to talk to cellular radio for the purpose of
+ * radio configuration, and it is not associated with any specific modem or slot.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ */
+interface IRadioConfig extends @1.1::IRadioConfig {
+
+};
diff --git a/vibrator/1.4/types.hal b/radio/config/1.3/IRadioConfigIndication.hal
similarity index 73%
copy from vibrator/1.4/types.hal
copy to radio/config/1.3/IRadioConfigIndication.hal
index acc49b1..9ef496c 100644
--- a/vibrator/1.4/types.hal
+++ b/radio/config/1.3/IRadioConfigIndication.hal
@@ -14,9 +14,13 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+package android.hardware.radio.config@1.3;
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
+import @1.2::IRadioConfigIndication;
+
+/**
+ * Interface declaring unsolicited radio config indications.
+ */
+interface IRadioConfigIndication extends @1.2::IRadioConfigIndication {
+
};
diff --git a/vibrator/1.4/types.hal b/radio/config/1.3/IRadioConfigResponse.hal
similarity index 72%
copy from vibrator/1.4/types.hal
copy to radio/config/1.3/IRadioConfigResponse.hal
index acc49b1..9c4c971 100644
--- a/vibrator/1.4/types.hal
+++ b/radio/config/1.3/IRadioConfigResponse.hal
@@ -14,9 +14,13 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+package android.hardware.radio.config@1.3;
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
+import @1.2::IRadioConfigResponse;
+
+/**
+ * Interface declaring response functions to solicited radio config requests.
+ */
+interface IRadioConfigResponse extends @1.2::IRadioConfigResponse {
+
};
diff --git a/radio/config/1.3/default/Android.bp b/radio/config/1.3/default/Android.bp
new file mode 100644
index 0000000..163c5c5
--- /dev/null
+++ b/radio/config/1.3/default/Android.bp
@@ -0,0 +1,28 @@
+cc_binary {
+ name: "android.hardware.radio.config@1.3-service",
+ init_rc: ["android.hardware.radio.config@1.3-service.rc"],
+ relative_install_path: "hw",
+ vintf_fragments: ["radio-config-default.xml"],
+ vendor: true,
+ srcs: [
+ "RadioConfig.cpp",
+ "RadioConfigIndication.cpp",
+ "RadioConfigResponse.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ "android.hardware.radio@1.0",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.2",
+ "android.hardware.radio@1.3",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.5",
+ ],
+}
diff --git a/radio/config/1.3/default/RadioConfig.cpp b/radio/config/1.3/default/RadioConfig.cpp
new file mode 100644
index 0000000..c28119c
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfig.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "RadioConfig.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfig follow.
+Return<void> RadioConfig::setResponseFunctions(
+ const sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
+ const sp<V1_0::IRadioConfigIndication>& radioConfigIndication) {
+ mRadioConfigResponse = radioConfigResponse;
+ mRadioConfigIndication = radioConfigIndication;
+
+ mRadioConfigResponseV1_3 =
+ V1_3::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
+ mRadioConfigIndicationV1_3 =
+ V1_3::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
+ if (mRadioConfigResponseV1_3 == nullptr || mRadioConfigIndicationV1_3 == nullptr) {
+ mRadioConfigResponseV1_3 = nullptr;
+ mRadioConfigIndicationV1_3 = nullptr;
+ }
+
+ mRadioConfigResponseV1_2 =
+ V1_2::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
+ mRadioConfigIndicationV1_2 =
+ V1_2::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
+ if (mRadioConfigResponseV1_2 == nullptr || mRadioConfigIndicationV1_2 == nullptr) {
+ mRadioConfigResponseV1_2 = nullptr;
+ mRadioConfigIndicationV1_2 = nullptr;
+ }
+
+ mRadioConfigResponseV1_1 =
+ V1_1::IRadioConfigResponse::castFrom(mRadioConfigResponse).withDefault(nullptr);
+ mRadioConfigIndicationV1_1 =
+ V1_1::IRadioConfigIndication::castFrom(mRadioConfigIndication).withDefault(nullptr);
+ if (mRadioConfigResponseV1_1 == nullptr || mRadioConfigIndicationV1_1 == nullptr) {
+ mRadioConfigResponseV1_1 = nullptr;
+ mRadioConfigIndicationV1_1 = nullptr;
+ }
+
+ return Void();
+}
+
+Return<void> RadioConfig::getSimSlotsStatus(int32_t /* serial */) {
+ hidl_vec<V1_0::SimSlotStatus> slotStatus;
+ RadioResponseInfo info;
+ mRadioConfigResponse->getSimSlotsStatusResponse(info, slotStatus);
+ return Void();
+}
+
+Return<void> RadioConfig::setSimSlotsMapping(int32_t /* serial */,
+ const hidl_vec<uint32_t>& /* slotMap */) {
+ RadioResponseInfo info;
+ mRadioConfigResponse->setSimSlotsMappingResponse(info);
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_1::IRadioConfig follow.
+Return<void> RadioConfig::getPhoneCapability(int32_t /* serial */) {
+ V1_1::PhoneCapability phoneCapability;
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->getPhoneCapabilityResponse(info, phoneCapability);
+ return Void();
+}
+
+Return<void> RadioConfig::setPreferredDataModem(int32_t /* serial */, uint8_t /* modemId */) {
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->setPreferredDataModemResponse(info);
+ return Void();
+}
+
+Return<void> RadioConfig::setModemsConfig(int32_t /* serial */,
+ const V1_1::ModemsConfig& /* modemsConfig */) {
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->setModemsConfigResponse(info);
+ return Void();
+}
+
+Return<void> RadioConfig::getModemsConfig(int32_t /* serial */) {
+ V1_1::ModemsConfig modemsConfig;
+ RadioResponseInfo info;
+ mRadioConfigResponseV1_1->getModemsConfigResponse(info, modemsConfig);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
diff --git a/radio/config/1.3/default/RadioConfig.h b/radio/config/1.3/default/RadioConfig.h
new file mode 100644
index 0000000..00585e6
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfig.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIG_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIG_H
+
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::config;
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioConfig : public V1_3::IRadioConfig {
+ sp<V1_0::IRadioConfigResponse> mRadioConfigResponse;
+ sp<V1_0::IRadioConfigIndication> mRadioConfigIndication;
+ sp<V1_1::IRadioConfigResponse> mRadioConfigResponseV1_1;
+ sp<V1_1::IRadioConfigIndication> mRadioConfigIndicationV1_1;
+ sp<V1_2::IRadioConfigResponse> mRadioConfigResponseV1_2;
+ sp<V1_2::IRadioConfigIndication> mRadioConfigIndicationV1_2;
+ sp<V1_3::IRadioConfigResponse> mRadioConfigResponseV1_3;
+ sp<V1_3::IRadioConfigIndication> mRadioConfigIndicationV1_3;
+
+ // Methods from ::android::hardware::radio::config::V1_0::IRadioConfig follow.
+ Return<void> setResponseFunctions(
+ const sp<V1_0::IRadioConfigResponse>& radioConfigResponse,
+ const sp<V1_0::IRadioConfigIndication>& radioConfigIndication);
+ Return<void> getSimSlotsStatus(int32_t serial);
+ Return<void> setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap);
+
+ // Methods from ::android::hardware::radio::config::V1_1::IRadioConfig follow.
+ Return<void> getPhoneCapability(int32_t serial);
+ Return<void> setPreferredDataModem(int32_t serial, uint8_t modemId);
+ Return<void> setModemsConfig(int32_t serial, const V1_1::ModemsConfig& modemsConfig);
+ Return<void> getModemsConfig(int32_t serial);
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIG_H
diff --git a/radio/config/1.3/default/RadioConfigIndication.cpp b/radio/config/1.3/default/RadioConfigIndication.cpp
new file mode 100644
index 0000000..eb77a48
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigIndication.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "RadioConfigIndication.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_0;
+using namespace ::android::hardware::radio::config::V1_2;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfigIndication follow.
+Return<void> RadioConfigIndication::simSlotsStatusChanged(
+ RadioIndicationType /* type */, const hidl_vec<V1_0::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_2::IRadioConfigIndication follow.
+Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
+ RadioIndicationType /* type */, const hidl_vec<V1_2::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
diff --git a/radio/config/1.3/default/RadioConfigIndication.h b/radio/config/1.3/default/RadioConfigIndication.h
new file mode 100644
index 0000000..3697492
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigIndication.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGINDICATION_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGINDICATION_H
+
+#include <android/hardware/radio/config/1.3/IRadioConfigIndication.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config;
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioConfigIndication : public IRadioConfigIndication {
+ // Methods from ::android::hardware::radio::config::V1_0::IRadioConfigIndication follow.
+ Return<void> simSlotsStatusChanged(RadioIndicationType type,
+ const hidl_vec<V1_0::SimSlotStatus>& slotStatus) override;
+
+ // Methods from ::android::hardware::radio::config::V1_2::IRadioConfigIndication follow.
+ Return<void> simSlotsStatusChanged_1_2(
+ RadioIndicationType type, const hidl_vec<V1_2::SimSlotStatus>& slotStatus) override;
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGINDICATION_H
diff --git a/radio/config/1.3/default/RadioConfigResponse.cpp b/radio/config/1.3/default/RadioConfigResponse.cpp
new file mode 100644
index 0000000..48e81da
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigResponse.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "RadioConfigResponse.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_0;
+using namespace ::android::hardware::radio::config::V1_1;
+using namespace ::android::hardware::radio::config::V1_2;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+ const RadioResponseInfo& /* info */,
+ const hidl_vec<V1_0::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_1::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+ const RadioResponseInfo& /* info */, const V1_1::PhoneCapability& /* phoneCapability */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+ const RadioResponseInfo& /* info */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const RadioResponseInfo& /* info */) {
+ // TODO implement
+ return Void();
+}
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(
+ const RadioResponseInfo& /* info */, const V1_1::ModemsConfig& /* modemsConfig */) {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::radio::config::V1_2::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+ const RadioResponseInfo& /* info */,
+ const hidl_vec<V1_2::SimSlotStatus>& /* slotStatus */) {
+ // TODO implement
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
diff --git a/radio/config/1.3/default/RadioConfigResponse.h b/radio/config/1.3/default/RadioConfigResponse.h
new file mode 100644
index 0000000..0f0033f
--- /dev/null
+++ b/radio/config/1.3/default/RadioConfigResponse.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGRESPONSE_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGRESPONSE_H
+
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_3 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioConfigResponse : public IRadioConfigResponse {
+ // Methods from ::android::hardware::radio::config::V1_0::IRadioConfigResponse follow.
+ Return<void> getSimSlotsStatusResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus)
+ override;
+ Return<void> setSimSlotsMappingResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+
+ // Methods from ::android::hardware::radio::config::V1_1::IRadioConfigResponse follow.
+ Return<void> getPhoneCapabilityResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::radio::config::V1_1::PhoneCapability& phoneCapability)
+ override;
+ Return<void> setPreferredDataModemResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+ Return<void> setModemsConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+ Return<void> getModemsConfigResponse(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::radio::config::V1_1::ModemsConfig& modemsConfig) override;
+
+ // Methods from ::android::hardware::radio::config::V1_2::IRadioConfigResponse follow.
+ Return<void> getSimSlotsStatusResponse_1_2(
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::config::V1_2::SimSlotStatus>& slotStatus)
+ override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace config
+} // namespace radio
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_RADIO_CONFIG_V1_3_RADIOCONFIGRESPONSE_H
diff --git a/radio/config/1.3/default/android.hardware.radio.config@1.3-service.rc b/radio/config/1.3/default/android.hardware.radio.config@1.3-service.rc
new file mode 100644
index 0000000..6df9b52
--- /dev/null
+++ b/radio/config/1.3/default/android.hardware.radio.config@1.3-service.rc
@@ -0,0 +1,7 @@
+service vendor.radio-config-hal-1-3 /vendor/bin/hw/android.hardware.radio.config@1.3-service
+ interface android.hardware.radio.config@1.0::IRadioConfig default
+ interface android.hardware.radio.config@1.1::IRadioConfig default
+ interface android.hardware.radio.config@1.3::IRadioConfig default
+ class hal
+ user system
+ group system
diff --git a/radio/config/1.3/default/radio-config-default.xml b/radio/config/1.3/default/radio-config-default.xml
new file mode 100644
index 0000000..72f363e
--- /dev/null
+++ b/radio/config/1.3/default/radio-config-default.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, The Android Open Source Project.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.radio.config</name>
+ <transport>hwbinder</transport>
+ <version>1.3</version>
+ <interface>
+ <name>IRadioConfig</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/radio/config/1.3/default/service.cpp b/radio/config/1.3/default/service.cpp
new file mode 100644
index 0000000..b1e6736
--- /dev/null
+++ b/radio/config/1.3/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "android.hardware.radio.config@1.3-service"
+
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "RadioConfig.h"
+
+using android::OK;
+using android::sp;
+using android::status_t;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::radio::config::V1_3::IRadioConfig;
+using android::hardware::radio::config::V1_3::implementation::RadioConfig;
+
+int main() {
+ configureRpcThreadpool(1, true);
+ sp<IRadioConfig> radioConfig = new RadioConfig;
+ const status_t status = radioConfig->registerAsService();
+ ALOGW_IF(status != OK, "Could not register IRadioConfig 1.3");
+ ALOGD("Default service is ready.");
+
+ joinRpcThreadpool();
+ return 1;
+}
diff --git a/vibrator/1.4/IVibratorCallback.hal b/radio/config/1.3/types.hal
similarity index 85%
copy from vibrator/1.4/IVibratorCallback.hal
copy to radio/config/1.3/types.hal
index 76281bc..866002a 100644
--- a/vibrator/1.4/IVibratorCallback.hal
+++ b/radio/config/1.3/types.hal
@@ -14,8 +14,4 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
-
-interface IVibratorCallback {
- oneway onComplete();
-};
+package android.hardware.radio.config@1.3;
diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp
new file mode 100644
index 0000000..6b28faf
--- /dev/null
+++ b/radio/config/1.3/vts/functional/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalRadioConfigV1_3TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "radio_config_hidl_hal_api.cpp",
+ "radio_config_hidl_hal_test.cpp",
+ "radio_config_response.cpp",
+ "VtsHalRadioConfigV1_3TargetTest.cpp",
+ ],
+ static_libs: [
+ "RadioVtsTestUtilBase",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ ],
+ header_libs: ["radio.util.header@1.0"],
+ test_suites: ["general-tests", "vts-core"],
+}
diff --git a/vibrator/1.4/types.hal b/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp
similarity index 65%
copy from vibrator/1.4/types.hal
copy to radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp
index acc49b1..3bacacf 100644
--- a/vibrator/1.4/types.hal
+++ b/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+#include <radio_config_hidl_hal_utils.h>
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, RadioConfigHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::radio::config::V1_3::IRadioConfig::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.4/IVibratorCallback.hal b/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp
similarity index 85%
rename from vibrator/1.4/IVibratorCallback.hal
rename to radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp
index 76281bc..07e9ede 100644
--- a/vibrator/1.4/IVibratorCallback.hal
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+#include <radio_config_hidl_hal_utils.h>
-interface IVibratorCallback {
- oneway onComplete();
-};
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
new file mode 100644
index 0000000..dbb4bf4
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <radio_config_hidl_hal_utils.h>
+
+void RadioConfigHidlTest::SetUp() {
+ radioConfig = ::android::hardware::radio::config::V1_3::IRadioConfig::getService(GetParam());
+ ASSERT_NE(nullptr, radioConfig.get());
+
+ radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this);
+ ASSERT_NE(nullptr, radioConfigRsp.get());
+
+ count_ = 0;
+
+ radioConfig->setResponseFunctions(radioConfigRsp, nullptr);
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioConfigHidlTest::notify(int receivedSerial) {
+ std::unique_lock<std::mutex> lock(mtx_);
+ if (serial == receivedSerial) {
+ count_++;
+ cv_.notify_one();
+ }
+}
+
+/*
+ * Wait till the response message is notified or till TIMEOUT_PERIOD.
+ */
+std::cv_status RadioConfigHidlTest::wait() {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) {
+ return status;
+ }
+ }
+ count_--;
+ return status;
+}
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
new file mode 100644
index 0000000..9b78c04
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+#include <android/hardware/radio/config/1.3/types.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "vts_test_util.h"
+
+using namespace ::android::hardware::radio::config::V1_1;
+using namespace ::android::hardware::radio::config::V1_2;
+using namespace ::android::hardware::radio::config::V1_3;
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::radio::V1_0::RadioResponseInfo;
+using ::android::hardware::radio::V1_0::RadioResponseType;
+
+#define TIMEOUT_PERIOD 75
+
+class RadioConfigHidlTest;
+
+/* Callback class for radio config response */
+class RadioConfigResponse : public ::android::hardware::radio::config::V1_3::IRadioConfigResponse {
+ protected:
+ RadioConfigHidlTest& parent;
+
+ public:
+ RadioResponseInfo rspInfo;
+ PhoneCapability phoneCap;
+
+ RadioConfigResponse(RadioConfigHidlTest& parent);
+ virtual ~RadioConfigResponse() = default;
+
+ /* 1.0 Api */
+ Return<void> getSimSlotsStatusResponse(
+ const RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus);
+
+ Return<void> setSimSlotsMappingResponse(const RadioResponseInfo& info);
+
+ /* 1.1 Api */
+ Return<void> getPhoneCapabilityResponse(const RadioResponseInfo& info,
+ const PhoneCapability& phoneCapability);
+
+ Return<void> setPreferredDataModemResponse(const RadioResponseInfo& info);
+
+ Return<void> getModemsConfigResponse(const RadioResponseInfo& info,
+ const ModemsConfig& mConfig);
+
+ Return<void> setModemsConfigResponse(const RadioResponseInfo& info);
+
+ /* 1.2 Api */
+ Return<void> getSimSlotsStatusResponse_1_2(const RadioResponseInfo& info,
+ const hidl_vec<SimSlotStatus>& slotStatus);
+};
+
+/* Callback class for radio config indication */
+class RadioConfigIndication
+ : public ::android::hardware::radio::config::V1_3::IRadioConfigIndication {
+ protected:
+ RadioConfigHidlTest& parent;
+
+ public:
+ RadioConfigIndication(RadioConfigHidlTest& parent);
+ virtual ~RadioConfigIndication() = default;
+
+ /* 1.2 Api */
+ Return<void> simSlotsStatusChanged_1_2(
+ ::android::hardware::radio::V1_0::RadioIndicationType type,
+ const hidl_vec<SimSlotStatus>& slotStatus);
+};
+
+// The main test class for Radio config HIDL.
+class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
+ protected:
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_;
+
+ public:
+ virtual void SetUp() override;
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ void notify(int receivedSerial);
+
+ /* Test code calls this function to wait for response */
+ std::cv_status wait();
+
+ void updateSimCardStatus();
+
+ /* Serial number for radio request */
+ int serial;
+
+ /* radio config service handle */
+ sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig;
+
+ /* radio config response handle */
+ sp<RadioConfigResponse> radioConfigRsp;
+};
diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp
new file mode 100644
index 0000000..1ca960e
--- /dev/null
+++ b/radio/config/1.3/vts/functional/radio_config_response.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <radio_config_hidl_hal_utils.h>
+
+using ::android::hardware::radio::V1_0::RadioResponseInfo;
+
+// SimSlotStatus slotStatus;
+
+RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {}
+
+/* 1.0 Apis */
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+ const RadioResponseInfo& /* info */,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::config::V1_0::SimSlotStatus>& /* slotStatus */) {
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) {
+ return Void();
+}
+
+/* 1.1 Apis */
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+ const RadioResponseInfo& info, const PhoneCapability& phoneCapability) {
+ rspInfo = info;
+ phoneCap = phoneCapability;
+ parent.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+ const RadioResponseInfo& /* info */) {
+ return Void();
+}
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(const RadioResponseInfo& /* info */,
+ const ModemsConfig& /* mConfig */) {
+ return Void();
+}
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const RadioResponseInfo& /* info */) {
+ return Void();
+}
+
+/* 1.2 Apis */
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+ const RadioResponseInfo& /* info */,
+ const ::android::hardware::hidl_vec<SimSlotStatus>& /* slotStatus */) {
+ return Void();
+}
\ No newline at end of file
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
index 7bb992b..1167fd4 100644
--- a/sensors/1.0/vts/functional/Android.bp
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -31,6 +31,6 @@
"android.hardware.sensors@1.0",
"VtsHalSensorsTargetTestUtils",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/sensors/1.0/vts/functional/AndroidTest.xml b/sensors/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..fb0d64c
--- /dev/null
+++ b/sensors/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalSensorsV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="stop"/>
+ <option name="teardown-command" value="start"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalSensorsV1_0TargetTest->/data/local/tmp/VtsHalSensorsV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-timeout" value="900000" />
+ <option name="runtime-hint" value="300000"/>
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalSensorsV1_0TargetTest" />
+ </test>
+</configuration>
\ No newline at end of file
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
index 00207b1..1e5e886 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.cpp
@@ -35,8 +35,7 @@
// this do ... while is for easy error handling
do {
step = "getService()";
- sensors = ISensors::getService(
- SensorsHidlEnvironmentV1_0::Instance()->getServiceName<ISensors>());
+ sensors = ISensors::getService(mServiceName);
if (sensors == nullptr) {
break;
}
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
index 0a9e59f..29bfa50 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
@@ -32,23 +32,14 @@
class SensorsHidlEnvironmentV1_0 : public SensorsHidlEnvironmentBase {
public:
using Event = ::android::hardware::sensors::V1_0::Event;
- // get the test environment singleton
- static SensorsHidlEnvironmentV1_0* Instance() {
- static SensorsHidlEnvironmentV1_0* instance = new SensorsHidlEnvironmentV1_0();
- return instance;
- }
+ SensorsHidlEnvironmentV1_0(const std::string& service_name)
+ : SensorsHidlEnvironmentBase(service_name) {}
- virtual void registerTestServices() override {
- registerTestService<android::hardware::sensors::V1_0::ISensors>();
- }
-
- private:
+ private:
friend SensorsHidlTest;
// sensors hidl service
sp<android::hardware::sensors::V1_0::ISensors> sensors;
- SensorsHidlEnvironmentV1_0() {}
-
bool resetHal() override;
void startPollingThread() override;
static void pollingThread(SensorsHidlEnvironmentV1_0* env, std::atomic_bool& stop);
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 5453ef6..2cad54d 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -19,6 +19,8 @@
#include <android/hardware/sensors/1.0/ISensors.h>
#include <android/hardware/sensors/1.0/types.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
#include <utils/SystemClock.h>
@@ -33,7 +35,17 @@
// The main test class for SENSORS HIDL HAL.
class SensorsHidlTest : public SensorsHidlTestBase {
- protected:
+ public:
+ virtual void SetUp() override {
+ mEnvironment = new SensorsHidlEnvironmentV1_0(GetParam());
+ mEnvironment->HidlSetUp();
+ // Ensure that we have a valid environment before performing tests
+ ASSERT_NE(S(), nullptr);
+ }
+
+ virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+
+ protected:
SensorInfo defaultSensorByType(SensorType type) override;
std::vector<SensorInfo> getSensorsList();
// implementation wrapper
@@ -66,11 +78,13 @@
return S()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
}
- inline sp<ISensors>& S() { return SensorsHidlEnvironmentV1_0::Instance()->sensors; }
+ inline sp<ISensors>& S() { return mEnvironment->sensors; }
- SensorsHidlEnvironmentBase* getEnvironment() override {
- return SensorsHidlEnvironmentV1_0::Instance();
- }
+ SensorsHidlEnvironmentBase* getEnvironment() override { return mEnvironment; }
+
+ private:
+ // Test environment for sensors HAL.
+ SensorsHidlEnvironmentV1_0* mEnvironment;
};
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -133,55 +147,52 @@
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, SensorListValid) {
- S()->getSensorsList(
- [&] (const auto &list) {
+TEST_P(SensorsHidlTest, SensorListValid) {
+ S()->getSensorsList([&](const auto& list) {
const size_t count = list.size();
for (size_t i = 0; i < count; ++i) {
- const auto &s = list[i];
- SCOPED_TRACE(::testing::Message() << i << "/" << count << ": "
- << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
- << s.sensorHandle << std::dec
- << " type=" << static_cast<int>(s.type)
- << " name=" << s.name);
+ const auto& s = list[i];
+ SCOPED_TRACE(::testing::Message()
+ << i << "/" << count << ": "
+ << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+ << s.sensorHandle << std::dec << " type=" << static_cast<int>(s.type)
+ << " name=" << s.name);
- // Test non-empty type string
- EXPECT_FALSE(s.typeAsString.empty());
+ // Test non-empty type string
+ EXPECT_FALSE(s.typeAsString.empty());
- // Test defined type matches defined string type
- EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(s.type, s.typeAsString));
+ // Test defined type matches defined string type
+ EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(s.type, s.typeAsString));
- // Test if all sensor has name and vendor
- EXPECT_FALSE(s.name.empty());
- EXPECT_FALSE(s.vendor.empty());
+ // Test if all sensor has name and vendor
+ EXPECT_FALSE(s.name.empty());
+ EXPECT_FALSE(s.vendor.empty());
- // Test power > 0, maxRange > 0
- EXPECT_LE(0, s.power);
- EXPECT_LT(0, s.maxRange);
+ // Test power > 0, maxRange > 0
+ EXPECT_LE(0, s.power);
+ EXPECT_LT(0, s.maxRange);
- // Info type, should have no sensor
- EXPECT_FALSE(
- s.type == SensorType::ADDITIONAL_INFO
- || s.type == SensorType::META_DATA);
+ // Info type, should have no sensor
+ EXPECT_FALSE(s.type == SensorType::ADDITIONAL_INFO || s.type == SensorType::META_DATA);
- // Test fifoMax >= fifoReserved
- EXPECT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount)
- << "max=" << s.fifoMaxEventCount << " reserved=" << s.fifoReservedEventCount;
+ // Test fifoMax >= fifoReserved
+ EXPECT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount)
+ << "max=" << s.fifoMaxEventCount << " reserved=" << s.fifoReservedEventCount;
- // Test Reporting mode valid
- EXPECT_NO_FATAL_FAILURE(assertTypeMatchReportMode(s.type, extractReportMode(s.flags)));
+ // Test Reporting mode valid
+ EXPECT_NO_FATAL_FAILURE(assertTypeMatchReportMode(s.type, extractReportMode(s.flags)));
- // Test min max are in the right order
- EXPECT_LE(s.minDelay, s.maxDelay);
- // Test min/max delay matches reporting mode
- EXPECT_NO_FATAL_FAILURE(
- assertDelayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
+ // Test min max are in the right order
+ EXPECT_LE(s.minDelay, s.maxDelay);
+ // Test min/max delay matches reporting mode
+ EXPECT_NO_FATAL_FAILURE(
+ assertDelayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
}
- });
+ });
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, SetOperationMode) {
+TEST_P(SensorsHidlTest, SetOperationMode) {
std::vector<SensorInfo> sensorList = getSensorsList();
bool needOperationModeSupport =
@@ -199,7 +210,7 @@
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, InjectSensorEventData) {
+TEST_P(SensorsHidlTest, InjectSensorEventData) {
std::vector<SensorInfo> sensorList = getSensorsList();
std::vector<SensorInfo> sensorSupportInjection;
@@ -244,224 +255,202 @@
}
// Test if sensor hal can do UI speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
- testStreamingOperation(SensorType::ACCELEROMETER,
- std::chrono::milliseconds(200),
- std::chrono::seconds(5),
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
+ testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(200),
+ std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do normal speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
- testStreamingOperation(SensorType::ACCELEROMETER,
- std::chrono::milliseconds(20),
- std::chrono::seconds(5),
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
+ testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(20),
+ std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do game speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationFast) {
- testStreamingOperation(SensorType::ACCELEROMETER,
- std::chrono::milliseconds(5),
- std::chrono::seconds(5),
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationFast) {
+ testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(5),
+ std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do UI speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
- testStreamingOperation(SensorType::GYROSCOPE,
- std::chrono::milliseconds(200),
- std::chrono::seconds(5),
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
+ testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(200),
+ std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do normal speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
- testStreamingOperation(SensorType::GYROSCOPE,
- std::chrono::milliseconds(20),
- std::chrono::seconds(5),
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
+ testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(20),
+ std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do game speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationFast) {
- testStreamingOperation(SensorType::GYROSCOPE,
- std::chrono::milliseconds(5),
- std::chrono::seconds(5),
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationFast) {
+ testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(5),
+ std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do UI speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
- testStreamingOperation(SensorType::MAGNETIC_FIELD,
- std::chrono::milliseconds(200),
- std::chrono::seconds(5),
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
+ testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(200),
+ std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do normal speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
- testStreamingOperation(SensorType::MAGNETIC_FIELD,
- std::chrono::milliseconds(20),
- std::chrono::seconds(5),
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
+ testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(20),
+ std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do game speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationFast) {
- testStreamingOperation(SensorType::MAGNETIC_FIELD,
- std::chrono::milliseconds(5),
- std::chrono::seconds(5),
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationFast) {
+ testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(5),
+ std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
- testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
- testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER, false /*fastToSlow*/);
+TEST_P(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
+ testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER, false /*fastToSlow*/);
}
// Test if sensor hal can do gyroscope sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
- testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
- testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE, false /*fastToSlow*/);
+TEST_P(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
+ testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE, false /*fastToSlow*/);
}
// Test if sensor hal can do magnetometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
- testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
- testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
+TEST_P(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
+ testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
}
// Test if sensor hal can do accelerometer batching properly
-TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
- testBatchingOperation(SensorType::ACCELEROMETER);
+TEST_P(SensorsHidlTest, AccelerometerBatchingOperation) {
+ testBatchingOperation(SensorType::ACCELEROMETER);
}
// Test if sensor hal can do gyroscope batching properly
-TEST_F(SensorsHidlTest, GyroscopeBatchingOperation) {
- testBatchingOperation(SensorType::GYROSCOPE);
+TEST_P(SensorsHidlTest, GyroscopeBatchingOperation) {
+ testBatchingOperation(SensorType::GYROSCOPE);
}
// Test if sensor hal can do magnetometer batching properly
-TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
- testBatchingOperation(SensorType::MAGNETIC_FIELD);
+TEST_P(SensorsHidlTest, MagnetometerBatchingOperation) {
+ testBatchingOperation(SensorType::MAGNETIC_FIELD);
}
// Test sensor event direct report with ashmem for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
+ sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
+ sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM,
+ RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
+ sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with ashmem for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
+ NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
+ NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
- testDirectReportOperation(
- SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::VERY_FAST, NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM,
+ RateLevel::VERY_FAST, NullChecker());
}
// Test sensor event direct report with gralloc for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::NORMAL,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::NORMAL,
+ sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::FAST,
+ sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
- sAccelNormChecker);
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC,
+ RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::NORMAL,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::NORMAL,
+ sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
- testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
- sGyroNormChecker);
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
+ sGyroNormChecker);
}
// Test sensor event direct report with gralloc for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::NORMAL,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::NORMAL,
+ NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
- testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::FAST,
- NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::FAST,
+ NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
- testDirectReportOperation(
- SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::VERY_FAST, NullChecker());
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
+ testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC,
+ RateLevel::VERY_FAST, NullChecker());
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV1_0::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SensorsHidlEnvironmentV1_0::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, SensorsHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISensors::descriptor)),
+ android::hardware::PrintInstanceNameToString);
// vim: set ts=2 sw=2
diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp
index c13eaf2..811c455 100644
--- a/sensors/2.0/multihal/Android.bp
+++ b/sensors/2.0/multihal/Android.bp
@@ -43,10 +43,10 @@
srcs: [
"service.cpp",
"HalProxy.cpp",
- "ScopedWakelock.cpp",
],
init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"],
vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"],
+ shared_libs: ["android.hardware.sensors@2.0-ScopedWakelock"]
}
cc_library_headers {
@@ -55,19 +55,40 @@
export_include_dirs: ["include"],
}
+cc_library_shared {
+ name: "android.hardware.sensors@2.0-ScopedWakelock",
+ defaults: [
+ "hidl_defaults",
+ "android.hardware.sensors@2.0-multihal-defaults",
+ ],
+ srcs: [
+ "ScopedWakelock.cpp",
+ ],
+ vendor_available: true,
+ export_header_lib_headers: [
+ "android.hardware.sensors@2.0-multihal.header"
+ ]
+}
+
// The below targets should only be used for testing.
cc_test_library {
name: "android.hardware.sensors@2.0-HalProxy",
- defaults: ["android.hardware.sensors@2.0-multihal-defaults"],
+ defaults: [
+ "hidl_defaults",
+ "android.hardware.sensors@2.0-multihal-defaults",
+ ],
vendor_available: true,
srcs: [
"HalProxy.cpp",
- "ScopedWakelock.cpp",
],
export_header_lib_headers: [
"android.hardware.sensors@2.0-multihal.header",
],
+ export_shared_lib_headers: [
+ "android.hardware.sensors@2.0-ScopedWakelock",
+ ],
shared_libs: [
"libutils",
+ "android.hardware.sensors@2.0-ScopedWakelock",
],
}
diff --git a/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml b/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml
index a771100..1acc8e6 100644
--- a/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml
+++ b/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml
@@ -5,7 +5,7 @@
<version>2.0</version>
<interface>
<name>ISensors</name>
- <instance>multihal</instance>
+ <instance>default</instance>
</interface>
</hal>
</manifest>
diff --git a/sensors/2.0/multihal/tests/Android.bp b/sensors/2.0/multihal/tests/Android.bp
index e7f9499..1637312 100644
--- a/sensors/2.0/multihal/tests/Android.bp
+++ b/sensors/2.0/multihal/tests/Android.bp
@@ -25,6 +25,7 @@
shared_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
+ "android.hardware.sensors@2.0-ScopedWakelock",
"libcutils",
"libfmq",
"libhardware",
@@ -83,6 +84,7 @@
shared_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
+ "android.hardware.sensors@2.0-ScopedWakelock",
"libbase",
"libcutils",
"libfmq",
diff --git a/sensors/2.0/vts/functional/AndroidTest.xml b/sensors/2.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..b710ed0
--- /dev/null
+++ b/sensors/2.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsHalSensorsV2_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="stop"/>
+ <option name="teardown-command" value="start"/>
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalSensorsV2_0TargetTest->/data/local/tmp/VtsHalSensorsV2_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-timeout" value="900000" />
+ <option name="runtime-hint" value="300000"/>
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalSensorsV2_0TargetTest" />
+ </test>
+</configuration>
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index dc54f27..81db5a0 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -58,8 +58,7 @@
bool SensorsHidlEnvironmentV2_0::resetHal() {
bool succeed = false;
do {
- mSensors = ISensors::getService(
- SensorsHidlEnvironmentV2_0::Instance()->getServiceName<ISensors>());
+ mSensors = ISensors::getService(mServiceName);
if (mSensors == nullptr) {
break;
}
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
index b0dbd90..819cdd4 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
@@ -42,22 +42,12 @@
class SensorsHidlEnvironmentV2_0 : public SensorsHidlEnvironmentBase {
public:
using Event = ::android::hardware::sensors::V1_0::Event;
- // get the test environment singleton
- static SensorsHidlEnvironmentV2_0* Instance() {
- static SensorsHidlEnvironmentV2_0* instance = new SensorsHidlEnvironmentV2_0();
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<android::hardware::sensors::V2_0::ISensors>();
- }
-
virtual void HidlTearDown() override;
protected:
friend SensorsHidlTest;
-
- SensorsHidlEnvironmentV2_0() : mEventQueueFlag(nullptr) {}
+ SensorsHidlEnvironmentV2_0(const std::string& service_name)
+ : SensorsHidlEnvironmentBase(service_name), mEventQueueFlag(nullptr) {}
/**
* Resets the HAL with new FMQs and a new Event Flag
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 8364ba9..c5eb442 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -20,6 +20,8 @@
#include <android/hardware/sensors/2.0/ISensors.h>
#include <android/hardware/sensors/2.0/types.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
#include <utils/SystemClock.h>
@@ -120,10 +122,14 @@
class SensorsHidlTest : public SensorsHidlTestBase {
public:
virtual void SetUp() override {
+ mEnvironment = new SensorsHidlEnvironmentV2_0(GetParam());
+ mEnvironment->HidlSetUp();
// Ensure that we have a valid environment before performing tests
ASSERT_NE(getSensors(), nullptr);
}
+ virtual void TearDown() override { mEnvironment->HidlTearDown(); }
+
protected:
SensorInfo defaultSensorByType(SensorType type) override;
std::vector<SensorInfo> getSensorsList();
@@ -160,12 +166,10 @@
}
inline sp<::android::hardware::sensors::V2_0::ISensors>& getSensors() {
- return SensorsHidlEnvironmentV2_0::Instance()->mSensors;
+ return mEnvironment->mSensors;
}
- SensorsHidlEnvironmentBase* getEnvironment() override {
- return SensorsHidlEnvironmentV2_0::Instance();
- }
+ SensorsHidlEnvironmentBase* getEnvironment() override { return mEnvironment; }
// Test helpers
void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
@@ -191,6 +195,10 @@
void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, RateLevel rateLevel);
void queryDirectChannelSupport(SharedMemType memType, bool* supportsSharedMemType,
bool* supportsAnyDirectChannel);
+
+ private:
+ // Test environment for sensors HAL.
+ SensorsHidlEnvironmentV2_0* mEnvironment;
};
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -301,7 +309,7 @@
}
// Test if sensor list returned is valid
-TEST_F(SensorsHidlTest, SensorListValid) {
+TEST_P(SensorsHidlTest, SensorListValid) {
getSensors()->getSensorsList([&](const auto& list) {
const size_t count = list.size();
for (size_t i = 0; i < count; ++i) {
@@ -346,7 +354,7 @@
}
// Test that SetOperationMode returns the expected value
-TEST_F(SensorsHidlTest, SetOperationMode) {
+TEST_P(SensorsHidlTest, SetOperationMode) {
std::vector<SensorInfo> sensors = getInjectEventSensors();
if (getInjectEventSensors().size() > 0) {
ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
@@ -358,7 +366,7 @@
}
// Test that an injected event is written back to the Event FMQ
-TEST_F(SensorsHidlTest, InjectSensorEventData) {
+TEST_P(SensorsHidlTest, InjectSensorEventData) {
std::vector<SensorInfo> sensors = getInjectEventSensors();
if (sensors.size() == 0) {
return;
@@ -414,196 +422,196 @@
}
// Test if sensor hal can do UI speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationSlow) {
testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(200),
std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do normal speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationNormal) {
testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(20),
std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do game speed accelerometer streaming properly
-TEST_F(SensorsHidlTest, AccelerometerStreamingOperationFast) {
+TEST_P(SensorsHidlTest, AccelerometerStreamingOperationFast) {
testStreamingOperation(SensorType::ACCELEROMETER, std::chrono::milliseconds(5),
std::chrono::seconds(5), sAccelNormChecker);
}
// Test if sensor hal can do UI speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationSlow) {
testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(200),
std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do normal speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationNormal) {
testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(20),
std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do game speed gyroscope streaming properly
-TEST_F(SensorsHidlTest, GyroscopeStreamingOperationFast) {
+TEST_P(SensorsHidlTest, GyroscopeStreamingOperationFast) {
testStreamingOperation(SensorType::GYROSCOPE, std::chrono::milliseconds(5),
std::chrono::seconds(5), sGyroNormChecker);
}
// Test if sensor hal can do UI speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationSlow) {
testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(200),
std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do normal speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationNormal) {
testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(20),
std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do game speed magnetometer streaming properly
-TEST_F(SensorsHidlTest, MagnetometerStreamingOperationFast) {
+TEST_P(SensorsHidlTest, MagnetometerStreamingOperationFast) {
testStreamingOperation(SensorType::MAGNETIC_FIELD, std::chrono::milliseconds(5),
std::chrono::seconds(5), NullChecker());
}
// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+TEST_P(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER, false /*fastToSlow*/);
}
// Test if sensor hal can do gyroscope sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
+TEST_P(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE, false /*fastToSlow*/);
}
// Test if sensor hal can do magnetometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
+TEST_P(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD, false /*fastToSlow*/);
}
// Test if sensor hal can do accelerometer batching properly
-TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+TEST_P(SensorsHidlTest, AccelerometerBatchingOperation) {
testBatchingOperation(SensorType::ACCELEROMETER);
}
// Test if sensor hal can do gyroscope batching properly
-TEST_F(SensorsHidlTest, GyroscopeBatchingOperation) {
+TEST_P(SensorsHidlTest, GyroscopeBatchingOperation) {
testBatchingOperation(SensorType::GYROSCOPE);
}
// Test if sensor hal can do magnetometer batching properly
-TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
+TEST_P(SensorsHidlTest, MagnetometerBatchingOperation) {
testBatchingOperation(SensorType::MAGNETIC_FIELD);
}
// Test sensor event direct report with ashmem for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::NORMAL,
sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM, RateLevel::FAST,
sAccelNormChecker);
}
// Test sensor event direct report with ashmem for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, AccelerometerAshmemDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::ASHMEM,
RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::NORMAL,
sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::FAST,
sGyroNormChecker);
}
// Test sensor event direct report with ashmem for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, GyroscopeAshmemDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::ASHMEM, RateLevel::VERY_FAST,
sGyroNormChecker);
}
// Test sensor event direct report with ashmem for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationNormal) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::NORMAL,
NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM, RateLevel::FAST,
NullChecker());
}
// Test sensor event direct report with ashmem for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, MagnetometerAshmemDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::ASHMEM,
RateLevel::VERY_FAST, NullChecker());
}
// Test sensor event direct report with gralloc for accel sensor at normal rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationNormal) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::NORMAL,
sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC, RateLevel::FAST,
sAccelNormChecker);
}
// Test sensor event direct report with gralloc for accel sensor at very fast rate
-TEST_F(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, AccelerometerGrallocDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::ACCELEROMETER, SharedMemType::GRALLOC,
RateLevel::VERY_FAST, sAccelNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at normal rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationNormal) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::NORMAL,
sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::FAST,
sGyroNormChecker);
}
// Test sensor event direct report with gralloc for gyro sensor at very fast rate
-TEST_F(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, GyroscopeGrallocDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::GYROSCOPE, SharedMemType::GRALLOC, RateLevel::VERY_FAST,
sGyroNormChecker);
}
// Test sensor event direct report with gralloc for mag sensor at normal rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationNormal) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::NORMAL,
NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC, RateLevel::FAST,
NullChecker());
}
// Test sensor event direct report with gralloc for mag sensor at very fast rate
-TEST_F(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
+TEST_P(SensorsHidlTest, MagnetometerGrallocDirectReportOperationVeryFast) {
testDirectReportOperation(SensorType::MAGNETIC_FIELD, SharedMemType::GRALLOC,
RateLevel::VERY_FAST, NullChecker());
}
@@ -619,9 +627,13 @@
// Test that if initialize is called twice, then the HAL writes events to the FMQs from the second
// call to the function.
-TEST_F(SensorsHidlTest, CallInitializeTwice) {
+TEST_P(SensorsHidlTest, CallInitializeTwice) {
// Create a helper class so that a second environment is able to be instantiated
- class SensorsHidlEnvironmentTest : public SensorsHidlEnvironmentV2_0 {};
+ class SensorsHidlEnvironmentTest : public SensorsHidlEnvironmentV2_0 {
+ public:
+ SensorsHidlEnvironmentTest(const std::string& service_name)
+ : SensorsHidlEnvironmentV2_0(service_name) {}
+ };
if (getSensorsList().size() == 0) {
// No sensors
@@ -633,7 +645,7 @@
// Create a new environment that calls initialize()
std::unique_ptr<SensorsHidlEnvironmentTest> newEnv =
- std::make_unique<SensorsHidlEnvironmentTest>();
+ std::make_unique<SensorsHidlEnvironmentTest>(GetParam());
newEnv->HidlSetUp();
if (HasFatalFailure()) {
return; // Exit early if setting up the new environment failed
@@ -662,7 +674,7 @@
activateAllSensors(false);
}
-TEST_F(SensorsHidlTest, CleanupConnectionsOnInitialize) {
+TEST_P(SensorsHidlTest, CleanupConnectionsOnInitialize) {
activateAllSensors(true);
// Verify that events are received
@@ -731,7 +743,7 @@
}
}
-TEST_F(SensorsHidlTest, FlushSensor) {
+TEST_P(SensorsHidlTest, FlushSensor) {
// Find a sensor that is not a one-shot sensor
std::vector<SensorInfo> sensors = getNonOneShotSensors();
if (sensors.size() == 0) {
@@ -743,7 +755,7 @@
runFlushTest(sensors, true /* activateSensor */, kFlushes, kFlushes, Result::OK);
}
-TEST_F(SensorsHidlTest, FlushOneShotSensor) {
+TEST_P(SensorsHidlTest, FlushOneShotSensor) {
// Find a sensor that is a one-shot sensor
std::vector<SensorInfo> sensors = getOneShotSensors();
if (sensors.size() == 0) {
@@ -754,7 +766,7 @@
Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, FlushInactiveSensor) {
+TEST_P(SensorsHidlTest, FlushInactiveSensor) {
// Attempt to find a non-one shot sensor, then a one-shot sensor if necessary
std::vector<SensorInfo> sensors = getNonOneShotSensors();
if (sensors.size() == 0) {
@@ -768,7 +780,7 @@
Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, FlushNonexistentSensor) {
+TEST_P(SensorsHidlTest, FlushNonexistentSensor) {
SensorInfo sensor;
std::vector<SensorInfo> sensors = getNonOneShotSensors();
if (sensors.size() == 0) {
@@ -783,7 +795,7 @@
0 /* expectedFlushCount */, Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, Batch) {
+TEST_P(SensorsHidlTest, Batch) {
if (getSensorsList().size() == 0) {
return;
}
@@ -815,7 +827,7 @@
Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, Activate) {
+TEST_P(SensorsHidlTest, Activate) {
if (getSensorsList().size() == 0) {
return;
}
@@ -841,7 +853,7 @@
ASSERT_EQ(activate(invalidHandle, false), Result::BAD_VALUE);
}
-TEST_F(SensorsHidlTest, NoStaleEvents) {
+TEST_P(SensorsHidlTest, NoStaleEvents) {
constexpr milliseconds kFiveHundredMs(500);
constexpr milliseconds kOneSecond(1000);
@@ -1021,11 +1033,11 @@
}
}
-TEST_F(SensorsHidlTest, DirectChannelAshmem) {
+TEST_P(SensorsHidlTest, DirectChannelAshmem) {
verifyDirectChannel(SharedMemType::ASHMEM);
}
-TEST_F(SensorsHidlTest, DirectChannelGralloc) {
+TEST_P(SensorsHidlTest, DirectChannelGralloc) {
verifyDirectChannel(SharedMemType::GRALLOC);
}
@@ -1064,7 +1076,7 @@
return found;
}
-TEST_F(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
+TEST_P(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
SensorInfo sensor;
SharedMemType memType;
RateLevel rate;
@@ -1078,7 +1090,7 @@
});
}
-TEST_F(SensorsHidlTest, CleanupDirectConnectionOnInitialize) {
+TEST_P(SensorsHidlTest, CleanupDirectConnectionOnInitialize) {
constexpr size_t kNumEvents = 1;
constexpr size_t kMemSize = kNumEvents * kEventSize;
@@ -1124,12 +1136,8 @@
mDirectChannelHandles = handles;
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV2_0::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- SensorsHidlEnvironmentV2_0::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, SensorsHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::sensors::V2_0::ISensors::descriptor)),
+ android::hardware::PrintInstanceNameToString);
// vim: set ts=2 sw=2
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
index 02dc608..bb4d329 100644
--- a/sensors/common/vts/utils/Android.bp
+++ b/sensors/common/vts/utils/Android.bp
@@ -16,6 +16,7 @@
cc_library_static {
name: "VtsHalSensorsTargetTestUtils",
+ defaults: ["VtsHalTargetTestDefaults"],
cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
srcs: [
"GrallocWrapper.cpp",
@@ -36,6 +37,5 @@
"android.hardware.graphics.mapper@2.1",
"android.hardware.graphics.mapper@3.0",
"android.hardware.sensors@1.0",
- "VtsHalHidlTargetTestBase",
],
}
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
index 6499fba..dbc9392 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
@@ -17,9 +17,8 @@
#ifndef ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
#define ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
-#include <VtsHalHidlTargetTestEnvBase.h>
-
#include <android/hardware/sensors/1.0/types.h>
+#include <gtest/gtest.h>
#include <atomic>
#include <memory>
@@ -33,11 +32,11 @@
virtual void onEvent(const ::android::hardware::sensors::V1_0::Event& event) = 0;
};
-class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
+class SensorsHidlEnvironmentBase {
+ public:
using Event = ::android::hardware::sensors::V1_0::Event;
- virtual void HidlSetUp() override;
- virtual void HidlTearDown() override;
+ virtual void HidlSetUp();
+ virtual void HidlTearDown();
// Get and clear all events collected so far (like "cat" shell command).
// If output is nullptr, it clears all collected events.
@@ -50,22 +49,27 @@
void unregisterCallback();
protected:
- SensorsHidlEnvironmentBase() : mCollectionEnabled(false), mCallback(nullptr) {}
+ SensorsHidlEnvironmentBase(const std::string& service_name)
+ : mCollectionEnabled(false), mCallback(nullptr) {
+ mServiceName = service_name;
+ }
+ virtual ~SensorsHidlEnvironmentBase(){};
- void addEvent(const Event& ev);
+ void addEvent(const Event& ev);
- virtual void startPollingThread() = 0;
- virtual bool resetHal() = 0;
+ virtual void startPollingThread() = 0;
+ virtual bool resetHal() = 0;
- bool mCollectionEnabled;
- std::atomic_bool mStopThread;
- std::thread mPollThread;
- std::vector<Event> mEvents;
- std::mutex mEventsMutex;
+ std::string mServiceName;
+ bool mCollectionEnabled;
+ std::atomic_bool mStopThread;
+ std::thread mPollThread;
+ std::vector<Event> mEvents;
+ std::mutex mEventsMutex;
- IEventCallback* mCallback;
+ IEventCallback* mCallback;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase);
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase);
};
#endif // ANDROID_SENSORS_HIDL_ENVIRONMENT_BASE_H
\ No newline at end of file
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index 6fd9a2b..5fb6c5c 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -23,6 +23,7 @@
#include <VtsHalHidlTargetTestBase.h>
#include <android/hardware/sensors/1.0/ISensors.h>
#include <android/hardware/sensors/1.0/types.h>
+#include <gtest/gtest.h>
#include <unordered_set>
#include <vector>
@@ -44,8 +45,8 @@
using ::android::hardware::sensors::V1_0::SharedMemInfo;
using ::android::hardware::sensors::V1_0::SharedMemType;
-class SensorsHidlTestBase : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class SensorsHidlTestBase : public testing::TestWithParam<std::string> {
+ public:
virtual SensorsHidlEnvironmentBase* getEnvironment() = 0;
virtual void SetUp() override {}
diff --git a/soundtrigger/2.1/Android.bp b/soundtrigger/2.1/Android.bp
index 68e425b..30173cb 100644
--- a/soundtrigger/2.1/Android.bp
+++ b/soundtrigger/2.1/Android.bp
@@ -15,5 +15,5 @@
"android.hardware.soundtrigger@2.0",
"android.hidl.base@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/soundtrigger/2.2/Android.bp b/soundtrigger/2.2/Android.bp
index 43898c7..7556aa4 100644
--- a/soundtrigger/2.2/Android.bp
+++ b/soundtrigger/2.2/Android.bp
@@ -15,5 +15,5 @@
"android.hardware.soundtrigger@2.1",
"android.hidl.base@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp
new file mode 100644
index 0000000..ef9b39b
--- /dev/null
+++ b/tests/extension/vibrator/aidl/Android.bp
@@ -0,0 +1,29 @@
+aidl_interface {
+ // This is an example test interface showing how to add functionality
+ // with setExtension/getExtension
+ name: "test-vintf-vibrator-ext",
+ vendor_available: true,
+ srcs: [
+ // Using android.hardware as the package because this is in
+ // hardware/interfaces. For custom interfaces, normally you
+ // would use a different package.
+ "android/hardware/tests/extension/vibrator/Directionality.aidl",
+ "android/hardware/tests/extension/vibrator/ICustomVibrator.aidl",
+ "android/hardware/tests/extension/vibrator/VendorEffect.aidl",
+ ],
+
+ // This is agreeing to keep the interface stable.
+ stability: "vintf",
+
+ // This happens to use types from a core interface, so we import it, but
+ // this won't always be needed.
+ imports: [
+ "vintf-vibrator",
+ ],
+
+ backend: {
+ java: {
+ enabled: false,
+ },
+ },
+}
diff --git a/vibrator/1.4/types.hal b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/Directionality.aidl
similarity index 60%
copy from vibrator/1.4/types.hal
copy to tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/Directionality.aidl
index acc49b1..72bfd66 100644
--- a/vibrator/1.4/types.hal
+++ b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/Directionality.aidl
@@ -13,10 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.hardware.tests.extension.vibrator;
-package android.hardware.vibrator@1.4;
-
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+/**
+ * Can add custom enums. If these need to be extended further, new values can
+ * simply be added.
+ */
+@Backing(type="int")
+@VintfStability
+enum Directionality {
+ NONE,
+ /** vibrations should be transverse wrt primary screen */
+ TRANSVERSE,
+ /** vibrations should be longitudinal wrt primary screen */
+ LONGITUDINAL,
+}
diff --git a/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl
new file mode 100644
index 0000000..0b21f46
--- /dev/null
+++ b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.tests.extension.vibrator;
+
+// it's fine to use types from other interfaces
+import android.hardware.vibrator.IVibratorCallback;
+import android.hardware.tests.extension.vibrator.Directionality;
+import android.hardware.tests.extension.vibrator.VendorEffect;
+
+/**
+ * This is an example of an AIDL interface extension. Notice that it does not
+ * inherit from any other extension. Instead, it will be tagged onto that
+ * extension at runtime.
+ */
+@VintfStability
+interface ICustomVibrator {
+ /**
+ * Avoid conflicting with vendor properties. Giving this as an example
+ * because the core vibrator interface uses capabilities. In reality,
+ * since this is only one capability, it's probably not needed to construct
+ * a bitfield.
+ *
+ * This is for longitudinal/transverse waves, see setDirectionality.
+ */
+ const int CAP_VENDOR_DIRECTIONALITY = 1 << 0;
+
+ /**
+ * Any new methods can be added, this returns CAP_VENDOR_*.
+ */
+ int getVendorCapabilities();
+
+ /**
+ * Arbitrary new functionality can be added.
+ */
+ void setDirectionality(Directionality directionality);
+
+ /**
+ * Perform a custom vendor effect. Note, this is a separate effect enum to
+ * avoid conflicting with core types.
+ */
+ int perform(VendorEffect effect, IVibratorCallback callback);
+}
diff --git a/vibrator/1.4/types.hal b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/VendorEffect.aidl
similarity index 74%
copy from vibrator/1.4/types.hal
copy to tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/VendorEffect.aidl
index acc49b1..968532c 100644
--- a/vibrator/1.4/types.hal
+++ b/tests/extension/vibrator/aidl/android/hardware/tests/extension/vibrator/VendorEffect.aidl
@@ -13,10 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.hardware.tests.extension.vibrator;
-package android.hardware.vibrator@1.4;
-
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+/**
+ * Extending enum separately to avoid conflicts w/ upstream.
+ */
+@Backing(type="int")
+@VintfStability
+enum VendorEffect {
+ CRACKLE,
+ WIGGLE,
+}
diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp
new file mode 100644
index 0000000..f7b71f7
--- /dev/null
+++ b/tests/extension/vibrator/aidl/client/Android.bp
@@ -0,0 +1,26 @@
+
+// This example client is written as a test, but it is executing from a system
+// context. All this code would look the same if it was running in system
+// server for example.
+
+cc_test {
+ name: "test-vintf-vibrator-ext-client",
+ srcs: [
+ // system code has the option to use the unstable C++ libbinder API
+ // or the NDK one. For maximum code portability, using the ndk client
+ // makes the most sense, but both are provided here as an example.
+ "test-cpp-client.cpp",
+ "test-ndk-client.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ "vintf-vibrator-cpp",
+ "test-vintf-vibrator-ext-cpp",
+
+ "libbinder_ndk",
+ "vintf-vibrator-ndk_platform",
+ "test-vintf-vibrator-ext-ndk_platform",
+ ],
+}
+
diff --git a/tests/extension/vibrator/aidl/client/test-cpp-client.cpp b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
new file mode 100644
index 0000000..015a345
--- /dev/null
+++ b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/tests/extension/vibrator/ICustomVibrator.h>
+#include <android/hardware/vibrator/IVibrator.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+#include <gtest/gtest.h>
+
+using android::checked_interface_cast;
+using android::IBinder;
+using android::IInterface;
+using android::OK;
+using android::sp;
+using android::waitForVintfService;
+using android::hardware::tests::extension::vibrator::Directionality;
+using android::hardware::tests::extension::vibrator::ICustomVibrator;
+using android::hardware::vibrator::IVibrator;
+
+TEST(Cpp, CallRootMethod) {
+ sp<IVibrator> vib = waitForVintfService<IVibrator>();
+ ASSERT_NE(nullptr, vib.get());
+ ASSERT_TRUE(vib->off().isOk());
+}
+
+TEST(Cpp, CallExtMethod) {
+ // normally you would want to cache this
+ sp<IVibrator> vib = waitForVintfService<IVibrator>();
+ ASSERT_NE(nullptr, vib.get());
+
+ // getting the extension
+ sp<IBinder> ext;
+ ASSERT_EQ(OK, IInterface::asBinder(vib)->getExtension(&ext));
+ sp<ICustomVibrator> cvib = checked_interface_cast<ICustomVibrator>(ext);
+ ASSERT_NE(nullptr, cvib.get());
+
+ // calling extension method
+ ASSERT_TRUE(cvib->setDirectionality(Directionality::TRANSVERSE).isOk());
+}
diff --git a/tests/extension/vibrator/aidl/client/test-ndk-client.cpp b/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
new file mode 100644
index 0000000..c846495
--- /dev/null
+++ b/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/tests/extension/vibrator/ICustomVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/binder_manager.h>
+
+#include <gtest/gtest.h>
+
+using aidl::android::hardware::tests::extension::vibrator::Directionality;
+using aidl::android::hardware::tests::extension::vibrator::ICustomVibrator;
+using aidl::android::hardware::vibrator::IVibrator;
+using ndk::SpAIBinder;
+
+static const std::string kInstance = std::string() + IVibrator::descriptor + "/default";
+
+TEST(Ndk, CallRootMethod) {
+ SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
+ ASSERT_NE(nullptr, vibBinder.get());
+ std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
+ ASSERT_NE(nullptr, vib.get());
+ ASSERT_TRUE(vib->off().isOk());
+}
+
+TEST(Ndk, CallExtMethod) {
+ // normally you would want to cache this
+ //
+ SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
+ ASSERT_NE(nullptr, vibBinder.get());
+ std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
+ ASSERT_NE(nullptr, vib.get());
+
+ // getting the extension
+ SpAIBinder cvibBinder;
+ ASSERT_EQ(STATUS_OK, AIBinder_getExtension(vibBinder.get(), cvibBinder.getR()));
+ ASSERT_NE(nullptr, cvibBinder.get());
+ std::shared_ptr<ICustomVibrator> cvib = ICustomVibrator::fromBinder(cvibBinder);
+ ASSERT_NE(nullptr, cvib.get());
+
+ // calling extension method
+ ASSERT_TRUE(cvib->setDirectionality(Directionality::TRANSVERSE).isOk());
+}
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
new file mode 100644
index 0000000..9869657
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -0,0 +1,25 @@
+cc_binary {
+ name: "android.hardware.tests.extension.vibrator-service.example",
+ relative_install_path: "hw",
+ // normally you implement a service directly, but we are using an implementation
+ // from a library to attach our extension to.
+ static_libs: [
+ "libvibratorexampleimpl",
+ ],
+
+ // need to add this in the manifest and to init as well to use, see
+ // android.hardware.vibrator-service.example. This binary is being tested
+ // by running it manually as root.
+
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "CustomVibrator.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "vintf-vibrator-ndk_platform",
+ "test-vintf-vibrator-ext-ndk_platform",
+ ],
+}
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
new file mode 100644
index 0000000..2f3dfcb
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CustomVibrator.h"
+
+#include <android-base/logging.h>
+#include <thread>
+
+namespace aidl::android::hardware::tests::extension::vibrator {
+
+ndk::ScopedAStatus CustomVibrator::getVendorCapabilities(int32_t* _aidl_return) {
+ *_aidl_return = ICustomVibrator::CAP_VENDOR_DIRECTIONALITY;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus CustomVibrator::setDirectionality(Directionality directionality) {
+ LOG(INFO) << "Custom vibrator set directionality";
+ // do something cool in hardware
+ (void)directionality;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus CustomVibrator::perform(VendorEffect effect,
+ const std::shared_ptr<IVibratorCallback>& callback,
+ int32_t* _aidl_return) {
+ LOG(INFO) << "Custom vibrator perform";
+
+ if (effect != VendorEffect::CRACKLE && effect != VendorEffect::WIGGLE) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ constexpr size_t kEffectMillis = 100;
+
+ if (callback != nullptr) {
+ std::thread([=] {
+ LOG(INFO) << "Starting vendor perform on another thread";
+ usleep(kEffectMillis * 1000);
+ LOG(INFO) << "Notifying vendor perform complete";
+ callback->onComplete();
+ }).detach();
+ }
+
+ *_aidl_return = kEffectMillis;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.h b/tests/extension/vibrator/aidl/default/CustomVibrator.h
new file mode 100644
index 0000000..6dc5743
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tests/extension/vibrator/BnCustomVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibratorCallback.h>
+
+namespace aidl::android::hardware::tests::extension::vibrator {
+
+using aidl::android::hardware::vibrator::IVibratorCallback;
+
+class CustomVibrator : public BnCustomVibrator {
+ ndk::ScopedAStatus getVendorCapabilities(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus setDirectionality(Directionality directionality) override;
+ ndk::ScopedAStatus perform(VendorEffect effect,
+ const std::shared_ptr<IVibratorCallback>& callback,
+ int32_t* _aidl_return) override;
+};
+
+} // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tests/extension/vibrator/aidl/default/service.cpp b/tests/extension/vibrator/aidl/default/service.cpp
new file mode 100644
index 0000000..16290df
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/service.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vibrator-impl/Vibrator.h>
+#include "CustomVibrator.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::tests::extension::vibrator::CustomVibrator;
+using aidl::android::hardware::vibrator::Vibrator;
+
+int main() {
+ // these are threads in addition to the one we are joining below, so this
+ // service will have a single thread
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ // making the core service
+ std::shared_ptr<Vibrator> vib = ndk::SharedRefBase::make<Vibrator>();
+ ndk::SpAIBinder vibBinder = vib->asBinder();
+
+ // making the extension service
+ std::shared_ptr<CustomVibrator> cvib = ndk::SharedRefBase::make<CustomVibrator>();
+
+ // need to attach the extension to the same binder we will be registering
+ CHECK(STATUS_OK == AIBinder_setExtension(vibBinder.get(), cvib->asBinder().get()));
+
+ const std::string instance = std::string() + Vibrator::descriptor + "/default";
+ CHECK(STATUS_OK == AServiceManager_addService(vibBinder.get(), instance.c_str()));
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/tests/memory/1.0/Android.bp b/tests/memory/1.0/Android.bp
index 29f6be7..6612e31 100644
--- a/tests/memory/1.0/Android.bp
+++ b/tests/memory/1.0/Android.bp
@@ -11,5 +11,5 @@
"android.hidl.memory.block@1.0",
"android.hidl.memory.token@1.0",
],
- gen_java: false,
+ gen_java: true,
}
diff --git a/tests/memory/2.0/.hidl_for_test b/tests/memory/2.0/.hidl_for_test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/memory/2.0/.hidl_for_test
diff --git a/tests/memory/2.0/Android.bp b/tests/memory/2.0/Android.bp
new file mode 100644
index 0000000..d24bd21
--- /dev/null
+++ b/tests/memory/2.0/Android.bp
@@ -0,0 +1,14 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.tests.memory@2.0",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "IMemoryInterface.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/tests/memory/2.0/IMemoryInterface.hal b/tests/memory/2.0/IMemoryInterface.hal
new file mode 100644
index 0000000..2c824bf
--- /dev/null
+++ b/tests/memory/2.0/IMemoryInterface.hal
@@ -0,0 +1,12 @@
+package android.hardware.tests.memory@2.0;
+
+interface IMemoryInterface {
+ // Flips all the bits in the given memory buffer.
+ bitwiseNot(memory mem);
+ // Returns a read-only buffer of size 8, containing the bytes 0..7.
+ getTestMem() generates(memory mem);
+ // Given two memory regions of the same size, returns two memory fields of
+ // equal size, the first contains the byte-wise sum and the other the byte-
+ // wise difference.
+ getSumDiff(TwoMemory in) generates(TwoMemory out);
+};
diff --git a/tests/memory/2.0/types.hal b/tests/memory/2.0/types.hal
new file mode 100644
index 0000000..9ec357b
--- /dev/null
+++ b/tests/memory/2.0/types.hal
@@ -0,0 +1,6 @@
+package android.hardware.tests.memory@2.0;
+
+struct TwoMemory {
+ memory mem1;
+ memory mem2;
+};
diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal
index 9e799b4..16fc392 100644
--- a/tv/tuner/1.0/IDemux.hal
+++ b/tv/tuner/1.0/IDemux.hal
@@ -25,7 +25,6 @@
/**
* Demultiplexer(Demux) takes a single multiplexed input and splits it into
* one or more output.
- *
*/
interface IDemux {
/**
@@ -134,4 +133,30 @@
*/
openDvr(DvrType type, uint32_t bufferSize, IDvrCallback cb)
generates (Result result, IDvr dvr);
+
+ /**
+ * Connect Conditional Access Modules (CAM) through Common Interface (CI)
+ *
+ * It is used by the client to connect CI-CAM. The demux uses the output
+ * from the frontend as the input by default, and must change to use the
+ * output from CI-CAM as the input after this call take place.
+ *
+ * @param ciCamId specify CI-CAM Id to connect.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ connectCiCam(uint32_t ciCamId) generates (Result result);
+
+ /**
+ * Disconnect Conditional Access Modules (CAM)
+ *
+ * It is used by the client to disconnect CI-CAM. The demux will use the
+ * output from the frontend as the input after this call take place.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ disconnectCiCam() generates (Result result);
};
diff --git a/tv/tuner/1.0/IFilter.hal b/tv/tuner/1.0/IFilter.hal
index deaf3d4..3ed09f6 100644
--- a/tv/tuner/1.0/IFilter.hal
+++ b/tv/tuner/1.0/IFilter.hal
@@ -113,6 +113,21 @@
getId() generates (Result result, uint32_t filterId);
/**
+ * Release the handle reported by the HAL for AV memory.
+ *
+ * It is used by the client to notify the HAL that the AV handle won't be
+ * used any more in client side, so that the HAL can mark the memory
+ * presented by file descripor in the handle as released.
+ *
+ * @param avMemory A handle associated to the memory for audio or video.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_ARGUMENT if failed for wrong parameter.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ releaseAvHandle(handle avMemory) generates (Result result);
+
+ /**
* Set the filter's data source.
*
* A filter uses demux as data source by default. If the data was packetized
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index c5921f7..71a26ab 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -147,6 +147,20 @@
return Void();
}
+Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
+ ALOGV("%s", __FUNCTION__);
+
+ mCiCamId = ciCamId;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Demux::disconnectCiCam() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
Result Demux::removeFilter(uint32_t filterId) {
ALOGV("%s", __FUNCTION__);
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index a9756cc..037429d 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -76,6 +76,10 @@
virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
openDvr_cb _hidl_cb) override;
+ virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
+
+ virtual Return<Result> disconnectCiCam() override;
+
// Functions interacts with Tuner Service
void stopBroadcastInput();
Result removeFilter(uint32_t filterId);
@@ -118,6 +122,7 @@
void startTsFilter(vector<uint8_t> data);
uint32_t mDemuxId;
+ uint32_t mCiCamId;
/**
* Record the last used filter id. Initial value is -1.
* Filter Id starts with 0.
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
index 3d8a977..befd1e6 100644
--- a/tv/tuner/1.0/default/Filter.cpp
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -120,6 +120,12 @@
return Result::SUCCESS;
}
+Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
Return<Result> Filter::close() {
ALOGV("%s", __FUNCTION__);
@@ -289,6 +295,9 @@
case DemuxTsFilterType::RECORD:
startRecordFilterHandler();
break;
+ case DemuxTsFilterType::TEMI:
+ startTemiFilterHandler();
+ break;
}
break;
case DemuxFilterMainType::MMTP:
@@ -419,6 +428,11 @@
return Result::SUCCESS;
}
+Result Filter::startTemiFilterHandler() {
+ // TODO handle starting TEMI filter
+ return Result::SUCCESS;
+}
+
bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
// TODO check how many sections has been read
ALOGD("[Filter] section hander");
@@ -453,4 +467,4 @@
} // namespace tuner
} // namespace tv
} // namespace hardware
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h
index 21d4297..fbd965a 100644
--- a/tv/tuner/1.0/default/Filter.h
+++ b/tv/tuner/1.0/default/Filter.h
@@ -68,6 +68,8 @@
virtual Return<Result> flush() override;
+ virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory) override;
+
virtual Return<Result> close() override;
/**
@@ -129,6 +131,7 @@
Result startMediaFilterHandler();
Result startRecordFilterHandler();
Result startPcrFilterHandler();
+ Result startTemiFilterHandler();
Result startFilterLoop();
void deleteEventFlag();
@@ -176,4 +179,4 @@
} // namespace hardware
} // namespace android
-#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
\ No newline at end of file
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index fa00a6e..707f5df 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -1759,6 +1759,12 @@
* buffer of the record.
*/
RECORD,
+ /**
+ * A filter to filter out Timed External Media Information (TEMI) according
+ * to ISO/IEC 13818-1:2013/ DAM 6 from input stream, and send TEMI event to
+ * client through onFilterEvent.
+ */
+ TEMI,
};
/**
@@ -2170,7 +2176,8 @@
safe_union FilterSettings {
/**
- * Not additional parameters. it's used by PCR, TS subtype filters.
+ * Not additional parameters. it's used by PCR, TS, TEMI subtype
+ * filters.
*/
Monostate noinit;
@@ -2461,6 +2468,27 @@
};
/**
+ * Filter Event for Timed External Media Information (TEMI) data.
+ */
+struct DemuxFilterTemiEvent {
+ /**
+ * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+ * the same format as PTS (Presentation Time Stamp) in ISO/IEC 13818-1.
+ */
+ uint64_t pts;
+
+ /**
+ * TEMI Descriptor Tag
+ */
+ uint8_t descrTag;
+
+ /**
+ * TEMI Descriptor
+ */
+ vec<uint8_t> descrData;
+};
+
+/**
* Filter Event for MMTP Record data.
*/
struct DemuxFilterMmtpRecordEvent {
@@ -2521,6 +2549,8 @@
DemuxFilterDownloadEvent download;
DemuxFilterIpPayloadEvent ipPayload;
+
+ DemuxFilterTemiEvent temi;
};
/**
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index c666226..da3e300 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -159,6 +159,7 @@
RECORD,
MMTPRECORD,
DOWNLOAD,
+ TEMI,
};
struct PlaybackConf {
@@ -821,6 +822,9 @@
case DemuxTsFilterType::RECORD:
eventType = FilterEventType::RECORD;
break;
+ case DemuxTsFilterType::TEMI:
+ eventType = FilterEventType::TEMI;
+ break;
}
break;
case DemuxFilterMainType::MMTP:
diff --git a/usb/1.0/vts/functional/Android.bp b/usb/1.0/vts/functional/Android.bp
index 683ee17..1a3b56b 100644
--- a/usb/1.0/vts/functional/Android.bp
+++ b/usb/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalUsbV1_0TargetTest.cpp"],
static_libs: ["android.hardware.usb@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
index ee7ef1b..bba75c8 100644
--- a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
+++ b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
@@ -20,9 +20,10 @@
#include <android/hardware/usb/1.0/IUsb.h>
#include <android/hardware/usb/1.0/IUsbCallback.h>
#include <android/hardware/usb/1.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <log/log.h>
#include <stdlib.h>
#include <chrono>
@@ -49,20 +50,8 @@
using ::android::hardware::Void;
using ::android::sp;
-// Test environment for Usb HIDL HAL.
-class UsbHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static UsbHidlEnvironment* Instance() {
- static UsbHidlEnvironment* instance = new UsbHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IUsb>(); }
-};
-
// The main test class for the USB hidl HAL
-class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class UsbHidlTest : public testing::TestWithParam<std::string> {
public:
// Callback class for the USB HIDL hal.
// Usb Hal will call this object upon role switch or port query.
@@ -109,8 +98,7 @@
virtual void SetUp() override {
ALOGI("Setup");
- usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>(
- UsbHidlEnvironment::Instance()->getServiceName<IUsb>());
+ usb = IUsb::getService(GetParam());
ASSERT_NE(usb, nullptr);
usb_cb_2 = new UsbCallback(*this, 2);
@@ -182,7 +170,7 @@
* Callback oject is created and registered.
* Check to see if the hidl transaction succeeded.
*/
-TEST_F(UsbHidlTest, setCallback) {
+TEST_P(UsbHidlTest, setCallback) {
usb_cb_1 = new UsbCallback(*this, 1);
ASSERT_NE(usb_cb_1, nullptr);
Return<void> ret = usb->setCallback(usb_cb_1);
@@ -193,7 +181,7 @@
* Check to see if querying type-c
* port status succeeds.
*/
-TEST_F(UsbHidlTest, queryPortStatus) {
+TEST_P(UsbHidlTest, queryPortStatus) {
Return<void> ret = usb->queryPortStatus();
ASSERT_TRUE(ret.isOk());
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -206,7 +194,7 @@
* This test case tried to switch the port with empty
* name which is expected to fail.
*/
-TEST_F(UsbHidlTest, switchEmptyPort) {
+TEST_P(UsbHidlTest, switchEmptyPort) {
struct PortRole role;
role.type = PortRoleType::DATA_ROLE;
@@ -218,52 +206,6 @@
}
/*
- * Test switching the mode of usb port.
- * Test case queries the usb ports present in device.
- * If there is atleast one usb port, a mode switch
- * to DFP is attempted for the port.
- * The callback parametes are checked to see if the mode
- * switch was successfull. Upon success, Status::SUCCESS
- * is expected to be returned.
- */
-TEST_F(UsbHidlTest, switchModetoDFP) {
- struct PortRole role;
- role.type = PortRoleType::MODE;
- role.role = static_cast<uint32_t>(PortMode::DFP);
-
- Return<void> ret = usb->queryPortStatus();
- ASSERT_TRUE(ret.isOk());
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(2, usb_last_cookie);
-
- if (!usb_last_port_status.portName.empty()) {
- hidl_string portBeingSwitched = usb_last_port_status.portName;
- ALOGI("mode portname:%s", portBeingSwitched.c_str());
- usb_role_switch_done = false;
- Return<void> ret = usb->switchRole(portBeingSwitched.c_str(), role);
- ASSERT_TRUE(ret.isOk());
-
- std::cv_status waitStatus = wait();
- while (waitStatus == std::cv_status::no_timeout &&
- usb_role_switch_done == false)
- waitStatus = wait();
-
- EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
- EXPECT_EQ(2, usb_last_cookie);
-
- EXPECT_EQ(static_cast<uint32_t>(PortRoleType::MODE),
- static_cast<uint32_t>(usb_last_port_role.type));
- if (usb_last_status == Status::SUCCESS) {
- EXPECT_EQ(static_cast<uint32_t>(PortMode::DFP),
- static_cast<uint32_t>(usb_last_port_role.role));
- } else {
- EXPECT_NE(static_cast<uint32_t>(PortMode::UFP),
- static_cast<uint32_t>(usb_last_port_role.role));
- }
- }
-}
-
-/*
* Test switching the power role of usb port.
* Test case queries the usb ports present in device.
* If there is atleast one usb port, a power role switch
@@ -273,7 +215,7 @@
* is expected to be returned.
*/
-TEST_F(UsbHidlTest, switchPowerRole) {
+TEST_P(UsbHidlTest, switchPowerRole) {
struct PortRole role;
role.type = PortRoleType::POWER_ROLE;
role.role = static_cast<uint32_t>(PortPowerRole::SOURCE);
@@ -319,7 +261,7 @@
* switch was successfull. Upon success, Status::SUCCESS
* is expected to be returned.
*/
-TEST_F(UsbHidlTest, switchDataRole) {
+TEST_P(UsbHidlTest, switchDataRole) {
struct PortRole role;
role.type = PortRoleType::DATA_ROLE;
role.role = static_cast<uint32_t>(PortDataRole::HOST);
@@ -356,11 +298,7 @@
}
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(UsbHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- UsbHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, UsbHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.4/Android.bp b/vibrator/1.4/Android.bp
deleted file mode 100644
index acfc795..0000000
--- a/vibrator/1.4/Android.bp
+++ /dev/null
@@ -1,19 +0,0 @@
-// This file is autogenerated by hidl-gen -Landroidbp.
-
-hidl_interface {
- name: "android.hardware.vibrator@1.4",
- root: "android.hardware",
- srcs: [
- "types.hal",
- "IVibrator.hal",
- "IVibratorCallback.hal",
- ],
- interfaces: [
- "android.hardware.vibrator@1.0",
- "android.hardware.vibrator@1.1",
- "android.hardware.vibrator@1.2",
- "android.hardware.vibrator@1.3",
- "android.hidl.base@1.0",
- ],
- gen_java: true,
-}
diff --git a/vibrator/1.4/IVibrator.hal b/vibrator/1.4/IVibrator.hal
deleted file mode 100644
index 913abe3..0000000
--- a/vibrator/1.4/IVibrator.hal
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.vibrator@1.4;
-
-import @1.0::EffectStrength;
-import @1.3::Effect;
-import @1.0::Status;
-import @1.3::IVibrator;
-import IVibratorCallback;
-
-interface IVibrator extends @1.3::IVibrator {
- /**
- * Determine capabilities of the vibrator HAL.
- */
- getCapabilities() generates (bitfield<Capabilities> capabilities);
-
- /**
- * Turn on vibrator
- *
- * This function must only be called after the previous timeout has expired or
- * was canceled (through off()).
- * @param timeoutMs number of milliseconds to vibrate.
- * @param callback A callback used to inform Frameworks of state change, if supported.
- * @return vibratorOnRet whether vibrator command was successful or not.
- */
- on_1_4(uint32_t timeoutMs, IVibratorCallback callback) generates (Status vibratorOnRet);
-
- /**
- * Fire off a predefined haptic event.
- *
- * @param effect The type of haptic event to trigger.
- * @param strength The intensity of haptic event to trigger.
- * @param callback A callback used to inform Frameworks of state change, if supported.
- * @return status Whether the effect was successfully performed or not. Must
- * return Status::UNSUPPORTED_OPERATION if the effect is not supported.
- * @return lengthMs The length of time the event is expected to take in
- * milliseconds. This doesn't need to be perfectly accurate, but should be a reasonable
- * approximation. Should be a positive, non-zero value if the returned status is Status::OK,
- * and set to 0 otherwise.
- */
- perform_1_4(Effect effect, EffectStrength strength, IVibratorCallback callback)
- generates (Status status, uint32_t lengthMs);
-};
diff --git a/vibrator/1.4/vts/functional/VtsHalVibratorV1_4TargetTest.cpp b/vibrator/1.4/vts/functional/VtsHalVibratorV1_4TargetTest.cpp
deleted file mode 100644
index 1b6abe9..0000000
--- a/vibrator/1.4/vts/functional/VtsHalVibratorV1_4TargetTest.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "vibrator_hidl_hal_test"
-
-#include <android-base/logging.h>
-#include <android/hardware/vibrator/1.0/types.h>
-#include <android/hardware/vibrator/1.4/IVibrator.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-
-#include <getopt.h>
-#include <unistd.h>
-
-#include <future>
-
-using ::android::sp;
-using ::android::hardware::hidl_bitfield;
-using ::android::hardware::hidl_enum_range;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::vibrator::V1_0::EffectStrength;
-using ::android::hardware::vibrator::V1_0::Status;
-using ::android::hardware::vibrator::V1_3::Effect;
-using ::android::hardware::vibrator::V1_4::Capabilities;
-using ::android::hardware::vibrator::V1_4::IVibrator;
-using ::android::hardware::vibrator::V1_4::IVibratorCallback;
-
-static uint32_t sCompletionLimitMs = UINT32_MAX;
-
-#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
-
-class CompletionCallback : public IVibratorCallback {
- public:
- CompletionCallback(std::function<void()> callback) : mCallback(callback) {}
- Return<void> onComplete() override {
- mCallback();
- return Void();
- }
-
- private:
- std::function<void()> mCallback;
-};
-
-class VibratorHidlTest_1_4 : public testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- vibrator = IVibrator::getService(GetParam());
- ASSERT_NE(vibrator, nullptr);
- capabilities = vibrator->getCapabilities();
- }
-
- virtual void TearDown() override {}
-
- sp<IVibrator> vibrator;
- hidl_bitfield<Capabilities> capabilities;
-};
-
-TEST_P(VibratorHidlTest_1_4, OnWithCallback) {
- if (capabilities & Capabilities::ON_COMPLETION_CALLBACK) {
- std::promise<void> completionPromise;
- std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
- uint32_t duration = 250;
- std::chrono::milliseconds timeout{duration * 2};
- EXPECT_EQ(Status::OK, vibrator->on_1_4(duration, callback));
- EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
- vibrator->off();
- }
-}
-
-static void validatePerformEffectUnsupportedOperation(Status status, uint32_t lengthMs) {
- ASSERT_EQ(Status::UNSUPPORTED_OPERATION, status);
- ASSERT_EQ(static_cast<uint32_t>(0), lengthMs)
- << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
-}
-
-static void validatePerformEffect(Status status, uint32_t lengthMs) {
- ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
- if (status == Status::OK) {
- ASSERT_LT(static_cast<uint32_t>(0), lengthMs)
- << "Effects that return OK must return a positive duration";
- } else {
- validatePerformEffectUnsupportedOperation(status, lengthMs);
- }
-}
-
-/*
- * Test to make sure effects within the valid range return are either supported and return OK with
- * a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
- */
-TEST_P(VibratorHidlTest_1_4, PerformEffect_1_4) {
- Status performStatus;
- uint32_t performLength;
- auto validateWrapper = [&](Status status, uint32_t lengthMs) {
- performStatus = status;
- performLength = lengthMs;
- validatePerformEffect(status, lengthMs);
- };
- for (const auto& effect : hidl_enum_range<Effect>()) {
- for (const auto& strength : hidl_enum_range<EffectStrength>()) {
- std::promise<void> completionPromise;
- std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
- EXPECT_OK(vibrator->perform_1_4(effect, strength, callback, validateWrapper));
- if (performStatus == Status::OK && performLength < sCompletionLimitMs &&
- (capabilities & Capabilities::PERFORM_COMPLETION_CALLBACK)) {
- std::chrono::milliseconds timeout{performLength * 2};
- EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
- }
- }
- }
-}
-
-/*
- * Test to make sure effect values above the valid range are rejected.
- */
-TEST_P(VibratorHidlTest_1_4, PerformEffect_1_4_BadEffects_AboveValidRange) {
- Effect effect = *std::prev(hidl_enum_range<Effect>().end());
- Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
- EXPECT_OK(vibrator->perform_1_4(badEffect, EffectStrength::LIGHT, nullptr,
- validatePerformEffectUnsupportedOperation));
-}
-
-/*
- * Test to make sure effect values below the valid range are rejected.
- */
-TEST_P(VibratorHidlTest_1_4, PerformEffect_1_4_BadEffects_BelowValidRange) {
- Effect effect = *hidl_enum_range<Effect>().begin();
- Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
- EXPECT_OK(vibrator->perform_1_4(badEffect, EffectStrength::LIGHT, nullptr,
- validatePerformEffectUnsupportedOperation));
-}
-
-/*
- * Test to make sure strength values above the valid range are rejected.
- */
-TEST_P(VibratorHidlTest_1_4, PerformEffect_1_4_BadStrength_AboveValidRange) {
- EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
- EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
- EXPECT_OK(vibrator->perform_1_4(Effect::THUD, badStrength, nullptr,
- validatePerformEffectUnsupportedOperation));
-}
-
-/*
- * Test to make sure strength values below the valid range are rejected.
- */
-TEST_P(VibratorHidlTest_1_4, PerformEffect_1_4_BadStrength_BelowValidRange) {
- EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
- EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
- EXPECT_OK(vibrator->perform_1_4(Effect::THUD, badStrength, nullptr,
- validatePerformEffectUnsupportedOperation));
-}
-
-INSTANTIATE_TEST_SUITE_P(
- PerInstance, VibratorHidlTest_1_4,
- testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
- android::hardware::PrintInstanceNameToString);
-
-enum {
- OPTION_COMPLETION_LIMIT_MS,
-};
-
-int main(int argc, char** argv) {
- struct option options[] = {
- {"completion-limit-ms", required_argument, 0, OPTION_COMPLETION_LIMIT_MS}, {}};
-
- printf("Running main() from %s\n", __FILE__);
- testing::InitGoogleTest(&argc, argv);
-
- while (true) {
- int opt = getopt_long(argc, argv, "", options, nullptr);
- if (opt == -1) {
- break;
- }
- switch (opt) {
- case OPTION_COMPLETION_LIMIT_MS:
- std::istringstream(optarg) >> sCompletionLimitMs;
- break;
- default:
- printf("Unrecognized option\n");
- return -EINVAL;
- }
- }
-
- return RUN_ALL_TESTS();
-}
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index 18468ef..1eec1da 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -7,8 +7,12 @@
stability: "vintf",
backend: {
java: {
- enabled: false,
+ platform_apis: true,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
},
},
}
-
diff --git a/vibrator/1.4/types.hal b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
similarity index 67%
copy from vibrator/1.4/types.hal
copy to vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
index acc49b1..84556b5 100644
--- a/vibrator/1.4/types.hal
+++ b/vibrator/aidl/android/hardware/vibrator/CompositeEffect.aidl
@@ -14,9 +14,15 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+package android.hardware.vibrator;
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+import android.hardware.vibrator.CompositePrimitive;
+
+@VintfStability
+parcelable CompositeEffect {
+ /* Period of silence preceding primitive. */
+ int delayMs;
+ CompositePrimitive primitive;
+ /* 0.0 (exclusive) - 1.0 (inclusive) */
+ float scale;
+}
diff --git a/vibrator/1.4/types.hal b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
similarity index 76%
rename from vibrator/1.4/types.hal
rename to vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
index acc49b1..2a9d0be 100644
--- a/vibrator/1.4/types.hal
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
@@ -14,9 +14,16 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+package android.hardware.vibrator;
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+@VintfStability
+@Backing(type="int")
+enum CompositePrimitive {
+ NOOP,
+ CLICK,
+ THUD,
+ SPIN,
+ QUICK_RISE,
+ SLOW_RISE,
+ QUICK_FALL,
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index 8c4fd05..ebf5faa 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -19,6 +19,8 @@
import android.hardware.vibrator.IVibratorCallback;
import android.hardware.vibrator.Effect;
import android.hardware.vibrator.EffectStrength;
+import android.hardware.vibrator.CompositeEffect;
+import android.hardware.vibrator.CompositePrimitive;
@VintfStability
interface IVibrator {
@@ -42,6 +44,10 @@
* Whether setAmplitude is supported (when external control is enabled)
*/
const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 1 << 4;
+ /**
+ * Whether compose is supported.
+ */
+ const int CAP_COMPOSE_EFFECTS = 1 << 5;
/**
* Determine capabilities of the vibrator HAL (CAP_* mask)
@@ -107,11 +113,10 @@
* CAP_EXTERNAL_AMPLITUDE_CONTROL.
*
* @param amplitude The unitless force setting. Note that this number must
- * be between 1 and 255, inclusive. If the motor does not
- * have exactly 255 steps, it must do it's best to map it
- * onto the number of steps it does have.
+ * be between 0.0 (exclusive) and 1.0 (inclusive). It must
+ * do it's best to map it onto the number of steps it does have.
*/
- void setAmplitude(in int amplitude);
+ void setAmplitude(in float amplitude);
/**
* Enables/disables control override of vibrator to audio.
@@ -128,4 +133,36 @@
* @param enabled Whether external control should be enabled or disabled.
*/
void setExternalControl(in boolean enabled);
+
+ /**
+ * Retrieve composition delay limit.
+ *
+ * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
+ *
+ * @return Maximum delay for a single CompositeEffect[] entry.
+ */
+ int getCompositionDelayMax();
+
+ /**
+ * Retrieve composition size limit.
+ *
+ * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
+ *
+ * @return Maximum number of entries in CompositeEffect[].
+ * @param maxDelayMs Maximum delay for a single CompositeEffect[] entry.
+ */
+ int getCompositionSizeMax();
+
+ /**
+ * Fire off a string of effect primitives, combined to perform richer effects.
+ *
+ * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
+ *
+ * Doing this operation while the vibrator is already on is undefined behavior. Clients should
+ * explicitly call off.
+ *
+ * @param composite Array of composition parameters.
+ */
+ void compose(in CompositeEffect[] composite, in IVibratorCallback callback);
+
}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index f399887..dc8867f 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -1,3 +1,19 @@
+cc_library_static {
+ name: "libvibratorexampleimpl",
+ vendor: true,
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "vintf-vibrator-ndk_platform",
+ ],
+ export_include_dirs: ["include"],
+ srcs: ["Vibrator.cpp"],
+ visibility: [
+ ":__subpackages__",
+ "//hardware/interfaces/tests/extension/vibrator:__subpackages__",
+ ],
+}
+
cc_binary {
name: "android.hardware.vibrator-service.example",
relative_install_path: "hw",
@@ -9,5 +25,8 @@
"libbinder_ndk",
"vintf-vibrator-ndk_platform",
],
- srcs: ["main.cpp", "Vibrator.cpp"],
+ static_libs: [
+ "libvibratorexampleimpl",
+ ],
+ srcs: ["main.cpp"],
}
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 18be1a6..befdeab 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "Vibrator.h"
+#include "vibrator-impl/Vibrator.h"
#include <android-base/logging.h>
#include <thread>
@@ -24,11 +24,14 @@
namespace hardware {
namespace vibrator {
+static constexpr int32_t kComposeDelayMaxMs = 1000;
+static constexpr int32_t kComposeSizeMax = 256;
+
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
LOG(INFO) << "Vibrator reporting capabilities";
*_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
- IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
+ IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS;
return ndk::ScopedAStatus::ok();
}
@@ -45,7 +48,9 @@
LOG(INFO) << "Starting on on another thread";
usleep(timeoutMs * 1000);
LOG(INFO) << "Notifying on complete";
- callback->onComplete();
+ if (!callback->onComplete().isOk()) {
+ LOG(ERROR) << "Failed to call onComplete";
+ }
}).detach();
}
return ndk::ScopedAStatus::ok();
@@ -84,9 +89,9 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Vibrator::setAmplitude(int32_t amplitude) {
+ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
LOG(INFO) << "Vibrator set amplitude: " << amplitude;
- if (amplitude <= 0 || amplitude > 255) {
+ if (amplitude <= 0.0f || amplitude > 1.0f) {
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
}
return ndk::ScopedAStatus::ok();
@@ -97,6 +102,55 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t* maxDelayMs) {
+ *maxDelayMs = kComposeDelayMaxMs;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize) {
+ *maxSize = kComposeSizeMax;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) {
+ if (composite.size() > kComposeSizeMax) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ for (auto& e : composite) {
+ if (e.delayMs > kComposeDelayMaxMs) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (e.scale <= 0.0f || e.scale > 1.0f) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (e.primitive < CompositePrimitive::NOOP ||
+ e.primitive > CompositePrimitive::QUICK_FALL) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ }
+
+ std::thread([=] {
+ LOG(INFO) << "Starting compose on another thread";
+
+ for (auto& e : composite) {
+ if (e.delayMs) {
+ usleep(e.delayMs * 1000);
+ }
+ LOG(INFO) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
+ << e.scale;
+ }
+
+ if (callback != nullptr) {
+ LOG(INFO) << "Notifying perform complete";
+ callback->onComplete();
+ }
+ }).detach();
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace vibrator
} // namespace hardware
} // namespace android
diff --git a/vibrator/aidl/default/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
similarity index 80%
rename from vibrator/aidl/default/Vibrator.h
rename to vibrator/aidl/default/include/vibrator-impl/Vibrator.h
index 14e7292..817ec80 100644
--- a/vibrator/aidl/default/Vibrator.h
+++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
@@ -32,8 +32,12 @@
const std::shared_ptr<IVibratorCallback>& callback,
int32_t* _aidl_return) override;
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
- ndk::ScopedAStatus setAmplitude(int32_t amplitude) override;
+ ndk::ScopedAStatus setAmplitude(float amplitude) override;
ndk::ScopedAStatus setExternalControl(bool enabled) override;
+ ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs);
+ ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize);
+ ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
};
} // namespace vibrator
diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp
index d1619ff..ebb0905 100644
--- a/vibrator/aidl/default/main.cpp
+++ b/vibrator/aidl/default/main.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "Vibrator.h"
+#include "vibrator-impl/Vibrator.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index b6aa9e2..6f9ba1a 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -28,6 +28,8 @@
using android::String16;
using android::binder::Status;
using android::hardware::vibrator::BnVibratorCallback;
+using android::hardware::vibrator::CompositeEffect;
+using android::hardware::vibrator::CompositePrimitive;
using android::hardware::vibrator::Effect;
using android::hardware::vibrator::EffectStrength;
using android::hardware::vibrator::IVibrator;
@@ -55,6 +57,20 @@
static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
};
+// TODO(b/143992652): autogenerate
+const std::vector<CompositePrimitive> kCompositePrimitives = {
+ CompositePrimitive::NOOP, CompositePrimitive::CLICK,
+ CompositePrimitive::THUD, CompositePrimitive::SPIN,
+ CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
+ CompositePrimitive::QUICK_FALL,
+};
+// TODO(b/143992652): autogenerate
+
+const std::vector<CompositePrimitive> kInvalidPrimitives = {
+ static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
+ static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
+};
+
class CompletionCallback : public BnVibratorCallback {
public:
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
@@ -119,13 +135,12 @@
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
if (isEffectSupported) {
- EXPECT_TRUE(status.isOk())
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
EXPECT_GT(lengthMs, 0);
usleep(lengthMs * 1000);
} else {
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ << toString(effect) << " " << toString(strength);
EXPECT_EQ(lengthMs, 0);
}
}
@@ -186,7 +201,7 @@
int32_t lengthMs;
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ << toString(effect) << " " << toString(strength);
}
}
for (Effect effect : kEffects) {
@@ -194,18 +209,18 @@
int32_t lengthMs;
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
- << static_cast<int>(effect) << " " << static_cast<int>(strength);
+ << toString(effect) << " " << toString(strength);
}
}
}
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
- EXPECT_TRUE(vibrator->setAmplitude(1).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
- EXPECT_TRUE(vibrator->setAmplitude(128).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
sleep(1);
- EXPECT_TRUE(vibrator->setAmplitude(255).isOk());
+ EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
sleep(1);
}
}
@@ -214,7 +229,7 @@
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(256).exceptionCode());
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
}
}
@@ -240,7 +255,7 @@
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
- Status amplitudeStatus = vibrator->setAmplitude(128);
+ Status amplitudeStatus = vibrator->setAmplitude(0.5);
if (supportsExternalAmplitudeControl) {
EXPECT_TRUE(amplitudeStatus.isOk());
} else {
@@ -259,6 +274,102 @@
}
}
+TEST_P(VibratorAidl, ComposeValidPrimitives) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ int32_t maxDelay, maxSize;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+
+ std::vector<CompositeEffect> composite;
+
+ for (auto primitive : kCompositePrimitives) {
+ CompositeEffect effect;
+
+ effect.delayMs = std::rand() % (maxDelay + 1);
+ effect.primitive = primitive;
+ effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
+ composite.emplace_back(effect);
+
+ if (composite.size() == maxSize) {
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ composite.clear();
+ vibrator->off();
+ }
+ }
+
+ if (composite.size() != 0) {
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+ }
+}
+
+TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ for (auto primitive : kInvalidPrimitives) {
+ std::vector<CompositeEffect> composite(1);
+
+ for (auto& effect : composite) {
+ effect.delayMs = 0;
+ effect.primitive = primitive;
+ effect.scale = 1.0f;
+ }
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+ vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+ }
+}
+
+TEST_P(VibratorAidl, CompseDelayBoundary) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ int32_t maxDelay;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+
+ std::vector<CompositeEffect> composite(1);
+ CompositeEffect effect;
+
+ effect.delayMs = 1;
+ effect.primitive = CompositePrimitive::CLICK;
+ effect.scale = 1.0f;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+ effect.delayMs = maxDelay + 1;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+}
+
+TEST_P(VibratorAidl, CompseSizeBoundary) {
+ if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
+ int32_t maxSize;
+
+ EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+
+ std::vector<CompositeEffect> composite(maxSize);
+ CompositeEffect effect;
+
+ effect.delayMs = 1;
+ effect.primitive = CompositePrimitive::CLICK;
+ effect.scale = 1.0f;
+
+ std::fill(composite.begin(), composite.end(), effect);
+ EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
+
+ composite.emplace_back(effect);
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ vibrator->compose(composite, nullptr).exceptionCode());
+ vibrator->off();
+ }
+}
+
INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
android::PrintInstanceNameToString);
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index f3068f2..bf77503 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -52,7 +52,7 @@
"android.hardware.wifi@1.3",
"libwifi-system-iface"
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
// These tests are split out so that they can be conditioned on presence of the
@@ -70,7 +70,7 @@
"android.hardware.wifi@1.0",
"libwifi-system-iface"
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
// These tests are split out so that they can be conditioned on presence of
@@ -88,5 +88,5 @@
"android.hardware.wifi@1.0",
"libwifi-system-iface"
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp b/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
index 9d25014..128dae5 100644
--- a/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
+++ b/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
@@ -14,34 +14,8 @@
* limitations under the License.
*/
-#include <android-base/logging.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
-#include "wifi_hidl_test_utils.h"
-
-class WifiVtsHidlEnvironment_1_0 : public WifiHidlEnvironment {
- public:
- // get the test environment singleton
- static WifiVtsHidlEnvironment_1_0* Instance() {
- static WifiVtsHidlEnvironment_1_0* instance =
- new WifiVtsHidlEnvironment_1_0;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<android::hardware::wifi::V1_0::IWifi>();
- }
-
- private:
- WifiVtsHidlEnvironment_1_0() {}
-};
-
-WifiHidlEnvironment* gEnv = WifiVtsHidlEnvironment_1_0::Instance();
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(gEnv);
- ::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
index c55221d..8be8a0c 100644
--- a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -16,35 +16,37 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiApIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
+using ::android::sp;
using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifi;
using ::android::hardware::wifi::V1_0::IWifiApIface;
using ::android::hardware::wifi::V1_0::WifiBand;
using ::android::hardware::wifi::V1_0::WifiStatusCode;
-using ::android::sp;
/**
* Fixture to use for all AP Iface HIDL interface tests.
*/
-class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiApIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_ap_iface_ = getWifiApIface();
+ wifi_ap_iface_ = getWifiApIface(GetInstanceName());
ASSERT_NE(nullptr, wifi_ap_iface_.get());
}
- virtual void TearDown() override {
- stopWifi();
- }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
sp<IWifiApIface> wifi_ap_iface_;
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -52,16 +54,15 @@
* Ensures that an instance of the IWifiApIface proxy object is
* successfully created.
*/
-TEST(WifiApIfaceHidlTestNoFixture, Create) {
- EXPECT_NE(nullptr, getWifiApIface().get());
- stopWifi();
+TEST_P(WifiApIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
}
/*
* GetType:
* Ensures that the correct interface type is returned for AP interface.
*/
-TEST_F(WifiApIfaceHidlTest, GetType) {
+TEST_P(WifiApIfaceHidlTest, GetType) {
const auto& status_and_type = HIDL_INVOKE(wifi_ap_iface_, getType);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code);
EXPECT_EQ(IfaceType::AP, status_and_type.second);
@@ -72,7 +73,7 @@
* Ensures that a call to set the country code will return with a success
* status code.
*/
-TEST_F(WifiApIfaceHidlTest, SetCountryCode) {
+TEST_P(WifiApIfaceHidlTest, SetCountryCode) {
const android::hardware::hidl_array<int8_t, 2> kCountryCode{
std::array<int8_t, 2>{{0x55, 0x53}}};
EXPECT_EQ(WifiStatusCode::SUCCESS,
@@ -83,9 +84,15 @@
* GetValidFrequenciesForBand:
* Ensures that we can retrieve valid frequencies for 2.4 GHz band.
*/
-TEST_F(WifiApIfaceHidlTest, GetValidFrequenciesForBand) {
+TEST_P(WifiApIfaceHidlTest, GetValidFrequenciesForBand) {
const auto& status_and_freqs = HIDL_INVOKE(
wifi_ap_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code);
EXPECT_GT(status_and_freqs.second.size(), 0u);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiApIfaceHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp
index 232ffdd..33817d5 100644
--- a/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp
@@ -16,9 +16,11 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiChip.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -26,6 +28,7 @@
using ::android::sp;
using ::android::hardware::wifi::V1_0::ChipModeId;
using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifi;
using ::android::hardware::wifi::V1_0::IWifiApIface;
using ::android::hardware::wifi::V1_0::IWifiChip;
using ::android::hardware::wifi::V1_0::IWifiIface;
@@ -35,14 +38,14 @@
/**
* Fixture for IWifiChip tests that are conditioned on SoftAP support.
*/
-class WifiChipHidlApTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiChipHidlApTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_chip_ = getWifiChip();
+ wifi_chip_ = getWifiChip(GetInstanceName());
ASSERT_NE(nullptr, wifi_chip_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
// Helper function to configure the Chip in one of the supported modes.
@@ -72,6 +75,9 @@
}
sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -79,7 +85,7 @@
* Configures the chip in AP mode and ensures that at least 1 iface creation
* succeeds.
*/
-TEST_F(WifiChipHidlApTest, CreateApIface) {
+TEST_P(WifiChipHidlApTest, CreateApIface) {
configureChipForIfaceType(IfaceType::AP, true);
sp<IWifiApIface> iface;
@@ -93,7 +99,7 @@
* before creating the iface. Then, create the iface and ensure that
* iface name is returned via the list.
*/
-TEST_F(WifiChipHidlApTest, GetApIfaceNames) {
+TEST_P(WifiChipHidlApTest, GetApIfaceNames) {
configureChipForIfaceType(IfaceType::AP, true);
const auto& status_and_iface_names1 =
@@ -125,7 +131,7 @@
* the iface object using the correct name and ensure any other name
* doesn't retrieve an iface object.
*/
-TEST_F(WifiChipHidlApTest, GetApIface) {
+TEST_P(WifiChipHidlApTest, GetApIface) {
configureChipForIfaceType(IfaceType::AP, true);
sp<IWifiApIface> ap_iface;
@@ -151,7 +157,7 @@
* the iface object using the correct name and ensure any other name
* doesn't remove the iface.
*/
-TEST_F(WifiChipHidlApTest, RemoveApIface) {
+TEST_P(WifiChipHidlApTest, RemoveApIface) {
configureChipForIfaceType(IfaceType::AP, true);
sp<IWifiApIface> ap_iface;
@@ -166,3 +172,9 @@
// No such iface exists now. So, this should return failure.
EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeApIface(iface_name));
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlApTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp
index 595f23a..95f223d 100644
--- a/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp
@@ -16,9 +16,11 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiChip.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -26,6 +28,7 @@
using ::android::sp;
using ::android::hardware::wifi::V1_0::ChipModeId;
using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifi;
using ::android::hardware::wifi::V1_0::IWifiChip;
using ::android::hardware::wifi::V1_0::IWifiIface;
using ::android::hardware::wifi::V1_0::IWifiNanIface;
@@ -35,14 +38,14 @@
/**
* Fixture for IWifiChip tests that are conditioned on NAN support.
*/
-class WifiChipHidlNanTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiChipHidlNanTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_chip_ = getWifiChip();
+ wifi_chip_ = getWifiChip(GetInstanceName());
ASSERT_NE(nullptr, wifi_chip_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
// Helper function to configure the Chip in one of the supported modes.
@@ -72,6 +75,9 @@
}
sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -79,7 +85,7 @@
* Configures the chip in NAN mode and ensures that at least 1 iface creation
* succeeds.
*/
-TEST_F(WifiChipHidlNanTest, CreateNanIface) {
+TEST_P(WifiChipHidlNanTest, CreateNanIface) {
configureChipForIfaceType(IfaceType::NAN, true);
sp<IWifiNanIface> iface;
@@ -93,7 +99,7 @@
* before creating the iface. Then, create the iface and ensure that
* iface name is returned via the list.
*/
-TEST_F(WifiChipHidlNanTest, GetNanIfaceNames) {
+TEST_P(WifiChipHidlNanTest, GetNanIfaceNames) {
configureChipForIfaceType(IfaceType::NAN, true);
const auto& status_and_iface_names1 =
@@ -125,7 +131,7 @@
* the iface object using the correct name and ensure any other name
* doesn't retrieve an iface object.
*/
-TEST_F(WifiChipHidlNanTest, GetNanIface) {
+TEST_P(WifiChipHidlNanTest, GetNanIface) {
configureChipForIfaceType(IfaceType::NAN, true);
sp<IWifiNanIface> nan_iface;
@@ -151,7 +157,7 @@
* the iface object using the correct name and ensure any other name
* doesn't remove the iface.
*/
-TEST_F(WifiChipHidlNanTest, RemoveNanIface) {
+TEST_P(WifiChipHidlNanTest, RemoveNanIface) {
configureChipForIfaceType(IfaceType::NAN, true);
sp<IWifiNanIface> nan_iface;
@@ -167,3 +173,9 @@
// No such iface exists now. So, this should return failure.
EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name));
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlNanTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
index 2601b78..ec96fcf 100644
--- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -16,10 +16,12 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiChip.h>
#include <android/hardware/wifi/1.3/IWifiChip.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -27,19 +29,20 @@
using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
-using ::android::hardware::wifi::V1_0::IfaceType;
using ::android::hardware::wifi::V1_0::ChipId;
using ::android::hardware::wifi::V1_0::ChipModeId;
-using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
-using ::android::hardware::wifi::V1_0::WifiDebugRingBufferVerboseLevel;
-using ::android::hardware::wifi::V1_0::WifiDebugHostWakeReasonStats;
-using ::android::hardware::wifi::V1_0::WifiStatus;
-using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifi;
using ::android::hardware::wifi::V1_0::IWifiChip;
using ::android::hardware::wifi::V1_0::IWifiIface;
using ::android::hardware::wifi::V1_0::IWifiP2pIface;
using ::android::hardware::wifi::V1_0::IWifiRttController;
using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::hardware::wifi::V1_0::WifiDebugHostWakeReasonStats;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferVerboseLevel;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
extern WifiHidlEnvironment* gEnv;
@@ -67,14 +70,14 @@
* Tests that require SoftAP or NAN support should go into WifiChipHidlApTest or
* WifiChipHidlNanTest respectively.
*/
-class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_chip_ = getWifiChip();
+ wifi_chip_ = getWifiChip(GetInstanceName());
ASSERT_NE(nullptr, wifi_chip_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
// Helper function to configure the Chip in one of the supported modes.
@@ -136,6 +139,9 @@
}
sp<IWifiChip> wifi_chip_;
+
+ protected:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -143,15 +149,14 @@
* Ensures that an instance of the IWifiChip proxy object is
* successfully created.
*/
-TEST(WifiChipHidlTestNoFixture, Create) {
- EXPECT_NE(nullptr, getWifiChip().get());
- stopWifi();
+TEST_P(WifiChipHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
}
/*
* GetId:
*/
-TEST_F(WifiChipHidlTest, GetId) {
+TEST_P(WifiChipHidlTest, GetId) {
EXPECT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(wifi_chip_, getId).first.code);
}
@@ -159,7 +164,7 @@
/*
* GetAvailableMode:
*/
-TEST_F(WifiChipHidlTest, GetAvailableModes) {
+TEST_P(WifiChipHidlTest, GetAvailableModes) {
const auto& status_and_modes = HIDL_INVOKE(wifi_chip_, getAvailableModes);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_modes.first.code);
EXPECT_LT(0u, status_and_modes.second.size());
@@ -168,17 +173,17 @@
/*
* ConfigureChip:
*/
-TEST_F(WifiChipHidlTest, ConfigureChip) {
+TEST_P(WifiChipHidlTest, ConfigureChip) {
const auto& status_and_modes = HIDL_INVOKE(wifi_chip_, getAvailableModes);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_modes.first.code);
EXPECT_LT(0u, status_and_modes.second.size());
for (const auto& mode : status_and_modes.second) {
// configureChip() requires to be called with a fresh IWifiChip object.
- wifi_chip_ = getWifiChip();
+ wifi_chip_ = getWifiChip(GetInstanceName());
ASSERT_NE(nullptr, wifi_chip_.get());
EXPECT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(wifi_chip_, configureChip, mode.id).code);
- stopWifi();
+ stopWifi(GetInstanceName());
// Sleep for 5 milliseconds between each wifi state toggle.
usleep(5000);
}
@@ -187,7 +192,7 @@
/*
* GetCapabilities:
*/
-TEST_F(WifiChipHidlTest, GetCapabilities) {
+TEST_P(WifiChipHidlTest, GetCapabilities) {
configureChipForIfaceType(IfaceType::STA, true);
const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
if (status_and_caps.first.code != WifiStatusCode::SUCCESS) {
@@ -200,7 +205,7 @@
/*
* GetMode:
*/
-TEST_F(WifiChipHidlTest, GetMode) {
+TEST_P(WifiChipHidlTest, GetMode) {
ChipModeId chip_mode_id = configureChipForIfaceType(IfaceType::STA, true);
const auto& status_and_mode = HIDL_INVOKE(wifi_chip_, getMode);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_mode.first.code);
@@ -210,7 +215,7 @@
/*
* RequestChipDebugInfo:
*/
-TEST_F(WifiChipHidlTest, RequestChipDebugInfo) {
+TEST_P(WifiChipHidlTest, RequestChipDebugInfo) {
configureChipForIfaceType(IfaceType::STA, true);
const auto& status_and_chip_info =
HIDL_INVOKE(wifi_chip_, requestChipDebugInfo);
@@ -222,7 +227,7 @@
/*
* RequestFirmwareDebugDump
*/
-TEST_F(WifiChipHidlTest, RequestFirmwareDebugDump) {
+TEST_P(WifiChipHidlTest, RequestFirmwareDebugDump) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status_and_firmware_dump =
HIDL_INVOKE(wifi_chip_, requestFirmwareDebugDump);
@@ -237,7 +242,7 @@
/*
* RequestDriverDebugDump
*/
-TEST_F(WifiChipHidlTest, RequestDriverDebugDump) {
+TEST_P(WifiChipHidlTest, RequestDriverDebugDump) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status_and_driver_dump =
HIDL_INVOKE(wifi_chip_, requestDriverDebugDump);
@@ -254,7 +259,7 @@
/*
* GetDebugRingBuffersStatus
*/
-TEST_F(WifiChipHidlTest, GetDebugRingBuffersStatus) {
+TEST_P(WifiChipHidlTest, GetDebugRingBuffersStatus) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status_and_ring_buffer_status =
HIDL_INVOKE(wifi_chip_, getDebugRingBuffersStatus);
@@ -273,7 +278,7 @@
/*
* StartLoggingToDebugRingBuffer
*/
-TEST_F(WifiChipHidlTest, StartLoggingToDebugRingBuffer) {
+TEST_P(WifiChipHidlTest, StartLoggingToDebugRingBuffer) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
std::string ring_name;
const auto& status_and_ring_buffer_status =
@@ -301,7 +306,7 @@
/*
* ForceDumpToDebugRingBuffer
*/
-TEST_F(WifiChipHidlTest, ForceDumpToDebugRingBuffer) {
+TEST_P(WifiChipHidlTest, ForceDumpToDebugRingBuffer) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
std::string ring_name;
const auto& status_and_ring_buffer_status =
@@ -327,7 +332,7 @@
/*
* GetDebugHostWakeReasonStats
*/
-TEST_F(WifiChipHidlTest, GetDebugHostWakeReasonStats) {
+TEST_P(WifiChipHidlTest, GetDebugHostWakeReasonStats) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status_and_debug_wake_reason =
HIDL_INVOKE(wifi_chip_, getDebugHostWakeReasonStats);
@@ -345,7 +350,7 @@
* Configures the chip in P2P mode and ensures that at least 1 iface creation
* succeeds.
*/
-TEST_F(WifiChipHidlTest, CreateP2pIface) {
+TEST_P(WifiChipHidlTest, CreateP2pIface) {
configureChipForIfaceType(IfaceType::P2P, true);
sp<IWifiP2pIface> iface;
@@ -359,7 +364,7 @@
* before creating the iface. Then, create the iface and ensure that
* iface name is returned via the list.
*/
-TEST_F(WifiChipHidlTest, GetP2pIfaceNames) {
+TEST_P(WifiChipHidlTest, GetP2pIfaceNames) {
configureChipForIfaceType(IfaceType::P2P, true);
const auto& status_and_iface_names1 =
@@ -391,7 +396,7 @@
* the iface object using the correct name and ensure any other name
* doesn't retrieve an iface object.
*/
-TEST_F(WifiChipHidlTest, GetP2pIface) {
+TEST_P(WifiChipHidlTest, GetP2pIface) {
configureChipForIfaceType(IfaceType::P2P, true);
sp<IWifiP2pIface> p2p_iface;
@@ -417,7 +422,7 @@
* the iface object using the correct name and ensure any other name
* doesn't remove the iface.
*/
-TEST_F(WifiChipHidlTest, RemoveP2pIface) {
+TEST_P(WifiChipHidlTest, RemoveP2pIface) {
configureChipForIfaceType(IfaceType::P2P, true);
sp<IWifiP2pIface> p2p_iface;
@@ -438,7 +443,7 @@
* Configures the chip in STA mode and ensures that at least 1 iface creation
* succeeds.
*/
-TEST_F(WifiChipHidlTest, CreateStaIface) {
+TEST_P(WifiChipHidlTest, CreateStaIface) {
configureChipForIfaceType(IfaceType::STA, true);
sp<IWifiStaIface> iface;
@@ -452,7 +457,7 @@
* before creating the iface. Then, create the iface and ensure that
* iface name is returned via the list.
*/
-TEST_F(WifiChipHidlTest, GetStaIfaceNames) {
+TEST_P(WifiChipHidlTest, GetStaIfaceNames) {
configureChipForIfaceType(IfaceType::STA, true);
const auto& status_and_iface_names1 =
@@ -484,7 +489,7 @@
* the iface object using the correct name and ensure any other name
* doesn't retrieve an iface object.
*/
-TEST_F(WifiChipHidlTest, GetStaIface) {
+TEST_P(WifiChipHidlTest, GetStaIface) {
configureChipForIfaceType(IfaceType::STA, true);
sp<IWifiStaIface> sta_iface;
@@ -510,7 +515,7 @@
* the iface object using the correct name and ensure any other name
* doesn't remove the iface.
*/
-TEST_F(WifiChipHidlTest, RemoveStaIface) {
+TEST_P(WifiChipHidlTest, RemoveStaIface) {
configureChipForIfaceType(IfaceType::STA, true);
sp<IWifiStaIface> sta_iface;
@@ -529,7 +534,7 @@
/*
* CreateRttController
*/
-TEST_F(WifiChipHidlTest, CreateRttController) {
+TEST_P(WifiChipHidlTest, CreateRttController) {
configureChipForIfaceType(IfaceType::STA, true);
sp<IWifiStaIface> iface;
@@ -541,3 +546,9 @@
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_rtt_controller.first.code);
EXPECT_NE(nullptr, status_and_rtt_controller.second.get());
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
index b8e501c..512701a 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
@@ -18,7 +18,9 @@
#include <android/hardware/wifi/1.0/IWifi.h>
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_test_utils.h"
@@ -28,13 +30,14 @@
/**
* Fixture to use for all root Wifi HIDL interface tests.
*/
-class WifiHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -42,7 +45,12 @@
* Ensures that an instance of the IWifi proxy object is
* successfully created.
*/
-TEST(WifiHidlTestNoFixture, Create) {
- EXPECT_NE(nullptr, getWifi().get());
- stopWifi();
+TEST_P(WifiHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
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 45454bf..d584d4b 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -214,7 +214,7 @@
if (!wifi_chip.get()) {
return nullptr;
}
- sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface();
+ sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface(instance_name);
if (!wifi_sta_iface.get()) {
return nullptr;
}
diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
index 64b4fb6..422e3f6 100644
--- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -16,10 +16,12 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiNanIface.h>
#include <android/hardware/wifi/1.0/IWifiNanIfaceEventCallback.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -29,27 +31,28 @@
using namespace ::android::hardware::wifi::V1_0;
+using ::android::sp;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::sp;
+using ::android::hardware::wifi::V1_0::IWifi;
#define TIMEOUT_PERIOD 10
/**
* Fixture to use for all NAN Iface HIDL interface tests.
*/
-class WifiNanIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
virtual void SetUp() override {
- iwifiNanIface = getWifiNanIface();
- ASSERT_NE(nullptr, iwifiNanIface.get());
- ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, registerEventCallback,
- new WifiNanIfaceEventCallback(*this)).code);
+ iwifiNanIface = getWifiNanIface(GetInstanceName());
+ ASSERT_NE(nullptr, iwifiNanIface.get());
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, registerEventCallback,
+ new WifiNanIfaceEventCallback(*this))
+ .code);
}
- virtual void TearDown() override {
- stopWifi();
- }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
/* Used as a mechanism to inform the test about data/event callback */
inline void notify() {
@@ -438,6 +441,8 @@
NanFollowupReceivedInd nanFollowupReceivedInd;
NanDataPathRequestInd nanDataPathRequestInd;
NanDataPathConfirmInd nanDataPathConfirmInd;
+
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -445,9 +450,8 @@
* Ensures that an instance of the IWifiNanIface proxy object is
* successfully created.
*/
-TEST(WifiNanIfaceHidlTestNoFixture, Create) {
- ASSERT_NE(nullptr, getWifiNanIface().get());
- stopWifi();
+TEST_P(WifiNanIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
}
/*
@@ -455,41 +459,51 @@
* Ensure that API calls fail with ERROR_WIFI_IFACE_INVALID when using an interface once wifi
* is disabled.
*/
-TEST(WifiNanIfaceHidlTestNoFixture, FailOnIfaceInvalid) {
- android::sp<IWifiNanIface> iwifiNanIface = getWifiNanIface();
- ASSERT_NE(nullptr, iwifiNanIface.get());
- stopWifi();
- sleep(5); // make sure that all chips/interfaces are invalidated
- ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
- HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, 0).code);
+TEST_P(WifiNanIfaceHidlTest, FailOnIfaceInvalid) {
+ stopWifi(GetInstanceName());
+ android::sp<IWifiNanIface> iwifiNanIface =
+ getWifiNanIface(GetInstanceName());
+ ASSERT_NE(nullptr, iwifiNanIface.get());
+ stopWifi(GetInstanceName());
+ sleep(5); // make sure that all chips/interfaces are invalidated
+ ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, 0).code);
}
/*
* getCapabilitiesRequest: validate that returns capabilities.
*/
-TEST_F(WifiNanIfaceHidlTest, getCapabilitiesRequest) {
- uint16_t inputCmdId = 10;
- callbackType = INVALID;
- ASSERT_EQ(WifiStatusCode::SUCCESS,
+TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ASSERT_EQ(
+ WifiStatusCode::SUCCESS,
HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId).code);
- // wait for a callback
- ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE));
- ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE, callbackType);
- ASSERT_EQ(id, inputCmdId);
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE));
+ ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
- // check for reasonable capability values
- EXPECT_GT(capabilities.maxConcurrentClusters, (unsigned int) 0);
- EXPECT_GT(capabilities.maxPublishes, (unsigned int) 0);
- EXPECT_GT(capabilities.maxSubscribes, (unsigned int) 0);
- EXPECT_EQ(capabilities.maxServiceNameLen, (unsigned int) 255);
- EXPECT_EQ(capabilities.maxMatchFilterLen, (unsigned int) 255);
- EXPECT_GT(capabilities.maxTotalMatchFilterLen, (unsigned int) 255);
- EXPECT_EQ(capabilities.maxServiceSpecificInfoLen, (unsigned int) 255);
- EXPECT_GE(capabilities.maxExtendedServiceSpecificInfoLen, (unsigned int) 255);
- EXPECT_GT(capabilities.maxNdiInterfaces, (unsigned int) 0);
- EXPECT_GT(capabilities.maxNdpSessions, (unsigned int) 0);
- EXPECT_GT(capabilities.maxAppInfoLen, (unsigned int) 0);
- EXPECT_GT(capabilities.maxQueuedTransmitFollowupMsgs, (unsigned int) 0);
- EXPECT_GT(capabilities.maxSubscribeInterfaceAddresses, (unsigned int) 0);
- EXPECT_NE(capabilities.supportedCipherSuites, (unsigned int) 0);
+ // check for reasonable capability values
+ EXPECT_GT(capabilities.maxConcurrentClusters, (unsigned int)0);
+ EXPECT_GT(capabilities.maxPublishes, (unsigned int)0);
+ EXPECT_GT(capabilities.maxSubscribes, (unsigned int)0);
+ EXPECT_EQ(capabilities.maxServiceNameLen, (unsigned int)255);
+ EXPECT_EQ(capabilities.maxMatchFilterLen, (unsigned int)255);
+ EXPECT_GT(capabilities.maxTotalMatchFilterLen, (unsigned int)255);
+ EXPECT_EQ(capabilities.maxServiceSpecificInfoLen, (unsigned int)255);
+ EXPECT_GE(capabilities.maxExtendedServiceSpecificInfoLen,
+ (unsigned int)255);
+ EXPECT_GT(capabilities.maxNdiInterfaces, (unsigned int)0);
+ EXPECT_GT(capabilities.maxNdpSessions, (unsigned int)0);
+ EXPECT_GT(capabilities.maxAppInfoLen, (unsigned int)0);
+ EXPECT_GT(capabilities.maxQueuedTransmitFollowupMsgs, (unsigned int)0);
+ EXPECT_GT(capabilities.maxSubscribeInterfaceAddresses, (unsigned int)0);
+ EXPECT_NE(capabilities.supportedCipherSuites, (unsigned int)0);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiNanIfaceHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
index 269eb6c..8f33271 100644
--- a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
@@ -16,25 +16,29 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_test_utils.h"
-using ::android::hardware::wifi::V1_0::IWifiP2pIface;
using ::android::sp;
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
/**
* Fixture to use for all P2P Iface HIDL interface tests.
*/
-class WifiP2pIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiP2pIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -42,7 +46,13 @@
* Ensures that an instance of the IWifiP2pIface proxy object is
* successfully created.
*/
-TEST(WifiP2pIfaceHidlTestNoFixture, Create) {
- EXPECT_NE(nullptr, getWifiP2pIface().get());
- stopWifi();
+TEST_P(WifiP2pIfaceHidlTest, Create) {
+ stopWifi(GetInstanceName());
+ EXPECT_NE(nullptr, getWifiP2pIface(GetInstanceName()).get());
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiP2pIfaceHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
index e13086d..e1ee34f 100644
--- a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
@@ -16,25 +16,29 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiRttController.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_test_utils.h"
-using ::android::hardware::wifi::V1_0::IWifiRttController;
using ::android::sp;
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiRttController;
/**
* Fixture to use for all RTT controller HIDL interface tests.
*/
-class WifiRttControllerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiRttControllerHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -42,7 +46,13 @@
* Ensures that an instance of the IWifiRttController proxy object is
* successfully created.
*/
-TEST(WifiRttControllerHidlTestNoFixture, Create) {
- EXPECT_NE(nullptr, getWifiRttController().get());
- stopWifi();
+TEST_P(WifiRttControllerHidlTest, Create) {
+ stopWifi(GetInstanceName());
+ EXPECT_NE(nullptr, getWifiRttController(GetInstanceName()).get());
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiRttControllerHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
index a413863..30b6fba 100644
--- a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -16,10 +16,12 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.0/IWifiStaIface.h>
#include <android/hardware/wifi/1.3/IWifiStaIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -28,6 +30,7 @@
using ::android::hardware::wifi::V1_0::Bssid;
using ::android::hardware::wifi::V1_0::CommandId;
using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifi;
using ::android::hardware::wifi::V1_0::IWifiStaIface;
using ::android::hardware::wifi::V1_0::Rssi;
using ::android::hardware::wifi::V1_0::Ssid;
@@ -41,14 +44,14 @@
/**
* Fixture to use for all STA Iface HIDL interface tests.
*/
-class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiStaIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_sta_iface_ = getWifiStaIface();
+ wifi_sta_iface_ = getWifiStaIface(GetInstanceName());
ASSERT_NE(nullptr, wifi_sta_iface_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) {
@@ -59,6 +62,7 @@
}
sp<IWifiStaIface> wifi_sta_iface_;
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -66,15 +70,14 @@
* Ensures that an instance of the IWifiStaIface proxy object is
* successfully created.
*/
-TEST(WifiStaIfaceHidlTestNoFixture, Create) {
- EXPECT_NE(nullptr, getWifiStaIface().get());
- stopWifi();
+TEST_P(WifiStaIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
}
/*
* GetCapabilities:
*/
-TEST_F(WifiStaIfaceHidlTest, GetCapabilities) {
+TEST_P(WifiStaIfaceHidlTest, GetCapabilities) {
const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getCapabilities);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
EXPECT_GT(status_and_caps.second, 0u);
@@ -84,7 +87,7 @@
* GetType:
* Ensures that the correct interface type is returned for station interface.
*/
-TEST_F(WifiStaIfaceHidlTest, GetType) {
+TEST_P(WifiStaIfaceHidlTest, GetType) {
const auto& status_and_type = HIDL_INVOKE(wifi_sta_iface_, getType);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code);
EXPECT_EQ(IfaceType::STA, status_and_type.second);
@@ -94,7 +97,7 @@
* GetApfPacketFilterCapabilities:
* Ensures that we can retrieve APF packet filter capabilites.
*/
-TEST_F(WifiStaIfaceHidlTest, GetApfPacketFilterCapabilities) {
+TEST_P(WifiStaIfaceHidlTest, GetApfPacketFilterCapabilities) {
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::APF)) {
// No-op if APF packet filer is not supported.
return;
@@ -109,7 +112,7 @@
* GetBackgroundScanCapabilities:
* Ensures that we can retrieve background scan capabilities.
*/
-TEST_F(WifiStaIfaceHidlTest, GetBackgroundScanCapabilities) {
+TEST_P(WifiStaIfaceHidlTest, GetBackgroundScanCapabilities) {
if (!isCapabilitySupported(
IWifiStaIface::StaIfaceCapabilityMask::BACKGROUND_SCAN)) {
// No-op if background scan is not supported.
@@ -125,7 +128,7 @@
* GetValidFrequenciesForBand:
* Ensures that we can retrieve valid frequencies for 2.4 GHz band.
*/
-TEST_F(WifiStaIfaceHidlTest, GetValidFrequenciesForBand) {
+TEST_P(WifiStaIfaceHidlTest, GetValidFrequenciesForBand) {
const auto& status_and_freqs = HIDL_INVOKE(
wifi_sta_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code);
@@ -137,7 +140,7 @@
* Ensures that calls to enable, disable, and retrieve link layer stats
* will return a success status code.
*/
-TEST_F(WifiStaIfaceHidlTest, LinkLayerStatsCollection) {
+TEST_P(WifiStaIfaceHidlTest, LinkLayerStatsCollection) {
if (!isCapabilitySupported(
IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
// No-op if link layer stats is not supported.
@@ -172,7 +175,7 @@
* Ensures that calls to disable RSSI monitoring will return an error status
* code if RSSI monitoring is not enabled.
*/
-TEST_F(WifiStaIfaceHidlTest, RSSIMonitoring) {
+TEST_P(WifiStaIfaceHidlTest, RSSIMonitoring) {
if (!isCapabilitySupported(
IWifiStaIface::StaIfaceCapabilityMask::RSSI_MONITOR)) {
// No-op if RSSI monitor is not supported.
@@ -197,7 +200,7 @@
* Ensures that calls to configure and enable roaming will return a success
* status code.
*/
-TEST_F(WifiStaIfaceHidlTest, RoamingControl) {
+TEST_P(WifiStaIfaceHidlTest, RoamingControl) {
if (!isCapabilitySupported(
IWifiStaIface::StaIfaceCapabilityMask::CONTROL_ROAMING)) {
// No-op if roaming control is not supported.
@@ -242,9 +245,9 @@
* Ensures that calls to enable neighbor discovery offload will return a success
* status code.
*/
-TEST_F(WifiStaIfaceHidlTest, EnableNDOffload) {
- if (!isCapabilitySupported(
- IWifiStaIface::StaIfaceCapabilityMask::ND_OFFLOAD)) {
+TEST_P(WifiStaIfaceHidlTest, EnableNDOffload) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::ND_OFFLOAD)) {
// No-op if nd offload is not supported.
return;
}
@@ -257,7 +260,7 @@
* Ensures that calls to set scanning MAC OUI will return a success status
* code.
*/
-TEST_F(WifiStaIfaceHidlTest, SetScanningMacOui) {
+TEST_P(WifiStaIfaceHidlTest, SetScanningMacOui) {
if (!isCapabilitySupported(
IWifiStaIface::StaIfaceCapabilityMask::SCAN_RAND)) {
// No-op if SetScanningMacOui is not supported.
@@ -274,9 +277,9 @@
* Ensures that calls to start packet fate monitoring and retrieve TX/RX
* packets will return a success status code.
*/
-TEST_F(WifiStaIfaceHidlTest, PacketFateMonitoring) {
- if (!isCapabilitySupported(
- IWifiStaIface::StaIfaceCapabilityMask::DEBUG_PACKET_FATE)) {
+TEST_P(WifiStaIfaceHidlTest, PacketFateMonitoring) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::DEBUG_PACKET_FATE)) {
// No-op if packet fate monitor is not supported.
return;
}
@@ -291,3 +294,9 @@
EXPECT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(wifi_sta_iface_, getDebugRxPacketFates).first.code);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiStaIfaceHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp
index 6d7635d..775031e 100644
--- a/wifi/1.1/vts/functional/Android.bp
+++ b/wifi/1.1/vts/functional/Android.bp
@@ -28,5 +28,5 @@
"android.hardware.wifi@1.3",
"libwifi-system-iface"
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
index 673fed3..4b62b15 100644
--- a/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
+++ b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
@@ -14,34 +14,8 @@
* limitations under the License.
*/
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.1/IWifi.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
-#include "wifi_hidl_test_utils.h"
-
-class WifiHidlEnvironment_1_1 : public WifiHidlEnvironment {
- public:
- // get the test environment singleton
- static WifiHidlEnvironment_1_1* Instance() {
- static WifiHidlEnvironment_1_1* instance = new WifiHidlEnvironment_1_1;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<android::hardware::wifi::V1_1::IWifi>();
- }
-
- private:
- WifiHidlEnvironment_1_1() {}
-};
-
-WifiHidlEnvironment* gEnv = WifiHidlEnvironment_1_1::Instance();
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(gEnv);
- ::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
index 6323547..08de240 100644
--- a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
@@ -19,8 +19,9 @@
#include <android/hardware/wifi/1.1/IWifi.h>
#include <android/hardware/wifi/1.1/IWifiChip.h>
#include <android/hardware/wifi/1.3/IWifiChip.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -45,14 +46,14 @@
/**
* Fixture to use for all Wifi chip HIDL interface tests.
*/
-class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_chip_ = IWifiChip::castFrom(getWifiChip());
+ wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
ASSERT_NE(nullptr, wifi_chip_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
uint32_t configureChipForStaIfaceAndGetCapabilities() {
@@ -77,12 +78,15 @@
}
sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
* SelectTxPowerScenario
*/
-TEST_F(WifiChipHidlTest, SelectTxPowerScenario) {
+TEST_P(WifiChipHidlTest, SelectTxPowerScenario) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status =
HIDL_INVOKE(wifi_chip_, selectTxPowerScenario, kFakePowerScenario);
@@ -96,7 +100,7 @@
/*
* ResetTxPowerScenario
*/
-TEST_F(WifiChipHidlTest, ResetTxPowerScenario) {
+TEST_P(WifiChipHidlTest, ResetTxPowerScenario) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status =
HIDL_INVOKE(wifi_chip_, resetTxPowerScenario);
@@ -106,3 +110,9 @@
EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
}
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp
index 97853d0..f43e49e 100644
--- a/wifi/1.2/vts/functional/Android.bp
+++ b/wifi/1.2/vts/functional/Android.bp
@@ -30,7 +30,8 @@
"android.hardware.wifi@1.3",
"libwifi-system-iface"
],
- test_suites: ["general-tests"],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
cc_test {
@@ -47,5 +48,6 @@
"android.hardware.wifi@1.2",
"libwifi-system-iface"
],
- test_suites: ["general-tests"],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp b/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp
index c765cdc..52c7a4a 100644
--- a/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp
+++ b/wifi/1.2/vts/functional/VtsHalWifiV1_2TargetTest.cpp
@@ -14,35 +14,8 @@
* limitations under the License.
*/
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.2/IWifi.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
-#include "wifi_hidl_test_utils.h"
-
-using ::android::hardware::wifi::V1_2::IWifi;
-
-// Test environment for Wifi HIDL HAL.
-class WifiHidlEnvironment_1_2 : public WifiHidlEnvironment {
- public:
- // get the test environment singleton
- static WifiHidlEnvironment_1_2* Instance() {
- static WifiHidlEnvironment_1_2* instance = new WifiHidlEnvironment_1_2;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IWifi>(); }
-
- private:
- WifiHidlEnvironment_1_2() {}
-};
-
-WifiHidlEnvironment_1_2* gEnv = WifiHidlEnvironment_1_2::Instance();
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(gEnv);
- ::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
diff --git a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
index 9d567fe..47faec8 100644
--- a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
@@ -16,12 +16,14 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.2/IWifi.h>
#include <android/hardware/wifi/1.2/IWifiChip.h>
#include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
#include <android/hardware/wifi/1.3/IWifiChip.h>
-
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -50,14 +52,14 @@
/**
* Fixture to use for all Wifi chip HIDL interface tests.
*/
-class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_chip_ = IWifiChip::castFrom(getWifiChip());
+ wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
ASSERT_NE(nullptr, wifi_chip_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
// A simple test implementation of WifiChipEventCallback.
class WifiChipEventCallback
@@ -123,6 +125,9 @@
}
sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -130,7 +135,7 @@
* This test case tests the selectTxPowerScenario_1_2() API with SAR scenarios
* newly defined in 1.2
*/
-TEST_F(WifiChipHidlTest, SelectTxPowerScenario_1_2_body) {
+TEST_P(WifiChipHidlTest, SelectTxPowerScenario_1_2_body) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status =
HIDL_INVOKE(wifi_chip_, selectTxPowerScenario_1_2, kPowerScenarioBody);
@@ -147,7 +152,7 @@
* This test case tests the selectTxPowerScenario_1_2() API with previously
* defined SAR scenarios
*/
-TEST_F(WifiChipHidlTest, SelectTxPowerScenario_1_2_voiceCall) {
+TEST_P(WifiChipHidlTest, SelectTxPowerScenario_1_2_voiceCall) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status =
HIDL_INVOKE(wifi_chip_, selectTxPowerScenario_1_2, kPowerScenarioVoiceCall);
@@ -167,9 +172,15 @@
* since event is triggered internally in the HAL implementation, and can not be
* triggered from the test case
*/
-TEST_F(WifiChipHidlTest, registerEventCallback_1_2) {
+TEST_P(WifiChipHidlTest, registerEventCallback_1_2) {
sp<WifiChipEventCallback> wifiChipEventCallback = new WifiChipEventCallback();
const auto& status =
HIDL_INVOKE(wifi_chip_, registerEventCallback_1_2, wifiChipEventCallback);
EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_2::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp
index 4dbc82b..f3f76e1 100644
--- a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp
+++ b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -16,10 +16,12 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.2/IWifi.h>
#include <android/hardware/wifi/1.2/IWifiNanIface.h>
#include <android/hardware/wifi/1.2/IWifiNanIfaceEventCallback.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
@@ -36,19 +38,19 @@
#define TIMEOUT_PERIOD 10
-android::sp<android::hardware::wifi::V1_2::IWifiNanIface>
-getWifiNanIface_1_2() {
+android::sp<android::hardware::wifi::V1_2::IWifiNanIface> getWifiNanIface_1_2(
+ const std::string& instance_name) {
return android::hardware::wifi::V1_2::IWifiNanIface::castFrom(
- getWifiNanIface());
+ getWifiNanIface(instance_name));
}
/**
* Fixture to use for all NAN Iface HIDL interface tests.
*/
-class WifiNanIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- iwifiNanIface = getWifiNanIface_1_2();
+ iwifiNanIface = getWifiNanIface_1_2(GetInstanceName());
ASSERT_NE(nullptr, iwifiNanIface.get());
ASSERT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_2,
@@ -56,7 +58,7 @@
.code);
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
/* Used as a mechanism to inform the test about data/event callback */
inline void notify() {
@@ -458,6 +460,8 @@
::android::hardware::wifi::V1_2::NanDataPathConfirmInd
nanDataPathConfirmInd_1_2;
NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd;
+
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -465,15 +469,14 @@
* Ensures that an instance of the IWifiNanIface proxy object is
* successfully created.
*/
-TEST(WifiNanIfaceHidlTestNoFixture, Create) {
- ASSERT_NE(nullptr, getWifiNanIface_1_2().get());
- stopWifi();
+TEST_P(WifiNanIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
}
/*
* enableRequest_1_2InvalidArgs: validate that fails with invalid arguments
*/
-TEST_F(WifiNanIfaceHidlTest, enableRequest_1_2InvalidArgs) {
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_2InvalidArgs) {
uint16_t inputCmdId = 10;
callbackType = INVALID;
NanEnableRequest nanEnableRequest = {};
@@ -493,7 +496,7 @@
* enableRequest_1_2ShimInvalidArgs: validate that fails with invalid arguments
* to the shim
*/
-TEST_F(WifiNanIfaceHidlTest, enableRequest_1_2ShimInvalidArgs) {
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_2ShimInvalidArgs) {
uint16_t inputCmdId = 10;
NanEnableRequest nanEnableRequest = {};
nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon =
@@ -508,7 +511,7 @@
/*
* configRequest_1_2InvalidArgs: validate that fails with invalid arguments
*/
-TEST_F(WifiNanIfaceHidlTest, configRequest_1_2InvalidArgs) {
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_2InvalidArgs) {
uint16_t inputCmdId = 10;
callbackType = INVALID;
NanConfigRequest nanConfigRequest = {};
@@ -528,7 +531,7 @@
* configRequest_1_2ShimInvalidArgs: validate that fails with invalid arguments
* to the shim
*/
-TEST_F(WifiNanIfaceHidlTest, configRequest_1_2ShimInvalidArgs) {
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_2ShimInvalidArgs) {
uint16_t inputCmdId = 10;
NanConfigRequest nanConfigRequest = {};
nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127
@@ -538,3 +541,9 @@
nanConfigRequest, nanConfigRequestSupp)
.code);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiNanIfaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_2::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp
index 92f5d14..1b907b2 100644
--- a/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -19,9 +19,11 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.2/IWifi.h>
#include <android/hardware/wifi/1.2/IWifiStaIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -34,14 +36,15 @@
/**
* Fixture to use for all STA Iface HIDL interface tests.
*/
-class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiStaIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_sta_iface_ = IWifiStaIface::castFrom(getWifiStaIface());
+ wifi_sta_iface_ =
+ IWifiStaIface::castFrom(getWifiStaIface(GetInstanceName()));
ASSERT_NE(nullptr, wifi_sta_iface_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) {
@@ -52,6 +55,9 @@
}
sp<IWifiStaIface> wifi_sta_iface_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -59,7 +65,7 @@
* Ensures that calls to set MAC address will return a success status
* code.
*/
-TEST_F(WifiStaIfaceHidlTest, SetMacAddress) {
+TEST_P(WifiStaIfaceHidlTest, SetMacAddress) {
const android::hardware::hidl_array<uint8_t, 6> kMac{
std::array<uint8_t, 6>{{0x12, 0x22, 0x33, 0x52, 0x10, 0x41}}};
EXPECT_EQ(WifiStatusCode::SUCCESS,
@@ -76,7 +82,7 @@
* TODO: We can't execute APF opcodes from this test because there's no way
* to loop test packets through the wifi firmware (b/73804303#comment29).
*/
-TEST_F(WifiStaIfaceHidlTest, DISABLED_ReadApfPacketFilterData) {
+TEST_P(WifiStaIfaceHidlTest, DISABLED_ReadApfPacketFilterData) {
if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::APF)) {
// Disable test if APF packet filer is not supported.
LOG(WARNING) << "TEST SKIPPED: APF packet filtering not supported";
@@ -107,3 +113,9 @@
EXPECT_EQ(status_and_data.second, data);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiStaIfaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_2::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.3/vts/functional/Android.bp b/wifi/1.3/vts/functional/Android.bp
index 9ffda8b..fe9c791 100644
--- a/wifi/1.3/vts/functional/Android.bp
+++ b/wifi/1.3/vts/functional/Android.bp
@@ -30,4 +30,6 @@
"android.hardware.wifi@1.3",
"libwifi-system-iface"
],
+ disable_framework: true,
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp b/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp
index faf426e..52c7a4a 100644
--- a/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp
+++ b/wifi/1.3/vts/functional/VtsHalWifiV1_3TargetTest.cpp
@@ -14,37 +14,8 @@
* limitations under the License.
*/
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.3/IWifi.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
-#include "wifi_hidl_test_utils.h"
-
-using ::android::hardware::wifi::V1_3::IWifi;
-
-// Test environment for Wifi HIDL HAL.
-class WifiHidlEnvironment_1_3 : public WifiHidlEnvironment {
- public:
- // get the test environment singleton
- static WifiHidlEnvironment_1_3* Instance() {
- static WifiHidlEnvironment_1_3* instance = new WifiHidlEnvironment_1_3;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<android::hardware::wifi::V1_3::IWifi>();
- }
-
- private:
- WifiHidlEnvironment_1_3() {}
-};
-
-WifiHidlEnvironment_1_3* gEnv = WifiHidlEnvironment_1_3::Instance();
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(gEnv);
- ::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
diff --git a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp
index d980fcb..db93967 100644
--- a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp
@@ -16,9 +16,11 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.3/IWifi.h>
#include <android/hardware/wifi/1.3/IWifiChip.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -39,14 +41,14 @@
/**
* Fixture to use for all Wifi chip HIDL interface tests.
*/
-class WifiChipHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_chip_ = IWifiChip::castFrom(getWifiChip());
+ wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
ASSERT_NE(nullptr, wifi_chip_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
// Helper function to configure the Chip in one of the supported modes.
@@ -70,6 +72,9 @@
}
sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -77,7 +82,7 @@
* This test case tests the setLatencyMode() API with
* Latency mode NORMAL
*/
-TEST_F(WifiChipHidlTest, SetLatencyMode_normal) {
+TEST_P(WifiChipHidlTest, SetLatencyMode_normal) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status =
HIDL_INVOKE(wifi_chip_, setLatencyMode, kLatencyModeNormal);
@@ -92,7 +97,7 @@
* SetLatencyMode_low
* This test case tests the setLatencyMode() API with Latency mode LOW
*/
-TEST_F(WifiChipHidlTest, SetLatencyMode_low) {
+TEST_P(WifiChipHidlTest, SetLatencyMode_low) {
uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
const auto& status =
HIDL_INVOKE(wifi_chip_, setLatencyMode, kLatencyModeLow);
@@ -106,7 +111,7 @@
/*
* GetCapabilities_1_3
*/
-TEST_F(WifiChipHidlTest, GetCapabilities_1_3) {
+TEST_P(WifiChipHidlTest, GetCapabilities_1_3) {
configureChipForIfaceType(IfaceType::STA, true);
const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities_1_3);
if (status_and_caps.first.code != WifiStatusCode::SUCCESS) {
@@ -116,3 +121,9 @@
}
EXPECT_NE(0u, status_and_caps.second);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiChipHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_3::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp
index d382f30..c5acc3c 100644
--- a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -19,9 +19,11 @@
#include <android-base/logging.h>
+#include <android/hardware/wifi/1.3/IWifi.h>
#include <android/hardware/wifi/1.3/IWifiStaIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -35,14 +37,15 @@
/**
* Fixture to use for all STA Iface HIDL interface tests.
*/
-class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiStaIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_sta_iface_ = IWifiStaIface::castFrom(getWifiStaIface());
+ wifi_sta_iface_ =
+ IWifiStaIface::castFrom(getWifiStaIface(GetInstanceName()));
ASSERT_NE(nullptr, wifi_sta_iface_.get());
}
- virtual void TearDown() override { stopWifi(); }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) {
@@ -53,6 +56,9 @@
}
sp<IWifiStaIface> wifi_sta_iface_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -60,7 +66,7 @@
* Ensures that calls to get factory MAC address will retrieve a non-zero MAC
* and return a success status code.
*/
-TEST_F(WifiStaIfaceHidlTest, GetFactoryMacAddress) {
+TEST_P(WifiStaIfaceHidlTest, GetFactoryMacAddress) {
std::pair<WifiStatus, hidl_array<uint8_t, 6> > status_and_mac =
HIDL_INVOKE(wifi_sta_iface_, getFactoryMacAddress);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_mac.first.code);
@@ -73,7 +79,7 @@
* Ensures that calls to get link layer stats V1_3 will retrieve a non-empty
* StaLinkLayerStats after link layer stats collection is enabled.
*/
-TEST_F(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) {
+TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) {
if (!isCapabilitySupported(
IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
// No-op if link layer stats is not supported.
@@ -94,3 +100,9 @@
WifiStatusCode::SUCCESS,
HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiStaIfaceHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_3::IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp
index e197859..b443230 100644
--- a/wifi/1.4/Android.bp
+++ b/wifi/1.4/Android.bp
@@ -11,8 +11,11 @@
"IWifi.hal",
"IWifiApIface.hal",
"IWifiChip.hal",
+ "IWifiChipEventCallback.hal",
+ "IWifiNanIface.hal",
"IWifiRttController.hal",
"IWifiRttControllerEventCallback.hal",
+ "IWifiStaIface.hal",
],
interfaces: [
"android.hardware.wifi@1.0",
diff --git a/wifi/1.4/IWifiChip.hal b/wifi/1.4/IWifiChip.hal
index d269427..07f4a65 100644
--- a/wifi/1.4/IWifiChip.hal
+++ b/wifi/1.4/IWifiChip.hal
@@ -19,6 +19,7 @@
import @1.0::WifiStatus;
import @1.0::IWifiIface;
import @1.3::IWifiChip;
+import IWifiChipEventCallback;
import IWifiRttController;
/**
@@ -26,6 +27,21 @@
*/
interface IWifiChip extends @1.3::IWifiChip {
/**
+ * Requests notifications of significant events on this chip. Multiple calls
+ * to this must register multiple callbacks each of which must receive all
+ * events.
+ *
+ * @param callback An instance of the |IWifiChipEventCallback| HIDL interface
+ * object.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+ */
+ registerEventCallback_1_4(IWifiChipEventCallback callback) generates (WifiStatus status);
+
+ /**
* Create a RTTController instance.
*
* RTT controller can be either:
diff --git a/wifi/1.4/IWifiChipEventCallback.hal b/wifi/1.4/IWifiChipEventCallback.hal
new file mode 100644
index 0000000..9ead344
--- /dev/null
+++ b/wifi/1.4/IWifiChipEventCallback.hal
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.2::IWifiChipEventCallback;
+import WifiBand;
+
+/**
+ * Wifi chip event callbacks.
+ */
+interface IWifiChipEventCallback extends @1.2::IWifiChipEventCallback {
+ /**
+ * Struct describing the state of each hardware radio chain (hardware MAC)
+ * on the device.
+ */
+ struct RadioModeInfo {
+ /**
+ * Identifier for this radio chain. This is vendor dependent & used
+ * only for debugging purposes.
+ */
+ uint32_t radioId;
+
+ /**
+ * List of bands on which this radio chain is operating.
+ * Can be one of:
+ * a) WifiBand.BAND_24GHZ => 2.4Ghz.
+ * b) WifiBand.BAND_5GHZ => 5Ghz.
+ * c) WifiBand.BAND_24GHZ_5GHZ = 2.4Ghz + 5Ghz (Radio is time sharing
+ * across the 2 bands).
+ * d) WifiBand.BAND_6GHZ => 6Ghz.
+ * e) WifiBand.BAND_5GHZ_6GHZ => 5Ghz + 6Ghz (Radio is time sharing
+ * across the 2 bands).
+ * f) WifiBand.BAND_24GHZ_5GHZ_6GHZ => 2.4Ghz + 5Ghz + 6Ghz (Radio is
+ * time sharing across the 3 bands).
+ */
+ WifiBand bandInfo;
+
+ /**
+ * List of interfaces on this radio chain (hardware MAC).
+ */
+ vec<IfaceInfo> ifaceInfos;
+ };
+
+ /**
+ * Asynchronous callback indicating a radio mode change.
+ * Radio mode change could be a result of:
+ * a) Bringing up concurrent interfaces (For ex: STA + AP).
+ * b) Change in operating band of one of the concurrent interfaces (For ex:
+ * STA connection moved from 2.4G to 5G)
+ *
+ * @param radioModeInfos List of RadioModeInfo structures for each
+ * radio chain (hardware MAC) on the device.
+ */
+ oneway onRadioModeChange_1_4(vec<RadioModeInfo> radioModeInfos);
+};
diff --git a/wifi/1.4/IWifiNanIface.hal b/wifi/1.4/IWifiNanIface.hal
new file mode 100644
index 0000000..881d06c
--- /dev/null
+++ b/wifi/1.4/IWifiNanIface.hal
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.0::CommandIdShort;
+import @1.0::WifiStatus;
+import @1.2::IWifiNanIface;
+import @1.2::NanConfigRequestSupplemental;
+import NanConfigRequest;
+import NanEnableRequest;
+
+/**
+ * Interface used to represent a single NAN (Neighbour Aware Network) iface.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+interface IWifiNanIface extends @1.2::IWifiNanIface {
+ /**
+ * Enable NAN: configures and activates NAN clustering (does not start
+ * a discovery session or set up data-interfaces or data-paths). Use the
+ * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled
+ * NAN interface.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|.
+ *
+ * Note: supersedes the @1.2::IWifiNanIface.enableRequest() method which is deprecated as of
+ * HAL version 1.4.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @param msg1 Instance of |NanEnableRequest|.
+ * @param msg2 Instance of |NanConfigRequestSupplemental|.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ enableRequest_1_4(CommandIdShort cmdId, NanEnableRequest msg1,
+ NanConfigRequestSupplemental msg2) generates (WifiStatus status);
+
+ /**
+ * Configure NAN: configures an existing NAN functionality (i.e. assumes
+ * |IWifiNanIface.enableRequest| already submitted and succeeded).
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|.
+ *
+ * Note: supersedes the @1.2::IWifiNanIface.configRequest() method which is deprecated as of
+ * HAL version 1.4.
+ *
+ * @param cmdId command Id to use for this invocation.
+ * @param msg1 Instance of |NanConfigRequest|.
+ * @param msg1 Instance of |NanConfigRequestSupplemental|.
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ configRequest_1_4(CommandIdShort cmdId, NanConfigRequest msg1,
+ NanConfigRequestSupplemental msg2) generates (WifiStatus status);
+};
diff --git a/wifi/1.4/IWifiStaIface.hal b/wifi/1.4/IWifiStaIface.hal
new file mode 100644
index 0000000..8bb0de8
--- /dev/null
+++ b/wifi/1.4/IWifiStaIface.hal
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.0::WifiStatus;
+import @1.0::MacAddress;
+import @1.0::IWifiStaIface;
+import @1.3::IWifiStaIface;
+
+/**
+ * Interface used to represent a single STA iface.
+ *
+ * IWifiChip.createStaIface() may return a @1.4::IWifiStaIface when supported.
+ */
+interface IWifiStaIface extends @1.3::IWifiStaIface {
+ enum StaIfaceCapabilityMask : @1.0::IWifiStaIface.StaIfaceCapabilityMask {
+ STA_6G = 1 << 15,
+ };
+
+ /**
+ * Get the capabilities supported by this STA iface.
+ *
+ * @return status WifiStatus of the operation.
+ * Possible status codes:
+ * |WifiStatusCode.SUCCESS|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ * @return capabilities Bitset of |StaIfaceCapabilityMask| values.
+ */
+ getCapabilities_1_4()
+ generates (WifiStatus status, bitfield<StaIfaceCapabilityMask> capabilities);
+};
diff --git a/wifi/1.4/default/hidl_struct_util.cpp b/wifi/1.4/default/hidl_struct_util.cpp
index 61f311e..a7c5686 100644
--- a/wifi/1.4/default/hidl_struct_util.cpp
+++ b/wifi/1.4/default/hidl_struct_util.cpp
@@ -91,7 +91,7 @@
}
IWifiStaIface::StaIfaceCapabilityMask
-convertLegacyFeatureToHidlStaIfaceCapability(uint32_t feature) {
+convertLegacyFeatureToHidlStaIfaceCapability(uint64_t feature) {
using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
switch (feature) {
case WIFI_FEATURE_GSCAN:
@@ -120,6 +120,8 @@
return HidlStaIfaceCaps::ND_OFFLOAD;
case WIFI_FEATURE_MKEEP_ALIVE:
return HidlStaIfaceCaps::KEEP_ALIVE;
+ case WIFI_FEATURE_INFRA_6G:
+ return HidlStaIfaceCaps::STA_6G;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -314,7 +316,7 @@
bool convertLegacyWifiMacInfoToHidl(
const legacy_hal::WifiMacInfo& legacy_mac_info,
- V1_2::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
+ IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
if (!hidl_radio_mode_info) {
return false;
}
@@ -323,8 +325,17 @@
hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
// Convert from bitmask of bands in the legacy HAL to enum value in
// the HIDL interface.
- if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
- legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) {
+ hidl_radio_mode_info->bandInfo = WifiBand::BAND_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ;
} else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ;
@@ -346,15 +357,14 @@
bool convertLegacyWifiMacInfosToHidl(
const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>*
- hidl_radio_mode_infos) {
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) {
if (!hidl_radio_mode_infos) {
return false;
}
*hidl_radio_mode_infos = {};
for (const auto& legacy_mac_info : legacy_mac_infos) {
- V1_2::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
+ IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info,
&hidl_radio_mode_info)) {
return false;
@@ -365,7 +375,7 @@
}
bool convertLegacyFeaturesToHidlStaCapabilities(
- uint32_t legacy_feature_set, uint32_t legacy_logger_feature_set,
+ uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set,
uint32_t* hidl_caps) {
if (!hidl_caps) {
return false;
@@ -384,7 +394,8 @@
WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO,
WIFI_FEATURE_TDLS, WIFI_FEATURE_TDLS_OFFCHANNEL,
- WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+ WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE,
+ WIFI_FEATURE_INFRA_6G}) {
if (feature & legacy_feature_set) {
*hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
}
@@ -446,21 +457,21 @@
return true;
}
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(WifiBand band) {
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) {
switch (band) {
- case WifiBand::BAND_UNSPECIFIED:
+ case V1_0::WifiBand::BAND_UNSPECIFIED:
return legacy_hal::WIFI_BAND_UNSPECIFIED;
- case WifiBand::BAND_24GHZ:
+ case V1_0::WifiBand::BAND_24GHZ:
return legacy_hal::WIFI_BAND_BG;
- case WifiBand::BAND_5GHZ:
+ case V1_0::WifiBand::BAND_5GHZ:
return legacy_hal::WIFI_BAND_A;
- case WifiBand::BAND_5GHZ_DFS:
+ case V1_0::WifiBand::BAND_5GHZ_DFS:
return legacy_hal::WIFI_BAND_A_DFS;
- case WifiBand::BAND_5GHZ_WITH_DFS:
+ case V1_0::WifiBand::BAND_5GHZ_WITH_DFS:
return legacy_hal::WIFI_BAND_A_WITH_DFS;
- case WifiBand::BAND_24GHZ_5GHZ:
+ case V1_0::WifiBand::BAND_24GHZ_5GHZ:
return legacy_hal::WIFI_BAND_ABG;
- case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+ case V1_0::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
};
CHECK(false);
@@ -1259,16 +1270,20 @@
hidl_request.debugConfigs
.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ /* TODO: b/145609058
+ * Missing updates needed to legacy_hal::NanEnableRequest and conversion to
+ * it for 6GHz band */
+
return true;
}
-bool convertHidlNanEnableRequest_1_2ToLegacy(
+bool convertHidlNanEnableRequest_1_4ToLegacy(
const NanEnableRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanEnableRequest* legacy_request) {
if (!legacy_request) {
LOG(ERROR)
- << "convertHidlNanEnableRequest_1_2ToLegacy: null legacy_request";
+ << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request";
return false;
}
@@ -1769,16 +1784,19 @@
legacy_request->config_dw.dw_5g_interval_val =
hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
.discoveryWindowIntervalVal;
+ /* TODO: b/145609058
+ * Missing updates needed to legacy_hal::NanConfigRequest and conversion to
+ * it for 6GHz band */
return true;
}
-bool convertHidlNanConfigRequest_1_2ToLegacy(
+bool convertHidlNanConfigRequest_1_4ToLegacy(
const NanConfigRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanConfigRequest* legacy_request) {
if (!legacy_request) {
- LOG(ERROR) << "convertHidlNanConfigRequest_1_2ToLegacy: legacy_request "
+ LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request "
"is null";
return false;
}
@@ -1819,7 +1837,13 @@
convertHidlNanDataPathChannelCfgToLegacy(
hidl_request.channelRequestType);
legacy_request->channel = hidl_request.channel;
- strcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str());
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(),
+ IFNAMSIZ + 1);
legacy_request->ndp_cfg.security_cfg =
(hidl_request.securityConfig.securityType !=
NanDataPathSecurityType::OPEN)
@@ -1900,7 +1924,13 @@
? legacy_hal::NAN_DP_REQUEST_ACCEPT
: legacy_hal::NAN_DP_REQUEST_REJECT;
legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
- strcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str());
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(),
+ IFNAMSIZ + 1);
legacy_request->ndp_cfg.security_cfg =
(hidl_request.securityConfig.securityType !=
NanDataPathSecurityType::OPEN)
diff --git a/wifi/1.4/default/hidl_struct_util.h b/wifi/1.4/default/hidl_struct_util.h
index a99c1ac..160870a 100644
--- a/wifi/1.4/default/hidl_struct_util.h
+++ b/wifi/1.4/default/hidl_struct_util.h
@@ -21,10 +21,11 @@
#include <android/hardware/wifi/1.0/IWifiChip.h>
#include <android/hardware/wifi/1.0/types.h>
-#include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
#include <android/hardware/wifi/1.2/types.h>
#include <android/hardware/wifi/1.3/IWifiChip.h>
#include <android/hardware/wifi/1.3/types.h>
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <android/hardware/wifi/1.4/IWifiStaIface.h>
#include <android/hardware/wifi/1.4/types.h>
#include "wifi_legacy_hal.h"
@@ -64,12 +65,11 @@
V1_2::IWifiChip::TxPowerScenario hidl_scenario);
bool convertLegacyWifiMacInfosToHidl(
const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>*
- hidl_radio_mode_infos);
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(
- uint32_t legacy_feature_set, uint32_t legacy_logger_feature_set,
+ uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set,
uint32_t* hidl_caps);
bool convertLegacyApfCapabilitiesToHidl(
const legacy_hal::PacketFilterCapabilities& legacy_caps,
@@ -77,7 +77,7 @@
bool convertLegacyGscanCapabilitiesToHidl(
const legacy_hal::wifi_gscan_capabilities& legacy_caps,
StaBackgroundScanCapabilities* hidl_caps);
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(WifiBand band);
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band);
bool convertHidlGscanParamsToLegacy(
const StaBackgroundScanParameters& hidl_scan_params,
legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
@@ -118,11 +118,11 @@
bool convertHidlNanConfigRequestToLegacy(
const NanConfigRequest& hidl_request,
legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanEnableRequest_1_2ToLegacy(
+bool convertHidlNanEnableRequest_1_4ToLegacy(
const NanEnableRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequest_1_2ToLegacy(
+bool convertHidlNanConfigRequest_1_4ToLegacy(
const NanConfigRequest& hidl_request1,
const V1_2::NanConfigRequestSupplemental& hidl_request2,
legacy_hal::NanConfigRequest* legacy_request);
diff --git a/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
index 14a1504..b71d549 100644
--- a/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp
@@ -55,8 +55,7 @@
legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
legacy_mac_infos.push_back(legacy_mac_info1);
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>
- hidl_radio_mode_infos;
+ std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
legacy_mac_infos, &hidl_radio_mode_infos));
@@ -90,20 +89,18 @@
legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
legacy_mac_infos.push_back(legacy_mac_info2);
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>
- hidl_radio_mode_infos;
+ std::vector<IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
legacy_mac_infos, &hidl_radio_mode_infos));
ASSERT_EQ(2u, hidl_radio_mode_infos.size());
// Find mac info 1.
- const auto hidl_radio_mode_info1 =
- std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
- [&legacy_mac_info1](
- const V1_2::IWifiChipEventCallback::RadioModeInfo& x) {
- return x.radioId == legacy_mac_info1.wlan_mac_id;
- });
+ const auto hidl_radio_mode_info1 = std::find_if(
+ hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+ [&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return x.radioId == legacy_mac_info1.wlan_mac_id;
+ });
ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1);
EXPECT_EQ(WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo);
ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size());
@@ -113,12 +110,11 @@
hidl_iface_info1.channel);
// Find mac info 2.
- const auto hidl_radio_mode_info2 =
- std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
- [&legacy_mac_info2](
- const V1_2::IWifiChipEventCallback::RadioModeInfo& x) {
- return x.radioId == legacy_mac_info2.wlan_mac_id;
- });
+ const auto hidl_radio_mode_info2 = std::find_if(
+ hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+ [&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return x.radioId == legacy_mac_info2.wlan_mac_id;
+ });
ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2);
EXPECT_EQ(WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo);
ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size());
diff --git a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
index 90e81e1..d35adbc 100644
--- a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
@@ -720,13 +720,16 @@
ASSERT_EQ(iface_names[0], "wlan0");
});
// Retrieve the exact iface object.
- sp<IWifiNanIface> nan_iface;
- chip_->getNanIface("wlan0", [&nan_iface](const WifiStatus& status,
- const sp<IWifiNanIface>& iface) {
- ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
- ASSERT_NE(iface.get(), nullptr);
- nan_iface = iface;
- });
+ sp<android::hardware::wifi::V1_0::IWifiNanIface> nan_iface;
+ chip_->getNanIface(
+ "wlan0",
+ [&nan_iface](
+ const WifiStatus& status,
+ const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ ASSERT_NE(iface.get(), nullptr);
+ nan_iface = iface;
+ });
// Remove the STA iface.
removeIface(IfaceType::STA, "wlan0");
diff --git a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
index 8aefa92..9022792 100644
--- a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -41,6 +41,9 @@
namespace V1_4 {
namespace implementation {
+using android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback;
+using android::hardware::wifi::V1_2::NanDataPathConfirmInd;
+
bool CaptureIfaceEventHandlers(
const std::string& /* iface_name*/,
iface_util::IfaceEventHandlers in_iface_event_handlers,
@@ -96,9 +99,15 @@
Return<void>(uint16_t, const WifiNanStatus&));
MOCK_METHOD1(eventDataPathRequest,
Return<void>(const NanDataPathRequestInd&));
- MOCK_METHOD1(eventDataPathConfirm,
- Return<void>(const NanDataPathConfirmInd&));
+ MOCK_METHOD1(
+ eventDataPathConfirm,
+ Return<void>(
+ const android::hardware::wifi::V1_0::NanDataPathConfirmInd&));
MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
+ MOCK_METHOD1(eventDataPathConfirm_1_2,
+ Return<void>(const NanDataPathConfirmInd&));
+ MOCK_METHOD1(eventDataPathScheduleUpdate,
+ Return<void>(const NanDataPathScheduleUpdateInd&));
};
class WifiNanIfaceTest : public Test {
diff --git a/wifi/1.4/default/wifi_ap_iface.cpp b/wifi/1.4/default/wifi_ap_iface.cpp
index e677f19..8777a4c 100644
--- a/wifi/1.4/default/wifi_ap_iface.cpp
+++ b/wifi/1.4/default/wifi_ap_iface.cpp
@@ -64,7 +64,7 @@
}
Return<void> WifiApIface::getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+ V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiApIface::getValidFrequenciesForBandInternal,
hidl_status_cb, band);
@@ -100,7 +100,7 @@
}
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiApIface::getValidFrequenciesForBandInternal(WifiBand band) {
+WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
"Size mismatch");
legacy_hal::wifi_error legacy_status;
diff --git a/wifi/1.4/default/wifi_ap_iface.h b/wifi/1.4/default/wifi_ap_iface.h
index 4f3438c..bf16d5e 100644
--- a/wifi/1.4/default/wifi_ap_iface.h
+++ b/wifi/1.4/default/wifi_ap_iface.h
@@ -49,7 +49,8 @@
Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
setCountryCode_cb hidl_status_cb) override;
Return<void> getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) override;
+ V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) override;
Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
setMacAddress_cb hidl_status_cb) override;
Return<void> getFactoryMacAddress(
@@ -61,7 +62,7 @@
std::pair<WifiStatus, IfaceType> getTypeInternal();
WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
- getValidFrequenciesForBandInternal(WifiBand band);
+ getValidFrequenciesForBandInternal(V1_0::WifiBand band);
WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
std::pair<WifiStatus, std::array<uint8_t, 6>>
getFactoryMacAddressInternal();
diff --git a/wifi/1.4/default/wifi_chip.cpp b/wifi/1.4/default/wifi_chip.cpp
index 7685ac6..2b015d3 100644
--- a/wifi/1.4/default/wifi_chip.cpp
+++ b/wifi/1.4/default/wifi_chip.cpp
@@ -341,7 +341,7 @@
bool WifiChip::isValid() { return is_valid_; }
-std::set<sp<V1_2::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
+std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
return event_cb_handler_.getCallbacks();
}
@@ -628,6 +628,14 @@
hidl_status_cb, bound_iface);
}
+Return<void> WifiChip::registerEventCallback_1_4(
+ const sp<IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal_1_4,
+ hidl_status_cb, event_callback);
+}
+
void WifiChip::invalidateAndRemoveAllIfaces() {
invalidateAndClearAll(ap_ifaces_);
invalidateAndClearAll(nan_ifaces_);
@@ -1021,6 +1029,12 @@
max_interval_in_sec, min_data_size_in_bytes);
ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
ring_name, Ringbuffer(kMaxBufferSizeBytes)));
+ // if verbose logging enabled, turn up HAL daemon logging as well.
+ if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
+ android::base::SetMinimumLogSeverity(android::base::DEBUG);
+ } else {
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ }
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1119,11 +1133,9 @@
}
WifiStatus WifiChip::registerEventCallbackInternal_1_2(
- const sp<V1_2::IWifiChipEventCallback>& event_callback) {
- if (!event_cb_handler_.addCallback(event_callback)) {
- return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
- }
- return createWifiStatus(WifiStatusCode::SUCCESS);
+ const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
+ // Deprecated support for this callback.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
@@ -1173,6 +1185,14 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
}
+WifiStatus WifiChip::registerEventCallbackInternal_1_4(
+ const sp<IWifiChipEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
WifiStatus WifiChip::handleChipConfiguration(
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
ChipModeId mode_id) {
@@ -1275,7 +1295,7 @@
LOG(ERROR) << "Callback invoked on an invalid object";
return;
}
- std::vector<V1_2::IWifiChipEventCallback::RadioModeInfo>
+ std::vector<IWifiChipEventCallback::RadioModeInfo>
hidl_radio_mode_infos;
if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
mac_infos, &hidl_radio_mode_infos)) {
@@ -1283,9 +1303,9 @@
return;
}
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
- if (!callback->onRadioModeChange(hidl_radio_mode_infos)
+ if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos)
.isOk()) {
- LOG(ERROR) << "Failed to invoke onRadioModeChange"
+ LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
<< " callback on: " << toString(callback);
}
}
diff --git a/wifi/1.4/default/wifi_chip.h b/wifi/1.4/default/wifi_chip.h
index 3bf1847..c76eabf 100644
--- a/wifi/1.4/default/wifi_chip.h
+++ b/wifi/1.4/default/wifi_chip.h
@@ -71,7 +71,7 @@
// marked valid before processing them.
void invalidate();
bool isValid();
- std::set<sp<V1_2::IWifiChipEventCallback>> getEventCallbacks();
+ std::set<sp<IWifiChipEventCallback>> getEventCallbacks();
// HIDL methods exposed.
Return<void> getId(getId_cb hidl_status_cb) override;
@@ -156,6 +156,9 @@
Return<void> createRttController_1_4(
const sp<IWifiIface>& bound_iface,
createRttController_1_4_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_4(
+ const sp<IWifiChipEventCallback>& event_callback,
+ registerEventCallback_1_4_cb hidl_status_cb) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -223,6 +226,9 @@
std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
std::pair<WifiStatus, sp<IWifiRttController>>
createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface);
+ WifiStatus registerEventCallbackInternal_1_4(
+ const sp<IWifiChipEventCallback>& event_callback);
+
WifiStatus handleChipConfiguration(
std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
WifiStatus registerDebugRingBufferCallback();
@@ -271,7 +277,7 @@
// registration mechanism. Use this to check if we have already
// registered a callback.
bool debug_ring_buffer_cb_registered_;
- hidl_callback_util::HidlCallbackHandler<V1_2::IWifiChipEventCallback>
+ hidl_callback_util::HidlCallbackHandler<IWifiChipEventCallback>
event_cb_handler_;
DISALLOW_COPY_AND_ASSIGN(WifiChip);
diff --git a/wifi/1.4/default/wifi_legacy_hal.cpp b/wifi/1.4/default/wifi_legacy_hal.cpp
index 8139253..ae3c447 100644
--- a/wifi/1.4/default/wifi_legacy_hal.cpp
+++ b/wifi/1.4/default/wifi_legacy_hal.cpp
@@ -479,7 +479,7 @@
std::pair<wifi_error, uint32_t> WifiLegacyHal::getSupportedFeatureSet(
const std::string& iface_name) {
feature_set set;
- static_assert(sizeof(set) == sizeof(uint32_t),
+ static_assert(sizeof(set) == sizeof(uint64_t),
"Some feature_flags can not be represented in output");
wifi_error status = global_func_table_.wifi_get_supported_feature_set(
getIfaceHandle(iface_name), &set);
diff --git a/wifi/1.4/default/wifi_nan_iface.cpp b/wifi/1.4/default/wifi_nan_iface.cpp
index 981acb2..073101c 100644
--- a/wifi/1.4/default/wifi_nan_iface.cpp
+++ b/wifi/1.4/default/wifi_nan_iface.cpp
@@ -576,7 +576,7 @@
}
Return<void> WifiNanIface::enableRequest(uint16_t cmd_id,
- const NanEnableRequest& msg,
+ const V1_0::NanEnableRequest& msg,
enableRequest_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiNanIface::enableRequestInternal, hidl_status_cb,
@@ -584,7 +584,7 @@
}
Return<void> WifiNanIface::configRequest(uint16_t cmd_id,
- const NanConfigRequest& msg,
+ const V1_0::NanConfigRequest& msg,
configRequest_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiNanIface::configRequestInternal, hidl_status_cb,
@@ -687,7 +687,7 @@
}
Return<void> WifiNanIface::enableRequest_1_2(
- uint16_t cmd_id, const NanEnableRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
enableRequest_1_2_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
@@ -696,7 +696,7 @@
}
Return<void> WifiNanIface::configRequest_1_2(
- uint16_t cmd_id, const NanConfigRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
configRequest_1_2_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
@@ -704,6 +704,24 @@
hidl_status_cb, cmd_id, msg1, msg2);
}
+Return<void> WifiNanIface::enableRequest_1_4(
+ uint16_t cmd_id, const NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_4Internal,
+ hidl_status_cb, cmd_id, msg1, msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_4(
+ uint16_t cmd_id, const NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_4Internal,
+ hidl_status_cb, cmd_id, msg1, msg2);
+}
+
std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
}
@@ -727,12 +745,12 @@
}
WifiStatus WifiNanIface::enableRequestInternal(
- uint16_t /* cmd_id */, const NanEnableRequest& /* msg */) {
+ uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg */) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
WifiStatus WifiNanIface::configRequestInternal(
- uint16_t /* cmd_id */, const NanConfigRequest& /* msg */) {
+ uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg */) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
@@ -855,10 +873,22 @@
}
WifiStatus WifiNanIface::enableRequest_1_2Internal(
+ uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /*msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_2Internal(
+ uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_4Internal(
uint16_t cmd_id, const NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2) {
legacy_hal::NanEnableRequest legacy_msg;
- if (!hidl_struct_util::convertHidlNanEnableRequest_1_2ToLegacy(
+ if (!hidl_struct_util::convertHidlNanEnableRequest_1_4ToLegacy(
msg1, msg2, &legacy_msg)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
@@ -867,11 +897,11 @@
return createWifiStatusFromLegacyError(legacy_status);
}
-WifiStatus WifiNanIface::configRequest_1_2Internal(
+WifiStatus WifiNanIface::configRequest_1_4Internal(
uint16_t cmd_id, const NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2) {
legacy_hal::NanConfigRequest legacy_msg;
- if (!hidl_struct_util::convertHidlNanConfigRequest_1_2ToLegacy(
+ if (!hidl_struct_util::convertHidlNanConfigRequest_1_4ToLegacy(
msg1, msg2, &legacy_msg)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
diff --git a/wifi/1.4/default/wifi_nan_iface.h b/wifi/1.4/default/wifi_nan_iface.h
index e3a5c34..c16628b 100644
--- a/wifi/1.4/default/wifi_nan_iface.h
+++ b/wifi/1.4/default/wifi_nan_iface.h
@@ -19,7 +19,7 @@
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifiNanIfaceEventCallback.h>
-#include <android/hardware/wifi/1.2/IWifiNanIface.h>
+#include <android/hardware/wifi/1.4/IWifiNanIface.h>
#include "hidl_callback_util.h"
#include "wifi_iface_util.h"
@@ -31,11 +31,12 @@
namespace V1_4 {
namespace implementation {
using namespace android::hardware::wifi::V1_0;
+using namespace android::hardware::wifi::V1_2;
/**
* HIDL interface object used to control a NAN Iface instance.
*/
-class WifiNanIface : public V1_2::IWifiNanIface {
+class WifiNanIface : public V1_4::IWifiNanIface {
public:
WifiNanIface(const std::string& ifname,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
@@ -53,9 +54,11 @@
registerEventCallback_cb hidl_status_cb) override;
Return<void> getCapabilitiesRequest(
uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override;
- Return<void> enableRequest(uint16_t cmd_id, const NanEnableRequest& msg,
+ Return<void> enableRequest(uint16_t cmd_id,
+ const V1_0::NanEnableRequest& msg,
enableRequest_cb hidl_status_cb) override;
- Return<void> configRequest(uint16_t cmd_id, const NanConfigRequest& msg,
+ Return<void> configRequest(uint16_t cmd_id,
+ const V1_0::NanConfigRequest& msg,
configRequest_cb hidl_status_cb) override;
Return<void> disableRequest(uint16_t cmd_id,
disableRequest_cb hidl_status_cb) override;
@@ -94,10 +97,18 @@
const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
registerEventCallback_1_2_cb hidl_status_cb) override;
Return<void> enableRequest_1_2(
- uint16_t cmd_id, const NanEnableRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
enableRequest_1_2_cb hidl_status_cb) override;
Return<void> configRequest_1_2(
+ uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_2_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_4(
+ uint16_t cmd_id, const NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_2_cb hidl_status_cb) override;
+ Return<void> configRequest_1_4(
uint16_t cmd_id, const NanConfigRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2,
configRequest_1_2_cb hidl_status_cb) override;
@@ -110,9 +121,9 @@
const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
WifiStatus enableRequestInternal(uint16_t cmd_id,
- const NanEnableRequest& msg);
+ const V1_0::NanEnableRequest& msg);
WifiStatus configRequestInternal(uint16_t cmd_id,
- const NanConfigRequest& msg);
+ const V1_0::NanConfigRequest& msg);
WifiStatus disableRequestInternal(uint16_t cmd_id);
WifiStatus startPublishRequestInternal(uint16_t cmd_id,
const NanPublishRequest& msg);
@@ -136,9 +147,15 @@
WifiStatus registerEventCallback_1_2Internal(
const sp<V1_2::IWifiNanIfaceEventCallback>& callback);
WifiStatus enableRequest_1_2Internal(
- uint16_t cmd_id, const NanEnableRequest& msg1,
+ uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
const V1_2::NanConfigRequestSupplemental& msg2);
WifiStatus configRequest_1_2Internal(
+ uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus enableRequest_1_4Internal(
+ uint16_t cmd_id, const NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_4Internal(
uint16_t cmd_id, const NanConfigRequest& msg,
const V1_2::NanConfigRequestSupplemental& msg2);
diff --git a/wifi/1.4/default/wifi_sta_iface.cpp b/wifi/1.4/default/wifi_sta_iface.cpp
index 3e0127e..68c989d 100644
--- a/wifi/1.4/default/wifi_sta_iface.cpp
+++ b/wifi/1.4/default/wifi_sta_iface.cpp
@@ -113,7 +113,7 @@
}
Return<void> WifiStaIface::getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+ V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiStaIface::getValidFrequenciesForBandInternal,
hidl_status_cb, band);
@@ -266,6 +266,13 @@
hidl_status_cb);
}
+Return<void> WifiStaIface::getCapabilities_1_4(
+ getCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getCapabilitiesInternal_1_4,
+ hidl_status_cb);
+}
+
std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
}
@@ -283,26 +290,7 @@
}
std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
- legacy_hal::wifi_error legacy_status;
- uint32_t legacy_feature_set;
- std::tie(legacy_status, legacy_feature_set) =
- legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
- if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- return {createWifiStatusFromLegacyError(legacy_status), 0};
- }
- uint32_t legacy_logger_feature_set;
- std::tie(legacy_status, legacy_logger_feature_set) =
- legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
- if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- // some devices don't support querying logger feature set
- legacy_logger_feature_set = 0;
- }
- uint32_t hidl_caps;
- if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
- legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
- return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
- }
- return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
}
std::pair<WifiStatus, StaApfPacketFilterCapabilities>
@@ -356,7 +344,7 @@
}
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiStaIface::getValidFrequenciesForBandInternal(WifiBand band) {
+WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
"Size mismatch");
legacy_hal::wifi_error legacy_status;
@@ -640,6 +628,29 @@
return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
}
+std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal_1_4() {
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), 0};
+ }
+ uint32_t legacy_logger_feature_set;
+ std::tie(legacy_status, legacy_logger_feature_set) =
+ legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // some devices don't support querying logger feature set
+ legacy_logger_feature_set = 0;
+ }
+ uint32_t hidl_caps;
+ if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
+ legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
} // namespace implementation
} // namespace V1_4
} // namespace wifi
diff --git a/wifi/1.4/default/wifi_sta_iface.h b/wifi/1.4/default/wifi_sta_iface.h
index d8f7a01..e85e39d 100644
--- a/wifi/1.4/default/wifi_sta_iface.h
+++ b/wifi/1.4/default/wifi_sta_iface.h
@@ -19,7 +19,7 @@
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
-#include <android/hardware/wifi/1.3/IWifiStaIface.h>
+#include <android/hardware/wifi/1.4/IWifiStaIface.h>
#include "hidl_callback_util.h"
#include "wifi_iface_util.h"
@@ -35,7 +35,7 @@
/**
* HIDL interface object used to control a STA Iface instance.
*/
-class WifiStaIface : public V1_3::IWifiStaIface {
+class WifiStaIface : public V1_4::IWifiStaIface {
public:
WifiStaIface(const std::string& ifname,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
@@ -63,7 +63,8 @@
Return<void> getBackgroundScanCapabilities(
getBackgroundScanCapabilities_cb hidl_status_cb) override;
Return<void> getValidFrequenciesForBand(
- WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) override;
+ V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) override;
Return<void> startBackgroundScan(
uint32_t cmd_id, const StaBackgroundScanParameters& params,
startBackgroundScan_cb hidl_status_cb) override;
@@ -111,6 +112,8 @@
setMacAddress_cb hidl_status_cb) override;
Return<void> getFactoryMacAddress(
getFactoryMacAddress_cb hidl_status_cb) override;
+ Return<void> getCapabilities_1_4(
+ getCapabilities_1_4_cb hidl_status_cb) override;
private:
// Corresponding worker functions for the HIDL methods.
@@ -128,7 +131,7 @@
std::pair<WifiStatus, StaBackgroundScanCapabilities>
getBackgroundScanCapabilitiesInternal();
std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
- getValidFrequenciesForBandInternal(WifiBand band);
+ getValidFrequenciesForBandInternal(V1_0::WifiBand band);
WifiStatus startBackgroundScanInternal(
uint32_t cmd_id, const StaBackgroundScanParameters& params);
WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
@@ -159,6 +162,7 @@
WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
std::pair<WifiStatus, std::array<uint8_t, 6>>
getFactoryMacAddressInternal();
+ std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_4();
std::string ifname_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
diff --git a/wifi/1.4/types.hal b/wifi/1.4/types.hal
index 232e26f..4f1d22e 100644
--- a/wifi/1.4/types.hal
+++ b/wifi/1.4/types.hal
@@ -17,6 +17,8 @@
package android.hardware.wifi@1.4;
import @1.0::MacAddress;
+import @1.0::NanBandIndex;
+import @1.0::NanBandSpecificConfig;
import @1.0::Rssi;
import @1.0::RttBw;
import @1.0::RttConfig;
@@ -26,13 +28,47 @@
import @1.0::RttType;
import @1.0::TimeSpanInPs;
import @1.0::TimeStampInUs;
+import @1.0::WifiBand;
import @1.0::WifiChannelInfo;
+import @1.0::WifiChannelInMhz;
import @1.0::WifiChannelWidthInMhz;
import @1.0::WifiInformationElement;
import @1.0::WifiRateNss;
import @1.0::WifiRatePreamble;
/**
+ * Wifi bands defined in 80211 spec.
+ */
+enum WifiBand : @1.0::WifiBand {
+ /**
+ * 6 GHz.
+ */
+ BAND_6GHZ = 8,
+ /**
+ * 5 GHz no DFS + 6 GHz.
+ */
+ BAND_5GHZ_6GHZ = 10,
+ /**
+ * 2.4 GHz + 5 GHz no DFS + 6 GHz.
+ */
+ BAND_24GHZ_5GHZ_6GHZ = 11,
+ /**
+ * 2.4 GHz + 5 GHz with DFS + 6 GHz.
+ */
+ BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+};
+
+/**
+ * The discovery bands supported by NAN.
+ */
+enum NanBandIndex : @1.0::NanBandIndex {
+ /**
+ * Index for 6 GHz band.
+ */
+ NAN_BAND_6GHZ = 2,
+};
+
+/**
* Wifi Rate Preamble
*/
enum WifiRatePreamble : @1.0::WifiRatePreamble {
@@ -53,6 +89,183 @@
};
/**
+ * Debug configuration parameters. Many of these allow non-standard-compliant operation and are
+ * not intended for normal operational mode.
+ */
+struct NanDebugConfig {
+ /**
+ * Specification of the lower 2 bytes of the cluster ID. The cluster ID is 50-60-9a-01-00-00 to
+ * 50-60-9a-01-FF-FF. Configuration of the bottom and top values of the range (which defaults to
+ * 0x0000 and 0xFFFF respectively).
+ * Configuration is only used if |validClusterIdVals| is set to true.
+ */
+ bool validClusterIdVals;
+
+ uint16_t clusterIdBottomRangeVal;
+
+ uint16_t clusterIdTopRangeVal;
+
+ /**
+ * NAN management interface address, if specified (|validIntfAddrVal| is true) then overrides any
+ * other configuration (specifically the default randomization configured by
+ * |NanConfigRequest.macAddressRandomizationIntervalSec|).
+ */
+ bool validIntfAddrVal;
+
+ MacAddress intfAddrVal;
+
+ /**
+ * Combination of the 24 bit Organizationally Unique ID (OUI) and the 8 bit OUI Type.
+ * Used if |validOuiVal| is set to true.
+ */
+ bool validOuiVal;
+
+ uint32_t ouiVal;
+
+ /**
+ * Force the Random Factor to the specified value for all transmitted Sync/Discovery beacons.
+ * Used if |validRandomFactorForceVal| is set to true.
+ * NAN Spec: Master Indication Attribute / Random Factor
+ */
+ bool validRandomFactorForceVal;
+
+ uint8_t randomFactorForceVal;
+
+ /**
+ * Forces the hop-count for all transmitted Sync and Discovery Beacons NO matter the real
+ * hop-count being received over the air. Used if the |validHopCountForceVal}| flag is set to
+ * true.
+ * NAN Spec: Cluster Attribute / Anchor Master Information / Hop Count to Anchor Master
+ */
+ bool validHopCountForceVal;
+
+ uint8_t hopCountForceVal;
+
+ /**
+ * Frequency in MHz to of the discovery channel in the specified band. Indexed by |NanBandIndex|.
+ * Used if the |validDiscoveryChannelVal| is set to true.
+ */
+ bool validDiscoveryChannelVal;
+
+ WifiChannelInMhz[3] discoveryChannelMhzVal;
+
+ /**
+ * Specifies whether sync/discovery beacons are transmitted in the specified band. Indexed by
+ * |NanBandIndex|. Used if the |validUseBeaconsInBandVal| is set to true.
+ */
+ bool validUseBeaconsInBandVal;
+
+ bool[3] useBeaconsInBandVal;
+
+ /**
+ * Specifies whether SDF (service discovery frames) are transmitted in the specified band. Indexed
+ * by |NanBandIndex|. Used if the |validUseSdfInBandVal| is set to true.
+ */
+ bool validUseSdfInBandVal;
+
+ bool[3] useSdfInBandVal;
+};
+
+/**
+ * Configuration parameters of NAN: used when enabling and re-configuring a NAN cluster.
+ */
+struct NanConfigRequest {
+ /**
+ * Master preference of this device.
+ * NAN Spec: Master Indication Attribute / Master Preference
+ */
+ uint8_t masterPref;
+
+ /**
+ * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+ * for |NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED|.
+ */
+ bool disableDiscoveryAddressChangeIndication;
+
+ /**
+ * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+ * for |NanClusterEventType.STARTED_CLUSTER|.
+ */
+ bool disableStartedClusterIndication;
+
+ /**
+ * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+ * for |NanClusterEventType.JOINED_CLUSTER|.
+ */
+ bool disableJoinedClusterIndication;
+
+ /**
+ * Control whether publish service IDs are included in Sync/Discovery beacons.
+ * NAN Spec: Service ID List Attribute
+ */
+ bool includePublishServiceIdsInBeacon;
+
+ /**
+ * If |includePublishServiceIdsInBeacon| is true then specifies the number of publish service IDs
+ * to include in the Sync/Discovery beacons:
+ * Value = 0: include as many service IDs as will fit into the maximum allowed beacon frame size.
+ * Value must fit within 7 bits - i.e. <= 127.
+ */
+ uint8_t numberOfPublishServiceIdsInBeacon;
+
+ /**
+ * Control whether subscribe service IDs are included in Sync/Discovery beacons.
+ * Spec: Subscribe Service ID List Attribute
+ */
+ bool includeSubscribeServiceIdsInBeacon;
+
+ /**
+ * If |includeSubscribeServiceIdsInBeacon| is true then specifies the number of subscribe service
+ * IDs to include in the Sync/Discovery beacons:
+ * Value = 0: include as many service IDs as will fit into the maximum allowed beacon frame size.
+ * Value must fit within 7 bits - i.e. <= 127.
+ */
+ uint8_t numberOfSubscribeServiceIdsInBeacon;
+
+ /**
+ * Number of samples used to calculate RSSI.
+ */
+ uint16_t rssiWindowSize;
+
+ /**
+ * Specifies the interval in seconds that the NAN management interface MAC address is randomized.
+ * A value of 0 is used to disable the MAC address randomization
+ */
+ uint32_t macAddressRandomizationIntervalSec;
+
+ /**
+ * Additional configuration provided per band: indexed by |NanBandIndex|.
+ */
+ NanBandSpecificConfig[3] bandSpecificConfig;
+};
+
+/**
+ * Enable requests for NAN: start-up configuration |IWifiNanIface.enableRequest|.
+ */
+struct NanEnableRequest {
+ /**
+ * Enable operation in a specific band: indexed by |NanBandIndex|.
+ */
+ bool[3] operateInBand;
+
+ /**
+ * Specify extent of cluster by specifying the max hop count.
+ */
+ uint8_t hopCountMax;
+
+ /**
+ * Configurations of NAN cluster operation. Can also be modified at run-time using
+ * |IWifiNanIface.configRequest|.
+ */
+ NanConfigRequest configParams;
+
+ /**
+ * Non-standard configurations of NAN cluster operation - useful for debugging operations.
+ */
+ NanDebugConfig debugConfigs;
+};
+
+/**
* RTT configuration.
*/
struct RttConfig {
diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp
index 215a810..46ac3ee 100644
--- a/wifi/1.4/vts/functional/Android.bp
+++ b/wifi/1.4/vts/functional/Android.bp
@@ -21,6 +21,8 @@
srcs: [
"VtsHalWifiV1_4TargetTest.cpp",
"wifi_ap_iface_hidl_test.cpp",
+ "wifi_chip_hidl_test.cpp",
+ "wifi_nan_iface_hidl_test.cpp"
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
@@ -31,4 +33,5 @@
"android.hardware.wifi@1.4",
"libwifi-system-iface"
],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/1.4/vts/functional/VtsHalWifiV1_4TargetTest.cpp b/wifi/1.4/vts/functional/VtsHalWifiV1_4TargetTest.cpp
index deac0fa..7e0f3cd 100644
--- a/wifi/1.4/vts/functional/VtsHalWifiV1_4TargetTest.cpp
+++ b/wifi/1.4/vts/functional/VtsHalWifiV1_4TargetTest.cpp
@@ -14,37 +14,8 @@
* limitations under the License.
*/
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.4/IWifi.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
-#include "wifi_hidl_test_utils.h"
-
-using ::android::hardware::wifi::V1_4::IWifi;
-
-// Test environment for Wifi HIDL HAL.
-class WifiHidlEnvironment_1_4 : public WifiHidlEnvironment {
- public:
- // get the test environment singleton
- static WifiHidlEnvironment_1_4* Instance() {
- static WifiHidlEnvironment_1_4* instance = new WifiHidlEnvironment_1_4;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<android::hardware::wifi::V1_4::IWifi>();
- }
-
- private:
- WifiHidlEnvironment_1_4() {}
-};
-
-WifiHidlEnvironment_1_4* gEnv = WifiHidlEnvironment_1_4::Instance();
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(gEnv);
- ::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
diff --git a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
index 68e9bbb..017ecb6 100644
--- a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
+++ b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -14,9 +14,11 @@
* limitations under the License.
*/
+#include <android/hardware/wifi/1.4/IWifi.h>
#include <android/hardware/wifi/1.4/IWifiApIface.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"
@@ -25,6 +27,7 @@
using ::android::hardware::hidl_array;
using ::android::hardware::wifi::V1_0::WifiStatus;
using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifi;
using ::android::hardware::wifi::V1_4::IWifiApIface;
extern WifiHidlEnvironment* gEnv;
@@ -32,19 +35,21 @@
/**
* Fixture to use for all STA Iface HIDL interface tests.
*/
-class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiApIfaceHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_ap_iface_ = IWifiApIface::castFrom(getWifiApIface());
+ wifi_ap_iface_ =
+ IWifiApIface::castFrom(getWifiApIface(GetInstanceName()));
ASSERT_NE(nullptr, wifi_ap_iface_.get());
}
- virtual void TearDown() override {
- stopWifi();
- }
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
protected:
sp<IWifiApIface> wifi_ap_iface_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
};
/*
@@ -52,7 +57,7 @@
* Ensures that calls to set MAC address will return a success status
* code.
*/
-TEST_F(WifiApIfaceHidlTest, SetMacAddress) {
+TEST_P(WifiApIfaceHidlTest, SetMacAddress) {
const hidl_array<uint8_t, 6> kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x41}};
EXPECT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(wifi_ap_iface_, setMacAddress, kMac).code);
@@ -63,10 +68,16 @@
* Ensures that calls to get factory MAC address will retrieve a non-zero MAC
* and return a success status code.
*/
-TEST_F(WifiApIfaceHidlTest, GetFactoryMacAddress) {
+TEST_P(WifiApIfaceHidlTest, GetFactoryMacAddress) {
std::pair<WifiStatus, hidl_array<uint8_t, 6> > status_and_mac =
HIDL_INVOKE(wifi_ap_iface_, getFactoryMacAddress);
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_mac.first.code);
hidl_array<uint8_t, 6> all_zero{};
EXPECT_NE(all_zero, status_and_mac.second);
}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiApIfaceHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..8ca5214
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+
+#undef NAN // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.4/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifiChip.h>
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifiChip;
+using ::android::hardware::wifi::V1_4::IWifiChipEventCallback;
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
+ ASSERT_NE(nullptr, wifi_chip_.get());
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ // A simple test implementation of WifiChipEventCallback.
+ class WifiChipEventCallback
+ : public ::testing::VtsHalHidlTargetCallbackBase<WifiChipHidlTest>,
+ public IWifiChipEventCallback {
+ public:
+ WifiChipEventCallback(){};
+
+ virtual ~WifiChipEventCallback() = default;
+
+ Return<void> onChipReconfigured(uint32_t modeId __unused) {
+ return Void();
+ };
+
+ Return<void> onChipReconfigureFailure(
+ const WifiStatus& status __unused) {
+ return Void();
+ };
+
+ Return<void> onIfaceAdded(IfaceType type __unused,
+ const hidl_string& name __unused) {
+ return Void();
+ };
+
+ Return<void> onIfaceRemoved(IfaceType type __unused,
+ const hidl_string& name __unused) {
+ return Void();
+ };
+
+ Return<void> onDebugRingBufferDataAvailable(
+ const WifiDebugRingBufferStatus& status __unused,
+ const hidl_vec<uint8_t>& data __unused) {
+ return Void();
+ };
+
+ Return<void> onDebugErrorAlert(int32_t errorCode __unused,
+ const hidl_vec<uint8_t>& debugData
+ __unused) {
+ return Void();
+ };
+
+ Return<void> onRadioModeChange(
+ const hidl_vec<::android::hardware::wifi::V1_2::
+ IWifiChipEventCallback::RadioModeInfo>&
+ radioModeInfos __unused) {
+ return Void();
+ };
+
+ Return<void> onRadioModeChange_1_4(
+ const hidl_vec<RadioModeInfo>& radioModeInfos __unused) {
+ return Void();
+ };
+ };
+
+ protected:
+ sp<IWifiChip> wifi_chip_;
+
+ private:
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+/*
+ * registerEventCallback_1_4
+ * This test case tests the registerEventCallback_1_4() API which registers
+ * a call back function with the hal implementation
+ *
+ * Note: it is not feasible to test the invocation of the call back function
+ * since event is triggered internally in the HAL implementation, and can not be
+ * triggered from the test case
+ */
+TEST_P(WifiChipHidlTest, registerEventCallback_1_4) {
+ sp<WifiChipEventCallback> wifiChipEventCallback =
+ new WifiChipEventCallback();
+ const auto& status = HIDL_INVOKE(wifi_chip_, registerEventCallback_1_4,
+ wifiChipEventCallback);
+
+ if (status.code != WifiStatusCode::SUCCESS) {
+ EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
+ return;
+ }
+}
diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
new file mode 100644
index 0000000..245e906
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Nanache 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.2/IWifiNanIfaceEventCallback.h>
+#include <android/hardware/wifi/1.4/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifiNanIface.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using namespace ::android::hardware::wifi::V1_0;
+using namespace ::android::hardware::wifi::V1_2;
+using namespace ::android::hardware::wifi::V1_4;
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+#define TIMEOUT_PERIOD 10
+
+android::sp<android::hardware::wifi::V1_4::IWifiNanIface> getWifiNanIface_1_4(
+ const std::string& instance_name) {
+ return android::hardware::wifi::V1_4::IWifiNanIface::castFrom(
+ getWifiNanIface(instance_name));
+}
+
+/**
+ * Fixture to use for all NAN Iface HIDL interface tests.
+ */
+class WifiNanIfaceHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ iwifiNanIface = getWifiNanIface_1_4(GetInstanceName());
+ ASSERT_NE(nullptr, iwifiNanIface.get());
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_2,
+ new WifiNanIfaceEventCallback(*this))
+ .code);
+ }
+
+ virtual void TearDown() override { stopWifi(GetInstanceName()); }
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ inline void notify() {
+ std::unique_lock<std::mutex> lock(mtx_);
+ count_++;
+ cv_.notify_one();
+ }
+
+ enum CallbackType {
+ INVALID = -2,
+ ANY_CALLBACK = -1,
+
+ NOTIFY_CAPABILITIES_RESPONSE = 0,
+ NOTIFY_ENABLE_RESPONSE,
+ NOTIFY_CONFIG_RESPONSE,
+ NOTIFY_DISABLE_RESPONSE,
+ NOTIFY_START_PUBLISH_RESPONSE,
+ NOTIFY_STOP_PUBLISH_RESPONSE,
+ NOTIFY_START_SUBSCRIBE_RESPONSE,
+ NOTIFY_STOP_SUBSCRIBE_RESPONSE,
+ NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
+ NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_INITIATE_DATA_PATH_RESPONSE,
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
+ NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
+
+ EVENT_CLUSTER_EVENT,
+ EVENT_DISABLED,
+ EVENT_PUBLISH_TERMINATED,
+ EVENT_SUBSCRIBE_TERMINATED,
+ EVENT_MATCH,
+ EVENT_MATCH_EXPIRED,
+ EVENT_FOLLOWUP_RECEIVED,
+ EVENT_TRANSMIT_FOLLOWUP,
+ EVENT_DATA_PATH_REQUEST,
+ EVENT_DATA_PATH_CONFIRM,
+ EVENT_DATA_PATH_TERMINATED,
+ EVENT_DATA_PATH_CONFIRM_1_2,
+ EVENT_DATA_PATH_SCHEDULE_UPDATE
+ };
+
+ /* Test code calls this function to wait for data/event callback */
+ /* Must set callbackType = INVALID before call this function */
+ inline std::cv_status wait(CallbackType waitForCallbackType) {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a
+ // non-void-returning method
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock,
+ now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) return status;
+ if (waitForCallbackType != ANY_CALLBACK &&
+ callbackType != INVALID &&
+ callbackType != waitForCallbackType) {
+ count_--;
+ }
+ }
+ count_--;
+ return status;
+ }
+
+ class WifiNanIfaceEventCallback
+ : public ::android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback {
+ WifiNanIfaceHidlTest& parent_;
+
+ public:
+ WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent)
+ : parent_(parent){};
+
+ virtual ~WifiNanIfaceEventCallback() = default;
+
+ Return<void> notifyCapabilitiesResponse(
+ uint16_t id, const WifiNanStatus& status,
+ const NanCapabilities& capabilities) override {
+ parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.capabilities = capabilities;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyEnableResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_ENABLE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyConfigResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_CONFIG_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyDisableResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_DISABLE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStartPublishResponse(uint16_t id,
+ const WifiNanStatus& status,
+ uint8_t sessionId) override {
+ parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.sessionId = sessionId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStopPublishResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStartSubscribeResponse(uint16_t id,
+ const WifiNanStatus& status,
+ uint8_t sessionId) override {
+ parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.sessionId = sessionId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyStopSubscribeResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyTransmitFollowupResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyCreateDataInterfaceResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyDeleteDataInterfaceResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyInitiateDataPathResponse(
+ uint16_t id, const WifiNanStatus& status,
+ uint32_t ndpInstanceId) override {
+ parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+ parent_.ndpInstanceId = ndpInstanceId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyRespondToDataPathIndicationResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType =
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> notifyTerminateDataPathResponse(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventClusterEvent(
+ const NanClusterEventInd& event) override {
+ parent_.callbackType = EVENT_CLUSTER_EVENT;
+
+ parent_.nanClusterEventInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDisabled(const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_DISABLED;
+
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventPublishTerminated(
+ uint8_t sessionId, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_PUBLISH_TERMINATED;
+
+ parent_.sessionId = sessionId;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventSubscribeTerminated(
+ uint8_t sessionId, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED;
+
+ parent_.sessionId = sessionId;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventMatch(const NanMatchInd& event) override {
+ parent_.callbackType = EVENT_MATCH;
+
+ parent_.nanMatchInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventMatchExpired(uint8_t discoverySessionId,
+ uint32_t peerId) override {
+ parent_.callbackType = EVENT_MATCH_EXPIRED;
+
+ parent_.sessionId = discoverySessionId;
+ parent_.peerId = peerId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventFollowupReceived(
+ const NanFollowupReceivedInd& event) override {
+ parent_.callbackType = EVENT_FOLLOWUP_RECEIVED;
+
+ parent_.nanFollowupReceivedInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventTransmitFollowup(
+ uint16_t id, const WifiNanStatus& status) override {
+ parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP;
+
+ parent_.id = id;
+ parent_.status = status;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathRequest(
+ const NanDataPathRequestInd& event) override {
+ parent_.callbackType = EVENT_DATA_PATH_REQUEST;
+
+ parent_.nanDataPathRequestInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathConfirm(
+ const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event)
+ override {
+ parent_.callbackType = EVENT_DATA_PATH_CONFIRM;
+
+ parent_.nanDataPathConfirmInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathTerminated(uint32_t ndpInstanceId) override {
+ parent_.callbackType = EVENT_DATA_PATH_TERMINATED;
+
+ parent_.ndpInstanceId = ndpInstanceId;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathConfirm_1_2(
+ const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event)
+ override {
+ parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2;
+
+ parent_.nanDataPathConfirmInd_1_2 = event;
+
+ parent_.notify();
+ return Void();
+ }
+
+ Return<void> eventDataPathScheduleUpdate(
+ const NanDataPathScheduleUpdateInd& event) override {
+ parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE;
+
+ parent_.nanDataPathScheduleUpdateInd = event;
+
+ parent_.notify();
+ return Void();
+ }
+ };
+
+ private:
+ // synchronization objects
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_;
+
+ protected:
+ android::sp<::android::hardware::wifi::V1_4::IWifiNanIface> iwifiNanIface;
+
+ // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of
+ // all arguments to all callbacks. They are set by the callback
+ // (notifications or events) and can be retrieved by tests.
+ CallbackType callbackType;
+ uint16_t id;
+ WifiNanStatus status;
+ NanCapabilities capabilities;
+ uint8_t sessionId;
+ uint32_t ndpInstanceId;
+ NanClusterEventInd nanClusterEventInd;
+ NanMatchInd nanMatchInd;
+ uint32_t peerId;
+ NanFollowupReceivedInd nanFollowupReceivedInd;
+ NanDataPathRequestInd nanDataPathRequestInd;
+ ::android::hardware::wifi::V1_0::NanDataPathConfirmInd
+ nanDataPathConfirmInd;
+ ::android::hardware::wifi::V1_2::NanDataPathConfirmInd
+ nanDataPathConfirmInd_1_2;
+ NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd;
+
+ std::string GetInstanceName() { return GetParam(); }
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiNanIface proxy object is
+ * successfully created.
+ */
+TEST_P(WifiNanIfaceHidlTest, Create) {
+ // The creation of a proxy object is tested as part of SetUp method.
+}
+
+/*
+ * enableRequest_1_4InvalidArgs: validate that fails with invalid arguments
+ */
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp)
+ .code);
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+ ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+ ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
+}
+
+/*
+ * enableRequest_1_4ShimInvalidArgs: validate that fails with invalid arguments
+ * to the shim
+ */
+TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4ShimInvalidArgs) {
+ uint16_t inputCmdId = 10;
+ ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {};
+ nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon =
+ 128; // must be <= 127
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
+ HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId,
+ nanEnableRequest, nanConfigRequestSupp)
+ .code);
+}
+
+/*
+ * configRequest_1_4InvalidArgs: validate that fails with invalid arguments
+ */
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_4InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callbackType = INVALID;
+ ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp)
+ .code);
+ // wait for a callback
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
+ ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType);
+ ASSERT_EQ(id, inputCmdId);
+ ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS);
+}
+
+/*
+ * configRequest_1_4ShimInvalidArgs: validate that fails with invalid arguments
+ * to the shim
+ */
+TEST_P(WifiNanIfaceHidlTest, configRequest_1_4ShimInvalidArgs) {
+ uint16_t inputCmdId = 10;
+ ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {};
+ nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS,
+ HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId,
+ nanConfigRequest, nanConfigRequestSupp)
+ .code);
+}
diff --git a/wifi/1.4/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_sta_iface_hidl_test.cpp
new file mode 100644
index 0000000..ec4b2c9
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.4/IWifiStaIface.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifiStaIface;
+
+/**
+ * Fixture to use for all STA Iface HIDL interface tests.
+ */
+class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ wifi_sta_iface_ = IWifiStaIface::castFrom(getWifiStaIface());
+ ASSERT_NE(nullptr, wifi_sta_iface_.get());
+ }
+
+ virtual void TearDown() override { stopWifi(); }
+
+ protected:
+ sp<IWifiStaIface> wifi_sta_iface_;
+};
+
+/*
+ * GetCapabilities_1_4
+ */
+TEST_F(WifiStaIfaceHidlTest, GetCapabilities_1_4) {
+ configureChipForIfaceType(IfaceType::STA, true);
+
+ const auto& status_and_caps =
+ HIDL_INVOKE(wifi_sta_iface_, getCapabilities_1_4);
+ if (status_and_caps.first.code != WifiStatusCode::SUCCESS) {
+ EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
+ status_and_caps.first.code);
+ return;
+ }
+ EXPECT_NE(0u, status_and_caps.second);
+}
diff --git a/wifi/hostapd/1.2/Android.bp b/wifi/hostapd/1.2/Android.bp
new file mode 100644
index 0000000..3dcad71
--- /dev/null
+++ b/wifi/hostapd/1.2/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.wifi.hostapd@1.2",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IHostapd.hal",
+ ],
+ interfaces: [
+ "android.hardware.wifi.hostapd@1.0",
+ "android.hardware.wifi.hostapd@1.1",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/wifi/hostapd/1.2/IHostapd.hal b/wifi/hostapd/1.2/IHostapd.hal
new file mode 100644
index 0000000..31ade13
--- /dev/null
+++ b/wifi/hostapd/1.2/IHostapd.hal
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.hostapd@1.2;
+
+import @1.1::IHostapd;
+import HostapdStatus;
+import MacAddress;
+import Ieee80211ReasonCode;
+
+/**
+ * Top-level object for managing SoftAPs.
+ */
+interface IHostapd extends @1.1::IHostapd {
+ /**
+ * force one of the hotspot clients disconnect..
+ *
+ * @param ifaceName Name of the interface.
+ * @param clientAddress Mac Address of the hotspot client.
+ * @param reasonCode One of disconnect reason code which defined by 802.11.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |HostapdStatusCode.SUCCESS|,
+ * |HostapdStatusCode.FAILURE_IFACE_UNKNOWN|
+ * |HostapdStatusCode.FAILURE_CLIENT_UNKNOWN|
+ */
+ forceClientDisconnect(string ifaceName, MacAddress clientAddress,
+ Ieee80211ReasonCode reasonCode) generates (HostapdStatus status);
+};
diff --git a/wifi/hostapd/1.2/types.hal b/wifi/hostapd/1.2/types.hal
new file mode 100644
index 0000000..06e890b
--- /dev/null
+++ b/wifi/hostapd/1.2/types.hal
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.hostapd@1.2;
+
+import @1.0::HostapdStatusCode;
+
+/**
+ * Enum values indicating the status of any hostapd operation.
+ */
+enum HostapdStatusCode : @1.0::HostapdStatusCode {
+ /**
+ * Failure because unknown the client.
+ */
+ FAILURE_CLIENT_UNKNOWN,
+};
+
+/**
+ * Enum values indicating the reason code for disconnect packet.
+ * Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+ */
+enum Ieee80211ReasonCode : uint16_t {
+ WLAN_REASON_UNSPECIFIED = 1,
+ WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+ WLAN_REASON_DISASSOC_AP_BUSY = 5,
+};
+
+typedef uint8_t[6] MacAddress;
+
+/**
+ * Generic structure to return the status of any hostapd operation.
+ */
+struct HostapdStatus {
+ HostapdStatusCode code;
+
+ /**
+ * A vendor-specific error message to provide more information beyond the
+ * status code.
+ * This must be used for debugging purposes only.
+ */
+ string debugMessage;
+};
diff --git a/wifi/hostapd/1.2/vts/OWNERS b/wifi/hostapd/1.2/vts/OWNERS
new file mode 100644
index 0000000..8bfb148
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/OWNERS
@@ -0,0 +1,2 @@
+rpius@google.com
+etancohen@google.com
diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp
new file mode 100644
index 0000000..50cfdee
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalWifiHostapdV1_2TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "VtsHalWifiHostapdV1_2TargetTest.cpp",
+ "hostapd_hidl_test.cpp",
+ ],
+ static_libs: [
+ "VtsHalWifiV1_0TargetTestUtil",
+ "VtsHalWifiHostapdV1_0TargetTestUtil",
+ "android.hardware.wifi.hostapd@1.0",
+ "android.hardware.wifi.hostapd@1.1",
+ "android.hardware.wifi.hostapd@1.2",
+ "android.hardware.wifi@1.0",
+ "libgmock",
+ "libwifi-system",
+ "libwifi-system-iface",
+ ],
+ test_suites: ["general-tests", "vts-core"],
+}
+
diff --git a/vibrator/1.4/types.hal b/wifi/hostapd/1.2/vts/functional/VtsHalWifiHostapdV1_2TargetTest.cpp
similarity index 76%
copy from vibrator/1.4/types.hal
copy to wifi/hostapd/1.2/vts/functional/VtsHalWifiHostapdV1_2TargetTest.cpp
index acc49b1..7e0f3cd 100644
--- a/vibrator/1.4/types.hal
+++ b/wifi/hostapd/1.2/vts/functional/VtsHalWifiHostapdV1_2TargetTest.cpp
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-package android.hardware.vibrator@1.4;
+#include <VtsHalHidlTargetTestEnvBase.h>
-enum Capabilities : uint32_t {
- ON_COMPLETION_CALLBACK = 1 << 0,
- PERFORM_COMPLETION_CALLBACK = 1 << 1,
-};
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
new file mode 100644
index 0000000..0d37221
--- /dev/null
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/hostapd/1.2/IHostapd.h>
+
+#include "hostapd_hidl_call_util.h"
+#include "hostapd_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode;
+using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
+using ::android::hardware::wifi::hostapd::V1_2::IHostapd;
+using ::android::hardware::wifi::V1_0::IWifi;
+
+namespace {
+constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
+ '2', '3', '4', '5'};
+constexpr int kIfaceChannel = 6;
+constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0};
+constexpr Ieee80211ReasonCode kTestDisconnectReasonCode =
+ Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
+} // namespace
+
+class HostapdHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+ public:
+ virtual void SetUp() override {
+ wifi_instance_name_ = std::get<0>(GetParam());
+ hostapd_instance_name_ = std::get<1>(GetParam());
+ stopSupplicantIfNeeded(wifi_instance_name_);
+ startHostapdAndWaitForHidlService(wifi_instance_name_,
+ hostapd_instance_name_);
+ hostapd_ = IHostapd::getService(hostapd_instance_name_);
+ ASSERT_NE(hostapd_.get(), nullptr);
+ }
+
+ virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
+
+ protected:
+ std::string getPrimaryWlanIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
+ nullptr);
+ if (res > 0) return buffer.data();
+ property_get("wifi.interface", buffer.data(), "wlan0");
+ return buffer.data();
+ }
+
+ IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+ ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
+ iface_params;
+ IHostapd::IfaceParams iface_params_1_1;
+
+ iface_params.ifaceName = getPrimaryWlanIfaceName();
+ iface_params.hwModeParams.enable80211N = true;
+ iface_params.hwModeParams.enable80211AC = false;
+ iface_params.channelParams.enableAcs = false;
+ iface_params.channelParams.acsShouldExcludeDfs = false;
+ iface_params.channelParams.channel = kIfaceChannel;
+ iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ;
+ iface_params_1_1.V1_0 = iface_params;
+ return iface_params_1_1;
+ }
+
+ IHostapd::NetworkParams getOpenNwParams() {
+ IHostapd::NetworkParams nw_params;
+ nw_params.ssid =
+ std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+ nw_params.isHidden = false;
+ nw_params.encryptionType = IHostapd::EncryptionType::NONE;
+ return nw_params;
+ }
+
+ // IHostapd object used for all tests in this fixture.
+ sp<IHostapd> hostapd_;
+ std::string wifi_instance_name_;
+ std::string hostapd_instance_name_;
+};
+
+/**
+ * forceClientDisconnect should return FAILURE_IFACE_UNKNOWN
+ * when hotspot interface doesn't init..
+ */
+TEST_P(HostapdHidlTest, DisconnectClientWhenIfaceNotAvailable) {
+ auto status =
+ HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
+ EXPECT_EQ(HostapdStatusCode::FAILURE_IFACE_UNKNOWN, status.code);
+}
+
+/**
+ * forceClientDisconnect should return FAILURE_CLIENT_UNKNOWN
+ * when hotspot interface available.
+ */
+TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
+ auto status_1_0 =
+ HIDL_INVOKE(hostapd_, addAccessPoint_1_1, getIfaceParamsWithoutAcs(),
+ getOpenNwParams());
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status_1_0.code);
+
+ auto status_1_2 =
+ HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
+ kTestZeroMacAddr, kTestDisconnectReasonCode);
+ EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, HostapdHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index ba79738..15525bb 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -51,7 +51,7 @@
"libwifi-system",
"libwifi-system-iface",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
cc_test {
@@ -71,4 +71,5 @@
"libwifi-system",
"libwifi-system-iface",
],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
index 6ca0546..f582cc1 100644
--- a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
+++ b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
@@ -14,40 +14,8 @@
* limitations under the License.
*/
-#include <android-base/logging.h>
-
#include "supplicant_hidl_test_utils.h"
-#include "wifi_hidl_test_utils.h"
-class WifiSupplicantHidlEnvironment_1_0 : public WifiSupplicantHidlEnvironment {
- public:
- // get the test environment singleton
- static WifiSupplicantHidlEnvironment_1_0* Instance() {
- static WifiSupplicantHidlEnvironment_1_0* instance =
- new WifiSupplicantHidlEnvironment_1_0;
- return instance;
- }
- virtual void registerTestServices() override {
- registerTestService<::android::hardware::wifi::V1_0::IWifi>();
- registerTestService<
- ::android::hardware::wifi::supplicant::V1_0::ISupplicant>();
- }
-
- private:
- WifiSupplicantHidlEnvironment_1_0() {}
-};
-
-WifiSupplicantHidlEnvironment* gEnv =
- WifiSupplicantHidlEnvironment_1_0::Instance();
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(gEnv);
- ::testing::InitGoogleTest(&argc, argv);
- gEnv->init(&argc, argv);
- int status = gEnv->initFromOptions(argc, argv);
- if (status == 0) {
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- }
- return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+WifiSupplicantHidlEnvironment* gEnv = nullptr;
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h
index 1c0fcec..3fa6f9d 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_call_util.h
@@ -25,8 +25,6 @@
#include <type_traits>
#include <utility>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace {
namespace detail {
template <typename>
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
index 436b88b..4f25465 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
@@ -16,35 +16,47 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicant.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "supplicant_hidl_test_utils.h"
using ::android::sp;
using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
-using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::IWifi;
-extern WifiSupplicantHidlEnvironment* gEnv;
-
-class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class SupplicantHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
public:
virtual void SetUp() override {
- startSupplicantAndWaitForHidlService();
- supplicant_ = getSupplicant();
+ wifi_instance_name_ = std::get<0>(GetParam());
+ supplicant_instance_name_ = std::get<1>(GetParam());
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ isP2pOn_ =
+ testing::deviceSupportsFeature("android.hardware.wifi.direct");
+ supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
ASSERT_NE(supplicant_.get(), nullptr);
}
- virtual void TearDown() override { stopSupplicant(); }
+ virtual void TearDown() override { stopSupplicant(wifi_instance_name_); }
protected:
// ISupplicant object used for all tests in this fixture.
sp<ISupplicant> supplicant_;
+ bool isP2pOn_ = false;
+ std::string wifi_instance_name_;
+ std::string supplicant_instance_name_;
};
/*
@@ -52,16 +64,19 @@
* Ensures that an instance of the ISupplicant proxy object is
* successfully created.
*/
-TEST(SupplicantHidlTestNoFixture, Create) {
- startSupplicantAndWaitForHidlService();
- EXPECT_NE(nullptr, getSupplicant().get());
- stopSupplicant();
+TEST_P(SupplicantHidlTest, Create) {
+ // Stop the proxy object created in setup.
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ EXPECT_NE(nullptr,
+ getSupplicant(supplicant_instance_name_, isP2pOn_).get());
}
/*
* ListInterfaces
*/
-TEST_F(SupplicantHidlTest, ListInterfaces) {
+TEST_P(SupplicantHidlTest, ListInterfaces) {
std::vector<ISupplicant::IfaceInfo> ifaces;
supplicant_->listInterfaces(
[&](const SupplicantStatus& status,
@@ -74,7 +89,7 @@
std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) {
return iface.type == IfaceType::STA;
}));
- if (gEnv->isP2pOn) {
+ if (isP2pOn_) {
EXPECT_NE(
ifaces.end(),
std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) {
@@ -86,7 +101,7 @@
/*
* GetInterface
*/
-TEST_F(SupplicantHidlTest, GetInterface) {
+TEST_P(SupplicantHidlTest, GetInterface) {
std::vector<ISupplicant::IfaceInfo> ifaces;
supplicant_->listInterfaces(
[&](const SupplicantStatus& status,
@@ -107,7 +122,7 @@
/*
* SetDebugParams
*/
-TEST_F(SupplicantHidlTest, SetDebugParams) {
+TEST_P(SupplicantHidlTest, SetDebugParams) {
bool show_timestamp = true;
bool show_keys = true;
ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
@@ -124,7 +139,7 @@
/*
* GetDebugLevel
*/
-TEST_F(SupplicantHidlTest, GetDebugLevel) {
+TEST_P(SupplicantHidlTest, GetDebugLevel) {
bool show_timestamp = true;
bool show_keys = true;
ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
@@ -142,7 +157,7 @@
/*
* IsDebugShowTimestampEnabled
*/
-TEST_F(SupplicantHidlTest, IsDebugShowTimestampEnabled) {
+TEST_P(SupplicantHidlTest, IsDebugShowTimestampEnabled) {
bool show_timestamp = true;
bool show_keys = true;
ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
@@ -160,7 +175,7 @@
/*
* IsDebugShowKeysEnabled
*/
-TEST_F(SupplicantHidlTest, IsDebugShowKeysEnabled) {
+TEST_P(SupplicantHidlTest, IsDebugShowKeysEnabled) {
bool show_timestamp = true;
bool show_keys = true;
ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
@@ -178,15 +193,24 @@
/*
* SetConcurrenyPriority
*/
-TEST_F(SupplicantHidlTest, SetConcurrencyPriority) {
+TEST_P(SupplicantHidlTest, SetConcurrencyPriority) {
supplicant_->setConcurrencyPriority(
IfaceType::STA, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
- if (gEnv->isP2pOn) {
+ if (isP2pOn_) {
supplicant_->setConcurrencyPriority(
IfaceType::P2P, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
}
}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, SupplicantHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ISupplicant::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 7bd04dc..d47e42f 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -56,8 +56,8 @@
// Helper function to initialize the driver and firmware to STA mode
// using the vendor HAL HIDL interface.
-void initilializeDriverAndFirmware() {
- sp<IWifiChip> wifi_chip = getWifiChip();
+void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
ChipModeId mode_id;
EXPECT_TRUE(configureChipToSupportIfaceType(
wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
@@ -65,7 +65,9 @@
// Helper function to deinitialize the driver and firmware
// using the vendor HAL HIDL interface.
-void deInitilializeDriverAndFirmware() { stopWifi(); }
+void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ stopWifi(wifi_instance_name);
+}
// Helper function to find any iface of the desired type exposed.
bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
@@ -154,28 +156,38 @@
std::condition_variable condition_;
};
-void stopSupplicant() {
+void stopSupplicant() { stopSupplicant(""); }
+
+void stopSupplicant(const std::string& wifi_instance_name) {
SupplicantManager supplicant_manager;
ASSERT_TRUE(supplicant_manager.StopSupplicant());
- deInitilializeDriverAndFirmware();
+ deInitilializeDriverAndFirmware(wifi_instance_name);
ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
}
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
void startSupplicantAndWaitForHidlService() {
- initilializeDriverAndFirmware();
+ startSupplicantAndWaitForHidlService("",
+ gEnv->getServiceName<ISupplicant>());
+}
+
+void startSupplicantAndWaitForHidlService(
+ const std::string& wifi_instance_name,
+ const std::string& supplicant_instance_name) {
+ initilializeDriverAndFirmware(wifi_instance_name);
android::sp<ServiceNotificationListener> notification_listener =
new ServiceNotificationListener();
- string service_name = gEnv->getServiceName<ISupplicant>();
ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
- service_name));
+ supplicant_instance_name));
SupplicantManager supplicant_manager;
ASSERT_TRUE(supplicant_manager.StartSupplicant());
ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
- ASSERT_TRUE(notification_listener->waitForHidlService(500, service_name));
+ ASSERT_TRUE(notification_listener->waitForHidlService(
+ 500, supplicant_instance_name));
}
bool is_1_1(const sp<ISupplicant>& supplicant) {
@@ -218,6 +230,7 @@
});
}
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
sp<ISupplicant> getSupplicant() {
sp<ISupplicant> supplicant =
::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
@@ -232,8 +245,28 @@
return supplicant;
}
+sp<ISupplicant> getSupplicant(const std::string& supplicant_instance_name,
+ bool isP2pOn) {
+ sp<ISupplicant> supplicant =
+ ISupplicant::getService(supplicant_instance_name);
+ // For 1.1 supplicant, we need to add interfaces at initialization.
+ if (is_1_1(supplicant)) {
+ addSupplicantStaIface_1_1(supplicant);
+ if (isP2pOn) {
+ addSupplicantP2pIface_1_1(supplicant);
+ }
+ }
+ return supplicant;
+}
+
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
sp<ISupplicantStaIface> getSupplicantStaIface() {
sp<ISupplicant> supplicant = getSupplicant();
+ return getSupplicantStaIface(supplicant);
+}
+
+sp<ISupplicantStaIface> getSupplicantStaIface(
+ const sp<ISupplicant>& supplicant) {
if (!supplicant.get()) {
return nullptr;
}
@@ -257,8 +290,14 @@
return sta_iface;
}
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
sp<ISupplicantStaNetwork> createSupplicantStaNetwork() {
- sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
+ return createSupplicantStaNetwork(getSupplicant());
+}
+
+sp<ISupplicantStaNetwork> createSupplicantStaNetwork(
+ const sp<ISupplicant>& supplicant) {
+ sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface(supplicant);
if (!sta_iface.get()) {
return nullptr;
}
@@ -278,8 +317,13 @@
return sta_network;
}
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
sp<ISupplicantP2pIface> getSupplicantP2pIface() {
- sp<ISupplicant> supplicant = getSupplicant();
+ return getSupplicantP2pIface(getSupplicant());
+}
+
+sp<ISupplicantP2pIface> getSupplicantP2pIface(
+ const sp<ISupplicant>& supplicant) {
if (!supplicant.get()) {
return nullptr;
}
@@ -303,8 +347,12 @@
return p2p_iface;
}
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
bool turnOnExcessiveLogging() {
- sp<ISupplicant> supplicant = getSupplicant();
+ return turnOnExcessiveLogging(getSupplicant());
+}
+
+bool turnOnExcessiveLogging(const sp<ISupplicant>& supplicant) {
if (!supplicant.get()) {
return false;
}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 21a1ae6..40ad695 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -25,21 +25,47 @@
#include <getopt.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include "wifi_hidl_test_utils.h"
// Used to stop the android wifi framework before every test.
void stopWifiFramework();
+void stopWifiFramework(const std::string& wifi_instance_name);
void startWifiFramework();
+void startWifiFramework(const std::string& wifi_instance_name);
+
void stopSupplicant();
+void stopSupplicant(const std::string& wifi_instance_name);
// Used to configure the chip, driver and start wpa_supplicant before every
// test.
-void startSupplicantAndWaitForHidlService();
+void startSupplicantAndWaitForHidlService(
+ const std::string& wifi_instance_name,
+ const std::string& supplicant_instance_name);
// Helper functions to obtain references to the various HIDL interface objects.
// Note: We only have a single instance of each of these objects currently.
// These helper functions should be modified to return vectors if we support
// multiple instances.
android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>
+getSupplicant(const std::string& supplicant_instance_name, bool isP2pOn);
+android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface>
+getSupplicantStaIface(
+ const android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>&
+ supplicant);
+android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork>
+createSupplicantStaNetwork(
+ const android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>&
+ supplicant);
+android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface>
+getSupplicantP2pIface(
+ const android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>&
+ supplicant);
+bool turnOnExcessiveLogging(
+ const android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>&
+ supplicant);
+
+// TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
+void startSupplicantAndWaitForHidlService();
+android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>
getSupplicant();
android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface>
getSupplicantStaIface();
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 0181f7b..8d6f38d 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -15,9 +15,12 @@
*/
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
-#include <VtsHalHidlTargetTestBase.h>
-
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
#include "supplicant_hidl_call_util.h"
@@ -30,11 +33,13 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIfaceCallback;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantNetworkId;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::V1_0::IWifi;
namespace {
constexpr uint8_t kTestSsidPostfix[] = {'t', 'e', 's', 't'};
@@ -66,26 +71,38 @@
constexpr SupplicantNetworkId kTestNetworkId = 5;
} // namespace
-class SupplicantP2pIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class SupplicantP2pIfaceHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
public:
virtual void SetUp() override {
- startSupplicantAndWaitForHidlService();
- EXPECT_TRUE(turnOnExcessiveLogging());
- p2p_iface_ = getSupplicantP2pIface();
+ wifi_instance_name_ = std::get<0>(GetParam());
+ supplicant_instance_name_ = std::get<1>(GetParam());
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ isP2pOn_ =
+ testing::deviceSupportsFeature("android.hardware.wifi.direct");
+ supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
+ EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+ p2p_iface_ = getSupplicantP2pIface(supplicant_);
ASSERT_NE(p2p_iface_.get(), nullptr);
memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
memcpy(peer_mac_addr_.data(), kTestPeerMacAddr, peer_mac_addr_.size());
}
- virtual void TearDown() override { stopSupplicant(); }
+ virtual void TearDown() override { stopSupplicant(wifi_instance_name_); }
protected:
+ bool isP2pOn_ = false;
+ sp<ISupplicant> supplicant_;
// ISupplicantP2pIface object used for all tests in this fixture.
sp<ISupplicantP2pIface> p2p_iface_;
// MAC address to use for various tests.
std::array<uint8_t, 6> mac_addr_;
std::array<uint8_t, 6> peer_mac_addr_;
+ std::string wifi_instance_name_;
+ std::string supplicant_instance_name_;
};
class IfaceCallback : public ISupplicantP2pIfaceCallback {
@@ -177,16 +194,20 @@
* Ensures that an instance of the ISupplicantP2pIface proxy object is
* successfully created.
*/
-TEST(SupplicantP2pIfaceHidlTestNoFixture, Create) {
- startSupplicantAndWaitForHidlService();
- EXPECT_NE(nullptr, getSupplicantP2pIface().get());
- stopSupplicant();
+TEST_P(SupplicantP2pIfaceHidlTest, Create) {
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ sp<ISupplicantP2pIface> p2p_iface = getSupplicantP2pIface(
+ getSupplicant(supplicant_instance_name_, isP2pOn_));
+
+ EXPECT_NE(nullptr, p2p_iface.get());
}
/*
* RegisterCallback
*/
-TEST_F(SupplicantP2pIfaceHidlTest, RegisterCallback) {
+TEST_P(SupplicantP2pIfaceHidlTest, RegisterCallback) {
p2p_iface_->registerCallback(
new IfaceCallback(), [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -196,7 +217,7 @@
/*
* GetName
*/
-TEST_F(SupplicantP2pIfaceHidlTest, GetName) {
+TEST_P(SupplicantP2pIfaceHidlTest, GetName) {
const auto& status_and_interface_name = HIDL_INVOKE(p2p_iface_, getName);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
status_and_interface_name.first.code);
@@ -206,7 +227,7 @@
/*
* GetType
*/
-TEST_F(SupplicantP2pIfaceHidlTest, GetType) {
+TEST_P(SupplicantP2pIfaceHidlTest, GetType) {
const auto& status_and_interface_type = HIDL_INVOKE(p2p_iface_, getType);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
status_and_interface_type.first.code);
@@ -216,7 +237,7 @@
/*
* GetDeviceAddress
*/
-TEST_F(SupplicantP2pIfaceHidlTest, GetDeviceAddress) {
+TEST_P(SupplicantP2pIfaceHidlTest, GetDeviceAddress) {
p2p_iface_->getDeviceAddress(
[](const SupplicantStatus& status,
const hidl_array<uint8_t, 6>& /* mac_addr */) {
@@ -227,7 +248,7 @@
/*
* SetSsidPostfix
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetSsidPostfix) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetSsidPostfix) {
std::vector<uint8_t> ssid(kTestSsidPostfix,
kTestSsidPostfix + sizeof(kTestSsidPostfix));
p2p_iface_->setSsidPostfix(ssid, [](const SupplicantStatus& status) {
@@ -238,7 +259,7 @@
/*
* Find
*/
-TEST_F(SupplicantP2pIfaceHidlTest, Find) {
+TEST_P(SupplicantP2pIfaceHidlTest, Find) {
p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -247,7 +268,7 @@
/*
* StopFind
*/
-TEST_F(SupplicantP2pIfaceHidlTest, StopFind) {
+TEST_P(SupplicantP2pIfaceHidlTest, StopFind) {
p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -260,7 +281,7 @@
/*
* Flush
*/
-TEST_F(SupplicantP2pIfaceHidlTest, Flush) {
+TEST_P(SupplicantP2pIfaceHidlTest, Flush) {
p2p_iface_->flush([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -269,7 +290,7 @@
/*
* Connect
*/
-TEST_F(SupplicantP2pIfaceHidlTest, Connect) {
+TEST_P(SupplicantP2pIfaceHidlTest, Connect) {
p2p_iface_->connect(
mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
kTestConnectPin, false, false, kTestConnectGoIntent,
@@ -282,7 +303,7 @@
/*
* CancelConnect
*/
-TEST_F(SupplicantP2pIfaceHidlTest, CancelConnect) {
+TEST_P(SupplicantP2pIfaceHidlTest, CancelConnect) {
p2p_iface_->connect(
mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
kTestConnectPin, false, false, kTestConnectGoIntent,
@@ -299,7 +320,7 @@
/*
* ProvisionDiscovery
*/
-TEST_F(SupplicantP2pIfaceHidlTest, ProvisionDiscovery) {
+TEST_P(SupplicantP2pIfaceHidlTest, ProvisionDiscovery) {
p2p_iface_->provisionDiscovery(
mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
[](const SupplicantStatus& status) {
@@ -311,7 +332,7 @@
/*
* AddGroup
*/
-TEST_F(SupplicantP2pIfaceHidlTest, AddGroup) {
+TEST_P(SupplicantP2pIfaceHidlTest, AddGroup) {
p2p_iface_->addGroup(false, kTestNetworkId,
[](const SupplicantStatus& /* status */) {
// TODO: Figure out the initialization sequence for
@@ -324,7 +345,7 @@
/*
* RemoveGroup
*/
-TEST_F(SupplicantP2pIfaceHidlTest, RemoveGroup) {
+TEST_P(SupplicantP2pIfaceHidlTest, RemoveGroup) {
// This is not going to work with fake values.
EXPECT_NE(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, removeGroup, kTestGroupIfName).code);
@@ -333,7 +354,7 @@
/*
* Reject
*/
-TEST_F(SupplicantP2pIfaceHidlTest, Reject) {
+TEST_P(SupplicantP2pIfaceHidlTest, Reject) {
p2p_iface_->reject(mac_addr_, [](const SupplicantStatus& status) {
// This is not going to work with fake values.
EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
@@ -343,7 +364,7 @@
/*
* Invite
*/
-TEST_F(SupplicantP2pIfaceHidlTest, Invite) {
+TEST_P(SupplicantP2pIfaceHidlTest, Invite) {
p2p_iface_->invite(kTestGroupIfName, mac_addr_, peer_mac_addr_,
[](const SupplicantStatus& status) {
// This is not going to work with fake values.
@@ -355,7 +376,7 @@
/*
* Reinvoke
*/
-TEST_F(SupplicantP2pIfaceHidlTest, Reinvoke) {
+TEST_P(SupplicantP2pIfaceHidlTest, Reinvoke) {
p2p_iface_->reinvoke(
kTestNetworkId, mac_addr_, [](const SupplicantStatus& status) {
// This is not going to work with fake values.
@@ -367,7 +388,7 @@
/*
* ConfigureExtListen
*/
-TEST_F(SupplicantP2pIfaceHidlTest, ConfigureExtListen) {
+TEST_P(SupplicantP2pIfaceHidlTest, ConfigureExtListen) {
p2p_iface_->configureExtListen(kTestExtListenPeriod, kTestExtListenInterval,
[](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -378,7 +399,7 @@
/*
* SetListenChannel
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetListenChannel) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetListenChannel) {
p2p_iface_->setListenChannel(
kTestChannel, kTestOperatingClass, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -388,7 +409,7 @@
/*
* SetDisallowedFrequencies
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetDisallowedFrequencies) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetDisallowedFrequencies) {
std::vector<ISupplicantP2pIface::FreqRange> ranges = {
{kTestFreqRange[0], kTestFreqRange[1]}};
p2p_iface_->setDisallowedFrequencies(
@@ -400,7 +421,7 @@
/*
* GetSsid
*/
-TEST_F(SupplicantP2pIfaceHidlTest, GetSsid) {
+TEST_P(SupplicantP2pIfaceHidlTest, GetSsid) {
std::array<uint8_t, 6> mac_addr;
memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size());
p2p_iface_->getSsid(mac_addr, [](const SupplicantStatus& status,
@@ -413,7 +434,7 @@
/*
* GetGroupCapability
*/
-TEST_F(SupplicantP2pIfaceHidlTest, GetGroupCapability) {
+TEST_P(SupplicantP2pIfaceHidlTest, GetGroupCapability) {
std::array<uint8_t, 6> mac_addr;
memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size());
p2p_iface_->getGroupCapability(
@@ -426,7 +447,7 @@
/*
* FlushServices
*/
-TEST_F(SupplicantP2pIfaceHidlTest, FlushServices) {
+TEST_P(SupplicantP2pIfaceHidlTest, FlushServices) {
p2p_iface_->flushServices([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -435,7 +456,7 @@
/*
* SetMiracastMode
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetMiracastMode) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetMiracastMode) {
p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::DISABLED,
[](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -456,7 +477,7 @@
/*
* SetGroupIdle
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetGroupIdle) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetGroupIdle) {
// This is not going to work with fake values.
EXPECT_NE(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setGroupIdle, kTestGroupIfName,
@@ -467,7 +488,7 @@
/*
* SetPowerSave
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetPowerSave) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetPowerSave) {
// This is not going to work with fake values.
EXPECT_NE(
SupplicantStatusCode::SUCCESS,
@@ -481,7 +502,7 @@
/*
* SetWpsDeviceName
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsDeviceName) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsDeviceName) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsDeviceName, kTestWpsDeviceName).code);
@@ -490,7 +511,7 @@
/*
* SetWpsDeviceType
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsDeviceType) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsDeviceType) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsDeviceType, kTestWpsDeviceType).code);
@@ -499,7 +520,7 @@
/*
* SetWpsManufacturer
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsManufacturer) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsManufacturer) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsManufacturer, kTestWpsManufacturer).code);
@@ -508,7 +529,7 @@
/*
* SetWpsModelName
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsModelName) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsModelName) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsModelName, kTestWpsModelName).code);
}
@@ -516,7 +537,7 @@
/*
* SetWpsModelNumber
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsModelNumber) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsModelNumber) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsModelNumber, kTestWpsModelNumber).code);
@@ -525,7 +546,7 @@
/*
* SetWpsSerialNumber
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsSerialNumber) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsSerialNumber) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsSerialNumber, kTestWpsSerialNumber).code);
@@ -534,7 +555,7 @@
/*
* SetWpsConfigMethods
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWpsConfigMethods) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWpsConfigMethods) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWpsConfigMethods, kTestWpsConfigMethods)
@@ -548,7 +569,7 @@
* This also tests that removeBonjourSerive() returns error when there is no
* existing bonjour service with the same query data.
*/
-TEST_F(SupplicantP2pIfaceHidlTest, AddAndRemoveBonjourService) {
+TEST_P(SupplicantP2pIfaceHidlTest, AddAndRemoveBonjourService) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(
p2p_iface_, addBonjourService,
@@ -584,7 +605,7 @@
* This also tests that removeUpnpService() returns error when there is no
* exsiting upnp service with the same service name.
*/
-TEST_F(SupplicantP2pIfaceHidlTest, AddAndRemoveUpnpService) {
+TEST_P(SupplicantP2pIfaceHidlTest, AddAndRemoveUpnpService) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, addUpnpService, 0 /* version */,
kTestUpnpServiceName)
@@ -604,7 +625,7 @@
/*
* EnableWfd
*/
-TEST_F(SupplicantP2pIfaceHidlTest, EnableWfd) {
+TEST_P(SupplicantP2pIfaceHidlTest, EnableWfd) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, enableWfd, true).code);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -614,8 +635,17 @@
/*
* SetWfdDeviceInfo
*/
-TEST_F(SupplicantP2pIfaceHidlTest, SetWfdDeviceInfo) {
+TEST_P(SupplicantP2pIfaceHidlTest, SetWfdDeviceInfo) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(p2p_iface_, setWfdDeviceInfo, kTestWfdDeviceInfo).code);
}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, SupplicantP2pIfaceHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ISupplicant::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index ec102d5..089b3cd 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -15,9 +15,12 @@
*/
#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
-#include <VtsHalHidlTargetTestBase.h>
-
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
#include "supplicant_hidl_call_util.h"
@@ -30,12 +33,14 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIfaceCallback;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantNetworkId;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::V1_0::IWifi;
namespace {
constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
@@ -61,24 +66,36 @@
constexpr uint16_t kTestWpsConfigMethods = 0xffff;
} // namespace
-class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class SupplicantStaIfaceHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
public:
virtual void SetUp() override {
- startSupplicantAndWaitForHidlService();
- EXPECT_TRUE(turnOnExcessiveLogging());
- sta_iface_ = getSupplicantStaIface();
+ wifi_instance_name_ = std::get<0>(GetParam());
+ supplicant_instance_name_ = std::get<1>(GetParam());
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ isP2pOn_ =
+ testing::deviceSupportsFeature("android.hardware.wifi.direct");
+ supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
+ EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+ sta_iface_ = getSupplicantStaIface(supplicant_);
ASSERT_NE(sta_iface_.get(), nullptr);
memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
}
- virtual void TearDown() override { stopSupplicant(); }
+ virtual void TearDown() override { stopSupplicant(wifi_instance_name_); }
protected:
+ bool isP2pOn_ = false;
+ sp<ISupplicant> supplicant_;
// ISupplicantStaIface object used for all tests in this fixture.
sp<ISupplicantStaIface> sta_iface_;
// MAC address to use for various tests.
std::array<uint8_t, 6> mac_addr_;
+ std::string wifi_instance_name_;
+ std::string supplicant_instance_name_;
};
class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -159,16 +176,19 @@
* Ensures that an instance of the ISupplicantStaIface proxy object is
* successfully created.
*/
-TEST(SupplicantStaIfaceHidlTestNoFixture, Create) {
- startSupplicantAndWaitForHidlService();
- EXPECT_NE(nullptr, getSupplicantStaIface().get());
- stopSupplicant();
+TEST_P(SupplicantStaIfaceHidlTest, Create) {
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ EXPECT_NE(nullptr, getSupplicantStaIface(
+ getSupplicant(supplicant_instance_name_, isP2pOn_))
+ .get());
}
/*
* RegisterCallback
*/
-TEST_F(SupplicantStaIfaceHidlTest, RegisterCallback) {
+TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback) {
sta_iface_->registerCallback(
new IfaceCallback(), [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -178,7 +198,7 @@
/*
* GetName
*/
-TEST_F(SupplicantStaIfaceHidlTest, GetName) {
+TEST_P(SupplicantStaIfaceHidlTest, GetName) {
const auto& status_and_interface_name = HIDL_INVOKE(sta_iface_, getName);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
status_and_interface_name.first.code);
@@ -188,7 +208,7 @@
/*
* GetType
*/
-TEST_F(SupplicantStaIfaceHidlTest, GetType) {
+TEST_P(SupplicantStaIfaceHidlTest, GetType) {
const auto& status_and_interface_type = HIDL_INVOKE(sta_iface_, getType);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
status_and_interface_type.first.code);
@@ -198,14 +218,15 @@
/*
* listNetworks.
*/
-TEST_F(SupplicantStaIfaceHidlTest, listNetworks) {
+TEST_P(SupplicantStaIfaceHidlTest, listNetworks) {
sta_iface_->listNetworks([](const SupplicantStatus& status,
const hidl_vec<SupplicantNetworkId>& ids) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
EXPECT_EQ(0u, ids.size());
});
- sp<ISupplicantStaNetwork> sta_network = createSupplicantStaNetwork();
+ sp<ISupplicantStaNetwork> sta_network =
+ createSupplicantStaNetwork(supplicant_);
EXPECT_NE(nullptr, sta_network.get());
sta_iface_->listNetworks([](const SupplicantStatus& status,
@@ -218,7 +239,7 @@
/*
* Reassociate.
*/
-TEST_F(SupplicantStaIfaceHidlTest, Reassociate) {
+TEST_P(SupplicantStaIfaceHidlTest, Reassociate) {
sta_iface_->reassociate([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -227,7 +248,7 @@
/*
* Reconnect.
*/
-TEST_F(SupplicantStaIfaceHidlTest, Reconnect) {
+TEST_P(SupplicantStaIfaceHidlTest, Reconnect) {
sta_iface_->reconnect([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
status.code);
@@ -237,7 +258,7 @@
/*
* Disconnect.
*/
-TEST_F(SupplicantStaIfaceHidlTest, Disconnect) {
+TEST_P(SupplicantStaIfaceHidlTest, Disconnect) {
sta_iface_->disconnect([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -246,7 +267,7 @@
/*
* SetPowerSave.
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetPowerSave) {
+TEST_P(SupplicantStaIfaceHidlTest, SetPowerSave) {
sta_iface_->setPowerSave(true, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -258,7 +279,7 @@
/*
* InitiateTdlsDiscover.
*/
-TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsDiscover) {
+TEST_P(SupplicantStaIfaceHidlTest, InitiateTdlsDiscover) {
sta_iface_->initiateTdlsDiscover(
mac_addr_, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -268,7 +289,7 @@
/*
* InitiateTdlsSetup.
*/
-TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsSetup) {
+TEST_P(SupplicantStaIfaceHidlTest, InitiateTdlsSetup) {
sta_iface_->initiateTdlsSetup(
mac_addr_, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -278,7 +299,7 @@
/*
* InitiateTdlsTeardown.
*/
-TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsTeardown) {
+TEST_P(SupplicantStaIfaceHidlTest, InitiateTdlsTeardown) {
sta_iface_->initiateTdlsTeardown(
mac_addr_, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -288,7 +309,7 @@
/*
* InitiateAnqpQuery.
*/
-TEST_F(SupplicantStaIfaceHidlTest, InitiateAnqpQuery) {
+TEST_P(SupplicantStaIfaceHidlTest, InitiateAnqpQuery) {
std::vector<ISupplicantStaIface::AnqpInfoId> anqp_ids(
kTestAnqpInfoIds, kTestAnqpInfoIds + sizeof(kTestAnqpInfoIds));
std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> hs_types(
@@ -304,7 +325,7 @@
/*
* InitiateHs20IconQuery.
*/
-TEST_F(SupplicantStaIfaceHidlTest, InitiateHs20IconQuery) {
+TEST_P(SupplicantStaIfaceHidlTest, InitiateHs20IconQuery) {
sta_iface_->initiateHs20IconQuery(
mac_addr_, kTestHs20IconFile, [](const SupplicantStatus& status) {
// These requests will fail unless the BSSID mentioned is actually
@@ -316,7 +337,7 @@
/*
* GetMacAddress.
*/
-TEST_F(SupplicantStaIfaceHidlTest, GetMacAddress) {
+TEST_P(SupplicantStaIfaceHidlTest, GetMacAddress) {
sta_iface_->getMacAddress([](const SupplicantStatus& status,
const hidl_array<uint8_t, 6>& mac_addr) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -328,7 +349,7 @@
/*
* StartRxFilter.
*/
-TEST_F(SupplicantStaIfaceHidlTest, StartRxFilter) {
+TEST_P(SupplicantStaIfaceHidlTest, StartRxFilter) {
sta_iface_->startRxFilter([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -337,7 +358,7 @@
/*
* StopRxFilter.
*/
-TEST_F(SupplicantStaIfaceHidlTest, StopRxFilter) {
+TEST_P(SupplicantStaIfaceHidlTest, StopRxFilter) {
sta_iface_->stopRxFilter([](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -346,7 +367,7 @@
/*
* AddRxFilter.
*/
-TEST_F(SupplicantStaIfaceHidlTest, AddRxFilter) {
+TEST_P(SupplicantStaIfaceHidlTest, AddRxFilter) {
sta_iface_->addRxFilter(ISupplicantStaIface::RxFilterType::V4_MULTICAST,
[](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -362,7 +383,7 @@
/*
* RemoveRxFilter.
*/
-TEST_F(SupplicantStaIfaceHidlTest, RemoveRxFilter) {
+TEST_P(SupplicantStaIfaceHidlTest, RemoveRxFilter) {
sta_iface_->removeRxFilter(ISupplicantStaIface::RxFilterType::V4_MULTICAST,
[](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -378,7 +399,7 @@
/*
* SetBtCoexistenceMode.
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetBtCoexistenceMode) {
+TEST_P(SupplicantStaIfaceHidlTest, SetBtCoexistenceMode) {
sta_iface_->setBtCoexistenceMode(
ISupplicantStaIface::BtCoexistenceMode::ENABLED,
[](const SupplicantStatus& status) {
@@ -399,7 +420,7 @@
/*
* SetBtCoexistenceScanModeEnabled.
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetBtCoexistenceScanModeEnabled) {
+TEST_P(SupplicantStaIfaceHidlTest, SetBtCoexistenceScanModeEnabled) {
sta_iface_->setBtCoexistenceScanModeEnabled(
true, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -413,7 +434,7 @@
/*
* SetSuspendModeEnabled.
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetSuspendModeEnabled) {
+TEST_P(SupplicantStaIfaceHidlTest, SetSuspendModeEnabled) {
sta_iface_->setSuspendModeEnabled(true, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -426,7 +447,7 @@
/*
* SetCountryCode.
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetCountryCode) {
+TEST_P(SupplicantStaIfaceHidlTest, SetCountryCode) {
sta_iface_->setCountryCode(
kTestCountryCode, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -436,7 +457,7 @@
/*
* SetWpsDeviceName
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsDeviceName) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsDeviceName) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsDeviceName, kTestWpsDeviceName).code);
@@ -445,7 +466,7 @@
/*
* SetWpsDeviceType
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsDeviceType) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsDeviceType) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsDeviceType, kTestWpsDeviceType).code);
@@ -454,7 +475,7 @@
/*
* SetWpsManufacturer
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsManufacturer) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsManufacturer) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsManufacturer, kTestWpsManufacturer).code);
@@ -463,7 +484,7 @@
/*
* SetWpsModelName
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsModelName) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsModelName) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsModelName, kTestWpsModelName).code);
}
@@ -471,7 +492,7 @@
/*
* SetWpsModelNumber
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsModelNumber) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsModelNumber) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsModelNumber, kTestWpsModelNumber).code);
@@ -480,7 +501,7 @@
/*
* SetWpsSerialNumber
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsSerialNumber) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsSerialNumber) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsSerialNumber, kTestWpsSerialNumber).code);
@@ -489,7 +510,7 @@
/*
* SetWpsConfigMethods
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetWpsConfigMethods) {
+TEST_P(SupplicantStaIfaceHidlTest, SetWpsConfigMethods) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setWpsConfigMethods, kTestWpsConfigMethods)
@@ -499,7 +520,7 @@
/*
* SetExternalSim
*/
-TEST_F(SupplicantStaIfaceHidlTest, SetExternalSim) {
+TEST_P(SupplicantStaIfaceHidlTest, SetExternalSim) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, setExternalSim, true).code);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -509,7 +530,7 @@
/*
* AddExtRadioWork
*/
-TEST_F(SupplicantStaIfaceHidlTest, AddExtRadioWork) {
+TEST_P(SupplicantStaIfaceHidlTest, AddExtRadioWork) {
const auto& status_and_radio_work_id =
HIDL_INVOKE(sta_iface_, addExtRadioWork, kTestRadioWorkName,
kTestRadioWorkFrequency, kTestRadioWorkTimeout);
@@ -524,9 +545,18 @@
/*
* RemoveExtRadioWork
*/
-TEST_F(SupplicantStaIfaceHidlTest, RemoveExtRadioWork) {
+TEST_P(SupplicantStaIfaceHidlTest, RemoveExtRadioWork) {
// This fails because there is no on going radio work with kTestRadioWorkId.
EXPECT_NE(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_iface_, removeExtRadioWork, kTestRadioWorkId).code);
}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, SupplicantStaIfaceHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ISupplicant::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
index 832dd41..52f77a1 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -16,14 +16,16 @@
#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-
+#include <VtsCoreUtil.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
-
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include "supplicant_hidl_call_util.h"
#include "supplicant_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
using ::android::sp;
using ::android::hardware::hidl_array;
@@ -32,12 +34,14 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
using ::android::hardware::wifi::supplicant::V1_0::
ISupplicantStaNetworkCallback;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::V1_0::IWifi;
namespace {
constexpr char kTestSsidStr[] = "TestSsid1234";
@@ -74,37 +78,50 @@
ISupplicantStaNetwork::PairwiseCipherMask::TKIP);
} // namespace
-class SupplicantStaNetworkHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class SupplicantStaNetworkHidlTest
+ : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
public:
virtual void SetUp() override {
- startSupplicantAndWaitForHidlService();
- EXPECT_TRUE(turnOnExcessiveLogging());
- sta_network_ = createSupplicantStaNetwork();
+ wifi_instance_name_ = std::get<0>(GetParam());
+ supplicant_instance_name_ = std::get<1>(GetParam());
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ isP2pOn_ =
+ testing::deviceSupportsFeature("android.hardware.wifi.direct");
+ supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
+ EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+ sta_network_ = createSupplicantStaNetwork(supplicant_);
ASSERT_NE(sta_network_.get(), nullptr);
ssid_.assign(kTestSsidStr, kTestSsidStr + strlen(kTestSsidStr));
}
- virtual void TearDown() override { stopSupplicant(); }
+ virtual void TearDown() override { stopSupplicant(wifi_instance_name_); }
protected:
void removeNetwork() {
- sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
- ASSERT_NE(nullptr, sta_iface.get());
- uint32_t net_id;
- sta_network_->getId([&](const SupplicantStatus& status, int network_id) {
- ASSERT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- net_id = network_id;
- });
- sta_iface->removeNetwork(net_id, [](const SupplicantStatus& status) {
- ASSERT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- });
+ sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface(supplicant_);
+ ASSERT_NE(nullptr, sta_iface.get());
+ uint32_t net_id;
+ sta_network_->getId(
+ [&](const SupplicantStatus& status, int network_id) {
+ ASSERT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ net_id = network_id;
+ });
+ sta_iface->removeNetwork(net_id, [](const SupplicantStatus& status) {
+ ASSERT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
}
+ bool isP2pOn_ = false;
+ sp<ISupplicant> supplicant_;
// ISupplicantStaNetwork object used for all tests in this fixture.
sp<ISupplicantStaNetwork> sta_network_;
// SSID to use for various tests.
std::vector<uint8_t> ssid_;
+ std::string wifi_instance_name_;
+ std::string supplicant_instance_name_;
};
class NetworkCallback : public ISupplicantStaNetworkCallback {
@@ -126,16 +143,20 @@
* Ensures that an instance of the ISupplicantStaNetwork proxy object is
* successfully created.
*/
-TEST(SupplicantStaNetworkHidlTestNoFixture, Create) {
- startSupplicantAndWaitForHidlService();
- EXPECT_NE(nullptr, createSupplicantStaNetwork().get());
- stopSupplicant();
+TEST_P(SupplicantStaNetworkHidlTest, Create) {
+ stopSupplicant(wifi_instance_name_);
+ startSupplicantAndWaitForHidlService(wifi_instance_name_,
+ supplicant_instance_name_);
+ sp<ISupplicant> supplicant =
+ getSupplicant(supplicant_instance_name_, isP2pOn_);
+ EXPECT_TRUE(turnOnExcessiveLogging(supplicant));
+ EXPECT_NE(nullptr, createSupplicantStaNetwork(supplicant).get());
}
/*
* RegisterCallback
*/
-TEST_F(SupplicantStaNetworkHidlTest, RegisterCallback) {
+TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback) {
sta_network_->registerCallback(
new NetworkCallback(), [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -145,7 +166,7 @@
/*
* GetInterfaceName
*/
-TEST_F(SupplicantStaNetworkHidlTest, GetInterfaceName) {
+TEST_P(SupplicantStaNetworkHidlTest, GetInterfaceName) {
const auto& status_and_interface_name =
HIDL_INVOKE(sta_network_, getInterfaceName);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -156,7 +177,7 @@
/*
* GetType
*/
-TEST_F(SupplicantStaNetworkHidlTest, GetType) {
+TEST_P(SupplicantStaNetworkHidlTest, GetType) {
const auto& status_and_interface_type = HIDL_INVOKE(sta_network_, getType);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
status_and_interface_type.first.code);
@@ -167,7 +188,7 @@
/*
* SetGetSsid
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetSsid) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetSsid) {
sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -181,7 +202,7 @@
/*
* SetGetBssid
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetBssid) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetBssid) {
std::array<uint8_t, 6> set_bssid;
memcpy(set_bssid.data(), kTestBssid, set_bssid.size());
sta_network_->setBssid(set_bssid, [](const SupplicantStatus& status) {
@@ -199,7 +220,7 @@
/*
* SetGetKeyMgmt
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetKeyMgmt) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetKeyMgmt) {
sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -213,7 +234,7 @@
/*
* SetGetProto
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetProto) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetProto) {
sta_network_->setProto(kTestProto, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -226,7 +247,7 @@
/*
* SetGetKeyAuthAlg
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetAuthAlg) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetAuthAlg) {
sta_network_->setAuthAlg(kTestAuthAlg, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
@@ -240,7 +261,7 @@
/*
* SetGetGroupCipher
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupCipher) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetGroupCipher) {
sta_network_->setGroupCipher(
kTestGroupCipher, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -255,7 +276,7 @@
/*
* SetGetPairwiseCipher
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher) {
sta_network_->setPairwiseCipher(
kTestPairwiseCipher, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -270,7 +291,7 @@
/*
* SetGetPskPassphrase
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetPskPassphrase) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetPskPassphrase) {
sta_network_->setPskPassphrase(
kTestPskPassphrase, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -285,7 +306,7 @@
/*
* SetGetPsk
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetPsk) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetPsk) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, setPsk, kTestPsk).code);
const auto& status_and_psk = HIDL_INVOKE(sta_network_, getPsk);
@@ -297,7 +318,7 @@
/*
* SetGetWepKeys
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetWepTxKeyIdx) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetWepTxKeyIdx) {
sta_network_->setWepTxKeyIdx(
kTestWepTxKeyIdx, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -312,7 +333,7 @@
/*
* SetGetWepKeys
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetWepKeys) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetWepKeys) {
for (uint32_t i = 0;
i < static_cast<uint32_t>(
ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM);
@@ -334,7 +355,7 @@
/*
* SetGetScanSsid
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetScanSsid) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetScanSsid) {
sta_network_->setScanSsid(
true, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -349,7 +370,7 @@
/*
* SetGetRequirePmf
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetRequirePmf) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetRequirePmf) {
sta_network_->setRequirePmf(
true, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -364,7 +385,7 @@
/*
* SetGetIdStr
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetIdStr) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetIdStr) {
sta_network_->setIdStr(
kTestIdStr, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -376,11 +397,10 @@
});
}
-
/*
* SetGetEapMethod
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapMethod) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapMethod) {
ISupplicantStaNetwork::EapMethod set_eap_method =
ISupplicantStaNetwork::EapMethod::PEAP;
sta_network_->setEapMethod(
@@ -398,7 +418,7 @@
/*
* SetGetEapPhase2Method
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPhase2Method) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapPhase2Method) {
ISupplicantStaNetwork::EapMethod set_eap_method =
ISupplicantStaNetwork::EapMethod::PEAP;
sta_network_->setEapMethod(
@@ -422,7 +442,7 @@
/*
* SetGetEapIdentity
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapIdentity) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapIdentity) {
std::vector<uint8_t> set_identity(kTestIdentity, kTestIdentity + sizeof(kTestIdentity));
sta_network_->setEapIdentity(
set_identity, [](const SupplicantStatus& status) {
@@ -438,7 +458,7 @@
/*
* SetGetEapAnonymousIdentity
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapAnonymousIdentity) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapAnonymousIdentity) {
std::vector<uint8_t> set_identity(kTestIdentity, kTestIdentity + sizeof(kTestIdentity));
sta_network_->setEapAnonymousIdentity(
set_identity, [](const SupplicantStatus& status) {
@@ -454,7 +474,7 @@
/*
* SetGetEapPassword
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPassword) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapPassword) {
std::vector<uint8_t> set_eap_passwd(
kTestEapPasswdStr, kTestEapPasswdStr + strlen(kTestEapPasswdStr));
sta_network_->setEapPassword(
@@ -471,7 +491,7 @@
/*
* SetGetEapCACert
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapCACert) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapCACert) {
sta_network_->setEapCACert(
kTestEapCert, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -486,7 +506,7 @@
/*
* SetGetEapCAPath
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapCAPath) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapCAPath) {
sta_network_->setEapCAPath(
kTestEapCert, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -501,7 +521,7 @@
/*
* SetGetEapClientCert
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapClientCert) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapClientCert) {
sta_network_->setEapClientCert(
kTestEapCert, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -516,7 +536,7 @@
/*
* SetGetEapPrivateKeyId
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPrivateKeyId) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapPrivateKeyId) {
sta_network_->setEapPrivateKeyId(
kTestEapPrivateKeyId, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -531,7 +551,7 @@
/*
* SetGetEapAltSubjectMatch
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapAltSubjectMatch) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapAltSubjectMatch) {
sta_network_->setEapAltSubjectMatch(
kTestEapMatch, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -546,7 +566,7 @@
/*
* SetGetEapSubjectMatch
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapSubjectMatch) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapSubjectMatch) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, setEapSubjectMatch, kTestEapMatch).code);
@@ -561,7 +581,7 @@
/*
* SetGetEapDomainSuffixMatch
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapDomainSuffixMatch) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapDomainSuffixMatch) {
sta_network_->setEapDomainSuffixMatch(
kTestEapMatch, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -576,7 +596,7 @@
/*
* SetGetEapEngine
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapEngine) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapEngine) {
sta_network_->setEapEngine(
true, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -591,7 +611,7 @@
/*
* SetGetEapEngineID
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetGetEapEngineID) {
+TEST_P(SupplicantStaNetworkHidlTest, SetGetEapEngineID) {
sta_network_->setEapEngineID(
kTestEapEngineID, [](const SupplicantStatus& status) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
@@ -606,7 +626,7 @@
/*
* Enable
*/
-TEST_F(SupplicantStaNetworkHidlTest, Enable) {
+TEST_P(SupplicantStaNetworkHidlTest, Enable) {
// wpa_supplicant doesn't perform any connection initiation
// unless atleast the Ssid and Ket mgmt params are set.
sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
@@ -633,7 +653,7 @@
/*
* Disable
*/
-TEST_F(SupplicantStaNetworkHidlTest, Disable) {
+TEST_P(SupplicantStaNetworkHidlTest, Disable) {
// wpa_supplicant doesn't perform any connection initiation
// unless atleast the Ssid and Ket mgmt params are set.
sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
@@ -656,7 +676,7 @@
/*
* Select.
*/
-TEST_F(SupplicantStaNetworkHidlTest, Select) {
+TEST_P(SupplicantStaNetworkHidlTest, Select) {
// wpa_supplicant doesn't perform any connection initiation
// unless atleast the Ssid and Ket mgmt params are set.
sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
@@ -679,7 +699,7 @@
/*
* SendNetworkEapSimGsmAuthResponse
*/
-TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthResponse) {
+TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthResponse) {
std::vector<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
params;
ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams param;
@@ -695,7 +715,7 @@
/*
* SendNetworkEapSimGsmAuthFailure
*/
-TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthFailure) {
+TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthFailure) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, sendNetworkEapSimGsmAuthFailure).code);
}
@@ -703,7 +723,7 @@
/*
* SendNetworkEapSimUmtsAuthResponse
*/
-TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthResponse) {
+TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthResponse) {
ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams params;
params.res = std::vector<uint8_t>(kTestRes, kTestRes + sizeof(kTestRes));
memcpy(params.ik.data(), kTestIk, params.ik.size());
@@ -717,7 +737,7 @@
/*
* SendNetworkEapSimUmtsAuthFailure
*/
-TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthFailure) {
+TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthFailure) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, sendNetworkEapSimUmtsAuthFailure).code);
}
@@ -725,7 +745,7 @@
/*
* SendNetworkEapSimUmtsAutsResponse
*/
-TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAutsResponse) {
+TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAutsResponse) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, sendNetworkEapSimUmtsAutsResponse,
kTestAutParam)
@@ -735,7 +755,7 @@
/*
* SendNetworkEapIdentityResponse
*/
-TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse) {
+TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse) {
sta_network_->sendNetworkEapIdentityResponse(
std::vector<uint8_t>(kTestIdentity,
kTestIdentity + sizeof(kTestIdentity)),
@@ -747,7 +767,7 @@
/*
* SetUpdateIdentifier
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetUpdateIdentifier) {
+TEST_P(SupplicantStaNetworkHidlTest, SetUpdateIdentifier) {
EXPECT_EQ(
SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, setUpdateIdentifier, kTestUpdateIdentifier)
@@ -757,7 +777,7 @@
/*
* SetProactiveKeyCaching
*/
-TEST_F(SupplicantStaNetworkHidlTest, SetProactiveKeyCaching) {
+TEST_P(SupplicantStaNetworkHidlTest, SetProactiveKeyCaching) {
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, setProactiveKeyCaching, true).code);
EXPECT_EQ(SupplicantStatusCode::SUCCESS,
@@ -767,7 +787,7 @@
/*
* GetWpsNfcConfigurationToken
*/
-TEST_F(SupplicantStaNetworkHidlTest, GetWpsNfcConfigurationToken) {
+TEST_P(SupplicantStaNetworkHidlTest, GetWpsNfcConfigurationToken) {
ASSERT_EQ(SupplicantStatusCode::SUCCESS,
HIDL_INVOKE(sta_network_, setSsid, ssid_).code);
ASSERT_EQ(SupplicantStatusCode::SUCCESS,
@@ -780,3 +800,12 @@
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status_and_token.first.code);
EXPECT_FALSE(0 == status_and_token.second.size());
}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, SupplicantStaNetworkHidlTest,
+ testing::Combine(
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+ ISupplicant::descriptor))),
+ android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file