Merge "Avoid calling non-exist set_mode hal function"
diff --git a/audio/2.0/vts/functional/Android.bp b/audio/2.0/vts/functional/Android.bp
index 02f9330..f5ab76f 100644
--- a/audio/2.0/vts/functional/Android.bp
+++ b/audio/2.0/vts/functional/Android.bp
@@ -22,6 +22,7 @@
"libbase",
"liblog",
"libhidlbase",
+ "libhidltransport",
"libutils",
"libcutils",
"android.hardware.audio@2.0",
diff --git a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index e50b912..6270c9c 100644
--- a/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -50,6 +50,7 @@
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::audio::V2_0::AudioDrain;
using ::android::hardware::audio::V2_0::DeviceAddress;
using ::android::hardware::audio::V2_0::IDevice;
using ::android::hardware::audio::V2_0::IPrimaryDevice;
@@ -57,9 +58,11 @@
using ::android::hardware::audio::V2_0::IDevicesFactory;
using ::android::hardware::audio::V2_0::IStream;
using ::android::hardware::audio::V2_0::IStreamIn;
+using ::android::hardware::audio::V2_0::TimeSpec;
using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
using ::android::hardware::audio::V2_0::IStreamOut;
+using ::android::hardware::audio::V2_0::IStreamOutCallback;
using ::android::hardware::audio::V2_0::MmapBufferInfo;
using ::android::hardware::audio::V2_0::MmapPosition;
using ::android::hardware::audio::V2_0::ParameterValue;
@@ -790,9 +793,9 @@
checkGetParameter(stream.get(), {"Non existing key"} /* keys */,
{Result::INVALID_ARGUMENTS}))
-static vector<Result> okOrNotSupported = {Result::OK, Result::INVALID_ARGUMENTS};
+static vector<Result> okOrInvalidArguments = {Result::OK, Result::INVALID_ARGUMENTS};
TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
- ASSERT_RESULT(okOrNotSupported, stream->setParameters({})))
+ ASSERT_RESULT(okOrInvalidArguments, stream->setParameters({})))
TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
ASSERT_RESULT(Result::INVALID_ARGUMENTS,
@@ -921,6 +924,183 @@
}
//////////////////////////////////////////////////////////////////////////////
+///////////////////////////////// StreamIn ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+TEST_P(OutputStreamTest, getLatency) {
+ doc::test("Make sure latency is over 0");
+ auto result = stream->getLatency();
+ ASSERT_TRUE(result.isOk());
+ ASSERT_GT(result, 0U);
+}
+
+TEST_P(OutputStreamTest, setVolume) {
+ doc::test("Try to set the output volume");
+ auto result = stream->setVolume(1, 1);
+ ASSERT_TRUE(result.isOk());
+ if (result == Result::NOT_SUPPORTED) {
+ doc::partialTest("setVolume is not supported");
+ return;
+ }
+ testUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); });
+}
+
+static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
+ Result res;
+ // Ignore output parameters as the call should fail
+ ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
+ [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
+ EXPECT_RESULT(invalidArgsOrNotSupported, res);
+}
+
+TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
+ doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
+ testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
+}
+
+TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
+ doc::test("Preparing a stream for writing with a overflowing sized buffer should fail");
+ auto uintMax = std::numeric_limits<uint32_t>::max();
+ testPrepareForWriting(stream.get(), uintMax, uintMax);
+}
+
+struct Capability {
+ Capability(IStreamOut* stream) {
+ EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
+ auto ret = stream->supportsDrain();
+ EXPECT_TRUE(ret.isOk());
+ if (ret.isOk()) {
+ drain = ret;
+ }
+ }
+ bool pause = false;
+ bool resume = false;
+ bool drain = false;
+};
+
+TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
+ Capability(stream.get());
+}
+
+TEST_P(OutputStreamTest, GetRenderPosition) {
+ uint32_t dspFrames;
+ ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
+ if (res == Result::NOT_SUPPORTED) {
+ doc::partialTest("getRenderPosition is not supported");
+ return;
+ }
+ ASSERT_OK(res);
+ ASSERT_EQ(0U, dspFrames);
+}
+
+TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
+ uint64_t timestampUs;
+ ASSERT_OK(stream->getRenderPosition(returnIn(res, timestampUs)));
+ if (res == Result::NOT_SUPPORTED) {
+ doc::partialTest("getRenderPosition is not supported");
+ return;
+ }
+ ASSERT_OK(res);
+ ASSERT_EQ(0U, timestampUs);
+}
+
+/** Stub implementation of out stream callback. */
+class MockOutCallbacks : public IStreamOutCallback {
+ Return<void> onWriteReady() override { return {}; }
+ Return<void> onDrainReady() override { return {}; }
+ Return<void> onError() override { return {}; }
+};
+
+static bool isAsyncModeSupported(IStreamOut *stream) {
+ auto res = stream->setCallback(new MockOutCallbacks);
+ stream->clearCallback(); // try to restore the no callback state, ignore any error
+ auto okOrNotSupported = { Result::OK, Result::NOT_SUPPORTED };
+ EXPECT_RESULT(okOrNotSupported, res);
+ return res.isOk() ? res == Result::OK : false;
+}
+
+TEST_P(OutputStreamTest, SetCallback) {
+ if (!isAsyncModeSupported(stream.get())) {
+ doc::partialTest("The stream does not support async operations");
+ return;
+ }
+ ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+ ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+}
+
+TEST_P(OutputStreamTest, clearCallback) {
+ if (!isAsyncModeSupported(stream.get())) {
+ doc::partialTest("The stream does not support async operations");
+ return;
+ }
+ // TODO: Clarify if clearing a non existing callback should fail
+ ASSERT_OK(stream->setCallback(new MockOutCallbacks));
+ ASSERT_OK(stream->clearCallback());
+}
+
+TEST_P(OutputStreamTest, Resume) {
+ if (!Capability(stream.get()).resume) {
+ doc::partialTest("The output stream does not support resume");
+ return;
+ }
+ ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+}
+
+TEST_P(OutputStreamTest, Pause) {
+ if (!Capability(stream.get()).pause) {
+ doc::partialTest("The output stream does not support pause");
+ return;
+ }
+ ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+}
+
+static void testDrain(IStreamOut *stream, AudioDrain type) {
+ if (!Capability(stream).drain) {
+ doc::partialTest("The output stream does not support pause");
+ return;
+ }
+ ASSERT_RESULT(Result::OK, stream->drain(type));
+}
+
+TEST_P(OutputStreamTest, DrainAll) {
+ testDrain(stream.get(), AudioDrain::ALL);
+}
+
+TEST_P(OutputStreamTest, DrainEarlyNotify) {
+ testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
+}
+
+TEST_P(OutputStreamTest, FlushStop) {
+ ASSERT_OK(stream->flush());
+}
+
+/** Return thee difference in us of two TimeSpec */
+uint64_t operator-(TimeSpec left, TimeSpec right) {
+ auto toMicroSec = [](auto ts) { return ts.tvSec * 1e+6 + ts.tvNSec / 1e+3; };
+ return toMicroSec(left) - toMicroSec(right);
+}
+
+TEST_P(OutputStreamTest, GetPresentationPositionStop) {
+ uint64_t frames;
+ TimeSpec mesureTS;
+ ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
+ if (res == Result::NOT_SUPPORTED) {
+ doc::partialTest("getpresentationPosition is not supported");
+ return;
+ }
+ ASSERT_EQ(0U, frames);
+
+ struct timespec currentTS;
+ ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, ¤tTS)) << errno;
+
+ auto toMicroSec = [](uint64_t sec, auto nsec) { return sec * 1e+6 + nsec / 1e+3; };
+ auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
+ auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
+ ASSERT_PRED2([](auto c, auto m){ return c - m < 1e+6; }, currentTime, mesureTime);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
/////////////////////////////// PrimaryDevice ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
diff --git a/audio/2.0/vts/functional/utility/AssertOk.h b/audio/2.0/vts/functional/utility/AssertOk.h
index 39c9a1d..10b088c 100644
--- a/audio/2.0/vts/functional/utility/AssertOk.h
+++ b/audio/2.0/vts/functional/utility/AssertOk.h
@@ -29,13 +29,13 @@
ASSERT_EQ(expected, result);
}
-inline void assertResult(Result expected, Return<Result> ret) {
+inline void assertResult(Result expected, const Return<Result> &ret) {
ASSERT_TRUE(ret.isOk());
Result result = ret;
assertResult(expected, result);
}
-inline void assertResult(std::vector<Result> expected, Result result) {
+inline void assertResult(const std::vector<Result> &expected, Result result) {
if (std::find(expected.begin(), expected.end(), result) != expected.end()) {
return; // result is in expected
}
@@ -43,13 +43,13 @@
<< " to be one of " << ::testing::PrintToString(expected);
}
-inline void assertResult(std::vector<Result> expected, Return<Result> ret) {
+inline void assertResult(const std::vector<Result> &expected, const Return<Result> &ret) {
ASSERT_TRUE(ret.isOk());
Result result = ret;
assertResult(expected, result);
}
-inline void assertOk(Return<void> ret) {
+inline void assertOk(const Return<void> &ret) {
ASSERT_TRUE(ret.isOk());
}
@@ -57,8 +57,8 @@
assertResult(Result::OK, result);
}
-inline void assertOk(Return<Result> ret) {
- assertResult(Result::OK, std::move(ret));
+inline void assertOk(const Return<Result> &ret) {
+ assertResult(Result::OK, ret);
}
}
@@ -68,4 +68,4 @@
#define EXPECT_OK(ret) EXPECT_NO_FATAL_FAILURE(detail::assertOk(ret))
#define ASSERT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
-#define EXPECT_RESULT(expected, ret) ASSERT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
+#define EXPECT_RESULT(expected, ret) EXPECT_NO_FATAL_FAILURE(detail::assertResult(expected, ret))
diff --git a/audio/common/2.0/types.hal b/audio/common/2.0/types.hal
index 93b898b..8760a58 100644
--- a/audio/common/2.0/types.hal
+++ b/audio/common/2.0/types.hal
@@ -672,7 +672,7 @@
DIRECT_PCM = 0x2000, // Audio stream containing PCM data that needs
// to pass through compress path for DSP post proc.
MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode.
- VOIP_CALL_RX = 0x8000, // preferred output for VoIP calls.
+ VOIP_RX = 0x8000, // preferred output for VoIP calls.
};
/*
@@ -689,7 +689,7 @@
RAW = 0x4, // minimize signal processing
SYNC = 0x8, // synchronize I/O streams
MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode.
- VOIP_CALL_TX = 0x20, // preferred input for VoIP calls.
+ VOIP_TX = 0x20, // preferred input for VoIP calls.
};
@export(name="audio_usage_t", value_prefix="AUDIO_USAGE_")
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 95ca37b..545de39 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
@@ -28,9 +28,9 @@
namespace impl {
-const VehicleProperty kHvacPowerProperties[] = {
- VehicleProperty::HVAC_FAN_SPEED,
- VehicleProperty::HVAC_FAN_DIRECTION,
+const int32_t kHvacPowerProperties[] = {
+ toInt(VehicleProperty::HVAC_FAN_SPEED),
+ toInt(VehicleProperty::HVAC_FAN_DIRECTION),
};
const VehiclePropConfig kVehicleProperties[] = {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
index 808aafb..e6a3e56 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
@@ -503,16 +503,15 @@
StatusCode status;
switch (propId) {
default:
- if (mHvacPowerProps.find(VehicleProperty(propId)) !=
- mHvacPowerProps.end()) {
- auto prop = mProps.find(
- std::make_pair(toInt(VehicleProperty::HVAC_POWER_ON), 0));
- if (prop != mProps.end()) {
- if (prop->second->value.int32Values.size() == 1 &&
- prop->second->value.int32Values[0] == 0) {
- status = StatusCode::NOT_AVAILABLE;
- break;
- }
+ if (mHvacPowerProps.count(propId)) {
+ std::lock_guard<std::mutex> lock(mPropsMutex);
+ auto hvacPowerOn = getVehiclePropValueLocked(toInt(VehicleProperty::HVAC_POWER_ON),
+ toInt(VehicleAreaZone::ROW_1));
+
+ if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1
+ && hvacPowerOn->value.int32Values[0] == 0) {
+ status = StatusCode::NOT_AVAILABLE;
+ break;
}
}
status = updateProperty(propValue);
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
index 98eef27..bbbe955 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
@@ -47,7 +47,7 @@
DefaultVehicleHal() : mRecurrentTimer(
std::bind(&DefaultVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)) {
for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
- mPropConfigMap[kVehicleProperties->prop] = &kVehicleProperties[i];
+ mPropConfigMap[kVehicleProperties[i].prop] = &kVehicleProperties[i];
}
}
@@ -108,7 +108,7 @@
std::pair<int32_t /*VehicleProperty*/, int32_t /*areaId*/>,
std::unique_ptr<VehiclePropValue>> mProps;
std::atomic<int> mExit;
- std::unordered_set<VehicleProperty> mHvacPowerProps;
+ std::unordered_set<int32_t> mHvacPowerProps;
std::mutex mPropsMutex;
std::thread mThread;
std::unique_ptr<CommBase> mComm{nullptr};
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index b33b6ee..a998d33 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -191,7 +191,7 @@
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE|VehiclePropertyChangeMode:CONTINUOUS
* @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELCIUS
+ * @unit VehicleUnit:CELSIUS
*/
ENGINE_COOLANT_TEMP = (
0x0301
@@ -204,7 +204,7 @@
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE|VehiclePropertyChangeMode:CONTINUOUS
* @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELCIUS
+ * @unit VehicleUnit:CELSIUS
*/
ENGINE_OIL_TEMP = (
0x0304
@@ -645,7 +645,7 @@
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE|VehiclePropertyChangeMode:CONTINUOUS
* @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELCIUS
+ * @unit VehicleUnit:CELSIUS
*/
ENV_OUTSIDE_TEMPERATURE = (
0x0703
@@ -658,7 +658,7 @@
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE|VehiclePropertyChangeMode:CONTINUOUS
* @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELCIUS
+ * @unit VehicleUnit:CELSIUS
*/
ENV_CABIN_TEMPERATURE = (
0x0704
diff --git a/automotive/vehicle/2.1/Android.bp b/automotive/vehicle/2.1/Android.bp
index dcf395c..cf4d8b0 100644
--- a/automotive/vehicle/2.1/Android.bp
+++ b/automotive/vehicle/2.1/Android.bp
@@ -51,6 +51,7 @@
"libutils",
"libcutils",
"android.hardware.automotive.vehicle@2.0",
+ "android.hidl.base@1.0",
],
export_shared_lib_headers: [
"libhidlbase",
@@ -58,5 +59,6 @@
"libhwbinder",
"libutils",
"android.hardware.automotive.vehicle@2.0",
+ "android.hidl.base@1.0",
],
}
diff --git a/biometrics/fingerprint/2.1/default/service.cpp b/biometrics/fingerprint/2.1/default/service.cpp
index d6b91c6..1697c07 100644
--- a/biometrics/fingerprint/2.1/default/service.cpp
+++ b/biometrics/fingerprint/2.1/default/service.cpp
@@ -35,7 +35,7 @@
configureRpcThreadpool(1, true /*callerWillJoin*/);
if (bio != nullptr) {
- bio->registerAsService("fingerprint_hal");
+ bio->registerAsService();
} else {
ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
}
diff --git a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
index c07c3e3..cd38f2e 100644
--- a/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
+++ b/biometrics/fingerprint/2.1/vts/functional/VtsHalBiometricsFingerprintV2_1TargetTest.cpp
@@ -15,7 +15,6 @@
*/
#define LOG_TAG "fingerprint_hidl_hal_test"
-#define SERVICE_NAME "fingerprint_hal"
#include <android-base/logging.h>
#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
@@ -123,7 +122,7 @@
FingerprintHidlTest (): mCallbackCalled(false) {}
virtual void SetUp() override {
- mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFingerprint>(SERVICE_NAME);
+ mService = ::testing::VtsHalHidlTargetTestBase::getService<IBiometricsFingerprint>();
ASSERT_NE(mService, nullptr);
clearErr();
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
index 5a282bf..fec5b81 100644
--- a/bluetooth/1.0/default/bluetooth_hci.cc
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -30,6 +30,19 @@
static const uint8_t HCI_DATA_TYPE_ACL = 2;
static const uint8_t HCI_DATA_TYPE_SCO = 3;
+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");
+ mHci->close();
+ }
+ sp<IBluetoothHci> mHci;
+};
+
BluetoothHci::BluetoothHci()
: deathRecipient(new BluetoothDeathRecipient(this)) {}
@@ -41,19 +54,37 @@
bool rc = VendorInterface::Initialize(
[this](bool status) {
- event_cb_->initializationComplete(
+ auto hidl_status = event_cb_->initializationComplete(
status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call initializationComplete()");
+ }
},
[this](const hidl_vec<uint8_t>& packet) {
- event_cb_->hciEventReceived(packet);
+ auto hidl_status = event_cb_->hciEventReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call hciEventReceived()");
+ }
},
[this](const hidl_vec<uint8_t>& packet) {
- event_cb_->aclDataReceived(packet);
+ auto hidl_status = event_cb_->aclDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call aclDataReceived()");
+ }
},
[this](const hidl_vec<uint8_t>& packet) {
- event_cb_->scoDataReceived(packet);
+ auto hidl_status = event_cb_->scoDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call scoDataReceived()");
+ }
});
- if (!rc) event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
+ if (!rc) {
+ auto hidl_status =
+ event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
+ }
+ }
return Void();
}
diff --git a/bluetooth/1.0/default/bluetooth_hci.h b/bluetooth/1.0/default/bluetooth_hci.h
index 67d6c37..4f92231 100644
--- a/bluetooth/1.0/default/bluetooth_hci.h
+++ b/bluetooth/1.0/default/bluetooth_hci.h
@@ -30,16 +30,7 @@
using ::android::hardware::Return;
using ::android::hardware::hidl_vec;
-struct BluetoothDeathRecipient : hidl_death_recipient {
- BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
-
- virtual void serviceDied(
- uint64_t /*cookie*/,
- const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
- mHci->close();
- }
- sp<IBluetoothHci> mHci;
-};
+class BluetoothDeathRecipient;
class BluetoothHci : public IBluetoothHci {
public:
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index 26f52f7..68cac5f 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -248,10 +248,9 @@
new hci::MctProtocol(fd_list, intercept_events, acl_cb);
fd_watcher_.WatchFdForNonBlockingReads(
fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
- if (fd_count >= CH_ACL_IN)
- fd_watcher_.WatchFdForNonBlockingReads(
- fd_list[CH_ACL_IN],
- [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
+ fd_watcher_.WatchFdForNonBlockingReads(
+ fd_list[CH_ACL_IN],
+ [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
hci_ = mct_hci;
}
@@ -266,6 +265,13 @@
}
void VendorInterface::Close() {
+ // These callbacks may send HCI events (vendor-dependent), so make sure to
+ // StopWatching the file descriptor after this.
+ if (lib_interface_ != nullptr) {
+ bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
+ lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
+ }
+
fd_watcher_.StopWatchingFileDescriptors();
if (hci_ != nullptr) {
diff --git a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
index 74911f0..4ec19c7 100644
--- a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
+++ b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
@@ -33,7 +33,6 @@
using ::android::Mutex;
using ::android::Condition;
using ::android::hardware::Return;
-using ::android::hardware::Status;
using ::android::hardware::Void;
using ::android::hardware::broadcastradio::V1_0::IBroadcastRadioFactory;
using ::android::hardware::broadcastradio::V1_0::IBroadcastRadio;
@@ -455,6 +454,7 @@
* - the HAL implements the method
* - the method returns 0 (no error)
* - the tuned callback is received within kTuneCallbacktimeoutNs ns
+ * - skipping sub-channel or not does not fail the call
*/
TEST_F(BroadcastRadioHidlTest, Scan) {
ASSERT_EQ(true, openTuner());
@@ -468,7 +468,7 @@
// test scan DOWN
mCallbackCalled = false;
- hidlResult = mTuner->scan(Direction::DOWN, true);
+ hidlResult = mTuner->scan(Direction::DOWN, false);
EXPECT_TRUE(hidlResult.isOk());
EXPECT_EQ(Result::OK, hidlResult);
EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
@@ -481,13 +481,14 @@
* - the HAL implements the method
* - the method returns 0 (no error)
* - the tuned callback is received within kTuneCallbacktimeoutNs ns
+ * - skipping sub-channel or not does not fail the call
*/
TEST_F(BroadcastRadioHidlTest, Step) {
ASSERT_EQ(true, openTuner());
ASSERT_TRUE(checkAntenna());
// test step UP
mCallbackCalled = false;
- Return<Result> hidlResult = mTuner->step(Direction::UP, true);
+ Return<Result> hidlResult = mTuner->step(Direction::UP, false);
EXPECT_TRUE(hidlResult.isOk());
EXPECT_EQ(Result::OK, hidlResult);
EXPECT_EQ(true, waitForCallback(kTuneCallbacktimeoutNs));
diff --git a/broadcastradio/1.1/Android.bp b/broadcastradio/1.1/Android.bp
index c9a8b10..570d1ae 100644
--- a/broadcastradio/1.1/Android.bp
+++ b/broadcastradio/1.1/Android.bp
@@ -65,6 +65,7 @@
"libutils",
"libcutils",
"android.hardware.broadcastradio@1.0",
+ "android.hidl.base@1.0",
],
export_shared_lib_headers: [
"libhidlbase",
@@ -72,5 +73,6 @@
"libhwbinder",
"libutils",
"android.hardware.broadcastradio@1.0",
+ "android.hidl.base@1.0",
],
}
diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
index aad01f6..a29f6dc 100644
--- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
+++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
@@ -35,7 +35,6 @@
using ::android::Mutex;
using ::android::Condition;
using ::android::hardware::Return;
-using ::android::hardware::Status;
using ::android::hardware::Void;
using ::android::hardware::broadcastradio::V1_0::BandConfig;
using ::android::hardware::broadcastradio::V1_0::Class;
diff --git a/camera/device/3.2/ICameraDeviceCallback.hal b/camera/device/3.2/ICameraDeviceCallback.hal
index 753d085..bf51da2 100644
--- a/camera/device/3.2/ICameraDeviceCallback.hal
+++ b/camera/device/3.2/ICameraDeviceCallback.hal
@@ -35,7 +35,8 @@
/**
* processCaptureResult:
*
- * Send results from a completed capture to the framework.
+ * Send results from one or more completed or partially completed captures
+ * to the framework.
* processCaptureResult() may be invoked multiple times by the HAL in
* response to a single capture request. This allows, for example, the
* metadata and low-resolution buffers to be returned in one call, and
@@ -61,11 +62,14 @@
* acceptable and expected that the buffer for request 5 for stream A may be
* returned after the buffer for request 6 for stream B is. And it is
* acceptable that the result metadata for request 6 for stream B is
- * returned before the buffer for request 5 for stream A is.
+ * returned before the buffer for request 5 for stream A is. If multiple
+ * capture results are included in a single call, camera framework must
+ * process results sequentially from lower index to higher index, as if
+ * these results were sent to camera framework one by one, from lower index
+ * to higher index.
*
* The HAL retains ownership of result structure, which only needs to be
- * valid to access during this call. The framework must copy whatever it
- * needs before this call returns.
+ * valid to access during this call.
*
* The output buffers do not need to be filled yet; the framework must wait
* on the stream buffer release sync fence before reading the buffer
@@ -93,20 +97,23 @@
*
* Performance requirements:
*
- * This is a non-blocking call. The framework must return this call in 5ms.
+ * This is a non-blocking call. The framework must handle each CaptureResult
+ * within 5ms.
*
* The pipeline latency (see S7 for definition) should be less than or equal to
* 4 frame intervals, and must be less than or equal to 8 frame intervals.
*
*/
- processCaptureResult(CaptureResult result);
+ processCaptureResult(vec<CaptureResult> results);
/**
* notify:
*
* Asynchronous notification callback from the HAL, fired for various
* reasons. Only for information independent of frame capture, or that
- * require specific timing.
+ * require specific timing. Multiple messages may be sent in one call; a
+ * message with a higher index must be considered to have occurred after a
+ * message with a lower index.
*
* Multiple threads may call notify() simultaneously.
*
@@ -119,8 +126,8 @@
* ------------------------------------------------------------------------
* Performance requirements:
*
- * This is a non-blocking call. The framework must return this call in 5ms.
+ * This is a non-blocking call. The framework must handle each message in 5ms.
*/
- notify(NotifyMsg msg);
+ notify(vec<NotifyMsg> msgs);
};
diff --git a/camera/device/3.2/ICameraDeviceSession.hal b/camera/device/3.2/ICameraDeviceSession.hal
index e92d756..d8d3177 100644
--- a/camera/device/3.2/ICameraDeviceSession.hal
+++ b/camera/device/3.2/ICameraDeviceSession.hal
@@ -171,14 +171,16 @@
/**
* processCaptureRequest:
*
- * Send a new capture request to the HAL. The HAL must not return from
- * this call until it is ready to accept the next request to process. Only
- * one call to processCaptureRequest() must be made at a time by the
- * framework, and the calls must all be from the same thread. The next call
- * to processCaptureRequest() must be made as soon as a new request and
- * its associated buffers are available. In a normal preview scenario, this
- * means the function is generally called again by the framework almost
- * instantly.
+ * Send a list of capture requests to the HAL. The HAL must not return from
+ * this call until it is ready to accept the next set of requests to
+ * process. Only one call to processCaptureRequest() must be made at a time
+ * by the framework, and the calls must all be from the same thread. The
+ * next call to processCaptureRequest() must be made as soon as a new
+ * request and its associated buffers are available. In a normal preview
+ * scenario, this means the function is generally called again by the
+ * framework almost instantly. If more than one request is provided by the
+ * client, the HAL must process the requests in order of lowest index to
+ * highest index.
*
* The actual request processing is asynchronous, with the results of
* capture being returned by the HAL through the processCaptureResult()
@@ -229,10 +231,14 @@
* If the camera device has encountered a serious error. After this
* error is returned, only the close() method can be successfully
* called by the framework.
+ * @return numRequestProcessed Number of requests successfully processed by
+ * camera HAL. When status is OK, this must be equal to the size of
+ * requests. When the call fails, this number is the number of requests
+ * that HAL processed successfully before HAL runs into an error.
*
*/
- processCaptureRequest(CaptureRequest request)
- generates (Status status);
+ processCaptureRequest(vec<CaptureRequest> requests)
+ generates (Status status, uint32_t numRequestProcessed);
/**
* flush:
diff --git a/camera/device/3.2/default/CameraDevice.cpp b/camera/device/3.2/default/CameraDevice.cpp
index 0a457ad..a742335 100644
--- a/camera/device/3.2/default/CameraDevice.cpp
+++ b/camera/device/3.2/default/CameraDevice.cpp
@@ -229,7 +229,18 @@
return Void();
}
- session = new CameraDeviceSession(device, callback);
+ struct camera_info info;
+ res = mModule->getCameraInfo(mCameraIdInt, &info);
+ if (res != OK) {
+ ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
+ device->common.close(&device->common);
+ mLock.unlock();
+ _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
+ return Void();
+ }
+
+ session = new CameraDeviceSession(
+ device, info.static_camera_characteristics, callback);
if (session == nullptr) {
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
mLock.unlock();
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index ae5d576..fb1d1ff 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "CamDevSession@3.2-impl"
#include <android/log.h>
+#include <set>
#include <utils/Trace.h>
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
@@ -30,12 +31,25 @@
namespace implementation {
HandleImporter& CameraDeviceSession::sHandleImporter = HandleImporter::getInstance();
+const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
CameraDeviceSession::CameraDeviceSession(
- camera3_device_t* device, const sp<ICameraDeviceCallback>& callback) :
+ camera3_device_t* device,
+ const camera_metadata_t* deviceInfo,
+ const sp<ICameraDeviceCallback>& callback) :
camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
mDevice(device),
- mCallback(callback) {
+ mResultBatcher(callback) {
+
+ mDeviceInfo = deviceInfo;
+ uint32_t numPartialResults = 1;
+ camera_metadata_entry partialResultsCount =
+ mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
+ if (partialResultsCount.count > 0) {
+ numPartialResults = partialResultsCount.data.i32[0];
+ }
+ mResultBatcher.setNumPartialResults(numPartialResults);
+
mInitFail = initialize();
}
@@ -177,6 +191,354 @@
}
}
+CameraDeviceSession::ResultBatcher::ResultBatcher(
+ const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {};
+
+bool CameraDeviceSession::ResultBatcher::InflightBatch::allDelivered() const {
+ if (!mShutterDelivered) return false;
+
+ if (mPartialResultProgress < mNumPartialResults) {
+ return false;
+ }
+
+ for (const auto& pair : mBatchBufs) {
+ if (!pair.second.mDelivered) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) {
+ Mutex::Autolock _l(mLock);
+ mNumPartialResults = n;
+}
+
+void CameraDeviceSession::ResultBatcher::setBatchedStreams(
+ const std::vector<int>& streamsToBatch) {
+ Mutex::Autolock _l(mLock);
+ mStreamsToBatch = streamsToBatch;
+}
+
+void CameraDeviceSession::ResultBatcher::registerBatch(
+ const hidl_vec<CaptureRequest>& requests) {
+ auto batch = std::make_shared<InflightBatch>();
+ batch->mFirstFrame = requests[0].frameNumber;
+ batch->mBatchSize = requests.size();
+ batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
+ batch->mNumPartialResults = mNumPartialResults;
+ for (int id : mStreamsToBatch) {
+ batch->mBatchBufs[id] = InflightBatch::BufferBatch();
+ }
+ Mutex::Autolock _l(mLock);
+ mInflightBatches.push_back(batch);
+}
+
+std::pair<int, std::shared_ptr<CameraDeviceSession::ResultBatcher::InflightBatch>>
+CameraDeviceSession::ResultBatcher::getBatch(
+ uint32_t frameNumber) {
+ Mutex::Autolock _l(mLock);
+ int numBatches = mInflightBatches.size();
+ if (numBatches == 0) {
+ return std::make_pair(NOT_BATCHED, nullptr);
+ }
+ uint32_t frameMin = mInflightBatches[0]->mFirstFrame;
+ uint32_t frameMax = mInflightBatches[numBatches - 1]->mLastFrame;
+ if (frameNumber < frameMin || frameNumber > frameMax) {
+ return std::make_pair(NOT_BATCHED, nullptr);
+ }
+ for (int i = 0; i < numBatches; i++) {
+ if (frameNumber >= mInflightBatches[i]->mFirstFrame &&
+ frameNumber <= mInflightBatches[i]->mLastFrame) {
+ return std::make_pair(i, mInflightBatches[i]);
+ }
+ }
+ return std::make_pair(NOT_BATCHED, nullptr);
+}
+
+void CameraDeviceSession::ResultBatcher::checkAndRemoveFirstBatch() {
+ Mutex::Autolock _l(mLock);
+ if (mInflightBatches.size() > 0) {
+ std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
+ bool shouldRemove = false;
+ {
+ Mutex::Autolock _l(batch->mLock);
+ if (batch->allDelivered()) {
+ batch->mRemoved = true;
+ shouldRemove = true;
+ }
+ }
+ if (shouldRemove) {
+ mInflightBatches.pop_front();
+ }
+ }
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch) {
+ if (batch->mShutterDelivered) {
+ ALOGW("%s: batch shutter callback already sent!", __FUNCTION__);
+ return;
+ }
+
+ mCallback->notify(batch->mShutterMsgs);
+ batch->mShutterDelivered = true;
+ batch->mShutterMsgs.clear();
+}
+
+void CameraDeviceSession::ResultBatcher::freeReleaseFences(hidl_vec<CaptureResult>& results) {
+ for (auto& result : results) {
+ if (result.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
+ native_handle_t* handle = const_cast<native_handle_t*>(
+ result.inputBuffer.releaseFence.getNativeHandle());
+ native_handle_delete(handle);
+ }
+ for (auto& buf : result.outputBuffers) {
+ if (buf.releaseFence.getNativeHandle() != nullptr) {
+ native_handle_t* handle = const_cast<native_handle_t*>(
+ buf.releaseFence.getNativeHandle());
+ native_handle_delete(handle);
+ }
+ }
+ }
+ return;
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) {
+ sendBatchBuffersLocked(batch, mStreamsToBatch);
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
+ std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams) {
+ size_t batchSize = 0;
+ for (int streamId : streams) {
+ auto it = batch->mBatchBufs.find(streamId);
+ if (it != batch->mBatchBufs.end()) {
+ InflightBatch::BufferBatch& bb = it->second;
+ if (bb.mDelivered) {
+ continue;
+ }
+ if (bb.mBuffers.size() > batchSize) {
+ batchSize = bb.mBuffers.size();
+ }
+ } else {
+ ALOGE("%s: stream ID %d is not batched!", __FUNCTION__, streamId);
+ return;
+ }
+ }
+
+ if (batchSize == 0) {
+ ALOGW("%s: there is no buffer to be delivered for this batch.", __FUNCTION__);
+ for (int streamId : streams) {
+ InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
+ bb.mDelivered = true;
+ }
+ return;
+ }
+
+ hidl_vec<CaptureResult> results;
+ results.resize(batchSize);
+ for (size_t i = 0; i < batchSize; i++) {
+ results[i].frameNumber = batch->mFirstFrame + i;
+ results[i].partialResult = 0; // 0 for buffer only results
+ results[i].inputBuffer.streamId = -1;
+ results[i].inputBuffer.bufferId = 0;
+ results[i].inputBuffer.buffer = nullptr;
+ std::vector<StreamBuffer> outBufs;
+ for (int streamId : streams) {
+ InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
+ if (bb.mDelivered) {
+ continue;
+ }
+ if (i < bb.mBuffers.size()) {
+ outBufs.push_back(bb.mBuffers[i]);
+ }
+ }
+ results[i].outputBuffers = outBufs;
+ }
+ mCallback->processCaptureResult(results);
+ freeReleaseFences(results);
+ for (int streamId : streams) {
+ InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
+ bb.mDelivered = true;
+ bb.mBuffers.clear();
+ }
+}
+
+void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked(
+ std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx) {
+ if (lastPartialResultIdx <= batch->mPartialResultProgress) {
+ // Result has been delivered. Return
+ ALOGW("%s: partial result %u has been delivered", __FUNCTION__, lastPartialResultIdx);
+ return;
+ }
+
+ std::vector<CaptureResult> results;
+ std::vector<uint32_t> toBeRemovedIdxes;
+ for (auto& pair : batch->mResultMds) {
+ uint32_t partialIdx = pair.first;
+ if (partialIdx > lastPartialResultIdx) {
+ continue;
+ }
+ toBeRemovedIdxes.push_back(partialIdx);
+ InflightBatch::MetadataBatch& mb = pair.second;
+ for (const auto& p : mb.mMds) {
+ CaptureResult result;
+ result.frameNumber = p.first;
+ result.result = std::move(p.second);
+ result.inputBuffer.streamId = -1;
+ result.inputBuffer.bufferId = 0;
+ result.inputBuffer.buffer = nullptr;
+ result.partialResult = partialIdx;
+ results.push_back(std::move(result));
+ }
+ mb.mMds.clear();
+ }
+ mCallback->processCaptureResult(results);
+ batch->mPartialResultProgress = lastPartialResultIdx;
+ for (uint32_t partialIdx : toBeRemovedIdxes) {
+ batch->mResultMds.erase(partialIdx);
+ }
+}
+
+void CameraDeviceSession::ResultBatcher::notifySingleMsg(NotifyMsg& msg) {
+ mCallback->notify({msg});
+ return;
+}
+
+void CameraDeviceSession::ResultBatcher::notify(NotifyMsg& msg) {
+ uint32_t frameNumber;
+ if (CC_LIKELY(msg.type == MsgType::SHUTTER)) {
+ frameNumber = msg.msg.shutter.frameNumber;
+ } else {
+ frameNumber = msg.msg.error.frameNumber;
+ }
+
+ auto pair = getBatch(frameNumber);
+ int batchIdx = pair.first;
+ if (batchIdx == NOT_BATCHED) {
+ notifySingleMsg(msg);
+ return;
+ }
+
+ // When error happened, stop batching for all batches earlier
+ if (CC_UNLIKELY(msg.type == MsgType::ERROR)) {
+ Mutex::Autolock _l(mLock);
+ for (int i = 0; i <= batchIdx; i++) {
+ // Send batched data up
+ std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
+ {
+ Mutex::Autolock _l(batch->mLock);
+ sendBatchShutterCbsLocked(batch);
+ sendBatchBuffersLocked(batch);
+ sendBatchMetadataLocked(batch, mNumPartialResults);
+ if (!batch->allDelivered()) {
+ ALOGE("%s: error: some batch data not sent back to framework!",
+ __FUNCTION__);
+ }
+ batch->mRemoved = true;
+ }
+ mInflightBatches.pop_front();
+ }
+ // Send the error up
+ notifySingleMsg(msg);
+ return;
+ }
+ // Queue shutter callbacks for future delivery
+ std::shared_ptr<InflightBatch> batch = pair.second;
+ {
+ Mutex::Autolock _l(batch->mLock);
+ // Check if the batch is removed (mostly by notify error) before lock was acquired
+ if (batch->mRemoved) {
+ // Fall back to non-batch path
+ notifySingleMsg(msg);
+ return;
+ }
+
+ batch->mShutterMsgs.push_back(msg);
+ if (frameNumber == batch->mLastFrame) {
+ sendBatchShutterCbsLocked(batch);
+ }
+ } // end of batch lock scope
+
+ // see if the batch is complete
+ if (frameNumber == batch->mLastFrame) {
+ checkAndRemoveFirstBatch();
+ }
+}
+
+void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
+ hidl_vec<CaptureResult> results = {result};
+ mCallback->processCaptureResult(results);
+ freeReleaseFences(results);
+ return;
+}
+
+void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& result) {
+ auto pair = getBatch(result.frameNumber);
+ int batchIdx = pair.first;
+ if (batchIdx == NOT_BATCHED) {
+ processOneCaptureResult(result);
+ return;
+ }
+ std::shared_ptr<InflightBatch> batch = pair.second;
+ {
+ Mutex::Autolock _l(batch->mLock);
+ // Check if the batch is removed (mostly by notify error) before lock was acquired
+ if (batch->mRemoved) {
+ // Fall back to non-batch path
+ processOneCaptureResult(result);
+ return;
+ }
+
+ // queue metadata
+ if (result.result.size() != 0) {
+ // Save a copy of metadata
+ batch->mResultMds[result.partialResult].mMds.push_back(
+ std::make_pair(result.frameNumber, result.result));
+ }
+
+ // queue buffer
+ std::vector<int> filledStreams;
+ std::vector<StreamBuffer> nonBatchedBuffers;
+ for (auto& buffer : result.outputBuffers) {
+ auto it = batch->mBatchBufs.find(buffer.streamId);
+ if (it != batch->mBatchBufs.end()) {
+ InflightBatch::BufferBatch& bb = it->second;
+ bb.mBuffers.push_back(buffer);
+ filledStreams.push_back(buffer.streamId);
+ } else {
+ nonBatchedBuffers.push_back(buffer);
+ }
+ }
+
+ // send non-batched buffers up
+ if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
+ CaptureResult nonBatchedResult;
+ nonBatchedResult.frameNumber = result.frameNumber;
+ nonBatchedResult.outputBuffers = nonBatchedBuffers;
+ nonBatchedResult.inputBuffer = result.inputBuffer;
+ nonBatchedResult.partialResult = 0; // 0 for buffer only results
+ processOneCaptureResult(nonBatchedResult);
+ }
+
+ if (result.frameNumber == batch->mLastFrame) {
+ // Send data up
+ if (result.partialResult > 0) {
+ sendBatchMetadataLocked(batch, result.partialResult);
+ }
+ // send buffer up
+ if (filledStreams.size() > 0) {
+ sendBatchBuffersLocked(batch, filledStreams);
+ }
+ }
+ } // end of batch lock scope
+
+ // see if the batch is complete
+ if (result.frameNumber == batch->mLastFrame) {
+ checkAndRemoveFirstBatch();
+ }
+}
+
// Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
Return<void> CameraDeviceSession::constructDefaultRequestSettings(
RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) {
@@ -283,6 +645,16 @@
++it;
}
}
+
+ // Track video streams
+ mVideoStreamIds.clear();
+ for (const auto& stream : requestedConfiguration.streams) {
+ if (stream.streamType == StreamType::OUTPUT &&
+ stream.usage & graphics::allocator::V2_0::ConsumerUsage::VIDEO_ENCODER) {
+ mVideoStreamIds.push_back(stream.id);
+ }
+ }
+ mResultBatcher.setBatchedStreams(mVideoStreamIds);
}
if (ret == -EINVAL) {
@@ -306,7 +678,26 @@
mCirculatingBuffers.erase(id);
}
-Return<Status> CameraDeviceSession::processCaptureRequest(const CaptureRequest& request) {
+Return<void> CameraDeviceSession::processCaptureRequest(
+ const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) {
+ uint32_t numRequestProcessed = 0;
+ Status s = Status::OK;
+ for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
+ s = processOneCaptureRequest(requests[i]);
+ if (s != Status::OK) {
+ break;
+ }
+ }
+
+ if (s == Status::OK && requests.size() > 1) {
+ mResultBatcher.registerBatch(requests);
+ }
+
+ _hidl_cb(s, numRequestProcessed);
+ return Void();
+}
+
+Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request) {
Status status = initStatus();
if (status != Status::OK) {
ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
@@ -437,7 +828,7 @@
bool hasInputBuf = (hal_result->input_buffer != nullptr);
size_t numOutputBufs = hal_result->num_output_buffers;
size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
- {
+ if (numBufs > 0) {
Mutex::Autolock _l(d->mInflightLock);
if (hasInputBuf) {
int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
@@ -463,10 +854,7 @@
}
// We don't need to validate/import fences here since we will be passing them to camera service
// within the scope of this function
-
CaptureResult result;
- hidl_vec<native_handle_t*> releaseFences;
- releaseFences.resize(numBufs);
result.frameNumber = frameNumber;
result.partialResult = hal_result->partial_result;
convertToHidl(hal_result->result, &result.result);
@@ -477,11 +865,11 @@
result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
// skip acquire fence since it's no use to camera service
if (hal_result->input_buffer->release_fence != -1) {
- releaseFences[numOutputBufs] = native_handle_create(/*numFds*/1, /*numInts*/0);
- releaseFences[numOutputBufs]->data[0] = hal_result->input_buffer->release_fence;
- result.inputBuffer.releaseFence = releaseFences[numOutputBufs];
+ native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
+ handle->data[0] = hal_result->input_buffer->release_fence;
+ result.inputBuffer.releaseFence = handle;
} else {
- releaseFences[numOutputBufs] = nullptr;
+ result.inputBuffer.releaseFence = nullptr;
}
} else {
result.inputBuffer.streamId = -1;
@@ -495,11 +883,11 @@
result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
// skip acquire fence since it's of no use to camera service
if (hal_result->output_buffers[i].release_fence != -1) {
- releaseFences[i] = native_handle_create(/*numFds*/1, /*numInts*/0);
- releaseFences[i]->data[0] = hal_result->output_buffers[i].release_fence;
- result.outputBuffers[i].releaseFence = releaseFences[i];
+ native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
+ handle->data[0] = hal_result->output_buffers[i].release_fence;
+ result.outputBuffers[i].releaseFence = handle;
} else {
- releaseFences[i] = nullptr;
+ result.outputBuffers[i].releaseFence = nullptr;
}
}
@@ -507,21 +895,17 @@
// Do this before call back to camera service because camera service might jump to
// configure_streams right after the processCaptureResult call so we need to finish
// updating inflight queues first
- {
+ if (numBufs > 0) {
Mutex::Autolock _l(d->mInflightLock);
if (hasInputBuf) {
int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
auto key = std::make_pair(streamId, frameNumber);
- // TODO (b/34169301): currently HAL closed the fence
- //sHandleImporter.closeFence(d->mInflightBuffers[key].acquire_fence);
d->mInflightBuffers.erase(key);
}
for (size_t i = 0; i < numOutputBufs; i++) {
int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
auto key = std::make_pair(streamId, frameNumber);
- // TODO (b/34169301): currently HAL closed the fence
- //sHandleImporter.closeFence(d->mInflightBuffers[key].acquire_fence);
d->mInflightBuffers.erase(key);
}
@@ -530,12 +914,7 @@
}
}
- d->mCallback->processCaptureResult(result);
-
- for (size_t i = 0; i < releaseFences.size(); i++) {
- // We don't close the FD here as HAL needs to signal it later.
- native_handle_delete(releaseFences[i]);
- }
+ d->mResultBatcher.processCaptureResult(result);
}
void CameraDeviceSession::sNotify(
@@ -545,15 +924,16 @@
const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
NotifyMsg hidlMsg;
convertToHidl(msg, &hidlMsg);
+
if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
hidlMsg.msg.error.errorStreamId != -1) {
if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
ALOGE("%s: unknown stream ID %d reports an error!",
__FUNCTION__, hidlMsg.msg.error.errorStreamId);
+ return;
}
- return;
}
- d->mCallback->notify(hidlMsg);
+ d->mResultBatcher.notify(hidlMsg);
}
} // namespace implementation
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 3786e4b..8923c05 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
#define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
+#include <deque>
+#include <map>
#include <unordered_map>
#include "hardware/camera_common.h"
#include "hardware/camera3.h"
@@ -27,6 +29,7 @@
#include <hidl/MQDescriptor.h>
#include <include/convert.h>
#include "HandleImporter.h"
+#include "CameraMetadata.h"
namespace android {
namespace hardware {
@@ -64,7 +67,9 @@
struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callback_ops {
- CameraDeviceSession(camera3_device_t*, const sp<ICameraDeviceCallback>&);
+ CameraDeviceSession(camera3_device_t*,
+ const camera_metadata_t* deviceInfo,
+ const sp<ICameraDeviceCallback>&);
~CameraDeviceSession();
// Call by CameraDevice to dump active device states
void dumpState(const native_handle_t* fd);
@@ -75,9 +80,12 @@
bool isClosed();
// Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
- Return<void> constructDefaultRequestSettings(RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
- Return<void> configureStreams(const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
- Return<Status> processCaptureRequest(const CaptureRequest& request) override;
+ Return<void> constructDefaultRequestSettings(
+ RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb) override;
+ Return<void> configureStreams(
+ const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
+ Return<void> processCaptureRequest(
+ const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
Return<Status> flush() override;
Return<void> close() override;
@@ -94,7 +102,6 @@
bool mDisconnected = false;
camera3_device_t* mDevice;
- const sp<ICameraDeviceCallback> mCallback;
// Stream ID -> Camera3Stream cache
std::map<int, Camera3Stream> mStreamMap;
@@ -114,6 +121,104 @@
static HandleImporter& sHandleImporter;
bool mInitFail;
+
+ common::V1_0::helper::CameraMetadata mDeviceInfo;
+
+ class ResultBatcher {
+ public:
+ ResultBatcher(const sp<ICameraDeviceCallback>& callback);
+ void setNumPartialResults(uint32_t n);
+ void setBatchedStreams(const std::vector<int>& streamsToBatch);
+
+ void registerBatch(const hidl_vec<CaptureRequest>& requests);
+ void notify(NotifyMsg& msg);
+ void processCaptureResult(CaptureResult& result);
+
+ private:
+ struct InflightBatch {
+ // Protect access to entire struct. Acquire this lock before read/write any data or
+ // calling any methods. processCaptureResult and notify will compete for this lock
+ // HIDL IPCs might be issued while the lock is held
+ Mutex mLock;
+
+ bool allDelivered() const;
+
+ uint32_t mFirstFrame;
+ uint32_t mLastFrame;
+ uint32_t mBatchSize;
+
+ bool mShutterDelivered = false;
+ std::vector<NotifyMsg> mShutterMsgs;
+
+ struct BufferBatch {
+ bool mDelivered = false;
+ // This currently assumes every batched request will output to the batched stream
+ // and since HAL must always send buffers in order, no frameNumber tracking is
+ // needed
+ std::vector<StreamBuffer> mBuffers;
+ };
+ // Stream ID -> VideoBatch
+ std::unordered_map<int, BufferBatch> mBatchBufs;
+
+ struct MetadataBatch {
+ // (frameNumber, metadata)
+ std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
+ };
+ // Partial result IDs that has been delivered to framework
+ uint32_t mNumPartialResults;
+ uint32_t mPartialResultProgress = 0;
+ // partialResult -> MetadataBatch
+ std::map<uint32_t, MetadataBatch> mResultMds;
+
+ // Set to true when batch is removed from mInflightBatches
+ // processCaptureResult and notify must check this flag after acquiring mLock to make
+ // sure this batch isn't removed while waiting for mLock
+ bool mRemoved = false;
+ };
+
+ static const int NOT_BATCHED = -1;
+
+ // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
+ // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
+ // It's possible that the InflightBatch is removed from mInflightBatches before the
+ // InflightBatch::mLock is acquired (most likely caused by an error notification), so
+ // caller must check InflightBatch::mRemoved flag after the lock is acquried.
+ // This method will hold ResultBatcher::mLock briefly
+ std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
+
+ // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
+ // This method will hold ResultBatcher::mLock briefly
+ void checkAndRemoveFirstBatch();
+
+ // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
+ // HIDL IPC methods will be called during these methods.
+ void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
+ // send buffers for all batched streams
+ void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
+ // send buffers for specified streams
+ void sendBatchBuffersLocked(
+ std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
+ void sendBatchMetadataLocked(
+ std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
+ // End of sendXXXX methods
+
+ // helper methods
+ void freeReleaseFences(hidl_vec<CaptureResult>&);
+ void notifySingleMsg(NotifyMsg& msg);
+ void processOneCaptureResult(CaptureResult& result);
+
+ // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
+ // processCaptureRequest, processCaptureResult, notify will compete for this lock
+ // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
+ mutable Mutex mLock;
+ std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
+ uint32_t mNumPartialResults;
+ std::vector<int> mStreamsToBatch;
+ const sp<ICameraDeviceCallback> mCallback;
+ } mResultBatcher;
+
+ std::vector<int> mVideoStreamIds;
+
bool initialize();
Status initStatus() const;
@@ -129,6 +234,7 @@
void cleanupBuffersLocked(int id);
+ Status processOneCaptureRequest(const CaptureRequest& request);
/**
* Static callback forwarding methods from HAL to instance
*/
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index fe1edbf..c7d38c1 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -151,6 +151,13 @@
* android.lens.opticalStabilizationMode (if it is supported)
* android.scaler.cropRegion
* android.statistics.faceDetectMode (if it is supported)
+ * 6. To reduce the amount of data passed across process boundaries at
+ * high frame rate, within one batch, camera framework only propagates
+ * the last shutter notify and the last capture results (including partial
+ * results and final result) to the app. The shutter notifies and capture
+ * results for the other requests in the batch are derived by
+ * the camera framework. As a result, the HAL can return empty metadata
+ * except for the last result in the batch.
*
* For more details about high speed stream requirements, see
* android.control.availableHighSpeedVideoConfigurations and
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 3369a3c..1656325 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -57,6 +57,8 @@
"android.hardware.camera.common@1.0",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
export_shared_lib_headers: [
@@ -67,6 +69,8 @@
"android.hardware.camera.common@1.0",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
}
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index ad9f0b8..8701ec1 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -183,6 +183,12 @@
}
ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
+ // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
+ VendorTagDescriptor::clearGlobalVendorTagDescriptor();
+ if (!setUpVendorTags()) {
+ ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
+ }
+
// Setup callback now because we are going to try openLegacy next
err = mModule->setCallbacks(this);
if (err != OK) {
@@ -225,11 +231,6 @@
}
}
- // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
- VendorTagDescriptor::clearGlobalVendorTagDescriptor();
- if (!setUpVendorTags()) {
- ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
- }
return false; // mInitFailed
}
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index cf66e04..df2602e 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -25,5 +25,5 @@
int main()
{
ALOGI("Camera provider Service is starting.");
- return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0");
-}
\ No newline at end of file
+ return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
+}
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 598127f..a79c9fa 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -445,13 +445,13 @@
hidl_vec<hidl_string> getCameraDeviceNames();
struct EmptyDeviceCb : public ICameraDeviceCallback {
- virtual Return<void> processCaptureResult(const CaptureResult& /*result*/) override {
+ virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override {
ALOGI("processCaptureResult callback");
ADD_FAILURE(); // Empty callback should not reach here
return Void();
}
- virtual Return<void> notify(const NotifyMsg& /*msg*/) override {
+ virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override {
ALOGI("notify callback");
ADD_FAILURE(); // Empty callback should not reach here
return Void();
@@ -460,8 +460,8 @@
struct DeviceCb : public ICameraDeviceCallback {
DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
- Return<void> processCaptureResult(const CaptureResult& result) override;
- Return<void> notify(const NotifyMsg& msg) override;
+ Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
+ Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
private:
CameraHidlTest *mParent; // Parent object
@@ -667,12 +667,13 @@
}
Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
- const CaptureResult& result) {
+ const hidl_vec<CaptureResult>& results) {
if (nullptr == mParent) {
return Void();
}
std::unique_lock<std::mutex> l(mParent->mLock);
+ const CaptureResult& result = results[0];
if(mParent->mResultFrameNumber != result.frameNumber) {
ALOGE("%s: Unexpected frame number! Expected: %u received: %u",
@@ -695,7 +696,8 @@
}
Return<void> CameraHidlTest::DeviceCb::notify(
- const NotifyMsg& message) {
+ const hidl_vec<NotifyMsg>& messages) {
+ const NotifyMsg& message = messages[0];
if (MsgType::ERROR == message.type) {
{
@@ -2477,10 +2479,17 @@
mResultFrameNumber = frameNumber;
}
- Return<Status> returnStatus = session->processCaptureRequest(
- request);
+ Status status = Status::INTERNAL_ERROR;
+ uint32_t numRequestProcessed = 0;
+ Return<void> returnStatus = session->processCaptureRequest(
+ {request},
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, 1u);
{
std::unique_lock<std::mutex> l(mLock);
@@ -2503,9 +2512,14 @@
}
returnStatus = session->processCaptureRequest(
- request);
+ {request},
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, 1u);
{
std::unique_lock<std::mutex> l(mLock);
@@ -2563,12 +2577,19 @@
emptyInputBuffer, outputBuffers};
//Settings were not correctly initialized, we should fail here
- Return<Status> returnStatus = session->processCaptureRequest(
- request);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::INTERNAL_ERROR, returnStatus);
+ Status status = Status::OK;
+ uint32_t numRequestProcessed = 0;
+ Return<void> ret = session->processCaptureRequest(
+ {request},
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Status::INTERNAL_ERROR, status);
+ ASSERT_EQ(numRequestProcessed, 0u);
- Return<void> ret = session->close();
+ ret = session->close();
ASSERT_TRUE(ret.isOk());
}
}
@@ -2609,11 +2630,17 @@
emptyInputBuffer, emptyOutputBuffers};
//Output buffers are missing, we should fail here
- Return<Status> returnStatus = session->processCaptureRequest(
- request);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::INTERNAL_ERROR,
- returnStatus);
+ Status status = Status::OK;
+ uint32_t numRequestProcessed = 0;
+ ret = session->processCaptureRequest(
+ {request},
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Status::INTERNAL_ERROR, status);
+ ASSERT_EQ(numRequestProcessed, 0u);
ret = session->close();
ASSERT_TRUE(ret.isOk());
@@ -2672,12 +2699,20 @@
mResultFrameNumber = frameNumber;
}
- Return<Status> returnStatus = session->processCaptureRequest(
- request);
- ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(Status::OK, returnStatus);
+ Status status = Status::INTERNAL_ERROR;
+ uint32_t numRequestProcessed = 0;
+ ret = session->processCaptureRequest(
+ {request},
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, 1u);
//Flush before waiting for request to complete.
- returnStatus = session->flush();
+ Return<Status> returnStatus = session->flush();
ASSERT_TRUE(returnStatus.isOk());
ASSERT_EQ(Status::OK, returnStatus);
diff --git a/configstore/1.0/ISurfaceFlingerConfigs.hal b/configstore/1.0/ISurfaceFlingerConfigs.hal
index f9a49ce..43c96ee 100644
--- a/configstore/1.0/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -70,4 +70,30 @@
* TARGET_HAS_HDR_DISPLAY to true in BoardConfig.mk
*/
hasHDRDisplay() generates (OptionalBool value);
+
+ /*
+ * Specify the offset in nanoseconds to add to vsync time when timestamping
+ * present fences.
+ */
+ presentTimeOffsetFromVSyncNs() generates(OptionalInt64 value);
+
+ /*
+ * Some hardware can do RGB->YUV conversion more efficiently in hardware
+ * controlled by HWC than in hardware controlled by the video encoder.
+ * This instruct VirtualDisplaySurface to use HWC for such conversion on
+ * GL composition.
+ */
+ useHwcForRGBtoYUV() generates(OptionalBool value);
+
+ /*
+ * Maximum dimension supported by HWC for virtual display.
+ * Must be equals to min(max_width, max_height).
+ */
+ maxVirtualDisplaySize() generates (OptionalUInt64 value);
+
+ /*
+ * Indicates if Sync framework is available. Sync framework provides fence
+ * mechanism which significantly reduces buffer processing latency.
+ */
+ hasSyncFramework() generates(OptionalBool value);
};
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
index 035479c..e8872e8 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -59,6 +59,16 @@
return Void();
}
+Return<void> SurfaceFlingerConfigs::hasSyncFramework(hasSyncFramework_cb _hidl_cb) {
+ bool value = true;
+#ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
+ value = false;
+#endif
+ _hidl_cb({true, value});
+ LOG(INFO) << "SurfaceFlinger hasSyncFramework: " << value;
+ return Void();
+}
+
Return<void> SurfaceFlingerConfigs::hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) {
bool value = false;
#ifdef HAS_HDR_DISPLAY
@@ -69,8 +79,39 @@
return Void();
}
-// Methods from ::android::hidl::base::V1_0::IBase follow.
+Return<void> SurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) {
+#ifdef PRESENT_TIME_OFFSET_FROM_VSYNC_NS
+ _hidl_cb({true, PRESENT_TIME_OFFSET_FROM_VSYNC_NS});
+ LOG(INFO) << "SurfaceFlinger presentTimeStampOffsetNs = " << PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
+#else
+ _hidl_cb({false, 0});
+#endif
+ return Void();
+}
+Return<void> SurfaceFlingerConfigs::useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) {
+ bool value = false;
+#ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
+ value = true;
+#endif
+ _hidl_cb({true, value});
+ LOG(INFO) << "SurfaceFlinger forceHwcForRGBtoYUV: " << value;
+ return Void();
+}
+
+Return<void> SurfaceFlingerConfigs::maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) {
+ uint64_t maxSize = 0;
+#ifdef MAX_VIRTUAL_DISPLAY_DIMENSION
+ maxSize = MAX_VIRTUAL_DISPLAY_DIMENSION;
+ _hidl_cb({true, maxSize});
+ LOG(INFO) << "SurfaceFlinger MaxVirtualDisplaySize: " << maxSize;
+#else
+ _hidl_cb({false, maxSize});
+#endif
+ return Void();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
ISurfaceFlingerConfigs* HIDL_FETCH_ISurfaceFlingerConfigs(const char* /* name */) {
return new SurfaceFlingerConfigs();
}
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.h b/configstore/1.0/default/SurfaceFlingerConfigs.h
index aa7fb8b..bea1ab1 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.h
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.h
@@ -30,6 +30,10 @@
Return<void> useContextPriority(useContextPriority_cb _hidl_cb) override;
Return<void> hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) override;
Return<void> hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) override;
+ Return<void> presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) override;
+ Return<void> useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) override;
+ Return<void> maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) override;
+ Return<void> hasSyncFramework(hasSyncFramework_cb _hidl_cb) override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
diff --git a/configstore/1.0/default/service.cpp b/configstore/1.0/default/service.cpp
index caec0ba..cb04215 100644
--- a/configstore/1.0/default/service.cpp
+++ b/configstore/1.0/default/service.cpp
@@ -24,10 +24,18 @@
using android::hardware::registerPassthroughServiceImplementation;
using android::hardware::joinRpcThreadpool;
+using android::status_t;
+using android::OK;
+
int main() {
// TODO(b/34857894): tune the max thread count.
configureRpcThreadpool(10, true);
- registerPassthroughServiceImplementation<ISurfaceFlingerConfigs>();
+
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<ISurfaceFlingerConfigs>();
+ LOG_ALWAYS_FATAL_IF(status != OK, "Could not register ISurfaceFlingerConfigs");
+
// other interface registration comes here
joinRpcThreadpool();
return 0;
diff --git a/configstore/1.0/default/surfaceflinger.mk b/configstore/1.0/default/surfaceflinger.mk
index 8ee3686..6e63fdc 100644
--- a/configstore/1.0/default/surfaceflinger.mk
+++ b/configstore/1.0/default/surfaceflinger.mk
@@ -29,3 +29,20 @@
LOCAL_CFLAGS += -DHAS_HDR_DISPLAY
endif
+ifneq ($(PRESENT_TIME_OFFSET_FROM_VSYNC_NS),)
+ LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=$(PRESENT_TIME_OFFSET_FROM_VSYNC_NS)
+else
+ LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
+endif
+
+ifeq ($(TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS),true)
+ LOCAL_CFLAGS += -DFORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
+endif
+
+ifneq ($(MAX_VIRTUAL_DISPLAY_DIMENSION),)
+ LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=$(MAX_VIRTUAL_DISPLAY_DIMENSION)
+endif
+
+ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true)
+ LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
+endif
diff --git a/drm/1.0/ICryptoPlugin.hal b/drm/1.0/ICryptoPlugin.hal
index ca8fa50..0a7fd26 100644
--- a/drm/1.0/ICryptoPlugin.hal
+++ b/drm/1.0/ICryptoPlugin.hal
@@ -99,7 +99,8 @@
* ERROR_DRM_RESOURCE_BUSY if the resources required to perform the
* decryption are not available, ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
* if required output protections are not active,
- * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened, or
+ * ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened,
+ * ERROR_DRM_DECRYPT if the decrypt operation fails, and
* ERROR_DRM_CANNOT_HANDLE in other failure cases.
* @return bytesWritten the number of bytes output from the decryption
* @return detailedError if the error is a vendor-specific error, the
diff --git a/drm/1.0/default/TypeConvert.cpp b/drm/1.0/default/TypeConvert.cpp
index ede2a38..3a262c3 100644
--- a/drm/1.0/default/TypeConvert.cpp
+++ b/drm/1.0/default/TypeConvert.cpp
@@ -59,6 +59,9 @@
case android::ERROR_DRM_DEVICE_REVOKED:
status = Status::ERROR_DRM_DEVICE_REVOKED;
break;
+ case android::ERROR_DRM_DECRYPT:
+ status = Status::ERROR_DRM_DECRYPT;
+ break;
default:
ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
legacyStatus);
diff --git a/drm/1.0/default/service.cpp b/drm/1.0/default/service.cpp
index d2507c4..a112aaf 100644
--- a/drm/1.0/default/service.cpp
+++ b/drm/1.0/default/service.cpp
@@ -31,7 +31,14 @@
int main() {
ALOGD("android.hardware.drm@1.0-service starting...");
configureRpcThreadpool(8, true /* callerWillJoin */);
- registerPassthroughServiceImplementation<IDrmFactory>("drm");
- registerPassthroughServiceImplementation<ICryptoFactory>("crypto");
+ android::status_t status =
+ registerPassthroughServiceImplementation<IDrmFactory>("drm");
+ LOG_ALWAYS_FATAL_IF(
+ status != android::OK,
+ "Error while registering drm service: %d", status);
+ status = registerPassthroughServiceImplementation<ICryptoFactory>("crypto");
+ LOG_ALWAYS_FATAL_IF(
+ status != android::OK,
+ "Error while registering crypto service: %d", status);
joinRpcThreadpool();
}
diff --git a/drm/1.0/types.hal b/drm/1.0/types.hal
index 5273044..cea5b16 100644
--- a/drm/1.0/types.hal
+++ b/drm/1.0/types.hal
@@ -90,6 +90,12 @@
ERROR_DRM_DEVICE_REVOKED,
/**
+ * The DRM Plugin must return ERROR_DRM_DECRYPT if the CryptoPlugin
+ * decrypt operation fails.
+ */
+ ERROR_DRM_DECRYPT,
+
+ /**
* ERROR_DRM_UNKNOWN must be returned when a fatal failure occurs and no
* other defined error is appropriate.
*/
diff --git a/graphics/Android.bp b/graphics/Android.bp
index eaa47ae..f4f7db4 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -3,6 +3,7 @@
"allocator/2.0",
"allocator/2.0/default",
"allocator/2.0/vts/functional",
+ "bufferqueue/1.0",
"common/1.0",
"composer/2.1",
"composer/2.1/default",
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
new file mode 100644
index 0000000..4ba764f
--- /dev/null
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -0,0 +1,70 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+ name: "android.hardware.graphics.bufferqueue@1.0_hal",
+ srcs: [
+ "IGraphicBufferProducer.hal",
+ "IProducerListener.hal",
+ ],
+}
+
+genrule {
+ name: "android.hardware.graphics.bufferqueue@1.0_genc++",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.bufferqueue@1.0",
+ srcs: [
+ ":android.hardware.graphics.bufferqueue@1.0_hal",
+ ],
+ out: [
+ "android/hardware/graphics/bufferqueue/1.0/GraphicBufferProducerAll.cpp",
+ "android/hardware/graphics/bufferqueue/1.0/ProducerListenerAll.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.graphics.bufferqueue@1.0_genc++_headers",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.graphics.bufferqueue@1.0",
+ srcs: [
+ ":android.hardware.graphics.bufferqueue@1.0_hal",
+ ],
+ out: [
+ "android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h",
+ "android/hardware/graphics/bufferqueue/1.0/IHwGraphicBufferProducer.h",
+ "android/hardware/graphics/bufferqueue/1.0/BnHwGraphicBufferProducer.h",
+ "android/hardware/graphics/bufferqueue/1.0/BpHwGraphicBufferProducer.h",
+ "android/hardware/graphics/bufferqueue/1.0/BsGraphicBufferProducer.h",
+ "android/hardware/graphics/bufferqueue/1.0/IProducerListener.h",
+ "android/hardware/graphics/bufferqueue/1.0/IHwProducerListener.h",
+ "android/hardware/graphics/bufferqueue/1.0/BnHwProducerListener.h",
+ "android/hardware/graphics/bufferqueue/1.0/BpHwProducerListener.h",
+ "android/hardware/graphics/bufferqueue/1.0/BsProducerListener.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.graphics.bufferqueue@1.0",
+ generated_sources: ["android.hardware.graphics.bufferqueue@1.0_genc++"],
+ generated_headers: ["android.hardware.graphics.bufferqueue@1.0_genc++_headers"],
+ export_generated_headers: ["android.hardware.graphics.bufferqueue@1.0_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.media@1.0",
+ "android.hidl.base@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.media@1.0",
+ "android.hidl.base@1.0",
+ ],
+}
diff --git a/media/omx/1.0/IOmxBufferProducer.hal b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
similarity index 95%
rename from media/omx/1.0/IOmxBufferProducer.hal
rename to graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
index 7e2172b..c59a16c 100644
--- a/media/omx/1.0/IOmxBufferProducer.hal
+++ b/graphics/bufferqueue/1.0/IGraphicBufferProducer.hal
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,29 @@
* limitations under the License.
*/
-package android.hardware.media.omx@1.0;
+package android.hardware.graphics.bufferqueue@1.0;
+
+import android.hardware.media@1.0::Fence;
+import android.hardware.media@1.0::AnwBuffer;
+import android.hardware.media@1.0::Rect;
+import android.hardware.media@1.0::Region;
import android.hardware.graphics.common@1.0::Dataspace;
import android.hardware.graphics.common@1.0::PixelFormat;
-import android.hardware.media@1.0::types;
-import IOmxProducerListener;
+import IProducerListener;
/**
* Ref: frameworks/native/include/gui/IGraphicBufferProducer.h:
* IGraphicBufferProducer
* This is a wrapper/wrapped HAL interface for the actual binder interface.
*/
-interface IOmxBufferProducer {
+interface IGraphicBufferProducer {
+
+ /**
+ * Type for return values of functions in IGraphicBufferProducer.
+ */
+ typedef int32_t Status;
/**
* Ref: frameworks/native/include/ui/FenceTime.h: FenceTime::Snapshot
@@ -142,7 +151,7 @@
/**
* requestBuffer requests a new buffer for the given index. The server (i.e.
- * the IOmxBufferProducer implementation) assigns the newly created
+ * the IProducerListener implementation) assigns the newly created
* buffer to the given slot index, and the client is expected to mirror the
* slot->buffer mapping so that it's not necessary to transfer an
* AnwBuffer for every dequeue operation.
@@ -466,12 +475,12 @@
);
/**
- * connect attempts to connect a client API to the IOmxBufferProducer.
- * This must be called before any other IOmxBufferProducer methods are
+ * connect attempts to connect a client API to the IGraphicBufferProducer.
+ * This must be called before any other IGraphicBufferProducer methods are
* called except for getAllocator. A consumer must be already connected.
*
* This method will fail if the connect was previously called on the
- * IOmxBufferProducer and no corresponding disconnect call was made.
+ * IGraphicBufferProducer and no corresponding disconnect call was made.
*
* The listener is an optional binder callback object that can be used if
* the producer wants to be notified when the consumer releases a buffer
@@ -506,7 +515,7 @@
* should be treated as opaque fatal unrecoverable errors.
*/
connect(
- IOmxProducerListener listener,
+ IProducerListener listener,
int32_t api,
bool producerControlledByApp
) generates (
@@ -516,8 +525,8 @@
/**
* disconnect attempts to disconnect a client API from the
- * IOmxBufferProducer. Calling this method will cause any subsequent
- * calls to other IOmxBufferProducer methods to fail except for
+ * IGraphicBufferProducer. Calling this method will cause any subsequent
+ * calls to other IGraphicBufferProducer methods to fail except for
* getAllocator and connect. Successfully calling connect after this will
* allow the other methods to succeed again.
*
@@ -526,7 +535,7 @@
* Alternatively if mode is AllLocal, then the API value is ignored, and any API
* connected from the same PID calling disconnect will be disconnected.
*
- * Disconnecting from an abandoned IOmxBufferProducer is legal and
+ * Disconnecting from an abandoned IGraphicBufferProducer is legal and
* is considered a no-op.
*
* Return of a value other than NO_ERROR means an error has occurred:
@@ -543,7 +552,7 @@
);
/**
- * Attaches a sideband buffer stream to the IOmxBufferProducer.
+ * Attaches a sideband buffer stream to the IGraphicBufferProducer.
*
* A sideband stream is a device-specific mechanism for passing buffers
* from the producer to the consumer without using dequeueBuffer/
diff --git a/media/omx/1.0/IOmxProducerListener.hal b/graphics/bufferqueue/1.0/IProducerListener.hal
similarity index 91%
rename from media/omx/1.0/IOmxProducerListener.hal
rename to graphics/bufferqueue/1.0/IProducerListener.hal
index 7fde93b..206a500 100644
--- a/media/omx/1.0/IOmxProducerListener.hal
+++ b/graphics/bufferqueue/1.0/IProducerListener.hal
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package android.hardware.media.omx@1.0;
+package android.hardware.graphics.bufferqueue@1.0;
/**
* Ref: frameworks/native/include/gui/IProducerListener.h: IProducerListener
* This is a wrapper/wrapped HAL interface for the actual binder interface.
*/
-interface IOmxProducerListener {
+interface IProducerListener {
oneway onBufferReleased();
needsReleaseNotify() generates (bool result);
};
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index d5da943..0367fcd 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -37,6 +37,7 @@
"liblog",
"libsync",
"libutils",
+ "libhwc2on1adapter"
],
}
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index cf82967..e6ff9e0 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -22,6 +22,8 @@
#include "ComposerClient.h"
#include "Hwc.h"
+#include "hardware/hwcomposer.h"
+#include "hwc2on1adapter/HWC2On1Adapter.h"
namespace android {
namespace hardware {
@@ -30,13 +32,36 @@
namespace V2_1 {
namespace implementation {
+
HwcHal::HwcHal(const hw_module_t* module)
- : mDevice(nullptr), mDispatch()
+ : mDevice(nullptr), mDispatch(), mAdapter()
{
- int status = hwc2_open(module, &mDevice);
- if (status) {
- LOG_ALWAYS_FATAL("failed to open hwcomposer2 device: %s",
- strerror(-status));
+ // Determine what kind of module is available (HWC2 vs HWC1.X).
+ hw_device_t* device = nullptr;
+ int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
+ if (error != 0) {
+ ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
+ abort();
+ }
+ uint32_t majorVersion = (device->version >> 24) & 0xF;
+
+ // If we don't have a HWC2, we need to wrap whatever we have in an adapter.
+ if (majorVersion != 2) {
+ uint32_t minorVersion = device->version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
+ minorVersion = (minorVersion >> 16) & 0xF;
+ ALOGI("Found HWC implementation v%d.%d", majorVersion, minorVersion);
+ if (minorVersion < 1) {
+ ALOGE("Cannot adapt to HWC version %d.%d. Minimum supported is 1.1",
+ majorVersion, minorVersion);
+ abort();
+ }
+ mAdapter = std::make_unique<HWC2On1Adapter>(
+ reinterpret_cast<hwc_composer_device_1*>(device));
+
+ // Place the adapter in front of the device module.
+ mDevice = mAdapter.get();
+ } else {
+ mDevice = reinterpret_cast<hwc2_device_t*>(device);
}
initCapabilities();
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index ca08cf0..b45389a 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -18,15 +18,23 @@
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
#include <mutex>
+#include <memory>
#include <unordered_set>
#include <vector>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
-
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
#include "ComposerBase.h"
namespace android {
+ class HWC2On1Adapter;
+}
+
+namespace android {
namespace hardware {
namespace graphics {
namespace composer {
@@ -204,6 +212,10 @@
std::mutex mClientMutex;
wp<ComposerClient> mClient;
+
+ // If the HWC implementation version is < 2.0, use an adapter to interface
+ // between HWC 2.0 <-> HWC 1.X.
+ std::unique_ptr<HWC2On1Adapter> mAdapter;
};
extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index 85d15ae..81dd617 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -6,11 +6,9 @@
"types.hal",
"IGraphicBufferSource.hal",
"IOmx.hal",
- "IOmxBufferProducer.hal",
"IOmxBufferSource.hal",
"IOmxNode.hal",
"IOmxObserver.hal",
- "IOmxProducerListener.hal",
],
}
@@ -25,11 +23,9 @@
"android/hardware/media/omx/1.0/types.cpp",
"android/hardware/media/omx/1.0/GraphicBufferSourceAll.cpp",
"android/hardware/media/omx/1.0/OmxAll.cpp",
- "android/hardware/media/omx/1.0/OmxBufferProducerAll.cpp",
"android/hardware/media/omx/1.0/OmxBufferSourceAll.cpp",
"android/hardware/media/omx/1.0/OmxNodeAll.cpp",
"android/hardware/media/omx/1.0/OmxObserverAll.cpp",
- "android/hardware/media/omx/1.0/OmxProducerListenerAll.cpp",
],
}
@@ -52,11 +48,6 @@
"android/hardware/media/omx/1.0/BnHwOmx.h",
"android/hardware/media/omx/1.0/BpHwOmx.h",
"android/hardware/media/omx/1.0/BsOmx.h",
- "android/hardware/media/omx/1.0/IOmxBufferProducer.h",
- "android/hardware/media/omx/1.0/IHwOmxBufferProducer.h",
- "android/hardware/media/omx/1.0/BnHwOmxBufferProducer.h",
- "android/hardware/media/omx/1.0/BpHwOmxBufferProducer.h",
- "android/hardware/media/omx/1.0/BsOmxBufferProducer.h",
"android/hardware/media/omx/1.0/IOmxBufferSource.h",
"android/hardware/media/omx/1.0/IHwOmxBufferSource.h",
"android/hardware/media/omx/1.0/BnHwOmxBufferSource.h",
@@ -72,11 +63,6 @@
"android/hardware/media/omx/1.0/BnHwOmxObserver.h",
"android/hardware/media/omx/1.0/BpHwOmxObserver.h",
"android/hardware/media/omx/1.0/BsOmxObserver.h",
- "android/hardware/media/omx/1.0/IOmxProducerListener.h",
- "android/hardware/media/omx/1.0/IHwOmxProducerListener.h",
- "android/hardware/media/omx/1.0/BnHwOmxProducerListener.h",
- "android/hardware/media/omx/1.0/BpHwOmxProducerListener.h",
- "android/hardware/media/omx/1.0/BsOmxProducerListener.h",
],
}
@@ -92,6 +78,7 @@
"liblog",
"libutils",
"libcutils",
+ "android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.common@1.0",
"android.hardware.media@1.0",
"android.hidl.base@1.0",
@@ -101,6 +88,7 @@
"libhidltransport",
"libhwbinder",
"libutils",
+ "android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.common@1.0",
"android.hardware.media@1.0",
"android.hidl.base@1.0",
diff --git a/media/omx/1.0/IOmx.hal b/media/omx/1.0/IOmx.hal
index acb1aae..78d4b32 100644
--- a/media/omx/1.0/IOmx.hal
+++ b/media/omx/1.0/IOmx.hal
@@ -16,11 +16,11 @@
package android.hardware.media.omx@1.0;
+import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
import android.hardware.media@1.0::types;
import IOmxNode;
import IOmxObserver;
-import IOmxBufferProducer;
import IGraphicBufferSource;
/**
@@ -76,7 +76,7 @@
createInputSurface(
) generates (
Status status,
- IOmxBufferProducer producer,
+ IGraphicBufferProducer producer,
IGraphicBufferSource source
);
};
diff --git a/radio/1.0/IRadio.hal b/radio/1.0/IRadio.hal
index b3e3e98..0b1bf40 100644
--- a/radio/1.0/IRadio.hal
+++ b/radio/1.0/IRadio.hal
@@ -630,7 +630,6 @@
/*
* Scans for available networks
- * This request must not respond until the new operator is selected and registered.
*
* @param serial Serial number of request.
*
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index cd0899a..d21bf0b 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -280,13 +280,34 @@
/*
* @param info Response info struct containing response type, serial no. and error
- * @param failCauseInfo Contains LastCallFailCause and vendor cause code. GSM failure reasons
- * are mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA
- * failure reasons are derived from the possible call failure scenarios
- * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
+ * @param failCauseInfo Contains LastCallFailCause and vendor cause code.
*
- * The implementation must return LastCallFailCause:ERROR_UNSPECIFIED for blocked
- * MO calls by restricted state (See unsolRestrictedStateChanged)
+ * The vendor cause code must be used for debugging purpose only.
+ * The implementation must return one of the values of LastCallFailCause
+ * as mentioned below
+ *
+ * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H
+ * where possible.
+ * CDMA failure reasons codes for the possible call failure scenarios
+ * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
+ * Any of the following reason codes if the call is failed or dropped due to reason
+ * mentioned with in the braces.
+ * LastCallFailCause:RADIO_OFF (Radio is OFF)
+ * LastCallFailCause:OUT_OF_SERVICE (No cell coverage)
+ * LastCallFailCause:NO_VALID_SIM (No valid SIM)
+ * LastCallFailCause:RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario)
+ * LastCallFailCause:NETWORK_RESP_TIMEOUT (No response from network)
+ * LastCallFailCause:NETWORK_REJECT (Explicit network reject)
+ * LastCallFailCause:RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH)
+ * LastCallFailCause:RADIO_LINK_FAILURE (Radio Link Failure)
+ * LastCallFailCause:RADIO_LINK_LOST (Radio link lost due to poor coverage)
+ * LastCallFailCause:RADIO_UPLINK_FAILURE (Radio uplink failure)
+ * LastCallFailCause:RADIO_SETUP_FAILURE (RRC connection setup failure)
+ * LastCallFailCause:RADIO_RELEASE_NORMAL (RRC connection release, normal)
+ * LastCallFailCause:RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal)
+ * LastCallFailCause:ACCESS_CLASS_BLOCKED (Access class barring)
+ * LastCallFailCause:NETWORK_DETACH (Explicit network detach)
+ * OEM causes (LastCallFailCause:OEM_CAUSE_XX) must be used for debug purpose only
*
* If the implementation does not have access to the exact cause codes,
* then it must return one of the values listed in LastCallFailCause,
@@ -787,10 +808,13 @@
*
* Valid errors returned:
* RadioError:NONE
- * RadioError:INVALID_ARGUMENTS
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:OPERATION_NOT_ALLOWED
- * RadioError:GENERIC_FAILURE
+ * RadioError:ABORTED
+ * RadioError:DEVICE_IN_USE
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:MODEM_ERR
*/
oneway getAvailableNetworksResponse(RadioResponseInfo info,
vec<OperatorInfo> networkInfos);
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 7c1d143..ad9f392 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -86,9 +86,11 @@
SS_MODIFIED_TO_SS = 27, // SS request modified to different SS request
LCE_NOT_SUPPORTED = 36, // LCE service not supported(36 in RILConstants.java)
NO_MEMORY = 37, // Not sufficient memory to process the request
- INTERNAL_ERR = 38, // Hit unexpected vendor internal error scenario
+ INTERNAL_ERR = 38, // Modem hit unexpected error scenario while handling
+ // this request
SYSTEM_ERR = 39, // Hit platform or system error
- MODEM_ERR = 40, // Hit unexpected modem error
+ MODEM_ERR = 40, // Vendor RIL got unexpected or incorrect response
+ // from modem for this request
INVALID_STATE = 41, // Unexpected request for the current state
NO_RESOURCES = 42, // Not sufficient resource to process the request
SIM_ERR = 43, // Received error from SIM card
@@ -381,6 +383,21 @@
DIAL_MODIFIED_TO_USSD = 244, // STK Call Control
DIAL_MODIFIED_TO_SS = 245,
DIAL_MODIFIED_TO_DIAL = 246,
+ RADIO_OFF = 247, // Radio is OFF
+ OUT_OF_SERVICE = 248, // No cellular coverage
+ NO_VALID_SIM = 249, // No valid SIM is present
+ RADIO_INTERNAL_ERROR = 250, // Internal error at Modem
+ NETWORK_RESP_TIMEOUT = 251, // No response from network
+ NETWORK_REJECT = 252, // Explicit network reject
+ RADIO_ACCESS_FAILURE = 253, // RRC connection failure. Eg.RACH
+ RADIO_LINK_FAILURE = 254, // Radio Link Failure
+ RADIO_LINK_LOST = 255, // Radio link lost due to poor coverage
+ RADIO_UPLINK_FAILURE = 256, // Radio uplink failure
+ RADIO_SETUP_FAILURE = 257, // RRC connection setup failure
+ RADIO_RELEASE_NORMAL = 258, // RRC connection release, normal
+ RADIO_RELEASE_ABNORMAL = 259, // RRC connection release, abnormal
+ ACCESS_CLASS_BLOCKED = 260, // Access class barring
+ NETWORK_DETACH = 261, // Explicit network detach
CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
CDMA_DROP = 1001,
CDMA_INTERCEPT = 1002,
@@ -391,10 +408,29 @@
CDMA_PREEMPTED = 1007,
CDMA_NOT_EMERGENCY = 1008, // For non-emergency number dialed during emergency
// callback mode
- CDMA_ACCESS_BLOCKED = 1009, // This error will be deprecated soon,
+ CDMA_ACCESS_BLOCKED = 1009,
+
+ /* OEM specific error codes. Used to distinguish error from
+ * CALL_FAIL_ERROR_UNSPECIFIED and help assist debugging */
+ OEM_CAUSE_1 = 0xf001,
+ OEM_CAUSE_2 = 0xf002,
+ OEM_CAUSE_3 = 0xf003,
+ OEM_CAUSE_4 = 0xf004,
+ OEM_CAUSE_5 = 0xf005,
+ OEM_CAUSE_6 = 0xf006,
+ OEM_CAUSE_7 = 0xf007,
+ OEM_CAUSE_8 = 0xf008,
+ OEM_CAUSE_9 = 0xf009,
+ OEM_CAUSE_10 = 0xf00a,
+ OEM_CAUSE_11 = 0xf00b,
+ OEM_CAUSE_12 = 0xf00c,
+ OEM_CAUSE_13 = 0xf00d,
+ OEM_CAUSE_14 = 0xf00e,
+ OEM_CAUSE_15 = 0xf00f,
+
+ ERROR_UNSPECIFIED = 0xffff, // This error will be deprecated soon,
// vendor code must make sure to map error
// code to specific error
- ERROR_UNSPECIFIED = 0xffff,
};
enum DataCallFailCause : int32_t {
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 7f16163..24e3926 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -17,11 +17,16 @@
cc_test {
name: "VtsHalRadioV1_0TargetTest",
defaults: ["hidl_defaults"],
- srcs: ["radio_hidl_hal_test.cpp",
- "radio_response.cpp",
- "radio_hidl_hal_voice.cpp",
+ srcs: ["radio_hidl_hal_cell_broadcast.cpp",
+ "radio_hidl_hal_data.cpp",
"radio_hidl_hal_icc.cpp",
+ "radio_hidl_hal_ims.cpp",
+ "radio_hidl_hal_misc.cpp",
"radio_hidl_hal_sms.cpp",
+ "radio_hidl_hal_stk.cpp",
+ "radio_hidl_hal_test.cpp",
+ "radio_hidl_hal_voice.cpp",
+ "radio_response.cpp",
"VtsHalRadioV1_0TargetTest.cpp"],
shared_libs: [
"libbase",
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
new file mode 100644
index 0000000..d87ce5f
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_cell_broadcast.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.setGsmBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, setGsmBroadcastConfig) {
+ int serial = 0;
+
+ // Create GsmBroadcastSmsConfigInfo #1
+ GsmBroadcastSmsConfigInfo gbSmsConfig1;
+ gbSmsConfig1.fromServiceId = 4352;
+ gbSmsConfig1.toServiceId = 4354;
+ gbSmsConfig1.fromCodeScheme = 0;
+ gbSmsConfig1.toCodeScheme = 255;
+ gbSmsConfig1.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #2
+ GsmBroadcastSmsConfigInfo gbSmsConfig2;
+ gbSmsConfig2.fromServiceId = 4356;
+ gbSmsConfig2.toServiceId = 4356;
+ gbSmsConfig2.fromCodeScheme = 0;
+ gbSmsConfig2.toCodeScheme = 255;
+ gbSmsConfig2.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #3
+ GsmBroadcastSmsConfigInfo gbSmsConfig3;
+ gbSmsConfig3.fromServiceId = 4370;
+ gbSmsConfig3.toServiceId = 4379;
+ gbSmsConfig3.fromCodeScheme = 0;
+ gbSmsConfig3.toCodeScheme = 255;
+ gbSmsConfig3.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #4
+ GsmBroadcastSmsConfigInfo gbSmsConfig4;
+ gbSmsConfig4.fromServiceId = 4383;
+ gbSmsConfig4.toServiceId = 4391;
+ gbSmsConfig4.fromCodeScheme = 0;
+ gbSmsConfig4.toCodeScheme = 255;
+ gbSmsConfig4.selected = true;
+
+ // Create GsmBroadcastSmsConfigInfo #5
+ GsmBroadcastSmsConfigInfo gbSmsConfig5;
+ gbSmsConfig5.fromServiceId = 4392;
+ gbSmsConfig5.toServiceId = 4392;
+ gbSmsConfig5.fromCodeScheme = 0;
+ gbSmsConfig5.toCodeScheme = 255;
+ gbSmsConfig5.selected = true;
+
+ android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo> gsmBroadcastSmsConfigsInfoList
+ = {gbSmsConfig1, gbSmsConfig2, gbSmsConfig3, gbSmsConfig4, gbSmsConfig5};
+
+ radio->setGsmBroadcastConfig(++serial, gsmBroadcastSmsConfigsInfoList);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.getGsmBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, getGsmBroadcastConfig) {
+ int serial = 0;
+
+ radio->getGsmBroadcastConfig(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setCdmaBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCdmaBroadcastConfig) {
+ int serial = 0;
+
+ CdmaBroadcastSmsConfigInfo cbSmsConfig;
+ cbSmsConfig.serviceCategory = 4096;
+ cbSmsConfig.language = 1;
+ cbSmsConfig.selected = true;
+
+ android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo> cdmaBroadcastSmsConfigInfoList
+ = {cbSmsConfig};
+
+ radio->setCdmaBroadcastConfig(++serial, cdmaBroadcastSmsConfigInfoList);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.getCdmaBroadcastConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCdmaBroadcastConfig) {
+ int serial = 0;
+
+ radio->getCdmaBroadcastConfig(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setCdmaBroadcastActivation() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCdmaBroadcastActivation) {
+ int serial = 0;
+ bool activate = false;
+
+ radio->setCdmaBroadcastActivation(++serial, activate);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setGsmBroadcastActivation() for the response returned.
+ */
+TEST_F(RadioHidlTest, setGsmBroadcastActivation) {
+ int serial = 0;
+ bool activate = false;
+
+ radio->setGsmBroadcastActivation(++serial, activate);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
new file mode 100644
index 0000000..06cab6a
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.getDataRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest, getDataRegistrationState) {
+ int serial = 0;
+
+ radio->getDataRegistrationState(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setupDataCall() for the response returned.
+ */
+TEST_F(RadioHidlTest, setupDataCall) {
+ int serial = 0;
+
+ RadioTechnology radioTechnology = RadioTechnology::LTE;
+
+ DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::IMS;
+ dataProfileInfo.apn = hidl_string("VZWIMS");
+ dataProfileInfo.protocol = hidl_string("IPV4V6");
+ dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = "";
+ dataProfileInfo.password = "";
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtu = 0;
+ dataProfileInfo.mvnoType = MvnoType::NONE;
+ dataProfileInfo.mvnoMatchData = hidl_string();
+
+ bool modemCognitive = false;
+ bool roamingAllowed = false;
+ bool isRoaming = false;
+
+ radio->setupDataCall(++serial, radioTechnology, dataProfileInfo, modemCognitive,
+ roamingAllowed, isRoaming);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.deactivateDataCall() for the response returned.
+ */
+TEST_F(RadioHidlTest, deactivateDataCall) {
+ int serial = 0;
+ int cid = 1;
+ bool reasonRadioShutDown = false;
+
+ radio->deactivateDataCall(++serial, cid, reasonRadioShutDown);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.getDataCallList() for the response returned.
+ */
+TEST_F(RadioHidlTest, getDataCallList) {
+ int serial = 0;
+
+ radio->getDataCallList(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setInitialAttachApn() for the response returned.
+ */
+TEST_F(RadioHidlTest, setInitialAttachApn) {
+ int serial = 0;
+
+ DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::IMS;
+ dataProfileInfo.apn = hidl_string("VZWIMS");
+ dataProfileInfo.protocol = hidl_string("IPV4V6");
+ dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = "";
+ dataProfileInfo.password = "";
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtu = 0;
+ dataProfileInfo.mvnoType = MvnoType::NONE;
+ dataProfileInfo.mvnoMatchData = hidl_string();
+
+ bool modemCognitive = true;
+ bool isRoaming = false;
+
+ radio->setInitialAttachApn(++serial, dataProfileInfo,
+ modemCognitive, isRoaming);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setDataAllowed() for the response returned.
+ */
+TEST_F(RadioHidlTest, setDataAllowed) {
+ int serial = 0;
+ bool allow = true;
+
+ radio->setDataAllowed(++serial, allow);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.setDataProfile() for the response returned.
+ */
+TEST_F(RadioHidlTest, setDataProfile) {
+ int serial = 0;
+
+ // Create a dataProfileInfo
+ DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::IMS;
+ dataProfileInfo.apn = hidl_string("VZWIMS");
+ dataProfileInfo.protocol = hidl_string("IPV4V6");
+ dataProfileInfo.roamingProtocol = hidl_string("IPV6");
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = "";
+ dataProfileInfo.password = "";
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP2;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtu = 0;
+ dataProfileInfo.mvnoType = MvnoType::NONE;
+ dataProfileInfo.mvnoMatchData = hidl_string();
+
+ // Create a dataProfileInfoList
+ android::hardware::hidl_vec<DataProfileInfo> dataProfileInfoList = {dataProfileInfo};
+
+ bool isRoadming = false;
+
+ radio->setDataProfile(++serial, dataProfileInfoList, isRoadming);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ // TODO(shuoq): Will add error check when we know the expected error from QC
+ }
+}
+
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 bd979b0..9cae9c2 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
@@ -287,4 +287,20 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
}
+}
+
+/*
+ * Test IRadio.supplyNetworkDepersonalization() for the response returned.
+ */
+TEST_F(RadioHidlTest, supplyNetworkDepersonalization) {
+ int serial = 1;
+
+ radio->supplyNetworkDepersonalization(serial, hidl_string("test"));
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::PASSWORD_INCORRECT);
+ }
}
\ No newline at end of file
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
new file mode 100644
index 0000000..fdc39d8
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_ims.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.getClir() for the response returned.
+ */
+TEST_F(RadioHidlTest, getClir) {
+ int serial = 0;
+
+ radio->getClir(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+ }
+}
+
+/*
+ * Test IRadio.setClir() for the response returned.
+ */
+TEST_F(RadioHidlTest, setClir) {
+ int serial = 0;
+ int32_t status = 1;
+
+ radio->setClir(++serial, status);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.getFacilityLockForApp() for the response returned.
+ */
+TEST_F(RadioHidlTest, getFacilityLockForApp) {
+ int serial = 0;
+ std::string facility = "";
+ std::string password = "";
+ int32_t serviceClass = 1;
+ std::string appId = "";
+
+ radio->getFacilityLockForApp(++serial, facility, password, serviceClass, appId);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+ }
+}
+
+/*
+ * Test IRadio.setFacilityLockForApp() for the response returned.
+ */
+TEST_F(RadioHidlTest, setFacilityLockForApp) {
+ int serial = 0;
+ std::string facility = "";
+ bool lockState = false;
+ std::string password = "";
+ int32_t serviceClass = 1;
+ std::string appId = "";
+
+ radio->setFacilityLockForApp(++serial, facility, lockState, password, serviceClass, appId);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+ }
+}
+
+/*
+ * Test IRadio.setBarringPassword() for the response returned.
+ */
+TEST_F(RadioHidlTest, setBarringPassword) {
+ int serial = 0;
+ std::string facility = "";
+ std::string oldPassword = "";
+ std::string newPassword = "";
+
+ radio->setBarringPassword(++serial, facility, oldPassword, newPassword);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+ }
+}
+
+/*
+ * Test IRadio.getClip() for the response returned.
+ */
+TEST_F(RadioHidlTest, getClip) {
+ int serial = 0;
+
+ radio->getClip(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+ }
+}
+
+/*
+ * Test IRadio.setSuppServiceNotifications() for the response returned.
+ */
+TEST_F(RadioHidlTest, setSuppServiceNotifications) {
+ int serial = 0;
+ bool enable = false;
+
+ radio->setSuppServiceNotifications(++serial, enable);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.requestIsimAuthentication() for the response returned.
+ */
+TEST_F(RadioHidlTest, requestIsimAuthentication) {
+ int serial = 0;
+ std::string challenge = "";
+
+ radio->requestIsimAuthentication(++serial, challenge);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.getImsRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest, getImsRegistrationState) {
+ int serial = 0;
+
+ radio->getImsRegistrationState(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
new file mode 100644
index 0000000..5fa11fc
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -0,0 +1,774 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include<radio_hidl_hal_utils.h>
+
+/*
+ * Test IRadio.getSignalStrength() for the response returned.
+ */
+TEST_F(RadioHidlTest, getSignalStrength) {
+ int serial = 1;
+
+ radio->getSignalStrength(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getVoiceRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest, getVoiceRegistrationState) {
+ int serial = 1;
+
+ radio->getVoiceRegistrationState(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getOperator() for the response returned.
+ */
+TEST_F(RadioHidlTest, getOperator) {
+ int serial = 1;
+
+ radio->getOperator(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setRadioPower() for the response returned.
+ */
+TEST_F(RadioHidlTest, setRadioPower) {
+ int serial = 1;
+
+ radio->setRadioPower(++serial, 0);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getNetworkSelectionMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, getNetworkSelectionMode) {
+ int serial = 1;
+
+ radio->getNetworkSelectionMode(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setNetworkSelectionModeAutomatic() for the response returned.
+ */
+TEST_F(RadioHidlTest, setNetworkSelectionModeAutomatic) {
+ int serial = 1;
+
+ radio->setNetworkSelectionModeAutomatic(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::ILLEGAL_SIM_OR_ME);
+ }
+}
+
+/*
+ * Test IRadio.setNetworkSelectionModeManual() for the response returned.
+ */
+TEST_F(RadioHidlTest, setNetworkSelectionModeManual) {
+ int serial = 1;
+
+ radio->setNetworkSelectionModeManual(++serial, "123456");
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::ILLEGAL_SIM_OR_ME);
+ }
+}
+
+/*
+ * Test IRadio.getAvailableNetworks() for the response returned.
+ */
+TEST_F(RadioHidlTest, getAvailableNetworks) {
+ int serial = 1;
+
+ radio->getAvailableNetworks(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getBasebandVersion() for the response returned.
+ */
+TEST_F(RadioHidlTest, getBasebandVersion) {
+ int serial = 1;
+
+ radio->getBasebandVersion(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setBandMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, setBandMode) {
+ int serial = 1;
+
+ radio->setBandMode(++serial, RadioBandMode::BAND_MODE_USA);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getAvailableBandModes() for the response returned.
+ */
+TEST_F(RadioHidlTest, getAvailableBandModes) {
+ int serial = 1;
+
+ radio->getAvailableBandModes(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setPreferredNetworkType() for the response returned.
+ */
+TEST_F(RadioHidlTest, setPreferredNetworkType) {
+ int serial = 1;
+
+ radio->setPreferredNetworkType(++serial, PreferredNetworkType::GSM_ONLY);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getPreferredNetworkType() for the response returned.
+ */
+TEST_F(RadioHidlTest, getPreferredNetworkType) {
+ int serial = 1;
+
+ radio->getPreferredNetworkType(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getNeighboringCids() for the response returned.
+ */
+TEST_F(RadioHidlTest, getNeighboringCids) {
+ int serial = 1;
+
+ radio->getNeighboringCids(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setLocationUpdates() for the response returned.
+ */
+TEST_F(RadioHidlTest, setLocationUpdates) {
+ int serial = 1;
+
+ radio->setLocationUpdates(++serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setCdmaRoamingPreference() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCdmaRoamingPreference) {
+ int serial = 1;
+
+ radio->setCdmaRoamingPreference(++serial, CdmaRoamingType::HOME_NETWORK);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getCdmaRoamingPreference() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCdmaRoamingPreference) {
+ int serial = 1;
+
+ radio->getCdmaRoamingPreference(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getTTYMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, getTTYMode) {
+ int serial = 1;
+
+ radio->getTTYMode(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setTTYMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, setTTYMode) {
+ int serial = 1;
+
+ radio->setTTYMode(++serial, TtyMode::OFF);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setPreferredVoicePrivacy() for the response returned.
+ */
+TEST_F(RadioHidlTest, setPreferredVoicePrivacy) {
+ int serial = 1;
+
+ radio->setPreferredVoicePrivacy(++serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getPreferredVoicePrivacy() for the response returned.
+ */
+TEST_F(RadioHidlTest, getPreferredVoicePrivacy) {
+ int serial = 1;
+
+ radio->getPreferredVoicePrivacy(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getCDMASubscription() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCDMASubscription) {
+ int serial = 1;
+
+ radio->getCDMASubscription(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getDeviceIdentity() for the response returned.
+ */
+TEST_F(RadioHidlTest, getDeviceIdentity) {
+ int serial = 1;
+
+ radio->getDeviceIdentity(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.exitEmergencyCallbackMode() for the response returned.
+ */
+TEST_F(RadioHidlTest, exitEmergencyCallbackMode) {
+ int serial = 1;
+
+ radio->exitEmergencyCallbackMode(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getCdmaSubscriptionSource() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCdmaSubscriptionSource) {
+ int serial = 1;
+
+ radio->getCdmaSubscriptionSource(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getVoiceRadioTechnology() for the response returned.
+ */
+TEST_F(RadioHidlTest, getVoiceRadioTechnology) {
+ int serial = 1;
+
+ radio->getVoiceRadioTechnology(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getCellInfoList() for the response returned.
+ */
+TEST_F(RadioHidlTest, getCellInfoList) {
+ int serial = 1;
+
+ radio->getCellInfoList(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setCellInfoListRate() for the response returned.
+ */
+TEST_F(RadioHidlTest, setCellInfoListRate) {
+ int serial = 1;
+
+ // TODO(sanketpadawe): RIL crashes with value of rate = 10
+ radio->setCellInfoListRate(++serial, 0);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.nvReadItem() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvReadItem) {
+ int serial = 1;
+
+ radio->nvReadItem(++serial, NvItem::LTE_BAND_ENABLE_25);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.nvWriteItem() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvWriteItem) {
+ int serial = 1;
+ NvWriteItem item;
+ memset(&item, 0, sizeof(item));
+ item.value = hidl_string();
+
+ radio->nvWriteItem(++serial, item);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.nvWriteCdmaPrl() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvWriteCdmaPrl) {
+ int serial = 1;
+ std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
+
+ radio->nvWriteCdmaPrl(++serial, hidl_vec<uint8_t>(prl));
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.nvResetConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, nvResetConfig) {
+ int serial = 1;
+
+ radio->nvResetConfig(++serial, ResetNvType::RELOAD);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setUiccSubscription() for the response returned.
+ */
+TEST_F(RadioHidlTest, setUiccSubscription) {
+ int serial = 1;
+ SelectUiccSub item;
+ memset(&item, 0, sizeof(item));
+
+ radio->setUiccSubscription(++serial, item);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getHardwareConfig() for the response returned.
+ */
+TEST_F(RadioHidlTest, getHardwareConfig) {
+ int serial = 1;
+
+ radio->getHardwareConfig(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.requestShutdown() for the response returned.
+ */
+TEST_F(RadioHidlTest, requestShutdown) {
+ int serial = 1;
+
+ radio->requestShutdown(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getRadioCapability() for the response returned.
+ */
+TEST_F(RadioHidlTest, getRadioCapability) {
+ int serial = 1;
+
+ radio->getRadioCapability(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setRadioCapability() for the response returned.
+ */
+TEST_F(RadioHidlTest, setRadioCapability) {
+ int serial = 1;
+ RadioCapability rc;
+ memset(&rc, 0, sizeof(rc));
+ rc.logicalModemUuid = hidl_string();
+
+ radio->setRadioCapability(++serial, rc);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.startLceService() for the response returned.
+ */
+TEST_F(RadioHidlTest, startLceService) {
+ int serial = 1;
+
+ radio->startLceService(++serial, 5, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE
+ || radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED);
+ }
+}
+
+/*
+ * Test IRadio.stopLceService() for the response returned.
+ */
+TEST_F(RadioHidlTest, stopLceService) {
+ int serial = 1;
+
+ radio->stopLceService(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE
+ || radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED);
+ }
+}
+
+/*
+ * Test IRadio.pullLceData() for the response returned.
+ */
+TEST_F(RadioHidlTest, pullLceData) {
+ int serial = 1;
+
+ radio->pullLceData(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE
+ || radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED);
+ }
+}
+
+/*
+ * Test IRadio.getModemActivityInfo() for the response returned.
+ */
+TEST_F(RadioHidlTest, getModemActivityInfo) {
+ int serial = 1;
+
+ radio->getModemActivityInfo(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setAllowedCarriers() for the response returned.
+ */
+TEST_F(RadioHidlTest, setAllowedCarriers) {
+ int serial = 1;
+ CarrierRestrictions carriers;
+ memset(&carriers, 0, sizeof(carriers));
+ carriers.allowedCarriers.resize(1);
+ carriers.excludedCarriers.resize(0);
+ carriers.allowedCarriers[0].mcc = hidl_string();
+ carriers.allowedCarriers[0].mnc = hidl_string();
+ carriers.allowedCarriers[0].matchType = CarrierMatchType::ALL;
+ carriers.allowedCarriers[0].matchData = hidl_string();
+
+ radio->setAllowedCarriers(++serial, false, carriers);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.getAllowedCarriers() for the response returned.
+ */
+TEST_F(RadioHidlTest, getAllowedCarriers) {
+ int serial = 1;
+
+ radio->getAllowedCarriers(++serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.sendDeviceState() for the response returned.
+ */
+TEST_F(RadioHidlTest, sendDeviceState) {
+ int serial = 1;
+
+ radio->sendDeviceState(++serial, DeviceStateType::POWER_SAVE_MODE, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setIndicationFilter() for the response returned.
+ */
+TEST_F(RadioHidlTest, setIndicationFilter) {
+ int serial = 1;
+
+ radio->setIndicationFilter(++serial, 1);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+ }
+}
+
+/*
+ * Test IRadio.setSimCardPower() for the response returned.
+ */
+TEST_F(RadioHidlTest, setSimCardPower) {
+ int serial = 1;
+
+ radio->setSimCardPower(++serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
+ }
+}
\ No newline at end of file
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 5bf7ae2..54ae7c0 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
@@ -34,12 +34,11 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- EXPECT_EQ(RadioError::INVALID_STATE, radioRsp->rspInfo.error);
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
EXPECT_EQ(0, radioRsp->sendSmsResult.errorCode);
- } else {
- EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
- EXPECT_EQ("", radioRsp->sendSmsResult.ackPDU);
- EXPECT_EQ(-1, radioRsp->sendSmsResult.errorCode);
}
}
@@ -61,11 +60,10 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- EXPECT_EQ(RadioError::INVALID_STATE, radioRsp->rspInfo.error);
- } else {
- EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
- EXPECT_EQ("", radioRsp->sendSmsResult.ackPDU);
- EXPECT_EQ(-1, radioRsp->sendSmsResult.errorCode);
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
}
}
@@ -84,9 +82,7 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- EXPECT_EQ(RadioError::INVALID_STATE, radioRsp->rspInfo.error);
- } else {
- // TODO(shuoq): Will test right behavior when inserted sim card is considered
+ EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
}
}
@@ -106,8 +102,6 @@
if (cardStatus.cardState == CardState::ABSENT) {
// TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- // TODO(shuoq): Will test right behavior when inserted sim card is considered
}
}
@@ -148,9 +142,10 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- // TODO(shuoq): radioRsp->sendSmsResult needs to be investigated when Sim card is in
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
}
}
@@ -173,8 +168,6 @@
if (cardStatus.cardState == CardState::ABSENT) {
EXPECT_EQ(RadioError::NO_SMS_TO_ACK, radioRsp->rspInfo.error);
- } else {
- EXPECT_EQ(RadioError::NO_SMS_TO_ACK, radioRsp->rspInfo.error);
}
}
@@ -224,9 +217,6 @@
if (cardStatus.cardState == CardState::ABSENT) {
EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
- } else {
- EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp->rspInfo.error);
- // TODO(shuoq): radioRsp->sendSmsResult needs to be investigated when sim card is in
}
}
@@ -243,10 +233,11 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
- // TODO(shuoq): radioRsp->smscAddress needs to be investigated when Sim card is in
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_STATE
+ || radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE);
}
}
@@ -265,8 +256,6 @@
if (cardStatus.cardState == CardState::ABSENT) {
EXPECT_EQ(RadioError::INVALID_SMS_FORMAT, radioRsp->rspInfo.error);
- } else {
- EXPECT_EQ(RadioError::INVALID_SMS_FORMAT, radioRsp->rspInfo.error);
}
}
@@ -287,9 +276,10 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- // TODO(shuoq): radioRsp->writeSmsToSimIndex needs to be investigated when Sim card is in
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
}
}
@@ -307,9 +297,10 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- EXPECT_EQ(RadioError::NO_SUCH_ENTRY, radioRsp->rspInfo.error);
+ EXPECT_EQ(RadioError::INVALID_SMS_FORMAT, radioRsp->rspInfo.error);
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR);
}
}
@@ -355,9 +346,10 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- // TODO(shuoq): radioRsp->writeSmsToRuimIndex needs to be investigated when sim card is in
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE
+ || radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
}
}
@@ -404,9 +396,9 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- // TODO(shuoq): Will test right behavior when inserted sim card is considered
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR);
}
}
@@ -424,8 +416,9 @@
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
if (cardStatus.cardState == CardState::ABSENT) {
- // TODO(shuoq): Will add error check when we know the expected error from QC
- } else {
- EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS
+ || radioRsp->rspInfo.error == RadioError::MODEM_ERR
+ || radioRsp->rspInfo.error == RadioError::SYSTEM_ERR
+ || radioRsp->rspInfo.error == RadioError::INVALID_STATE);
}
}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
new file mode 100644
index 0000000..f6d576d
--- /dev/null
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include<radio_hidl_hal_utils.h>
+
+using namespace ::android::hardware::radio::V1_0;
+
+/*
+ * Test IRadio.sendEnvelope() for the response returned.
+ */
+TEST_F(RadioHidlTest, sendEnvelope) {
+ int serial = 0;
+
+ // Test with sending empty string
+ std::string content = "";
+
+ radio->sendEnvelope(++serial, content);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+
+ // Test with sending random string
+ content = "0";
+
+ radio->sendEnvelope(++serial, content);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.sendTerminalResponseToSim() for the response returned.
+ */
+TEST_F(RadioHidlTest, sendTerminalResponseToSim) {
+ int serial = 0;
+
+ // Test with sending empty string
+ std::string commandResponse = "";
+
+ radio->sendTerminalResponseToSim(++serial, commandResponse);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+
+ // Test with sending random string
+ commandResponse = "0";
+
+ radio->sendTerminalResponseToSim(++serial, commandResponse);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.handleStkCallSetupRequestFromSim() for the response returned.
+ */
+TEST_F(RadioHidlTest, handleStkCallSetupRequestFromSim) {
+ int serial = 0;
+ bool accept = false;
+
+ radio->handleStkCallSetupRequestFromSim(++serial, accept);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.reportStkServiceIsRunning() for the response returned.
+ */
+TEST_F(RadioHidlTest, reportStkServiceIsRunning) {
+ int serial = 0;
+
+ radio->reportStkServiceIsRunning(++serial);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+}
+
+/*
+ * Test IRadio.sendEnvelopeWithStatus() for the response returned with empty string.
+ */
+TEST_F(RadioHidlTest, sendEnvelopeWithStatus) {
+ int serial = 0;
+
+ // Test with sending empty string
+ std::string contents = "";
+
+ radio->sendEnvelopeWithStatus(++serial, contents);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ EXPECT_EQ(RadioError::NONE, radioRsp->rspInfo.error);
+ }
+
+ // Test with sending random string
+ contents = "0";
+
+ radio->sendEnvelopeWithStatus(++serial, contents);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_FALSE(RadioError::NONE == radioRsp->rspInfo.error);
+ }
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils.h b/radio/1.0/vts/functional/radio_hidl_hal_utils.h
index bb693ac..126ad0d 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils.h
@@ -32,6 +32,7 @@
using ::android::hardware::radio::V1_0::CardState;
using ::android::hardware::radio::V1_0::Call;
using ::android::hardware::radio::V1_0::CallForwardInfo;
+using ::android::hardware::radio::V1_0::CarrierMatchType;
using ::android::hardware::radio::V1_0::CarrierRestrictions;
using ::android::hardware::radio::V1_0::CdmaRoamingType;
using ::android::hardware::radio::V1_0::CdmaBroadcastSmsConfigInfo;
@@ -39,6 +40,7 @@
using ::android::hardware::radio::V1_0::CellInfo;
using ::android::hardware::radio::V1_0::ClipStatus;
using ::android::hardware::radio::V1_0::DataRegStateResult;
+using ::android::hardware::radio::V1_0::DeviceStateType;
using ::android::hardware::radio::V1_0::Dial;
using ::android::hardware::radio::V1_0::GsmBroadcastSmsConfigInfo;
using ::android::hardware::radio::V1_0::HardwareConfig;
@@ -54,6 +56,8 @@
using ::android::hardware::radio::V1_0::LceDataInfo;
using ::android::hardware::radio::V1_0::LceStatusInfo;
using ::android::hardware::radio::V1_0::NeighboringCell;
+using ::android::hardware::radio::V1_0::NvItem;
+using ::android::hardware::radio::V1_0::NvWriteItem;
using ::android::hardware::radio::V1_0::OperatorInfo;
using ::android::hardware::radio::V1_0::PreferredNetworkType;
using ::android::hardware::radio::V1_0::RadioBandMode;
@@ -61,6 +65,8 @@
using ::android::hardware::radio::V1_0::RadioResponseType;
using ::android::hardware::radio::V1_0::RadioTechnology;
using ::android::hardware::radio::V1_0::RadioTechnologyFamily;
+using ::android::hardware::radio::V1_0::ResetNvType;
+using ::android::hardware::radio::V1_0::SelectUiccSub;
using ::android::hardware::radio::V1_0::SendSmsResult;
using ::android::hardware::radio::V1_0::SetupDataCallResult;
using ::android::hardware::radio::V1_0::SignalStrength;
@@ -69,11 +75,12 @@
using ::android::hardware::radio::V1_0::VoiceRegStateResult;
using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
-#define TIMEOUT_PERIOD 20
+#define TIMEOUT_PERIOD 40
class RadioHidlTest;
extern CardStatus cardStatus;
diff --git a/radio/1.0/vts/functional/radio_response.cpp b/radio/1.0/vts/functional/radio_response.cpp
index 3db2dd1..8759003 100644
--- a/radio/1.0/vts/functional/radio_response.cpp
+++ b/radio/1.0/vts/functional/radio_response.cpp
@@ -72,7 +72,9 @@
}
Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
- const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+ const RadioResponseInfo& info, int32_t /*remainingRetries*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -147,28 +149,38 @@
}
Return<void> RadioResponse::getSignalStrengthResponse(
- const RadioResponseInfo& /*info*/, const SignalStrength& /*sig_strength*/) {
+ const RadioResponseInfo& info, const SignalStrength& /*sig_strength*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getVoiceRegistrationStateResponse(
- const RadioResponseInfo& /*info*/, const VoiceRegStateResult& /*voiceRegResponse*/) {
+ const RadioResponseInfo& info, const VoiceRegStateResult& /*voiceRegResponse*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getDataRegistrationStateResponse(
- const RadioResponseInfo& /*info*/, const DataRegStateResult& /*dataRegResponse*/) {
+ const RadioResponseInfo& info, const DataRegStateResult& /*dataRegResponse*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getOperatorResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*longName*/,
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*longName*/,
const ::android::hardware::hidl_string& /*shortName*/,
const ::android::hardware::hidl_string& /*numeric*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setRadioPowerResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setRadioPowerResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -195,7 +207,9 @@
}
Return<void> RadioResponse::setupDataCallResponse(
- const RadioResponseInfo& /*info*/, const SetupDataCallResult& /*dcResponse*/) {
+ const RadioResponseInfo& info, const SetupDataCallResult& /*dcResponse*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -219,12 +233,16 @@
return Void();
}
-Return<void> RadioResponse::getClirResponse(const RadioResponseInfo& /*info*/, int32_t /*n*/,
+Return<void> RadioResponse::getClirResponse(const RadioResponseInfo& info, int32_t /*n*/,
int32_t /*m*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setClirResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setClirResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -267,42 +285,58 @@
return Void();
}
-Return<void> RadioResponse::deactivateDataCallResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::deactivateDataCallResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::getFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::getFacilityLockForAppResponse(const RadioResponseInfo& info,
int32_t /*response*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::setFacilityLockForAppResponse(const RadioResponseInfo& info,
int32_t /*retry*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setBarringPasswordResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setBarringPasswordResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getNetworkSelectionModeResponse(
- const RadioResponseInfo& /*info*/, bool /*manual*/) {
+ const RadioResponseInfo& info, bool /*manual*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getAvailableNetworksResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<OperatorInfo>& /*networkInfos*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -321,7 +355,9 @@
}
Return<void> RadioResponse::getBasebandVersionResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*version*/) {
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*version*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -343,14 +379,18 @@
return Void();
}
-Return<void> RadioResponse::getClipResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::getClipResponse(const RadioResponseInfo& info,
ClipStatus /*status*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getDataCallListResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<SetupDataCallResult>& /*dcResponse*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -367,7 +407,9 @@
}
Return<void> RadioResponse::setSuppServiceNotificationsResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -386,27 +428,37 @@
return Void();
}
-Return<void> RadioResponse::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setBandModeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getAvailableBandModesResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<RadioBandMode>& /*bandModes*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::sendEnvelopeResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::sendEnvelopeResponse(const RadioResponseInfo& info,
const ::android::hardware::hidl_string& /*commandResponse*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::sendTerminalResponseToSimResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::sendTerminalResponseToSimResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -416,23 +468,31 @@
return Void();
}
-Return<void> RadioResponse::setPreferredNetworkTypeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setPreferredNetworkTypeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getPreferredNetworkTypeResponse(
- const RadioResponseInfo& /*info*/, PreferredNetworkType /*nw_type*/) {
+ const RadioResponseInfo& info, PreferredNetworkType /*nw_type*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getNeighboringCidsResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<NeighboringCell>& /*cells*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setLocationUpdatesResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -440,30 +500,42 @@
return Void();
}
-Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(
- const RadioResponseInfo& /*info*/, CdmaRoamingType /*type*/) {
+ const RadioResponseInfo& info, CdmaRoamingType /*type*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setTTYModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setTTYModeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::getTTYModeResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse::getTTYModeResponse(const RadioResponseInfo& info,
TtyMode /*mode*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getPreferredVoicePrivacyResponse(
- const RadioResponseInfo& /*info*/, bool /*enable*/) {
+ const RadioResponseInfo& info, bool /*enable*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -493,39 +565,53 @@
}
Return<void> RadioResponse::getGsmBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setGsmBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setGsmBroadcastConfigResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setGsmBroadcastActivationResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setGsmBroadcastActivationResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getCdmaBroadcastConfigResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setCdmaBroadcastActivationResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCdmaBroadcastActivationResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getCDMASubscriptionResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*mdn*/,
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*mdn*/,
const ::android::hardware::hidl_string& /*hSid*/,
const ::android::hardware::hidl_string& /*hNid*/,
const ::android::hardware::hidl_string& /*min*/,
const ::android::hardware::hidl_string& /*prl*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -545,14 +631,18 @@
}
Return<void> RadioResponse::getDeviceIdentityResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imei*/,
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*imei*/,
const ::android::hardware::hidl_string& /*imeisv*/,
const ::android::hardware::hidl_string& /*esn*/,
const ::android::hardware::hidl_string& /*meid*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -576,17 +666,23 @@
return Void();
}
-Return<void> RadioResponse::reportStkServiceIsRunningResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::reportStkServiceIsRunningResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(
- const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+ const RadioResponseInfo& info, CdmaSubscriptionSource /*source*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::requestIsimAuthenticationResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*response*/) {
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*response*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -598,32 +694,44 @@
}
Return<void> RadioResponse::sendEnvelopeWithStatusResponse(
- const RadioResponseInfo& /*info*/, const IccIoResult& /*iccIo*/) {
+ const RadioResponseInfo& info, const IccIoResult& /*iccIo*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getVoiceRadioTechnologyResponse(
- const RadioResponseInfo& /*info*/, RadioTechnology /*rat*/) {
+ const RadioResponseInfo& info, RadioTechnology /*rat*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getCellInfoListResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<CellInfo>& /*cellInfo*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setCellInfoListRateResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setCellInfoListRateResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setInitialAttachApnResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setInitialAttachApnResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getImsRegistrationStateResponse(
- const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+ const RadioResponseInfo& info, bool /*isRegistered*/,
RadioTechnologyFamily /*ratFamily*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -667,33 +775,47 @@
}
Return<void> RadioResponse::nvReadItemResponse(
- const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*result*/) {
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& /*result*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::nvWriteItemResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::nvResetConfigResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setUiccSubscriptionResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setUiccSubscriptionResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setDataAllowedResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getHardwareConfigResponse(
- const RadioResponseInfo& /*info*/,
+ const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<HardwareConfig>& /*config*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
@@ -705,67 +827,93 @@
return Void();
}
-Return<void> RadioResponse::setDataProfileResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::setDataProfileResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
-Return<void> RadioResponse::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse::requestShutdownResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getRadioCapabilityResponse(
- const RadioResponseInfo& /*info*/, const RadioCapability& /*rc*/) {
+ const RadioResponseInfo& info, const RadioCapability& /*rc*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setRadioCapabilityResponse(
- const RadioResponseInfo& /*info*/, const RadioCapability& /*rc*/) {
+ const RadioResponseInfo& info, const RadioCapability& /*rc*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::startLceServiceResponse(
- const RadioResponseInfo& /*info*/, const LceStatusInfo& /*statusInfo*/) {
+ const RadioResponseInfo& info, const LceStatusInfo& /*statusInfo*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::stopLceServiceResponse(
- const RadioResponseInfo& /*info*/, const LceStatusInfo& /*statusInfo*/) {
+ const RadioResponseInfo& info, const LceStatusInfo& /*statusInfo*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::pullLceDataResponse(
- const RadioResponseInfo& /*info*/, const LceDataInfo& /*lceInfo*/) {
+ const RadioResponseInfo& info, const LceDataInfo& /*lceInfo*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getModemActivityInfoResponse(
- const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+ const RadioResponseInfo& info, const ActivityStatsInfo& /*activityInfo*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setAllowedCarriersResponse(
- const RadioResponseInfo& /*info*/, int32_t /*numAllowed*/) {
+ const RadioResponseInfo& info, int32_t /*numAllowed*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::getAllowedCarriersResponse(
- const RadioResponseInfo& /*info*/, bool /*allAllowed*/,
+ const RadioResponseInfo& info, bool /*allAllowed*/,
const CarrierRestrictions& /*carriers*/) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::sendDeviceStateResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setIndicationFilterResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
Return<void> RadioResponse::setSimCardPowerResponse(
- const RadioResponseInfo& /*info*/) {
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent.notify();
return Void();
}
diff --git a/renderscript/1.0/vts/functional/Android.bp b/renderscript/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..635e2e6
--- /dev/null
+++ b/renderscript/1.0/vts/functional/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalRenderscriptV1_0TargetTest",
+ srcs: [
+ "VtsHalRenderscriptV1_0TargetTest.cpp",
+ "VtsCopyTests.cpp",
+ "VtsMiscellaneousTests.cpp",
+ "VtsScriptTests.cpp",
+ "bitcode.cpp",
+ ],
+ defaults: ["hidl_defaults"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libcutils",
+ "libhidlbase",
+ "libhidltransport",
+ "libnativehelper",
+ "libutils",
+ "android.hardware.renderscript@1.0",
+ ],
+ static_libs: ["VtsHalHidlTargetTestBase"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/renderscript/1.0/vts/functional/VtsCopyTests.cpp b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
new file mode 100644
index 0000000..77217cb
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsCopyTests.cpp
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#include "VtsHalRenderscriptV1_0TargetTest.h"
+
+/*
+ * This test creates a 1D Allocation with 128 Float Elements, and two float
+ * vector dataIn & dataOut. dataIn is pre-populated with data, and copied into
+ * the Allocation using allocation1DWrite. Then the Allocation is copied into
+ * dataOut with allocation1DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation1DWrite,
+ * allocation1DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, Simple1DCopyTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x float1
+ Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ // 128 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ std::vector<float> dataIn(128), dataOut(128);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
+ context->allocation1DRead(allocation, 0, 0, (uint32_t)dataOut.size(), (Ptr)dataOut.data(),
+ (Size)dataOut.size()*sizeof(float));
+ bool same = std::all_of(dataOut.begin(), dataOut.end(),
+ [](float x){ static int val = 0; return x == (float)val++; });
+ EXPECT_EQ(true, same);
+}
+
+/*
+ * This test creates a 2D Allocation with 128 * 128 Float Elements, and two
+ * float vector dataIn & dataOut. dataIn is pre-populated with data, and copied
+ * into the Allocation using allocation2DWrite. Then the Allocation is copied
+ * into dataOut with allocation2DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, Simple2DCopyTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x 128 x float1
+ Type type = context->typeCreate(element, 128, 128, 0, false, false, YuvFormat::YUV_NONE);
+ // 128 x 128 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ std::vector<float> dataIn(128*128), dataOut(128*128);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ context->allocation2DWrite(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 128, 128,
+ _data, 0);
+ context->allocation2DRead(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 128, 128,
+ (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float), 0);
+ bool same = std::all_of(dataOut.begin(), dataOut.end(),
+ [](float x){ static int val = 0; return x == (float)val++; });
+ EXPECT_EQ(true, same);
+}
+
+/*
+ * This test creates a 3D Allocation with 32 * 32 * 32 Float Elements, and two
+ * float vector dataIn & dataOut. dataIn is pre-populated with data, and copied
+ * into the Allocation using allocation3DWrite. Then the Allocation is copied
+ * into dataOut with allocation3DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation3DWrite,
+ * allocation3DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, Simple3DCopyTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 32 x 32 x 32 x float1
+ Type type = context->typeCreate(element, 32, 32, 32, false, false, YuvFormat::YUV_NONE);
+ // 32 x 32 x 32 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ std::vector<float> dataIn(32*32*32), dataOut(32*32*32);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ context->allocation3DWrite(allocation, 0, 0, 0, 0, 32, 32, 32, _data, 0);
+ context->allocation3DRead(allocation, 0, 0, 0, 0, 32, 32, 32, (Ptr)dataOut.data(),
+ (Size)dataOut.size()*sizeof(float), 0);
+ bool same = std::all_of(dataOut.begin(), dataOut.end(),
+ [](float x){ static int val = 0; return x == (float)val++; });
+ EXPECT_EQ(true, same);
+}
+
+/*
+ * This test creates a 2D Allocation with 512 * 512 Float Elements with
+ * allocationCreateFromBitmap, and two float vector dataIn & dataOut. dataIn is
+ * pre-populated with data, and copied into the Allocation using
+ * allocationCopyToBitmap. Then the Allocation is copied into dataOut with
+ * allocationRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateFromBitmap,
+ * allocationCopyToBitmap, allocationRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleBitmapTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 512 x 512 x float1
+ Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<float> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ // 512 x 512 x float1
+ Allocation allocation = context->allocationCreateFromBitmap(type,
+ AllocationMipmapControl::NONE,
+ _data,
+ (int)AllocationUsageType::SCRIPT);
+ EXPECT_NE(allocation, Allocation(0));
+
+ context->allocationCopyToBitmap(allocation, (Ptr)dataOut1.data(),
+ (Size)dataOut1.size()*sizeof(float));
+ bool same1 = std::all_of(dataOut1.begin(), dataOut1.end(),
+ [](float x){ static int val = 0; return x == (float)val++; });
+ EXPECT_EQ(true, same1);
+
+ context->allocationRead(allocation, (Ptr)dataOut2.data(), (Size)dataOut2.size()*sizeof(float));
+ bool same2 = std::all_of(dataOut2.begin(), dataOut2.end(),
+ [](float x){ static int val = 0; return x == (float)val++; });
+ EXPECT_EQ(true, same2);
+}
+
+/*
+ * This test creates two 2D Allocations, one with 512 * 512 Float Elements, the
+ * other with 256 * 256 Float Elements. The larger Allocation is pre-populated
+ * with dataIn, and copied into the smaller Allocation using
+ * allocationCopy2DRange. Then the Allocation is copied into dataOut with
+ * allocationRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateFromBitmap,
+ * allocationCreateTyped, allocationCopy2DRange, allocationRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, AllocationCopy2DRangeTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 512 x 512 x float1
+ Type typeSrc = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ // 256 x 256 x float1
+ Type typeDst = context->typeCreate(element, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<float> dataIn(512*512), dataOut(256*256), expected(256*256);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ // 512 x 512 x float1
+ Allocation allocSrc = context->allocationCreateFromBitmap(typeSrc,
+ AllocationMipmapControl::NONE, _data,
+ (int)AllocationUsageType::SCRIPT);
+ // 256 x 256 x float1
+ Allocation allocDst = context->allocationCreateTyped(typeDst, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocationCopy2DRange(allocDst, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+ allocSrc, 128, 128, 0, AllocationCubemapFace::POSITIVE_X);
+ context->allocationRead(allocDst, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float));
+ for (int i = 0; i < 256; ++i) {
+ for (int j = 0; j < 256; ++j) {
+ expected[i*256 + j] = dataIn[(i+128)*512 + (j+128)];
+ }
+ }
+ EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates two 3D Allocations, one with 128 * 128 * 128 Float
+ * Elements, the other with 64 * 64 * 64 Float Elements. The larger Allocation
+ * is pre-populated with dataIn, and copied into the smaller Allocation using
+ * allocationCopy3DRange. Then the Allocation is copied into dataOut with
+ * allocationRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation3DWrite,
+ * allocationCopy3DRange, allocationRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, AllocationCopy3DRangeTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x 128 x 128 x float1
+ Type typeSrc = context->typeCreate(element, 128, 128, 128, false, false, YuvFormat::YUV_NONE);
+ // 64 x 64 x 64 x float1
+ Type typeDst = context->typeCreate(element, 64, 64, 64, false, false, YuvFormat::YUV_NONE);
+ std::vector<float> dataIn(128*128*128), dataOut(64*64*64), expected(64*64*64);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ // 512 x 512 x float1
+ Allocation allocSrc = context->allocationCreateTyped(typeSrc, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ // 256 x 256 x float1
+ Allocation allocDst = context->allocationCreateTyped(typeDst, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocation3DWrite(allocSrc, 0, 0, 0, 0, 128, 128, 128, _data, 128*sizeof(float));
+ context->allocationCopy3DRange(allocDst, 0, 0, 0, 0, 64, 64, 64, allocSrc, 32, 32, 32, 0);
+ context->allocationRead(allocDst, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float));
+ for (int i = 0; i < 64; ++i) {
+ for (int j = 0; j < 64; ++j) {
+ for (int k = 0; k < 64; ++k) {
+ expected[i*64*64 + j*64 + k] = dataIn[(i+32)*128*128 + (j+32)*128 + (k+32)];
+ }
+ }
+ }
+ EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates one 2D Allocations, one with 512 * 512 Float Elements, and
+ * one 2D AllocationAdapter with a window of 256 * 256 based on the Allocation.
+ * The Allocation is pre-populated with dataIn. Then the Allocation is copied
+ * into dataOut with allocationRead on the AllocationAdapter.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateFromBitmap,
+ * allocationAdapterCreate, allocationAdapterOffset, allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleAdapterTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 512 x 512 x float1
+ Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<float> dataIn(512*512), dataOut(256*256), expected;
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ // 512 x 512 x float1
+ Allocation allocation = context->allocationCreateFromBitmap(type,
+ AllocationMipmapControl::NONE,
+ _data,
+ (int)AllocationUsageType::SCRIPT);
+ // 256 x 256 x float1
+ Type subType = context->typeCreate(element, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+ // 256 x 256 x float1
+ AllocationAdapter allocationAdapter = context->allocationAdapterCreate(subType, allocation);
+ EXPECT_NE(AllocationAdapter(0), allocationAdapter);
+
+ std::vector<uint32_t> offsets(9, 0);
+ offsets[0] = 128;
+ offsets[1] = 128;
+ hidl_vec<uint32_t> _offsets;
+ _offsets.setToExternal(offsets.data(), offsets.size());
+ // origin at (128,128)
+ context->allocationAdapterOffset(allocationAdapter, _offsets);
+
+ context->allocation2DRead(allocationAdapter, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256,
+ 256, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float), 0);
+ for (int i = 128; i < 128 + 256; ++i) {
+ for (int j = 128; j < 128 + 256; ++j) {
+ expected.push_back(i * 512 + j);
+ }
+ }
+ EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates one 2D Allocations, one with 64 * 64 USIGNED_8 Elements,
+ * and with AllocationMipmapControl::FULL. The Allocation is pre-populated with
+ * dataIn and the mipmaps are filled with allocationGenerateMipmaps. Then
+ * dataOut is then overridden with allocation2DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * allocationGenerateMipmaps, allocationSyncAll, allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleMipmapTest) {
+ // uint8_t
+ Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ // 64 x 64 x uint8_t
+ Type type = context->typeCreate(element, 64, 64, 0, true, false, YuvFormat::YUV_NONE);
+ std::vector<uint8_t> dataIn(64*64), dataOut(32*32), expected(32*32);
+ std::generate(dataIn.begin(), dataIn.end(),
+ [](){ static int val = 0; return (uint8_t)(0xFF & val++); });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint8_t));
+ // 64 x 64 x uint8_t
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::FULL,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocation2DWrite(allocation, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 64, 64,
+ _data, 64*sizeof(uint8_t));
+ context->allocationGenerateMipmaps(allocation);
+ context->allocationSyncAll(allocation, AllocationUsageType::SCRIPT);
+ context->allocation2DRead(allocation, 0, 0, 1, AllocationCubemapFace::POSITIVE_X, 32, 32,
+ (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t),
+ 32*sizeof(uint8_t));
+ for (int i = 0; i < 32; ++i) {
+ for (int j = 0; j < 32; ++j) {
+ expected[i*32 + j] = ((uint32_t)dataIn[i*2*64 + j*2] + dataIn[i*2*64 + j*2 + 1] +
+ dataIn[i*2*64 + j*2 + 64] + dataIn[i*2*64 + j*2 + 64+1]) / 4;
+ }
+ }
+ EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates one 2D Allocations, one with 128 * 128 Float Elements with
+ * allocationCubeCreateFromBitmap. The Allocation is pre-populated with dataIn
+ * and the mipmaps are filled with allocationGenerateMipmaps. Then dataOut is
+ * then overridden with allocation2DRead.
+ *
+ * Calls: elementCreate, typeCreate, allocationCubeCreateFromBitmap,
+ * allocation2DRead
+ *
+ * Expect: dataIn & dataOut are the same.
+ */
+TEST_F(RenderscriptHidlTest, SimpleCubemapTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x 128 x float1
+ Type type = context->typeCreate(element, 128, 128, 0, false, true, YuvFormat::YUV_NONE);
+ std::vector<float> dataIn(128*128*6), dataOut(128*128), expected(128*128);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ // 128 x 128 x float1 x 6
+ Allocation allocation = context->allocationCubeCreateFromBitmap(
+ type, AllocationMipmapControl::NONE, _data, (int)AllocationUsageType::SCRIPT);
+ EXPECT_NE(Allocation(0), allocation);
+
+ context->allocation2DRead(allocation, 0, 0, 0, AllocationCubemapFace::NEGATIVE_Z, 128,
+ 128, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(float),
+ 128*sizeof(float));
+ for (int i = 0; i < 128; ++i) {
+ for (int j = 0; j < 128; ++j) {
+ expected[i*128 + j] = i*128*6 + j + 128*5;
+ }
+ }
+ EXPECT_EQ(expected, dataOut);
+}
+
+/*
+ * This test creates a complex element type (uint8_t, uint32_t) out of known
+ * elements. It then verifies the element structure was created correctly.
+ * Finally, the test creates a 128-wide, 1-dimension allocation of this type
+ * and transfers memory to and from this structure.
+ *
+ * Calls: elementCreate, elementComplexCreate, elementGetSubElements,
+ * typeCreate, allocationCreateTyped, allocationElementWrite,
+ * allocationElementRead
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ComplexElementTest) {
+ Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ Element element2 = context->elementCreate(DataType::UNSIGNED_32, DataKind::USER, false, 1);
+
+ hidl_vec<Element> eins = {element1, element2};
+ hidl_vec<hidl_string> names = {hidl_string("first"), hidl_string("second")};
+ hidl_vec<Size> arraySizesPtr = {sizeof(uint8_t), sizeof(uint32_t)};
+ Element element3 = context->elementComplexCreate(eins, names, arraySizesPtr);
+ EXPECT_NE(Element(0), element3);
+
+ std::vector<Element> ids;
+ std::vector<std::string> namesOut;
+ std::vector<Size> arraySizesOut;
+ context->elementGetSubElements(element3, 2, [&](const hidl_vec<Element>& _ids,
+ const hidl_vec<hidl_string>& _names,
+ const hidl_vec<Size>& _arraySizes){
+ ids = _ids;
+ namesOut.push_back(_names[0]);
+ namesOut.push_back(_names[1]);
+ arraySizesOut = _arraySizes;
+ });
+ EXPECT_NE(Element(0), ids[0]);
+ EXPECT_NE(Element(0), ids[1]);
+ EXPECT_EQ("first", namesOut[0]);
+ EXPECT_EQ("second", namesOut[1]);
+ EXPECT_EQ(sizeof(uint8_t), arraySizesOut[0]);
+ EXPECT_EQ(sizeof(uint32_t), arraySizesOut[1]);
+
+ // 128 x (uint8_t, uint32_t)
+ Type type = context->typeCreate(element3, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ // 128 x (uint8_t, uint32_t)
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ std::vector<uint32_t> dataIn(128), dataOut(128);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint32_t));
+ context->allocationElementWrite(allocation, 0, 0, 0, 0, _data, 1);
+ context->allocationElementRead(allocation, 0, 0, 0, 0, (Ptr)dataOut.data(),
+ (Size)dataOut.size()*sizeof(uint32_t), 1);
+ bool same = std::all_of(dataOut.begin(), dataOut.end(),
+ [](uint32_t x){ static uint32_t val = 0; return x == val++; });
+ EXPECT_EQ(true, same);
+}
+*/
diff --git a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
new file mode 100644
index 0000000..f505d01
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VtsHalRenderscriptV1_0TargetTest.h"
+
+// The main test class for RENDERSCRIPT HIDL HAL.
+void RenderscriptHidlTest::SetUp() {
+ device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>();
+ ASSERT_NE(nullptr, device.get());
+
+ uint32_t version = 0;
+ uint32_t flags = 0;
+ context = device->contextCreate(version, ContextType::NORMAL, flags);
+ ASSERT_NE(nullptr, context.get());
+}
+
+void RenderscriptHidlTest::TearDown() {
+ context->contextDestroy();
+}
+
+// A class for test environment setup (kept since this file is a template).
+class RenderscriptHidlEnvironment : public ::testing::Environment {
+public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+};
+
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(new RenderscriptHidlEnvironment);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
new file mode 100644
index 0000000..fc1b7e4
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsHalRenderscriptV1_0TargetTest.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
+#define VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
+
+#define LOG_TAG "renderscript_hidl_hal_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/renderscript/1.0/IContext.h>
+#include <android/hardware/renderscript/1.0/IDevice.h>
+#include <android/hardware/renderscript/1.0/types.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+
+using ::android::hardware::renderscript::V1_0::Allocation;
+using ::android::hardware::renderscript::V1_0::AllocationAdapter;
+using ::android::hardware::renderscript::V1_0::AllocationCubemapFace;
+using ::android::hardware::renderscript::V1_0::AllocationMipmapControl;
+using ::android::hardware::renderscript::V1_0::AllocationUsageType;
+using ::android::hardware::renderscript::V1_0::IContext;
+using ::android::hardware::renderscript::V1_0::IDevice;
+using ::android::hardware::renderscript::V1_0::ContextType;
+using ::android::hardware::renderscript::V1_0::DataType;
+using ::android::hardware::renderscript::V1_0::DataKind;
+using ::android::hardware::renderscript::V1_0::Element;
+using ::android::hardware::renderscript::V1_0::MessageToClientType;
+using ::android::hardware::renderscript::V1_0::NativeWindow;
+using ::android::hardware::renderscript::V1_0::ObjectBase;
+using ::android::hardware::renderscript::V1_0::OpaqueHandle;
+using ::android::hardware::renderscript::V1_0::Ptr;
+using ::android::hardware::renderscript::V1_0::Sampler;
+using ::android::hardware::renderscript::V1_0::SamplerValue;
+using ::android::hardware::renderscript::V1_0::Script;
+using ::android::hardware::renderscript::V1_0::ScriptFieldID;
+using ::android::hardware::renderscript::V1_0::ScriptGroup;
+using ::android::hardware::renderscript::V1_0::ScriptGroup2;
+using ::android::hardware::renderscript::V1_0::ScriptIntrinsicID;
+using ::android::hardware::renderscript::V1_0::ScriptInvokeID;
+using ::android::hardware::renderscript::V1_0::ScriptKernelID;
+using ::android::hardware::renderscript::V1_0::Size;
+using ::android::hardware::renderscript::V1_0::ThreadPriorities;
+using ::android::hardware::renderscript::V1_0::Type;
+using ::android::hardware::renderscript::V1_0::YuvFormat;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+// bitcode variables
+typedef signed char int8_t;
+extern const int8_t bitCode[];
+extern const int bitCodeLength;
+
+// The main test class for RENDERSCRIPT HIDL HAL.
+class RenderscriptHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+public:
+ virtual void SetUp() override;
+ virtual void TearDown() override;
+
+ sp<IContext> context;
+
+private:
+ sp<IDevice> device;
+};
+
+#endif // VTS_HAL_RENDERSCRIPT_V1_0_TARGET_TESTS_H
diff --git a/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
new file mode 100644
index 0000000..c2b3354
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsMiscellaneousTests.cpp
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VtsHalRenderscriptV1_0TargetTest.h"
+
+/*
+ * ContextCreateAndDestroy:
+ * Creates a RenderScript context and immediately destroys the context.
+ * Since create and destroy calls are a part of SetUp() and TearDown(),
+ * the test definition is intentionally kept empty
+ *
+ * Calls: getService<IDevice>, contextCreate, contextDestroy
+ */
+TEST_F(RenderscriptHidlTest, ContextCreateAndDestroy) {}
+
+/*
+ * Create an Element and verify the return value is valid.
+ *
+ * Calls: elementCreate
+ */
+TEST_F(RenderscriptHidlTest, ElementCreate) {
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ EXPECT_NE(Element(0), element);
+}
+
+/*
+ * Create an Element, a Type and an Allocation of that type, and verify the
+ * return values are valid.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocationGetType
+ */
+TEST_F(RenderscriptHidlTest, ElementTypeAllocationCreate) {
+ // Element create test
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ EXPECT_NE(Element(0), element);
+
+ // Type create test
+ Type type = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
+ EXPECT_NE(Type(0), type);
+
+ // Allocation create test
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)((uint32_t)AllocationUsageType::ALL
+ & ~(uint32_t)AllocationUsageType::OEM),
+ (Ptr)nullptr);
+ EXPECT_NE(Allocation(0), allocation);
+
+ // Allocation type test
+ Type type2 = context->allocationGetType(allocation);
+ EXPECT_EQ(type, type2);
+}
+
+/*
+ * Create an Element, a Type of the Element, and verify the native metadata can
+ * be retrieved correctly.
+ *
+ * Calls: elementCreate, typeCreate, elementGetNativeMetadata,
+ * typeGetNativeMetadata
+ */
+TEST_F(RenderscriptHidlTest, MetadataTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x float1
+ Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+
+ std::vector<uint32_t> elementMetadata(5);
+ context->elementGetNativeMetadata(element, [&](const hidl_vec<uint32_t>& _metadata){
+ elementMetadata = _metadata; });
+ EXPECT_EQ(DataType::FLOAT_32, (DataType)elementMetadata[0]);
+ EXPECT_EQ(DataKind::USER, (DataKind)elementMetadata[1]);
+ EXPECT_EQ(false, ((uint32_t)elementMetadata[2] == 1) ? true : false);
+ EXPECT_EQ(1u, (uint32_t)elementMetadata[3]);
+ EXPECT_EQ(0u, (uint32_t)elementMetadata[4]);
+
+ std::vector<OpaqueHandle> typeMetadata(6);
+ context->typeGetNativeMetadata(type, [&typeMetadata](const hidl_vec<OpaqueHandle>& _metadata){
+ typeMetadata = _metadata; });
+ EXPECT_EQ(128u, (uint32_t)typeMetadata[0]);
+ EXPECT_EQ(0u, (uint32_t)typeMetadata[1]);
+ EXPECT_EQ(0u, (uint32_t)typeMetadata[2]);
+ EXPECT_NE(true, typeMetadata[3]);
+ EXPECT_NE(true, typeMetadata[4]);
+ EXPECT_EQ(element, (Element)typeMetadata[5]);
+}
+
+/*
+ * Create a Allocation, and verified allocationGetPointer and allocationResize1D
+ * return valid values.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped,
+ * allocationGetPointer, allocationResize1D
+ */
+TEST_F(RenderscriptHidlTest, ResizeTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x float1
+ Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ // 128 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ Ptr dataPtr1, dataPtr2;
+ Size stride;
+ context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+ [&](Ptr _dataPtr, Size _stride){
+ dataPtr1 = _dataPtr; stride = _stride; });
+ EXPECT_EQ(0ul, stride);
+
+ context->allocationResize1D(allocation, 1024*1024);
+ context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+ [&](Ptr _dataPtr, Size _stride){
+ dataPtr2 = _dataPtr; stride = _stride; });
+ EXPECT_EQ(0ul, stride);
+ EXPECT_NE(dataPtr1, dataPtr2);
+}
+
+/*
+ * Test creates two allocations, one with IO_INPUT and one with IO_OUTPUT. The
+ * NativeWindow (Surface) is retrieved from one allocation and set to the other.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * allocationGetNativeWindow, allocationSetNativeWindow, allocationIoSend,
+ * allocationIoReceive, allocation2DRead
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, NativeWindowIoTest) {
+ // uint8x4
+ Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
+ // 512 x 512 x uint8x4
+ Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<uint32_t> dataIn(512*512), dataOut(512*512);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (uint32_t)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint32_t));
+ // 512 x 512 x float1
+ Allocation allocationRecv = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)(AllocationUsageType::SCRIPT
+ | AllocationUsageType::IO_INPUT),
+ (Ptr)nullptr);
+ Allocation allocationSend = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)(AllocationUsageType::SCRIPT
+ | AllocationUsageType::IO_OUTPUT),
+ (Ptr)nullptr);
+ context->allocation2DWrite(allocationSend, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
+ _data, 0);
+ NativeWindow nativeWindow = context->allocationGetNativeWindow(allocationRecv);
+ EXPECT_NE(NativeWindow(0), nativeWindow);
+
+ context->allocationSetNativeWindow(allocationSend, nativeWindow);
+ context->allocationIoSend(allocationSend);
+ context->allocationIoReceive(allocationRecv);
+ context->allocation2DRead(allocationRecv, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
+ (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint32_t), 0);
+ bool same = std::all_of(dataOut.begin(), dataOut.end(),
+ [](uint32_t x){ static int val = 0; return x == (uint32_t)val++; });
+ EXPECT_EQ(true, same);
+}
+*/
+
+/*
+ * Three allocations are created, two with IO_INPUT and one with IO_OUTPUT. The
+ * two allocations with IO_INPUT are made to share the same BufferQueue.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped,
+ * allocationCreateFromBitmap, allocationSetupBufferQueue,
+ * allocationShareBufferQueue
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, BufferQueueTest) {
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 512 x 512 x float1
+ Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<float> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return (float)val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(float));
+ // 512 x 512 x float1
+ Allocation allocationRecv1 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)(AllocationUsageType::SCRIPT
+ | AllocationUsageType::IO_INPUT),
+ (Ptr)nullptr);
+ Allocation allocationRecv2 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)(AllocationUsageType::SCRIPT
+ | AllocationUsageType::IO_INPUT),
+ (Ptr)nullptr);
+ Allocation allocationSend = context->allocationCreateFromBitmap(type,
+ AllocationMipmapControl::NONE,
+ _data,
+ (int)(AllocationUsageType::SCRIPT
+ | AllocationUsageType::IO_OUTPUT));
+ context->allocationSetupBufferQueue(allocationRecv1, 2);
+ context->allocationShareBufferQueue(allocationRecv1, allocationRecv2);
+ // TODO: test the buffer queue
+}
+*/
+
+/*
+ * This test sets up the message queue, sends a message, peeks at the message,
+ * and reads it back.
+ *
+ * Calls: contextInitToClient, contextSendMessage, contextPeekMessage,
+ * contextGetMessage, contextDeinitToClient, contextLog
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ContextMessageTest) {
+ context->contextInitToClient();
+
+ std::string messageOut = "correct";
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)const_cast<char*>(messageOut.c_str()), messageOut.length());
+ context->contextSendMessage(0, _data);
+ MessageToClientType messageType;
+ size_t size;
+ uint32_t subID;
+ context->contextPeekMessage([&](MessageToClientType _type, Size _size, uint32_t _subID){
+ messageType = _type; size = (uint32_t)_size; subID = _subID; });
+ std::vector<char> messageIn(size, '\0');
+ context->contextGetMessage(messageIn.data(), messageIn.size(),
+ [&](MessageToClientType _type, Size _size){
+ messageType = _type; size = (uint32_t)_size; });
+ EXPECT_EQ(messageOut, messageIn.data());
+
+ context->contextDeinitToClient();
+ context->contextLog();
+}
+*/
+
+/*
+ * Call through a bunch of APIs and make sure they don’t crash. Assign the name
+ * of a object and check getName returns the name just set.
+ *
+ * Calls: contextSetPriority, contextSetCacheDir, elementCreate, assignName,
+ * contextFinish, getName, objDestroy, samplerCreate
+ */
+TEST_F(RenderscriptHidlTest, MiscellaneousTests) {
+ context->contextSetPriority(ThreadPriorities::NORMAL);
+ context->contextSetCacheDir("/data/local/tmp/temp/");
+
+ Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ std::string nameIn = "element_test_name";
+ std::string nameOut = "not_name";
+ hidl_string _nameIn;
+ _nameIn.setToExternal(nameIn.c_str(), nameIn.length());
+ context->assignName(element, _nameIn);
+ context->contextFinish();
+ context->getName(element, [&](const hidl_string& _name){ nameOut = _name.c_str(); });
+ EXPECT_EQ("element_test_name", nameOut);
+
+ context->objDestroy(element);
+
+ Sampler sampler = context->samplerCreate(SamplerValue::LINEAR, SamplerValue::LINEAR,
+ SamplerValue::LINEAR, SamplerValue::LINEAR,
+ SamplerValue::LINEAR, 8.0f);
+ EXPECT_NE(Sampler(0), sampler);
+}
diff --git a/renderscript/1.0/vts/functional/VtsScriptTests.cpp b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
new file mode 100644
index 0000000..9531e19
--- /dev/null
+++ b/renderscript/1.0/vts/functional/VtsScriptTests.cpp
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VtsHalRenderscriptV1_0TargetTest.h"
+
+/*
+ * Create a Blur intrinsic with scriptIntrinsicCreate, and call
+ * scriptSetTimeZone to make sure it is not crashing.
+ *
+ * Calls: elementCreate, scriptIntrinsicCreate, scriptSetTimeZone
+ */
+TEST_F(RenderscriptHidlTest, IntrinsicTest) {
+ // uint8
+ Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ Script script = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element);
+ EXPECT_NE(Script(0), script);
+
+ context->scriptSetTimeZone(script, "UTF-8");
+}
+
+/*
+ * Create a user script “struct_test”, and verified the setters and getters work
+ * for the global variables.
+ *
+ * Calls: scriptCCreate, scriptGetVarV, scriptSetVarI, scriptSetVarJ,
+ * scriptSetVarF, scriptSetVarD, elementCreate, typeCreate,
+ * allocationCreateTyped, scriptSetVarObj, scriptSetVarV, scriptSetVarVE
+ */
+TEST_F(RenderscriptHidlTest, ScriptVarTest) {
+ hidl_vec<uint8_t> bitcode;
+ bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+ Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+ EXPECT_NE(Script(0), script);
+
+ // arg tests
+ context->scriptSetVarI(script, 0, 100);
+ int resultI = 0;
+ context->scriptGetVarV(script, 0, sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+ resultI = *((int*)_data.data()); });
+ EXPECT_EQ(100, resultI);
+
+ context->scriptSetVarJ(script, 1, 101l);
+ int resultJ = 0;
+ context->scriptGetVarV(script, 1, sizeof(long), [&](const hidl_vec<uint8_t>& _data){
+ resultJ = *((long*)_data.data()); });
+ EXPECT_EQ(101, resultJ);
+
+ context->scriptSetVarF(script, 2, 102.0f);
+ int resultF = 0.0f;
+ context->scriptGetVarV(script, 2, sizeof(float), [&](const hidl_vec<uint8_t>& _data){
+ resultF = *((float*)_data.data()); });
+ EXPECT_EQ(102.0f, resultF);
+
+ context->scriptSetVarD(script, 3, 103.0);
+ int resultD = 0.0;
+ context->scriptGetVarV(script, 3, sizeof(double), [&](const hidl_vec<uint8_t>& _data){
+ resultD = *((double*)_data.data()); });
+ EXPECT_EQ(103.0, resultD);
+
+ // float1
+ Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
+ // 128 x float1
+ Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
+ // 128 x float1
+ Allocation allocationIn = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ Allocation allocationOut = Allocation(0);
+ context->scriptSetVarObj(script, 4, (ObjectBase)allocationIn);
+ context->scriptGetVarV(script, 4, sizeof(ObjectBase), [&](const hidl_vec<uint8_t>& _data){
+ allocationOut = (Allocation) *((ObjectBase*)_data.data()); });
+ EXPECT_EQ(allocationOut, allocationIn);
+
+ std::vector<int> arrayIn = {500, 501, 502, 503};
+ std::vector<int> arrayOut(4);
+ hidl_vec<uint8_t> arrayData;
+ arrayData.setToExternal((uint8_t*)arrayIn.data(), arrayIn.size()*sizeof(int));
+ context->scriptSetVarV(script, 5, arrayData);
+ context->scriptGetVarV(script, 5, 4*sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+ arrayOut = std::vector<int>((int*)_data.data(),
+ (int*)_data.data() + 4); });
+ EXPECT_EQ(500, arrayOut[0]);
+ EXPECT_EQ(501, arrayOut[1]);
+ EXPECT_EQ(502, arrayOut[2]);
+ EXPECT_EQ(503, arrayOut[3]);
+
+ std::vector<int> dataVE = {1000, 1001};
+ std::vector<uint32_t> dimsVE = {1};
+ std::vector<int> outVE(2);
+ hidl_vec<uint8_t> _dataVE;
+ hidl_vec<uint32_t> _dimsVE;
+ _dataVE.setToExternal((uint8_t*)dataVE.data(), dataVE.size()*sizeof(int));
+ _dimsVE.setToExternal((uint32_t*)dimsVE.data(), dimsVE.size());
+ // intx2
+ Element elementVE = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 2);
+ context->scriptSetVarVE(script, 6, _dataVE, elementVE, _dimsVE);
+ context->scriptGetVarV(script, 6, 2*sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+ outVE = std::vector<int>((int*)_data.data(),
+ (int*)_data.data() + 2); });
+ EXPECT_EQ(1000, outVE[0]);
+ EXPECT_EQ(1001, outVE[1]);
+}
+
+/*
+ * Create a user script “struct_test”, and input and output Allocations.
+ * Verified the foreach launch correctly for the invoke kernel.
+ *
+ * Calls: scriptCCreate, scriptInvoke, scriptGetVarV, scriptInvokeV
+ */
+TEST_F(RenderscriptHidlTest, ScriptInvokeTest) {
+ hidl_vec<uint8_t> bitcode;
+ bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+ Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+ EXPECT_NE(Script(0), script);
+
+ // invoke test
+ int function_res = 0;
+ context->scriptInvoke(script, 0);
+ context->scriptGetVarV(script, 0, sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+ function_res = *((int*)_data.data()); });
+ EXPECT_NE(100, function_res);
+
+ // invokeV test
+ int functionV_arg = 5;
+ int functionV_res = 0;
+ hidl_vec<uint8_t> functionV_data;
+ functionV_data.setToExternal((uint8_t*)&functionV_arg, sizeof(int));
+ context->scriptInvokeV(script, 1, functionV_data);
+ context->scriptGetVarV(script, 0, sizeof(int), [&](const hidl_vec<uint8_t>& _data){
+ functionV_res = *((int*)_data.data()); });
+ EXPECT_EQ(5, functionV_res);
+}
+
+/*
+ * Create a user script “struct_test”, and input and output Allocations.
+ * Verified the foreach launch correctly for the foreach kernel.
+ *
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocation1DWrite, scriptForEach, allocationRead
+ */
+TEST_F(RenderscriptHidlTest, ScriptForEachTest) {
+ hidl_vec<uint8_t> bitcode;
+ bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+ Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+ EXPECT_NE(Script(0), script);
+
+ // uint8_t
+ Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
+ // 64 x uint8_t
+ Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<uint8_t> dataIn(64), dataOut(64);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static uint8_t val = 0; return val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size());
+ // 64 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ Allocation vout = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
+ hidl_vec<Allocation> vains;
+ vains.setToExternal(&allocation, 1);
+ hidl_vec<uint8_t> params;
+ context->scriptForEach(script, 1, vains, vout, params, nullptr);
+ context->allocationRead(vout, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t));
+ bool same = std::all_of(dataOut.begin(), dataOut.end(),
+ [](uint8_t x){ static uint8_t val = 1; return x == val++; });
+ EXPECT_EQ(true, same);
+}
+
+/*
+ * Create a user script “struct_test”, and input and output Allocations.
+ * Verified the foreach launch correctly for the reduction kernel.
+ *
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocation1DWrite, scriptReduce, contextFinish, allocationRead
+ */
+TEST_F(RenderscriptHidlTest, ScriptReduceTest) {
+ hidl_vec<uint8_t> bitcode;
+ bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+ Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+ EXPECT_NE(Script(0), script);
+
+ // uint8_t
+ Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
+ // 64 x uint8_t
+ Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+ Type type2 = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
+ std::vector<int> dataIn(64), dataOut(1);
+ std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return val++; });
+ hidl_vec<uint8_t> _data;
+ _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(int));
+ // 64 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ Allocation vaout = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
+ hidl_vec<Allocation> vains;
+ vains.setToExternal(&allocation, 1);
+ context->scriptReduce(script, 0, vains, vaout, nullptr);
+ context->contextFinish();
+ context->allocationRead(vaout, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(int));
+ // sum of 0, 1, 2, ..., 62, 63
+ int sum = 63*64/2;
+ EXPECT_EQ(sum, dataOut[0]);
+}
+
+/*
+ * This test creates an allocation and binds it to a data segment in the
+ * RenderScript script, represented in the bitcode.
+ *
+ * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
+ * allocationGetPointer, scriptBindAllocation
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ScriptBindTest) {
+ hidl_vec<uint8_t> bitcode;
+ bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
+ Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
+ EXPECT_NE(Script(0), script);
+
+ // uint8_t
+ Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
+ // 64 x uint8_t
+ Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
+ // 64 x float1
+ Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ Ptr dataPtr1, dataPtr2;
+ Size stride;
+ context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+ [&](Ptr _dataPtr, Size _stride){ dataPtr1 = _dataPtr;
+ stride = _stride; });
+ context->scriptBindAllocation(script, allocation, 7);
+ context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
+ [&](Ptr _dataPtr, Size _stride){ dataPtr2 = _dataPtr;
+ stride = _stride; });
+ EXPECT_NE(dataPtr1, dataPtr2);
+}
+*/
+
+/*
+ * This test groups together two RenderScript intrinsic kernels to run one after
+ * the other asynchronously with respect to the client. The test configures YuvToRGB(A) and Blur,
+ * and links them together such that Blur will execute after YuvToRGB(A) and use its result. The
+ * test checks the data returned to make sure it was changed after passing through the entire
+ * ScriptGroup.
+ *
+ * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
+ * scriptIntrinsicCreate, scriptKernelIDCreate, scriptGroupCreate,
+ * scriptGroupSetInput, scriptGroupSetOutput, scriptGroupExecute,
+ * allocation2DRead
+ *
+ * This test currently has a bug, and should be fixed by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ScriptGroupTest) {
+ //std::vector<uint8_t> dataIn(256*256*1, 128), dataOut(256*256*3, 0);
+ std::vector<uint8_t> dataIn(256*256*1, 128), dataOut(256*256*4, 0);
+ hidl_vec<uint8_t> _dataIn, _dataOut;
+ _dataIn.setToExternal(dataIn.data(), dataIn.size());
+ _dataOut.setToExternal(dataOut.data(), dataIn.size());
+
+ // 256 x 256 YUV pixels
+ Element element1 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_YUV, true, 1);
+ //Type type1 = context->typeCreate(element1, 256, 256, 0, false, false, YuvFormat::YUV_420_888);
+ Type type1 = context->typeCreate(element1, 256, 256, 0, false, false, YuvFormat::YUV_NV21);
+ Allocation allocation1 = context->allocationCreateTyped(type1, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocation2DWrite(allocation1, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+ _dataIn, 0);
+ Script yuv2rgb = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_YUV_TO_RGB, element1);
+ EXPECT_NE(Script(0), yuv2rgb);
+
+ ScriptKernelID yuv2rgbKID = context->scriptKernelIDCreate(yuv2rgb, 0, 2);
+ EXPECT_NE(ScriptKernelID(0), yuv2rgbKID);
+
+ // 256 x 256 RGB pixels
+ //Element element2 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_RGB, true, 3);
+ Element element2 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_RGBA, true, 4);
+ Type type2 = context->typeCreate(element2, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
+ Allocation allocation2 = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
+ (int)AllocationUsageType::SCRIPT,
+ (Ptr)nullptr);
+ context->allocation2DWrite(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+ _dataOut, 0);
+ Script blur = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element2);
+ EXPECT_NE(Script(0), blur);
+
+ ScriptKernelID blurKID = context->scriptKernelIDCreate(blur, 0, 2);
+ EXPECT_NE(ScriptKernelID(0), blurKID);
+
+ // ScriptGroup
+ hidl_vec<ScriptKernelID> kernels = {yuv2rgbKID, blurKID};
+ hidl_vec<ScriptKernelID> srcK = {yuv2rgbKID};
+ hidl_vec<ScriptKernelID> dstK = {blurKID};
+ hidl_vec<ScriptFieldID> dstF = {};
+ hidl_vec<Type> types = {type2};
+ ScriptGroup scriptGroup = context->scriptGroupCreate(kernels, srcK, dstK, dstF, types);
+ EXPECT_NE(ScriptGroup(0), scriptGroup);
+
+ context->scriptGroupSetInput(scriptGroup, yuv2rgbKID, allocation1);
+ context->scriptGroupSetOutput(scriptGroup, blurKID, allocation2);
+ context->scriptGroupExecute(scriptGroup);
+
+ // verify contents were changed
+ context->allocation2DRead(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
+ (Ptr)dataOut.data(), (Size)dataOut.size(), 0);
+ bool same = std::all_of(dataOut.begin(), dataOut.end(), [](uint8_t x){ return x != 0; });
+ EXPECT_EQ(true, same);
+}
+*/
+
+/*
+ * Similar to the ScriptGroup test, this test verifies the execution flow of
+ * RenderScript kernels and invokables.
+ *
+ * Calls: scriptFieldIDCreate, closureCreate, scriptInvokeIDCreate,
+ * invokeClosureCreate, closureSetArg, closureSetGlobal, scriptGroup2Create,
+ * scriptGroupExecute
+ *
+ * This test currently still a work in progress, and should be finished by 3/17.
+ * TODO(butlermichael)
+ */
+/*
+TEST_F(RenderscriptHidlTest, ScriptGroup2Test) {
+
+ ScriptFieldID fieldID = context->scriptFieldIDCreate(script, slot);
+ EXPECT_NE(ScriptFieldID(0), fieldID);
+
+ ScriptKernelID kernelID = context->scriptKernelIDCreate(script, slot, sig);
+ EXPECT_NE(ScriptKernelID(0), kernelID);
+
+ Allocation returnValue = 0;
+ hidl_vec<ScriptFieldID> fieldIDS = {};
+ hidl_vec<int64_t> values = {};
+ hidl_vec<int32_t> sizes = {};
+ hidl_veC<Closure> depClosures = {};
+ hidl_vec<ScriptFieldID> depFieldIDS = {};
+ Closure closure1 = context->closureCreate(kernelID, returnValue, fieldIDS, values, sizes,
+ depClosures, depFieldIDS);
+ EXPECT_NE(Closure(0), closure1);
+
+ ScriptInvokeID invokeID = context->scriptInvokeIDCreate(script, slot);
+ EXPECT_NE(ScriptInvokeID(0), invokeID);
+
+ hidl_vec<uint8_t> params = {};
+ hidl_vec<ScriptFieldID> fieldsIDS2 = {};
+ hidl_vec<int64_t> values2 = {};
+ hidl_vec<int32_t> sizes2 = {};
+ Closure closure2 = context->invokeClosureCreate(invokeID, params, fieldIDS2, values2, sizes2);
+ EXPECT_NE(Closure(0), closure2);
+
+ context->closureSetArg(closure, index, value, size);
+ context->closureSetGlobal(closure, fieldID, value, size);
+
+ hidl_string name = "script_group_2_test";
+ hidl_string cacheDir = "data/local/tmp/";
+ hidl_vec<Closures> closures;
+ ScriptGroup2 scriptGroup2 = context->scriptGroup2Create(name, cacheDir, closures);
+ EXPECT_NE(ScriptGroup2(0), scriptGroup2);
+
+ context->scriptGroupExecute(scriptGroup2);
+ // verify script group launched...
+}
+*/
diff --git a/renderscript/1.0/vts/functional/bitcode.cpp b/renderscript/1.0/vts/functional/bitcode.cpp
new file mode 100644
index 0000000..72143c9
--- /dev/null
+++ b/renderscript/1.0/vts/functional/bitcode.cpp
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+#include "shared.rsh"
+
+// types
+typedef struct Point2 {
+ int x;
+ int y;
+} Point_2;
+
+// variables
+int var_int;
+long var_long;
+float var_float;
+double var_double;
+rs_allocation var_allocation;
+int var_array[4];
+Point_2 var_point2;
+Point_2 *var_point2_ptr;
+
+// invoke
+void function() {
+ var_int = 1;
+ var_long = 2;
+ var_float = 3.0f;
+ var_double = 4.0;
+
+ var_array[0] = 5;
+ var_array[1] = 6;
+ var_array[2] = 7;
+ var_array[3] = 8;
+
+ var_point2.x = 9;
+ var_point2.y = 10;
+}
+
+// invokeV
+void functionV(int arg) {
+ var_int = arg;
+}
+
+// forEach
+uchar RS_KERNEL increment(uchar in) {
+ return in+1;
+}
+
+// reduction
+#pragma rs reduce(summation) accumulator(sumAccumulator) combiner(sumCombiner)
+
+static void sumAccumulator(int* accum, int val) {
+ *accum += val;
+}
+
+static void sumCombiner(int* accum, const int *val) {
+ *accum += *val;
+}
+*/
+
+#include "VtsHalRenderscriptV1_0TargetTest.h"
+
+#ifndef __LP64__
+
+const int8_t bitCode[] = {
+ -34, -64, 23, 11, 0, 0, 0, 0, 44, 0, 0, 0, -84, 10, 0, 0,
+ 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 1, 64, 4, 0,
+ 96, 9, 0, 0, 2, 64, 4, 0, 3, 0, 0, 0, 66, 67, -64, -34,
+ 33, 12, 0, 0, -88, 2, 0, 0, 1, 16, 0, 0, 18, 0, 0, 0,
+ 7, -127, 35, -111, 65, -56, 4, 73, 6, 16, 50, 57, -110, 1, -124, 12,
+ 37, 5, 8, 25, 30, 4, -117, 98, -128, 24, 69, 2, 66, -110, 11, 66,
+ -60, 16, 50, 20, 56, 8, 24, 73, 10, 50, 68, 36, 72, 10, -112, 33,
+ 35, -60, 82, -128, 12, 25, 33, 114, 36, 7, -56, -120, 17, 98, -88, -96,
+ -88, 64, -58, -16, 1, 0, 0, 0, 73, 24, 0, 0, 25, 0, 0, 0,
+ 11, -124, -1, -1, -1, -1, 31, -64, 96, -127, 1, 4, 65, -16, -1, -1,
+ -1, -1, 3, 24, 45, 32, 2, 16, 4, 65, 16, 36, -2, -1, -1, -1,
+ 127, 0, -125, 5, 70, 0, -126, 32, 8, -126, -124, 0, -126, 32, 8, -126,
+ -60, -1, -1, -1, -1, 15, 96, -80, 64, -8, -1, -1, -1, -1, 1, 12,
+ 22, 8, -1, -1, -1, -1, 63, 0, 11, -120, 0, 4, 65, 16, 4, -119,
+ -1, -1, -1, -1, 31, -64, 80, 88, 64, 4, -64, -1, -1, -1, -1, 15,
+ 96, 0, 0, 0, -119, 32, 0, 0, 33, 0, 0, 0, 50, 34, -120, 9,
+ 32, 100, -123, 4, 19, 35, -92, -124, 4, 19, 35, -29, -124, -95, -112, 20,
+ 18, 76, -116, -116, 11, -124, -60, 76, 16, -112, -63, 28, 1, 24, 16, 48,
+ 71, 0, 10, 36, -52, 0, 16, 49, 4, 64, 70, 18, 0, -124, 92, 35,
+ 77, 17, 37, 76, 126, -22, 32, -51, 100, 35, 1, 0, 72, -71, 75, -102,
+ 34, 74, -104, -4, 72, -6, -127, 101, 113, 4, 96, 66, -100, -58, -65, 115,
+ 20, 4, -60, -48, 50, 71, -128, -48, 67, -48, 8, 64, 9, 36, -102, -118,
+ 32, 1, 84, 21, -31, 121, -24, 42, -125, 20, 0, -108, -107, 65, 10, 2,
+ -38, -118, 32, 53, -44, -103, 0, -96, -81, 8, 18, 72, -31, 64, 0, 0,
+ 19, -80, 112, -112, -121, 118, -80, -121, 59, 104, 3, 119, 120, 7, 119, 40,
+ -121, 54, 96, -121, 116, 112, -121, 122, -64, -121, 54, 56, 7, 119, -88, -121,
+ 114, 8, 7, 113, 72, -121, 13, 100, 80, 14, 109, 0, 15, 122, 48, 7,
+ 114, -96, 7, 115, 32, 7, 109, -112, 14, 118, 64, 7, 122, 96, 7, 116,
+ -48, 6, -10, 16, 7, 114, -128, 7, 122, 96, 7, 116, -96, 7, 113, 32,
+ 7, 120, -48, 6, -18, 48, 7, 114, -48, 6, -77, 96, 7, 116, -96, -13,
+ 64, -118, 4, 50, 66, 100, 4, -40, -95, 4, -64, -124, 12, 0, 0, 4,
+ -64, 14, 101, 0, 44, -124, 0, 0, 32, 0, 118, 40, 5, 112, 33, 3,
+ 0, 0, 1, -80, 67, 57, 0, 12, 33, 0, 0, 8, -128, 29, 74, 2,
+ 100, -56, 0, 0, 64, 0, -20, 80, 22, 64, 67, 6, 0, 0, 2, -128,
+ 13, -121, -37, -95, 56, -64, -122, 12, 0, 0, 4, -64, 14, 37, 2, 58,
+ 96, 0, 0, 32, 0, 118, 40, 17, -32, 1, 3, 0, 0, 1, 48, 68,
+ -95, 0, 0, 8, 0, 0, 0, -126, 33, -118, 5, 0, 64, 0, 0, 0,
+ 16, 12, 81, 48, 0, 0, 4, 0, 0, -128, 96, -120, -94, 1, -64, 48,
+ 0, 0, 0, 0, 67, 20, 14, 0, 6, 2, 0, 0, 0, 24, -94, 80,
+ 0, 0, 20, 0, 0, 0, -63, 16, -59, 3, 2, -64, 0, 0, 0, 8,
+ -122, 40, 98, 0, 0, -64, 1, 0, 0, 16, 100, -127, 0, 0, 0, 0,
+ 13, 0, 0, 0, 50, 30, -104, 20, 25, 17, 76, -112, -116, 9, 38, 71,
+ -58, 4, 67, 2, 70, 0, 74, -96, 16, 72, 24, 1, 32, 98, 4, -128,
+ -116, 17, 0, 66, 70, 0, 72, 25, 1, -96, 101, 4, -128, -104, 17, 0,
+ -126, 108, -75, 6, 91, -50, 1, 0, 121, 24, 0, 0, -30, 0, 0, 0,
+ 26, 3, 76, -112, 70, 2, 19, 52, 68, 0, 38, 42, 119, 99, 104, 97,
+ 114, 95, 115, 105, 122, 101, 67, 4, -128, 26, 98, 0, -45, 24, 4, 0,
+ -59, -90, 45, -51, -19, -85, -52, -83, -82, -19, 107, 46, 77, -81, 108, -120,
+ 1, 76, 99, 64, 0, 20, -7, 32, -56, -115, 76, -18, 45, -115, 12, 100,
+ -116, 45, -52, -19, 12, -60, -82, 76, 110, 46, -19, -51, 13, 100, -58, 5,
+ -57, 69, -26, -90, -122, 6, 7, 6, 4, 4, 69, 44, 108, -82, -116, 12,
+ -28, -51, 13, -124, -119, -55, -86, 9, 100, -58, 5, -57, 69, -26, -90, -122,
+ 6, 7, 38, 101, -120, 48, 6, 6, 15, -69, 50, -71, -71, -76, 55, 55,
+ 6, 49, 67, -120, 49, 64, -58, 32, 97, -92, 22, 102, 23, -10, 5, 23,
+ 54, -74, 22, 118, 86, -10, -27, 22, -42, 86, -58, 105, -20, -83, -51, 37,
+ -52, -115, 76, -18, 45, -115, -52, 69, 110, -50, -123, -82, 108, -114, 110, 8,
+ 49, 6, -53, 24, 48, 60, -20, -62, -28, -66, -46, -36, -24, 24, -44, 12,
+ 33, -58, -64, 25, -125, -121, -120, 93, -104, -36, 23, -37, -101, -37, 25, 3,
+ -101, 33, -60, 24, 68, 99, 32, 49, -79, 11, -109, -5, 50, 99, 123, 11,
+ -93, 27, 66, -116, 1, 53, 6, 9, 21, -69, 48, -71, 47, -78, -73, 58,
+ 49, -74, 50, 6, 50, 67, -120, 49, -80, -58, -32, -94, 99, 23, 38, -9,
+ 21, -58, -58, -10, 54, 22, 70, -105, -10, -26, 70, 65, 6, 102, 8, 49,
+ 6, -39, 24, 104, 76, -20, -62, -28, -66, -62, -28, -28, -62, -14, -8, -16,
+ 12, -67, -71, -51, -47, -123, -71, -47, 5, -55, -55, -123, -27, -7, 12, 33,
+ -58, -128, 27, -125, -114, -118, 93, -104, -36, 23, -36, 91, -102, 27, -99, 12,
+ 13, -88, -73, 52, 55, 58, -103, 33, -60, 24, 124, 99, 0, 6, 116, -20,
+ -62, -28, -66, -32, -34, -46, -36, -24, 100, -66, -32, -24, -28, 120, -88, 64,
+ -67, -91, -71, -47, -55, 12, 33, -58, 64, 12, -58, 96, 12, 24, -48, 12,
+ 17, -58, -96, 12, -120, -104, -43, -71, -115, -47, -91, -67, -71, 13, 17, -58,
+ -32, 12, 24, -71, -96, -107, -79, -63, -107, -55, 125, -103, -43, -71, -115, -47,
+ -91, -67, -71, 89, 13, 17, -58, 32, 13, 72, -56, -67, -67, -47, 13, 17,
+ -58, 96, 13, -104, -92, -71, -115, -55, -107, -75, -107, -71, -47, 13, 17, -58,
+ -96, 13, 24, -64, 12, 17, -58, -32, 13, 40, -52, -44, 12, 17, -58, 32,
+ 14, -104, -52, -43, -75, -75, -123, -47, -91, -67, -71, -47, -103, -85, 107, 11,
+ 26, 27, -85, 107, -85, 99, 11, -93, 123, -109, 27, 66, -116, 1, 29, -116,
+ 65, -62, 101, -82, -82, 109, -24, -83, 77, 44, -51, -83, 76, 110, -120, 50,
+ 6, 115, 48, 6, 101, 48, 6, 117, 32, 1, 99, 96, 7, 67, -124, 49,
+ 0, 3, 6, 120, 28, -46, -36, -24, -122, 16, 99, -112, 7, 99, -96, 7,
+ 12, -14, -122, 16, 99, -64, 7, 99, -96, 7, 124, -34, -38, -36, -46, -32,
+ -34, -24, -54, -36, -24, 64, -58, -48, -62, -28, 24, 77, -91, -75, -63, -79,
+ -107, -127, 12, -67, 12, -83, -84, -128, 80, 9, 5, 5, 13, 17, -58, -32,
+ 15, -122, 8, 66, 53, -60, 24, 3, 63, 24, 3, 80, 16, -86, 33, -58,
+ 24, -24, -63, 24, -120, -126, 80, 13, 49, -58, 96, 20, -58, 96, 20, -124,
+ -118, 4, -37, -101, -37, -39, 16, 99, 12, 74, 97, 12, 68, 65, -88, -122,
+ 24, 99, 96, 10, 99, 96, 10, 66, -59, -62, -116, -19, 45, -116, 110, -120,
+ 49, 6, -88, 48, 6, -94, 32, 84, 67, -116, 49, 72, -123, 49, 72, 5,
+ -95, -94, 65, -10, 86, 39, -58, 86, 54, -60, 24, -125, 85, 24, 3, 81,
+ 16, -86, 33, -58, 24, -80, -62, 24, -80, -126, 80, 53, 98, 99, -77, 107,
+ 115, 105, 123, 35, -85, 99, 43, 115, 49, 99, 11, 59, -101, -101, 34, 12,
+ 69, 21, 54, 54, -69, 54, -105, 52, -78, 50, 55, -70, 41, -63, -47, 99,
+ 4, 78, 46, -20, -84, 45, 108, -118, -96, 52, 117, 70, -28, -26, -66, -54,
+ -16, -32, -34, -28, -24, -66, -20, -62, -28, -90, 32, -48, 84, 97, -101, 23,
+ 6, 100, 80, 104, 68, 110, -18, -21, 77, 76, -83, 108, -116, -18, 107, -114,
+ -19, -115, 110, 110, 74, 96, 6, 125, 70, -28, -26, -66, -54, -16, -32, -34,
+ -28, -24, -66, -52, -22, -36, -58, -90, 8, 104, -96, 6, -67, 70, -28, -26,
+ -66, -54, -16, -32, -34, -28, -24, -66, -52, -34, -28, -54, -62, -58, -48, -66,
+ -36, -62, -38, -54, -90, 8, 108, -32, 6, -107, 70, -28, -26, -66, -54, -16,
+ -32, -34, -28, -24, -66, -52, -34, -28, -54, -62, -58, -48, -90, 8, 112, 32,
+ 7, -115, 70, -28, -26, -66, -54, -16, -32, -34, -28, -24, -66, -28, -54, -56,
+ -22, -58, -54, -90, 4, 119, -48, 103, 68, 110, -18, -85, 12, 15, -18, 77,
+ -114, -18, -117, 46, 15, -82, 108, 74, -128, 7, 61, 74, -96, -34, -46, -36,
+ -24, 100, -90, 8, 123, -48, 7, 0, 121, 24, 0, 0, 92, 0, 0, 0,
+ 51, 8, -128, 28, -60, -31, 28, 102, 20, 1, 61, -120, 67, 56, -124, -61,
+ -116, 66, -128, 7, 121, 120, 7, 115, -104, 113, 12, -26, 0, 15, -19, 16,
+ 14, -12, -128, 14, 51, 12, 66, 30, -62, -63, 29, -50, -95, 28, 102, 48,
+ 5, 61, -120, 67, 56, -124, -125, 27, -52, 3, 61, -56, 67, 61, -116, 3,
+ 61, -52, 120, -116, 116, 112, 7, 123, 8, 7, 121, 72, -121, 112, 112, 7,
+ 122, 112, 3, 118, 120, -121, 112, 32, -121, 25, -52, 17, 14, -20, -112, 14,
+ -31, 48, 15, 110, 48, 15, -29, -16, 14, -16, 80, 14, 51, 16, -60, 29,
+ -34, 33, 28, -40, 33, 29, -62, 97, 30, 102, 48, -119, 59, -68, -125, 59,
+ -48, 67, 57, -76, 3, 60, -68, -125, 60, -124, 3, 59, -52, -16, 20, 118,
+ 96, 7, 123, 104, 7, 55, 104, -121, 114, 104, 7, 55, -128, -121, 112, -112,
+ -121, 112, 96, 7, 118, 40, 7, 118, -8, 5, 118, 120, -121, 119, -128, -121,
+ 95, 8, -121, 113, 24, -121, 114, -104, -121, 121, -104, -127, 44, -18, -16, 14,
+ -18, -32, 14, -11, -64, 14, -20, 48, 3, 98, -56, -95, 28, -28, -95, 28,
+ -52, -95, 28, -28, -95, 28, -36, 97, 28, -54, 33, 28, -60, -127, 29, -54,
+ 97, 6, -42, -112, 67, 57, -56, 67, 57, -104, 67, 57, -56, 67, 57, -72,
+ -61, 56, -108, 67, 56, -120, 3, 59, -108, -61, 47, -68, -125, 60, -4, -126,
+ 59, -44, 3, 59, -80, -61, 12, -57, 105, -121, 112, 88, -121, 114, 112, -125,
+ 116, 104, 7, 120, 96, -121, 116, 24, -121, 116, -96, -121, 25, -50, 83, 15,
+ -18, 0, 15, -14, 80, 14, -28, -112, 14, -29, 64, 15, -31, 32, 14, -20,
+ 80, 14, 51, 32, 40, 29, -36, -63, 30, -62, 65, 30, -46, 33, 28, -36,
+ -127, 30, -36, -32, 28, -28, -31, 29, -22, 1, 30, 102, 24, 81, 56, -80,
+ 67, 58, -100, -125, 59, -52, 80, 36, 118, 96, 7, 123, 104, 7, 55, 96,
+ -121, 119, 120, 7, 120, -104, 81, 76, -12, -112, 15, -16, 80, 14, 0, 0,
+ 113, 32, 0, 0, 56, 0, 0, 0, 6, 17, 6, -1, 92, -33, -111, -60,
+ 45, 4, 16, -95, 65, 66, 8, 83, 90, -33, -111, -12, 3, -53, -30, 8,
+ -64, -124, 56, -115, 13, 40, 21, 16, -3, -125, 67, 5, 11, 97, 5, 74,
+ 5, 68, -1, -29, 32, -51, 100, 27, 67, -126, 52, 66, 68, 48, 68, 51,
+ -103, 2, 82, 80, -115, 48, 33, 78, 99, 4, 73, 5, 68, 63, 16, 69,
+ 0, 102, 17, -111, 127, 16, -53, 67, 68, 127, 65, 53, -62, -124, 56, -51,
+ 107, 14, -117, 68, 49, -100, -61, 4, 72, 67, 68, 102, -32, 84, 64, -12,
+ 3, -53, -30, 8, -64, -124, 56, -115, 33, 112, 126, 36, -7, 17, 49, 80,
+ 2, -15, 23, -115, 47, 81, -116, 38, 8, 20, 67, 45, -64, -28, 68, 6,
+ 112, 84, 64, -12, 35, -51, 100, 13, -114, 68, 49, -102, 32, 80, 12, -75,
+ 0, -109, 19, 89, 0, 82, 1, -47, -65, 56, -115, 97, 7, 78, 5, 68,
+ -1, -29, 32, -51, 100, -1, -49, 20, -39, 3, -30, 71, -110, 63, 76, 78,
+ 100, 11, 73, 65, 53, -62, -124, 56, -51, 107, 2, 73, 5, 68, 127, -79,
+ 56, -64, 100, 9, -103, 31, 73, 126, 68, 12, -108, 64, -4, 69, -29, 75,
+ 20, -61, 57, 76, -128, 52, 68, 4, 97, 32, 0, 0, 54, 0, 0, 0,
+ 19, 4, 65, 44, 16, 0, 0, 0, 20, 0, 0, 0, 4, -108, 66, 49,
+ -108, 67, 17, 20, 68, 25, -108, 68, 81, -112, 80, 4, 20, 12, 101, 36,
+ 4, 32, 1, -45, 80, 70, 66, 0, 18, 16, 6, 67, 25, 9, 1, 72,
+ -64, 24, 12, 101, 44, 5, 32, 1, -46, 80, -58, 82, 0, 18, 48, 13,
+ 101, 36, 4, 32, 1, 18, 17, 99, 4, 32, 8, -126, 36, 24, -112, 49,
+ 70, 0, -126, 32, 8, -126, 32, 8, -126, 36, 72, 0, -125, 17, -64, 52,
+ 0, -125, 17, -127, 25, 16, -64, 96, -124, -48, 6, 3, 48, 24, 49, -72,
+ 1, 1, 12, 70, -80, -127, 55, 0, -125, 17, 103, -16, 13, -64, 96, 4,
+ 26, -128, -63, 0, 12, 70, -92, -127, 24, 12, -64, 96, -124, 26, -112, -63,
+ 0, 12, 70, -84, 65, 25, 12, 0, 6, -60, 0, 0, 13, 0, 0, 0,
+ 91, 6, 32, 32, -123, 45, 67, 16, -100, -62, -106, 65, 8, 84, 97, -53,
+ 48, 4, -83, -80, 101, 32, 2, 82, -40, 50, 20, 1, 41, 108, 25, -116,
+ -128, 20, -74, 12, 71, 64, 10, 91, 6, 36, 32, -123, 45, 67, 18, -112,
+ 2, 0, 0, 0, 0, 0, 0, 0, 97, 32, 0, 0, 11, 0, 0, 0,
+ 19, 4, -63, 96, 4, -32, 13, 0, -122, 3, 1, 0, 2, 0, 0, 0,
+ -26, 49, 0, -111, 1, 0, 0, 0, 1, 49, 0, 0, 2, 0, 0, 0,
+ 91, 6, 32, 32, 5, 0, 0, 0, 0, 0, 0, 0, 97, 32, 0, 0,
+ 11, 0, 0, 0, 19, 4, -63, 121, 64, -40, 55, -63, -32, -64, -32, -127,
+ 12, -125, 112, 32, 5, 0, 0, 0, -10, 65, 8, 78, 83, -103, -121, -128,
+ 52, 22, 82, 8, 78, 83, -43, 6, 50, 0, -61, 0, 0, 0, 0, 0,
+ 97, 32, 0, 0, 16, 0, 0, 0, 19, 4, 1, 121, -61, -64, -32, 3,
+ -63, 96, -124, 23, 6, 3, -128, -31, 64, 0, 0, 0, 4, 0, 0, 0,
+ -10, 49, 84, -64, 98, 30, 5, 32, 8, 20, 99, 33, 3, 48, 12, 0,
+ 1, 49, 0, 0, 3, 0, 0, 0, 91, 6, 32, 32, -123, 45, -125, 16,
+ -112, 2, 0, 0, 0, 0, 0, 0, 97, 32, 0, 0, 17, 0, 0, 0,
+ 19, 4, 1, 125, -125, -68, 97, 97, 0, 6, 32, 24, -116, -16, -60, 96,
+ 0, 48, 28, 8, 4, 0, 0, 0, -10, 49, 84, -64, 98, 30, 5, 32,
+ 8, 20, 99, 34, 3, 48, 12, 0, 1, 49, 0, 0, 4, 0, 0, 0,
+ 91, 6, 32, 32, -123, 45, 67, 16, -112, -62, -106, 97, 8, 72, 1, 0,
+ 0, 0, 0, 0, 97, 32, 0, 0, 3, 0, 0, 0, 19, 4, -63, -120,
+ 1, -127, 4, -112, -127, 0, 0, 0, 97, 32, 0, 0, 9, 0, 0, 0,
+ 19, 4, -63, 120, -125, 39, 73, -12, -115, 17, 3, 2, 8, 22, 48, -64,
+ 112, 32, 0, 0, 2, 0, 0, 0, 7, 80, 16, -51, 20, 97, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+const int bitCodeLength = 2776;
+
+#else
+
+const int8_t bitCode[] = {
+ -34, -64, 23, 11, 0, 0, 0, 0, 44, 0, 0, 0, -116, 10, 0, 0,
+ 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 1, 64, 4, 0,
+ 96, 9, 0, 0, 2, 64, 4, 0, 3, 0, 0, 0, 66, 67, -64, -34,
+ 33, 12, 0, 0, -96, 2, 0, 0, 1, 16, 0, 0, 18, 0, 0, 0,
+ 7, -127, 35, -111, 65, -56, 4, 73, 6, 16, 50, 57, -110, 1, -124, 12,
+ 37, 5, 8, 25, 30, 4, -117, 98, -128, 24, 69, 2, 66, -110, 11, 66,
+ -60, 16, 50, 20, 56, 8, 24, 73, 10, 50, 68, 36, 72, 10, -112, 33,
+ 35, -60, 82, -128, 12, 25, 33, 114, 36, 7, -56, -120, 17, 98, -88, -96,
+ -88, 64, -58, -16, 1, 0, 0, 0, 73, 24, 0, 0, 24, 0, 0, 0,
+ 11, -124, -1, -1, -1, -1, 31, -64, 96, -127, -16, -1, -1, -1, -1, 3,
+ 24, 45, 32, 2, 16, 4, 65, 16, 36, -2, -1, -1, -1, 127, 0, -125,
+ 5, 70, 0, -126, 32, 8, -126, -124, 0, -126, 32, 8, -126, -60, -1, -1,
+ -1, -1, 15, 96, -80, 64, -8, -1, -1, -1, -1, 1, 12, 22, 8, -1,
+ -1, -1, -1, 63, 0, 11, -120, 0, 4, 65, 16, 4, -119, -1, -1, -1,
+ -1, 31, -64, 80, 88, 64, 4, -64, -1, -1, -1, -1, 15, 96, 0, 0,
+ -119, 32, 0, 0, 34, 0, 0, 0, 50, 34, -120, 9, 32, 100, -123, 4,
+ 19, 35, -92, -124, 4, 19, 35, -29, -124, -95, -112, 20, 18, 76, -116, -116,
+ 11, -124, -60, 76, 16, -112, -63, 28, 1, 24, 16, 48, 71, 0, 10, 36,
+ -52, 0, 16, 49, 4, 64, 70, 18, 0, -124, 28, 36, 77, 17, 37, 76,
+ 126, -22, 32, -51, 100, -5, 61, -114, 4, 0, 32, -27, 46, 105, -118, 40,
+ 97, -14, 35, -23, 7, -106, -59, 17, -128, 9, 113, 26, -65, -49, 17, 49,
+ 12, -61, 64, 12, 45, 115, 4, 8, 61, 4, -115, 0, -108, 64, -94, -87,
+ 8, 18, 64, 85, 17, -98, -121, -82, 50, 72, 1, 64, 89, 25, -92, 32,
+ -96, -83, 8, 82, 67, -99, 9, 0, -6, -118, 32, -127, 20, 14, 4, 0,
+ 19, -76, 112, 8, 7, 121, 24, 7, 116, -80, 3, 58, 104, 3, 119, 120,
+ 7, 119, 40, -121, 54, 96, -121, 116, 112, -121, 122, -64, -121, 54, 56, 7,
+ 119, -88, -121, 114, 8, 7, 113, 72, -121, 13, 115, 80, 14, 109, -48, 14,
+ 122, 80, 14, 109, -112, 14, 120, -96, 7, 120, -96, 7, 115, 32, 7, 109,
+ -112, 14, 113, 96, 7, 122, 16, 7, 118, -96, 7, 115, 32, 7, 109, -112,
+ 14, 118, 64, 7, 122, 96, 7, 116, -48, 6, -23, 16, 7, 114, -128, 7,
+ 122, 16, 7, 114, -128, 7, 109, -32, 14, 115, 32, 7, 122, 96, 7, 116,
+ -48, 6, -77, 16, 7, 114, -128, 7, 58, 15, -92, 72, 32, 35, 68, 70,
+ -128, 29, 74, 0, 76, -56, 0, 0, 64, 0, -20, 80, 6, -128, 66, 8,
+ 0, 0, 2, 96, -121, 82, 0, 21, 50, 0, 0, 16, 0, 59, -108, 3,
+ -80, 16, 2, 0, -128, 0, -40, -95, 36, -64, -123, 12, 0, 0, 4, -64,
+ 14, 101, 1, 48, 100, 0, 0, 32, 0, -40, 104, -56, 29, -118, 3, 100,
+ 8, 1, 0, 64, 0, -20, 80, 34, 96, 3, 8, 0, 0, 2, 96, -121,
+ 18, 1, 28, 64, 0, 0, 16, 0, 67, 20, 10, 0, -128, 0, 0, 0,
+ 32, 24, -94, 88, 0, 0, 4, 0, 0, 0, -63, 16, 5, 3, 0, 64,
+ 0, 0, 0, 8, -122, 40, 26, 0, 12, 3, 0, 0, 0, 48, 68, -31,
+ 0, 96, 32, 0, 0, 0, -128, 33, 10, 5, 0, 64, 1, 0, 0, 16,
+ 12, 81, 60, 32, 0, 12, 0, 0, -128, 96, -120, 34, 6, 0, 0, 28,
+ 0, 0, 0, 65, 22, 8, 0, 0, 13, 0, 0, 0, 50, 30, -104, 20,
+ 25, 17, 76, -112, -116, 9, 38, 71, -58, 4, 67, 2, 70, 0, 72, 24,
+ 1, 32, 98, 4, -128, -116, 17, 0, 66, 70, 0, 72, 25, 1, -96, 101,
+ 4, -128, -104, 17, 0, -126, 108, -75, 6, 91, -50, 1, 0, 0, 0, 0,
+ 121, 24, 0, 0, -48, 0, 0, 0, 26, 3, 76, -112, 70, 2, 19, 68,
+ 62, 8, 114, 35, -109, 123, 75, 35, 3, 25, 99, 11, 115, 59, 3, -79,
+ 43, -109, -101, 75, 123, 115, 3, -103, 113, -63, 113, -111, -71, -87, -95, -63,
+ -127, 1, 1, 65, 17, 11, -101, 43, 35, 3, 121, 115, 3, 97, 98, -78,
+ 106, 2, -103, 113, -63, 113, -111, -71, -87, -95, -63, -127, 73, 25, 34, -116,
+ 1, -64, -61, -82, 76, 110, 46, -19, -51, -115, 65, -52, 16, 98, 12, -124,
+ 49, 24, 24, -87, -123, -39, -123, 125, -63, -123, -115, -83, -123, -99, -107, 125,
+ -71, -123, -75, -107, 113, 26, 123, 107, 115, 9, 115, 35, -109, 123, 75, 35,
+ 115, -111, -101, 115, -95, 43, -101, -93, 27, 66, -116, 65, 49, 6, 6, 15,
+ -69, 48, -71, -81, 52, 55, 58, 6, 53, 67, -120, 49, 64, -58, 32, 33,
+ 98, 23, 38, -9, -59, -10, -26, 118, -58, -64, 102, 8, 49, 6, -53, 24,
+ 48, 76, -20, -62, -28, -66, -52, -40, -34, -62, -24, -122, 16, 99, -32, -116,
+ -63, 64, -59, 46, 76, -18, -117, -20, -83, 78, -116, -83, -116, -127, -52, 16,
+ 98, 12, -96, 49, -120, -24, -40, -123, -55, 125, -123, -79, -79, -67, -115, -123,
+ -47, -91, -67, -71, 81, -112, -127, 25, 66, -116, -63, 52, 6, 20, 19, -69,
+ 48, -71, -81, 48, 57, -71, -80, 60, 62, 60, 67, 111, 110, 115, 116, 97,
+ 110, 116, 65, 114, 114, 97, 121, 62, 67, -120, 49, -80, -58, -32, -94, 98,
+ 23, 38, -9, 5, -9, -106, -26, 70, 39, 67, 3, -22, 45, -51, -115, 78,
+ 102, 8, 49, 6, -39, 24, 104, 116, -20, -62, -28, -66, -32, -34, -46, -36,
+ -24, 100, -66, -32, -24, -28, 120, -88, 64, -67, -91, -71, -47, -55, 12, 33,
+ -58, -128, 27, -125, -114, 1, -51, 16, 97, 12, 62, 34, 102, 117, 110, 99,
+ 116, 105, 111, 110, 67, -124, 49, 8, 3, 70, 46, 104, 101, 108, 112, 101,
+ 114, 95, 102, 117, 110, 99, 116, 105, 111, 110, 86, 67, -124, 49, 24, 3,
+ 18, 114, 111, 111, 116, 67, -124, 49, 40, 3, 38, 105, 110, 99, 114, 101,
+ 109, 101, 110, 116, 67, -124, 49, 56, 3, 6, 48, 67, -124, 49, 72, 3,
+ 10, 51, 53, 67, -124, 49, 88, 3, 38, 115, 117, 109, 109, 97, 116, 105,
+ 111, 110, 116, -26, -22, -38, -126, -58, -58, -22, -38, -22, -40, -62, -24, -34,
+ -28, -122, 16, 99, -32, 6, 99, 48, 112, -103, -85, 107, 27, 122, 107, 19,
+ 75, 115, 43, -109, 27, -94, -116, 65, 27, -116, -63, 55, 6, 111, 32, 1,
+ 99, 0, 7, 67, -124, 49, -48, 24, -32, 113, 72, 115, -93, 27, 66, -116,
+ -63, 28, -116, 1, 29, 48, -56, 27, 66, -116, -127, 29, -116, 1, 29, -16,
+ 121, 107, 115, 75, -125, 123, -93, 43, 115, -93, 3, 25, 67, 11, -109, 99,
+ 52, -107, -42, 6, -57, 86, 6, 50, -12, 50, -76, -78, 2, 66, 37, 20,
+ 20, 52, 68, 24, -125, 60, 24, 34, 8, -45, 16, 99, 12, -16, 96, 12,
+ -12, 64, -104, -122, 24, 99, 64, 7, 99, -64, 7, -62, 52, -60, 24, -125,
+ 62, 24, -125, 62, 16, 38, 18, 108, 111, 110, 103, 67, -116, 49, -8, -125,
+ 49, -32, 3, 97, 26, 98, -116, 1, 40, -116, 1, 40, 8, 19, 11, 51,
+ -74, -73, 48, -70, 33, -58, 24, -120, -62, 24, -16, -127, 48, 13, 49, -58,
+ 96, 20, -58, 96, 20, -124, -119, 6, -39, 91, -99, 24, 91, -39, 16, 99,
+ 12, 74, 97, 12, -8, 64, -104, -122, 24, 99, 96, 10, 99, 96, 10, -62,
+ 84, -123, -115, -51, -82, -51, 37, -115, -84, -52, -115, 110, 74, 16, -12, 24,
+ -127, -109, 11, 59, 107, 11, -101, 34, 16, 71, -99, 17, -71, -71, -81, 50,
+ 60, -72, 55, 57, -70, 47, -69, 48, -71, 41, -120, -46, 60, 82, -123, 109,
+ 94, -95, 17, -71, -71, -81, 55, 49, -75, -78, 49, -70, -81, 57, -74, 55,
+ -70, -71, 41, 1, 24, -12, 25, -111, -101, -5, 42, -61, -125, 123, -109, -93,
+ -5, 50, -85, 115, 27, -101, 34, -120, 1, 25, -12, 26, -111, -101, -5, 42,
+ -61, -125, 123, -109, -93, -5, 50, 123, -109, 43, 11, 27, 67, -5, 114, 11,
+ 107, 43, -101, 34, -104, 1, 26, 84, 26, -111, -101, -5, 42, -61, -125, 123,
+ -109, -93, -5, 50, 123, -109, 43, 11, 27, 67, -101, 34, -88, 1, 27, 52,
+ 26, -111, -101, -5, 42, -61, -125, 123, -109, -93, -5, -110, 43, 35, -85, 27,
+ 43, -101, 18, -60, 65, -97, 17, -71, -71, -81, 50, 60, -72, 55, 57, -70,
+ 47, -70, 60, -72, -78, 41, -127, 28, -12, 40, -127, 122, 75, 115, -93, -109,
+ -103, 34, -44, -63, 29, 0, 0, 0, 121, 24, 0, 0, 92, 0, 0, 0,
+ 51, 8, -128, 28, -60, -31, 28, 102, 20, 1, 61, -120, 67, 56, -124, -61,
+ -116, 66, -128, 7, 121, 120, 7, 115, -104, 113, 12, -26, 0, 15, -19, 16,
+ 14, -12, -128, 14, 51, 12, 66, 30, -62, -63, 29, -50, -95, 28, 102, 48,
+ 5, 61, -120, 67, 56, -124, -125, 27, -52, 3, 61, -56, 67, 61, -116, 3,
+ 61, -52, 120, -116, 116, 112, 7, 123, 8, 7, 121, 72, -121, 112, 112, 7,
+ 122, 112, 3, 118, 120, -121, 112, 32, -121, 25, -52, 17, 14, -20, -112, 14,
+ -31, 48, 15, 110, 48, 15, -29, -16, 14, -16, 80, 14, 51, 16, -60, 29,
+ -34, 33, 28, -40, 33, 29, -62, 97, 30, 102, 48, -119, 59, -68, -125, 59,
+ -48, 67, 57, -76, 3, 60, -68, -125, 60, -124, 3, 59, -52, -16, 20, 118,
+ 96, 7, 123, 104, 7, 55, 104, -121, 114, 104, 7, 55, -128, -121, 112, -112,
+ -121, 112, 96, 7, 118, 40, 7, 118, -8, 5, 118, 120, -121, 119, -128, -121,
+ 95, 8, -121, 113, 24, -121, 114, -104, -121, 121, -104, -127, 44, -18, -16, 14,
+ -18, -32, 14, -11, -64, 14, -20, 48, 3, 98, -56, -95, 28, -28, -95, 28,
+ -52, -95, 28, -28, -95, 28, -36, 97, 28, -54, 33, 28, -60, -127, 29, -54,
+ 97, 6, -42, -112, 67, 57, -56, 67, 57, -104, 67, 57, -56, 67, 57, -72,
+ -61, 56, -108, 67, 56, -120, 3, 59, -108, -61, 47, -68, -125, 60, -4, -126,
+ 59, -44, 3, 59, -80, -61, 12, -57, 105, -121, 112, 88, -121, 114, 112, -125,
+ 116, 104, 7, 120, 96, -121, 116, 24, -121, 116, -96, -121, 25, -50, 83, 15,
+ -18, 0, 15, -14, 80, 14, -28, -112, 14, -29, 64, 15, -31, 32, 14, -20,
+ 80, 14, 51, 32, 40, 29, -36, -63, 30, -62, 65, 30, -46, 33, 28, -36,
+ -127, 30, -36, -32, 28, -28, -31, 29, -22, 1, 30, 102, 24, 81, 56, -80,
+ 67, 58, -100, -125, 59, -52, 80, 36, 118, 96, 7, 123, 104, 7, 55, 96,
+ -121, 119, 120, 7, 120, -104, 81, 76, -12, -112, 15, -16, 80, 14, 0, 0,
+ 113, 32, 0, 0, 56, 0, 0, 0, 6, 17, 6, -1, 92, -33, -111, -60,
+ 45, 4, 16, -95, 65, 66, 8, 83, 90, -33, -111, -12, 3, -53, -30, 8,
+ -64, -124, 56, -115, 13, 40, 21, 16, -3, -125, 67, 5, 11, 97, 5, 74,
+ 5, 68, -1, -29, 32, -51, 100, 27, 67, -126, 52, 66, 68, 48, 68, 51,
+ -103, 2, 82, 80, -115, 48, 33, 78, 99, 4, 73, 5, 68, 63, 16, 69,
+ 0, 102, 17, -111, 127, 16, -53, 67, 68, 127, 65, 53, -62, -124, 56, -51,
+ 107, 14, -117, 68, 49, -100, -61, 4, 72, 67, 68, 102, -32, 84, 64, -12,
+ 3, -53, -30, 8, -64, -124, 56, -115, 33, 112, 126, 36, -7, 17, 49, 80,
+ 2, -15, 23, -115, 47, 81, -116, 38, 8, 20, 67, 45, -64, -28, 68, 6,
+ 112, 84, 64, -12, 35, -51, 100, 13, -114, 68, 49, -102, 32, 80, 12, -75,
+ 0, -109, 19, 89, 0, 82, 1, -47, -65, 56, -115, 97, 7, 78, 5, 68,
+ -1, -29, 32, -51, 100, -1, -49, 20, -39, 3, -30, 71, -110, 63, 76, 78,
+ 100, 11, 73, 65, 53, -62, -124, 56, -51, 107, 2, 73, 5, 68, 127, -79,
+ 56, -64, 100, 9, -103, 31, 73, 126, 68, 12, -108, 64, -4, 69, -29, 75,
+ 20, -61, 57, 76, -128, 52, 68, 4, 97, 32, 0, 0, 55, 0, 0, 0,
+ 19, 4, 65, 44, 16, 0, 0, 0, 21, 0, 0, 0, 4, -108, 64, 41,
+ 20, 67, 57, 20, 68, 73, 20, 5, 9, 101, 80, 2, 69, 64, -63, 80,
+ 70, 66, 8, -109, 48, 6, 67, 25, 75, 33, 76, -128, 52, -108, -79, 20,
+ -62, 4, 112, 67, 25, 9, 33, 76, 66, 25, 12, 101, 36, -124, 48, 9,
+ 100, 48, -108, -111, 16, -62, 36, 76, 68, -116, 17, -128, 32, 8, -110, 96,
+ 64, -58, 24, 1, 8, -126, 32, 8, -126, 32, 8, -110, 32, 1, 0, 0,
+ -125, 17, 0, 55, 0, -125, 17, 65, 25, 16, -64, 96, -124, -64, 6, 3,
+ 48, 24, 49, -76, 1, 1, 12, 70, -84, 65, 55, 0, -125, 17, 106, -32,
+ 13, -64, 96, 68, 26, 124, 3, 48, 24, 97, 6, 96, 48, 0, -125, 17,
+ 103, 16, 6, 3, 48, 24, -127, 6, 98, 48, 0, 24, 16, 3, 0, 0,
+ 13, 0, 0, 0, 91, 6, 32, -16, -125, 45, 67, 16, -124, -62, -106, 65,
+ 8, 72, 97, -53, 48, 4, -89, -80, 101, 32, 2, 63, -40, 50, 20, -127,
+ 31, 108, 25, -116, -64, 15, -74, 12, 71, -32, 7, 91, 6, 36, -16, -125,
+ 45, 67, 18, -8, 1, 0, 0, 0, 0, 0, 0, 0, 97, 32, 0, 0,
+ 11, 0, 0, 0, 19, 4, -63, 96, 4, -64, 13, 0, -122, 3, 1, 0,
+ 2, 0, 0, 0, -58, 49, 0, -111, 1, 0, 0, 0, 1, 49, 0, 0,
+ 2, 0, 0, 0, 91, 6, 32, -16, 3, 0, 0, 0, 0, 0, 0, 0,
+ 97, 32, 0, 0, 15, 0, 0, 0, 19, 4, 65, 44, 16, 0, 0, 0,
+ 1, 0, 0, 0, 4, -108, 0, 0, -57, 1, 97, 94, 7, -125, -5, 30,
+ 72, 48, 8, 7, 2, 0, 0, 0, 5, 0, 0, 0, -26, 65, 8, 78,
+ 83, 25, -121, -128, 52, 6, 82, 8, 78, 83, -43, -10, 49, 0, -61, 0,
+ 0, 0, 0, 0, 97, 32, 0, 0, 15, 0, 0, 0, 19, 4, 1, 113,
+ -61, -68, 14, 4, -125, 17, -36, 55, 0, 24, 14, 4, 4, 0, 0, 0,
+ -42, 49, 84, -64, 98, 28, 5, 32, 8, 20, 99, 31, 3, 48, 12, 0,
+ 1, 49, 0, 0, 3, 0, 0, 0, 91, 6, 32, -16, -125, 45, -125, 16,
+ -8, 1, 0, 0, 0, 0, 0, 0, 97, 32, 0, 0, 17, 0, 0, 0,
+ 19, 4, 1, 117, -125, -72, 97, -97, 7, -126, -63, 8, 14, 12, 6, 0,
+ -61, -127, 0, 0, 4, 0, 0, 0, -42, 49, 84, -64, 98, 28, 5, 32,
+ 8, 20, 99, 32, 3, 48, 12, 0, 1, 49, 0, 0, 4, 0, 0, 0,
+ 91, 6, 32, -16, -125, 45, 67, 16, -8, -63, -106, 97, 8, -4, 0, 0,
+ 0, 0, 0, 0, 97, 32, 0, 0, 3, 0, 0, 0, 19, 4, -63, -120,
+ 1, -127, 4, -112, -127, 0, 0, 0, 97, 32, 0, 0, 9, 0, 0, 0,
+ 19, 4, -63, 120, 3, 55, 73, -44, -115, 17, 3, 2, 8, 22, 15, -61,
+ -127, 0, 0, 0, 2, 0, 0, 0, 7, 80, 16, -51, 20, 97, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+const int bitCodeLength = 2744;
+
+#endif
diff --git a/renderscript/Android.bp b/renderscript/Android.bp
index ba90f2c..ed19a37 100644
--- a/renderscript/Android.bp
+++ b/renderscript/Android.bp
@@ -2,4 +2,5 @@
subdirs = [
"1.0",
"1.0/default",
+ "1.0/vts/functional",
]
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 1298e16..d21b512 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/sensors/1.0/types.h>
#include <android/log.h>
#include <cutils/ashmem.h>
+#include <utils/SystemClock.h>
#include <VtsHalHidlTargetTestBase.h>
#include <hardware/sensors.h> // for sensor type strings
@@ -42,6 +43,7 @@
using namespace ::android::hardware::sensors::V1_0;
// Test environment for sensors
+class SensorsHidlTest;
class SensorsHidlEnvironment : public ::testing::Environment {
public:
// get the test environment singleton
@@ -50,9 +52,6 @@
return instance;
}
- // sensors hidl service
- sp<ISensors> sensors;
-
virtual void SetUp();
virtual void TearDown();
@@ -64,10 +63,15 @@
void setCollection(bool enable);
private:
+ friend SensorsHidlTest;
+ // sensors hidl service
+ sp<ISensors> sensors;
+
SensorsHidlEnvironment() {}
void addEvent(const Event& ev);
void startPollingThread();
+ void resetHal();
static void pollingThread(SensorsHidlEnvironment* env, std::shared_ptr<bool> stop);
bool collectionEnabled;
@@ -80,9 +84,9 @@
};
void SensorsHidlEnvironment::SetUp() {
- sensors = ::testing::VtsHalHidlTargetTestBase::getService<ISensors>();
- ALOGI_IF(sensors, "sensors is not nullptr, %p", sensors.get());
- ASSERT_NE(sensors, nullptr);
+ resetHal();
+
+ ASSERT_NE(sensors, nullptr) << "sensors is nullptr, cannot get hidl service";
collectionEnabled = false;
startPollingThread();
@@ -93,14 +97,77 @@
}
void SensorsHidlEnvironment::TearDown() {
- ALOGI("TearDown SensorsHidlEnvironement");
-
if (stopThread) {
*stopThread = true;
}
pollThread.detach();
}
+void SensorsHidlEnvironment::resetHal() {
+ // wait upto 100ms * 10 = 1s for hidl service.
+ constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
+
+ std::string step;
+ bool succeed = false;
+ for (size_t retry = 10; retry > 0; --retry) {
+ // this do ... while is for easy error handling
+ do {
+ step = "getService()";
+ sensors = ISensors::getService();
+ if (sensors == nullptr) {
+ break;
+ }
+
+ step = "poll() check";
+ // Poke ISensor service. If it has lingering connection from previous generation of
+ // system server, it will kill itself. There is no intention to handle the poll result,
+ // which will be done since the size is 0.
+ if(!sensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
+ break;
+ }
+
+ step = "getSensorList";
+ std::vector<SensorInfo> sensorList;
+ if (!sensors->getSensorsList(
+ [&] (const ::android::hardware::hidl_vec<SensorInfo> &list) {
+ sensorList.reserve(list.size());
+ for (size_t i = 0; i < list.size(); ++i) {
+ sensorList.push_back(list[i]);
+ }
+ }).isOk()) {
+ break;
+ }
+
+ // stop each sensor individually
+ step = "stop each sensor";
+ bool ok = true;
+ for (const auto &i : sensorList) {
+ if (!sensors->activate(i.sensorHandle, false).isOk()) {
+ ok = false;
+ break;
+ }
+ }
+ if (!ok) {
+ break;
+ }
+
+ // mark it done
+ step = "done";
+ succeed = true;
+ } while(0);
+
+ if (succeed) {
+ return;
+ }
+
+ // Delay 100ms before retry, hidl service is expected to come up in short time after crash.
+ ALOGI("%s unsuccessful, try again soon (remaining retry %zu).", step.c_str(), retry - 1);
+ std::this_thread::sleep_for(RETRY_DELAY);
+ }
+
+ sensors = nullptr;
+}
+
void SensorsHidlEnvironment::catEvents(std::vector<Event>* output) {
std::lock_guard<std::mutex> lock(events_mutex);
if (output) {
@@ -257,6 +324,10 @@
}
break;
}
+ case SharedMemType::GRALLOC: {
+
+ break;
+ }
default:
break;
}
@@ -308,6 +379,58 @@
return m;
}
+class SensorEventsChecker {
+ public:
+ virtual bool check(const std::vector<Event> &events, std::string *out) const = 0;
+ virtual ~SensorEventsChecker() {}
+};
+
+class NullChecker : public SensorEventsChecker {
+ public:
+ virtual bool check(const std::vector<Event> &, std::string *) const {
+ return true;
+ }
+};
+
+class SensorEventPerEventChecker : public SensorEventsChecker {
+ public:
+ virtual bool checkEvent(const Event &event, std::string *out) const = 0;
+ virtual bool check(const std::vector<Event> &events, std::string *out) const {
+ for (const auto &e : events) {
+ if (!checkEvent(e, out)) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+class Vec3NormChecker : public SensorEventPerEventChecker {
+ public:
+ Vec3NormChecker(float min, float max) : mRange(min, max) {}
+ static Vec3NormChecker byNominal(float nominal, float allowedError) {
+ return Vec3NormChecker(nominal - allowedError, nominal + allowedError);
+ }
+
+ virtual bool checkEvent(const Event &event, std::string *out) const {
+ Vec3 v = event.u.vec3;
+ float norm = std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
+ if (norm < mRange.first || norm > mRange.second) {
+ if (out != nullptr) {
+ std::ostringstream ss;
+ ss << "Event @ " << event.timestamp << " (" << v.x << ", " << v.y << ", " << v.z << ")"
+ << " has norm " << norm << ", which is beyond range"
+ << " [" << mRange.first << ", " << mRange.second << "]";
+ *out = ss.str();
+ }
+ return false;
+ }
+ return true;
+ }
+ protected:
+ std::pair<float, float> mRange;
+};
+
// The main test class for SENSORS HIDL HAL.
class SensorsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
public:
@@ -332,6 +455,7 @@
protected:
SensorInfo defaultSensorByType(SensorType type);
+ std::vector<SensorInfo> getSensorsList();
std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
bool clearBeforeStart = true, bool changeCollection = true);
@@ -393,16 +517,36 @@
return (int32_t) type > 0;
}
- static bool typeMatchStringType(SensorType type, const hidl_string& stringType);
- static bool typeMatchReportMode(SensorType type, SensorFlagBits reportMode);
- static bool delayMatchReportMode(int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode);
+ void testStreamingOperation(SensorType type,
+ std::chrono::nanoseconds samplingPeriod,
+ std::chrono::seconds duration,
+ const SensorEventsChecker &checker);
+ void testSamplingRateHotSwitchOperation(SensorType type);
+ void testBatchingOperation(SensorType type);
+ void testDirectReportOperation(
+ SensorType type, SharedMemType memType, RateLevel rate, const SensorEventsChecker &checker);
+
+ static void assertTypeMatchStringType(SensorType type, const hidl_string& stringType);
+ static void assertTypeMatchReportMode(SensorType type, SensorFlagBits reportMode);
+ static void assertDelayMatchReportMode(
+ int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode);
static SensorFlagBits expectedReportModeForType(SensorType type);
+ static bool isDirectReportRateSupported(SensorInfo sensor, RateLevel rate);
+ static bool isDirectChannelTypeSupported(SensorInfo sensor, SharedMemType type);
+
+ // checkers
+ static const Vec3NormChecker sAccelNormChecker;
+ static const Vec3NormChecker sGyroNormChecker;
// all sensors and direct channnels used
std::unordered_set<int32_t> mSensorHandles;
std::unordered_set<int32_t> mDirectChannelHandles;
};
+const Vec3NormChecker SensorsHidlTest::sAccelNormChecker(
+ Vec3NormChecker::byNominal(GRAVITY_EARTH, 0.5f/*m/s^2*/));
+const Vec3NormChecker SensorsHidlTest::sGyroNormChecker(
+ Vec3NormChecker::byNominal(0.f, 0.1f/*rad/s*/));
Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
// If activating a sensor, add the handle in a set so that when test fails it can be turned off.
@@ -433,7 +577,7 @@
std::vector<Event> SensorsHidlTest::collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
bool clearBeforeStart, bool changeCollection) {
std::vector<Event> events;
- constexpr useconds_t SLEEP_GRANULARITY = 100*1000; //gradularity 100 ms
+ constexpr useconds_t SLEEP_GRANULARITY = 100*1000; //granularity 100 ms
ALOGI("collect max of %zu events for %d us, clearBeforeStart %d",
nEventLimit, timeLimitUs, clearBeforeStart);
@@ -464,94 +608,93 @@
return events;
}
-bool SensorsHidlTest::typeMatchStringType(SensorType type, const hidl_string& stringType) {
+void SensorsHidlTest::assertTypeMatchStringType(SensorType type, const hidl_string& stringType) {
if (type >= SensorType::DEVICE_PRIVATE_BASE) {
- return true;
+ return;
}
- bool res = true;
switch (type) {
#define CHECK_TYPE_STRING_FOR_SENSOR_TYPE(type) \
- case SensorType::type: res = stringType == SENSOR_STRING_TYPE_ ## type;\
- break;\
-
+ case SensorType::type: ASSERT_STREQ(SENSOR_STRING_TYPE_ ## type, stringType); break;
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TEMPERATURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER_UNCALIBRATED);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(AMBIENT_TEMPERATURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GAME_ROTATION_VECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GEOMAGNETIC_ROTATION_VECTOR);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_RATE);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
+ CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TEMPERATURE);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TILT_DETECTOR);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WAKE_GESTURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WRIST_TILT_GESTURE);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
- CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
default:
- ALOGW("Type %d is not checked, stringType = %s", (int)type, stringType.c_str());
+ FAIL() << "Type " << static_cast<int>(type) << " in android defined range is not checked, "
+ << "stringType = " << stringType;
#undef CHECK_TYPE_STRING_FOR_SENSOR_TYPE
}
- return res;
}
-bool SensorsHidlTest::typeMatchReportMode(SensorType type, SensorFlagBits reportMode) {
+void SensorsHidlTest::assertTypeMatchReportMode(SensorType type, SensorFlagBits reportMode) {
if (type >= SensorType::DEVICE_PRIVATE_BASE) {
- return true;
+ return;
}
SensorFlagBits expected = expectedReportModeForType(type);
- return expected == (SensorFlagBits)-1 || expected == reportMode;
+ ASSERT_TRUE(expected == (SensorFlagBits) -1 || expected == reportMode)
+ << "reportMode=" << static_cast<int>(reportMode)
+ << "expected=" << static_cast<int>(expected);
}
-bool SensorsHidlTest::delayMatchReportMode(
+void SensorsHidlTest::assertDelayMatchReportMode(
int32_t minDelay, int32_t maxDelay, SensorFlagBits reportMode) {
- bool res = true;
switch(reportMode) {
case SensorFlagBits::CONTINUOUS_MODE:
- res = (minDelay > 0) && (maxDelay >= 0);
+ ASSERT_LT(0, minDelay);
+ ASSERT_LE(0, maxDelay);
break;
case SensorFlagBits::ON_CHANGE_MODE:
- //TODO: current implementation does not satisfy minDelay == 0 on Proximity
- res = (minDelay >= 0) && (maxDelay >= 0);
- //res = (minDelay == 0) && (maxDelay >= 0);
+ ASSERT_LE(0, minDelay);
+ ASSERT_LE(0, maxDelay);
break;
case SensorFlagBits::ONE_SHOT_MODE:
- res = (minDelay == -1) && (maxDelay == 0);
+ ASSERT_EQ(-1, minDelay);
+ ASSERT_EQ(0, maxDelay);
break;
case SensorFlagBits::SPECIAL_REPORTING_MODE:
- res = (minDelay == 0) && (maxDelay == 0);
+ // do not enforce anything for special reporting mode
break;
default:
- res = false;
+ FAIL() << "Report mode " << static_cast<int>(reportMode) << " not checked";
}
-
- return res;
}
+// return -1 means no expectation for this type
SensorFlagBits SensorsHidlTest::expectedReportModeForType(SensorType type) {
switch (type) {
case SensorType::ACCELEROMETER:
@@ -599,6 +742,24 @@
}
}
+bool SensorsHidlTest::isDirectReportRateSupported(SensorInfo sensor, RateLevel rate) {
+ unsigned int r =
+ static_cast<unsigned int>(sensor.flags & SensorFlagBits::MASK_DIRECT_REPORT)
+ >> static_cast<unsigned int>(SensorFlagShift::DIRECT_REPORT);
+ return r >= static_cast<unsigned int>(rate);
+}
+
+bool SensorsHidlTest::isDirectChannelTypeSupported(SensorInfo sensor, SharedMemType type) {
+ switch (type) {
+ case SharedMemType::ASHMEM:
+ return (sensor.flags & SensorFlagBits::DIRECT_CHANNEL_ASHMEM) != 0;
+ case SharedMemType::GRALLOC:
+ return (sensor.flags & SensorFlagBits::DIRECT_CHANNEL_GRALLOC) != 0;
+ default:
+ return false;
+ }
+}
+
SensorInfo SensorsHidlTest::defaultSensorByType(SensorType type) {
SensorInfo ret;
@@ -617,60 +778,142 @@
return ret;
}
+std::vector<SensorInfo> SensorsHidlTest::getSensorsList() {
+ std::vector<SensorInfo> ret;
+
+ S()->getSensorsList(
+ [&] (const auto &list) {
+ const size_t count = list.size();
+ ret.reserve(list.size());
+ for (size_t i = 0; i < count; ++i) {
+ ret.push_back(list[i]);
+ }
+ });
+
+ return ret;
+}
+
// Test if sensor list returned is valid
TEST_F(SensorsHidlTest, SensorListValid) {
S()->getSensorsList(
[&] (const auto &list) {
const size_t count = list.size();
for (size_t i = 0; i < count; ++i) {
- auto &s = list[i];
- ALOGV("\t%zu: handle=%#08x type=%d name=%s",
- i, s.sensorHandle, (int)s.type, s.name.c_str());
+ 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
- ASSERT_FALSE(s.typeAsString.empty());
+ EXPECT_FALSE(s.typeAsString.empty());
// Test defined type matches defined string type
- ASSERT_TRUE(typeMatchStringType(s.type, s.typeAsString));
+ EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(s.type, s.typeAsString));
// Test if all sensor has name and vendor
- ASSERT_FALSE(s.name.empty());
- ASSERT_FALSE(s.vendor.empty());
+ EXPECT_FALSE(s.name.empty());
+ EXPECT_FALSE(s.vendor.empty());
// Test power > 0, maxRange > 0
- ASSERT_GE(s.power, 0);
- ASSERT_GT(s.maxRange, 0);
+ EXPECT_LE(0, s.power);
+ EXPECT_LT(0, s.maxRange);
// Info type, should have no sensor
- ASSERT_FALSE(
+ EXPECT_FALSE(
s.type == SensorType::ADDITIONAL_INFO
|| s.type == SensorType::META_DATA);
// Test fifoMax >= fifoReserved
- ALOGV("max reserve = %d, %d", s.fifoMaxEventCount, s.fifoReservedEventCount);
- ASSERT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount);
+ EXPECT_GE(s.fifoMaxEventCount, s.fifoReservedEventCount)
+ << "max=" << s.fifoMaxEventCount << " reserved=" << s.fifoReservedEventCount;
// Test Reporting mode valid
- ASSERT_TRUE(typeMatchReportMode(s.type, extractReportMode(s.flags)));
+ EXPECT_NO_FATAL_FAILURE(assertTypeMatchReportMode(s.type, extractReportMode(s.flags)));
// Test min max are in the right order
- ASSERT_LE(s.minDelay, s.maxDelay);
+ EXPECT_LE(s.minDelay, s.maxDelay);
// Test min/max delay matches reporting mode
- ASSERT_TRUE(delayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
+ EXPECT_NO_FATAL_FAILURE(
+ assertDelayMatchReportMode(s.minDelay, s.maxDelay, extractReportMode(s.flags)));
}
});
}
-// Test if sensor hal can do normal accelerometer streaming properly
-TEST_F(SensorsHidlTest, NormalAccelerometerStreamingOperation) {
+// Test if sensor list returned is valid
+TEST_F(SensorsHidlTest, SetOperationMode) {
+ std::vector<SensorInfo> sensorList = getSensorsList();
+ bool needOperationModeSupport =
+ std::any_of(sensorList.begin(), sensorList.end(),
+ [] (const auto& s) {
+ return (s.flags & SensorFlagBits::DATA_INJECTION) != 0;
+ });
+ if (!needOperationModeSupport) {
+ return;
+ }
+
+ ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+ ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::DATA_INJECTION));
+ ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+}
+
+// Test if sensor list returned is valid
+TEST_F(SensorsHidlTest, InjectSensorEventData) {
+ std::vector<SensorInfo> sensorList = getSensorsList();
+ std::vector<SensorInfo> sensorSupportInjection;
+
+ bool needOperationModeSupport =
+ std::any_of(sensorList.begin(), sensorList.end(),
+ [&sensorSupportInjection] (const auto& s) {
+ bool ret = (s.flags & SensorFlagBits::DATA_INJECTION) != 0;
+ if (ret) {
+ sensorSupportInjection.push_back(s);
+ }
+ return ret;
+ });
+ if (!needOperationModeSupport) {
+ return;
+ }
+
+ ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+ ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::DATA_INJECTION));
+
+ for (const auto &s : sensorSupportInjection) {
+ switch (s.type) {
+ case SensorType::ACCELEROMETER:
+ case SensorType::GYROSCOPE:
+ case SensorType::MAGNETIC_FIELD: {
+ usleep(100000); // sleep 100ms
+
+ Event dummy;
+ dummy.timestamp = android::elapsedRealtimeNano();
+ dummy.sensorType = s.type;
+ dummy.sensorHandle = s.sensorHandle;
+ Vec3 v = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
+ dummy.u.vec3 = v;
+
+ EXPECT_EQ(Result::OK, S()->injectSensorData(dummy));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+}
+
+void SensorsHidlTest::testStreamingOperation(SensorType type,
+ std::chrono::nanoseconds samplingPeriod,
+ std::chrono::seconds duration,
+ const SensorEventsChecker &checker) {
std::vector<Event> events;
- constexpr int64_t samplingPeriodInNs = 20ull*1000*1000; // 20ms
- constexpr int64_t batchingPeriodInNs = 0; // no batching
- constexpr useconds_t minTimeUs = 5*1000*1000; // 5 s
- constexpr size_t minNEvent = 100; // at lease 100 events
- constexpr SensorType type = SensorType::ACCELEROMETER;
+ const int64_t samplingPeriodInNs = samplingPeriod.count();
+ const int64_t batchingPeriodInNs = 0; // no batching
+ const useconds_t minTimeUs = std::chrono::microseconds(duration).count();
+ const size_t minNEvent = duration / samplingPeriod;
SensorInfo sensor = defaultSensorByType(type);
@@ -679,6 +922,11 @@
return;
}
+ if (std::chrono::microseconds(sensor.minDelay) > samplingPeriod) {
+ // rate not supported
+ return;
+ }
+
int32_t handle = sensor.sensorHandle;
ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
@@ -691,90 +939,110 @@
ASSERT_GT(events.size(), 0u);
size_t nRealEvent = 0;
+ bool handleMismatchReported = false;
+ bool metaSensorTypeErrorReported = false;
for (auto & e : events) {
if (e.sensorType == type) {
-
- ASSERT_EQ(e.sensorHandle, handle);
-
- Vec3 acc = e.u.vec3;
-
- double gravityNorm = std::sqrt(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z);
- ALOGV("Norm = %f", gravityNorm);
-
- // assert this is earth gravity
- ASSERT_TRUE(std::fabs(gravityNorm - GRAVITY_EARTH) < 1);
-
+ // avoid generating hundreds of error
+ if (!handleMismatchReported) {
+ EXPECT_EQ(e.sensorHandle, handle)
+ << (handleMismatchReported = true,
+ "Event of the same type must come from the sensor registered");
+ }
++ nRealEvent;
} else {
- ALOGI("Event type %d, handle %d", (int) e.sensorType, (int) e.sensorHandle);
- // Only meta types are allowed besides the subscribed sensor
- ASSERT_TRUE(isMetaSensorType(e.sensorType));
+ // avoid generating hundreds of error
+ if (!metaSensorTypeErrorReported) {
+ EXPECT_TRUE(isMetaSensorType(e.sensorType))
+ << (metaSensorTypeErrorReported = true,
+ "Only meta types are allowed besides the type registered");
+ }
}
}
- ASSERT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
+ std::string s;
+ EXPECT_TRUE(checker.check(events, &s)) << s;
+
+ EXPECT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
}
-// Test if sensor hal can do gyroscope streaming properly
-TEST_F(SensorsHidlTest, NormalGyroscopeStreamingOperation) {
- std::vector<Event> events;
-
- constexpr int64_t samplingPeriodInNs = 10ull*1000*1000; // 10ms
- constexpr int64_t batchingPeriodInNs = 0; // no batching
- constexpr useconds_t minTimeUs = 5*1000*1000; // 5 s
- constexpr size_t minNEvent = 200;
- constexpr SensorType type = SensorType::GYROSCOPE;
-
- SensorInfo sensor = defaultSensorByType(type);
-
- if (!isValidType(sensor.type)) {
- // no default sensor of this type
- return;
- }
-
- int32_t handle = sensor.sensorHandle;
-
- ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
- ASSERT_EQ(activate(handle, 1), Result::OK);
- events = collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
- ASSERT_EQ(activate(handle, 0), Result::OK);
-
- ALOGI("Collected %zu samples", events.size());
-
- ASSERT_GT(events.size(), 0u);
-
- size_t nRealEvent = 0;
- for (auto & e : events) {
- if (e.sensorType == type) {
-
- ASSERT_EQ(e.sensorHandle, handle);
-
- Vec3 gyro = e.u.vec3;
-
- double gyroNorm = std::sqrt(gyro.x * gyro.x + gyro.y * gyro.y + gyro.z * gyro.z);
- ALOGV("Gyro Norm = %f", gyroNorm);
-
- // assert not drifting
- ASSERT_TRUE(gyroNorm < 0.1); // < ~5 degree/s
-
- ++ nRealEvent;
- } else {
- ALOGI("Event type %d, handle %d", (int) e.sensorType, (int) e.sensorHandle);
- // Only meta types are allowed besides the subscribed sensor
- ASSERT_TRUE(isMetaSensorType(e.sensorType));
- }
- }
-
- ASSERT_GE(nRealEvent, minNEvent / 2); // make sure returned events are not all meta
+// 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 if sensor hal can do accelerometer sampling rate switch properly when sensor is active
-TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+// 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 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 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 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 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 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 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 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());
+}
+
+void SensorsHidlTest::testSamplingRateHotSwitchOperation(SensorType type) {
std::vector<Event> events1, events2;
constexpr int64_t batchingPeriodInNs = 0; // no batching
constexpr size_t minNEvent = 50;
- constexpr SensorType type = SensorType::ACCELEROMETER;
SensorInfo sensor = defaultSensorByType(type);
@@ -845,21 +1113,34 @@
maxDelayAverageInterval = timestampInterval / (nEvent - 1);
// change of rate is significant.
- ASSERT_GT((maxDelayAverageInterval - minDelayAverageInterval), minDelayAverageInterval / 10);
+ EXPECT_GT((maxDelayAverageInterval - minDelayAverageInterval), minDelayAverageInterval / 10);
// fastest rate sampling time is close to spec
ALOGI("minDelayAverageInterval = %" PRId64, minDelayAverageInterval);
- ASSERT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
+ EXPECT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
minSamplingPeriodInNs / 10);
}
-// Test if sensor hal can do normal accelerometer batching properly
-TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+// Test if sensor hal can do accelerometer sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, AccelerometerSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::ACCELEROMETER);
+}
+
+// Test if sensor hal can do gyroscope sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, GyroscopeSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::GYROSCOPE);
+}
+
+// Test if sensor hal can do magnetometer sampling rate switch properly when sensor is active
+TEST_F(SensorsHidlTest, MagnetometerSamplingPeriodHotSwitchOperation) {
+ testSamplingRateHotSwitchOperation(SensorType::MAGNETIC_FIELD);
+}
+
+void SensorsHidlTest::testBatchingOperation(SensorType type) {
std::vector<Event> events;
- constexpr int64_t oneSecondInNs = 1ull * 1000 * 1000 * 1000;
- constexpr SensorType type = SensorType::ACCELEROMETER;
constexpr int64_t maxBatchingTestTimeNs = 30ull * 1000 * 1000 * 1000;
+ constexpr int64_t oneSecondInNs = 1ull * 1000 * 1000 * 1000;
SensorInfo sensor = defaultSensorByType(type);
@@ -922,24 +1203,46 @@
ASSERT_GT(nEvent, (size_t)(batchingPeriodInNs / minSamplingPeriodInNs * 9 / 10));
}
-// Test sensor event direct report with ashmem for gyro sensor
-TEST_F(SensorsHidlTest, GyroscopeAshmemDirectReport) {
+// Test if sensor hal can do accelerometer batching properly
+TEST_F(SensorsHidlTest, AccelerometerBatchingOperation) {
+ testBatchingOperation(SensorType::ACCELEROMETER);
+}
- constexpr SensorType type = SensorType::GYROSCOPE;
- constexpr size_t kEventSize = 104;
+// Test if sensor hal can do gyroscope batching properly
+TEST_F(SensorsHidlTest, GyroscopeBatchingOperation) {
+ testBatchingOperation(SensorType::GYROSCOPE);
+}
+
+// Test if sensor hal can do magnetometer batching properly
+TEST_F(SensorsHidlTest, MagnetometerBatchingOperation) {
+ testBatchingOperation(SensorType::MAGNETIC_FIELD);
+}
+
+void SensorsHidlTest::testDirectReportOperation(
+ SensorType type, SharedMemType memType, RateLevel rate, const SensorEventsChecker &checker) {
+ constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
constexpr size_t kNEvent = 500;
constexpr size_t kMemSize = kEventSize * kNEvent;
+ constexpr float kNormalNominal = 50;
+ constexpr float kFastNominal = 200;
+ constexpr float kVeryFastNominal = 800;
+
+ constexpr float kNominalTestTimeSec = 1.f;
+ constexpr float kMaxTestTimeSec = kNominalTestTimeSec + 0.5f; // 0.5 second for initialization
+
SensorInfo sensor = defaultSensorByType(type);
- if (!(sensor.flags | SensorFlagBits::MASK_DIRECT_REPORT)
- || !(sensor.flags | SensorFlagBits::DIRECT_CHANNEL_ASHMEM)) {
- // does not declare support
+ if (!isDirectReportRateSupported(sensor, rate)) {
+ return;
+ }
+
+ if (!isDirectChannelTypeSupported(sensor, memType)) {
return;
}
std::unique_ptr<SensorsTestSharedMemory>
- mem(SensorsTestSharedMemory::create(SharedMemType::ASHMEM, kMemSize));
+ mem(SensorsTestSharedMemory::create(memType, kMemSize));
ASSERT_NE(mem, nullptr);
char* buffer = mem->getBuffer();
@@ -961,39 +1264,119 @@
}
int32_t eventToken;
- configDirectReport(sensor.sensorHandle, channelHandle, RateLevel::NORMAL,
+ configDirectReport(sensor.sensorHandle, channelHandle, rate,
[&eventToken] (auto result, auto token) {
ASSERT_EQ(result, Result::OK);
eventToken = token;
});
- usleep(1500000); // sleep 1 sec for data, plus 0.5 sec for initialization
+ usleep(static_cast<useconds_t>(kMaxTestTimeSec * 1e6f));
auto events = mem->parseEvents();
- // allowed to be 55% of nominal freq (50Hz)
- ASSERT_GT(events.size(), 50u / 2u);
- ASSERT_LT(events.size(), static_cast<size_t>(110*1.5));
+ // find norminal rate
+ float nominalFreq = 0.f;
+ switch (rate) {
+ case RateLevel::NORMAL:
+ nominalFreq = kNormalNominal;
+ break;
+ case RateLevel::FAST:
+ nominalFreq = kFastNominal;
+ break;
+ case RateLevel::VERY_FAST:
+ nominalFreq = kVeryFastNominal;
+ break;
+ case RateLevel::STOP:
+ FAIL();
+ }
+
+ // allowed to be between 55% and 220% of nominal freq
+ ASSERT_GT(events.size(), static_cast<size_t>(nominalFreq * 0.55f * kNominalTestTimeSec));
+ ASSERT_LT(events.size(), static_cast<size_t>(nominalFreq * 2.2f * kMaxTestTimeSec));
int64_t lastTimestamp = 0;
+ bool typeErrorReported = false;
+ bool tokenErrorReported = false;
+ bool timestampErrorReported = false;
for (auto &e : events) {
- ASSERT_EQ(e.sensorType, type);
- ASSERT_EQ(e.sensorHandle, eventToken);
- ASSERT_GT(e.timestamp, lastTimestamp);
-
- Vec3 gyro = e.u.vec3;
- double gyroNorm = std::sqrt(gyro.x * gyro.x + gyro.y * gyro.y + gyro.z * gyro.z);
- // assert not drifting
- ASSERT_TRUE(gyroNorm < 0.1); // < ~5 degree/sa
-
+ if (!typeErrorReported) {
+ EXPECT_EQ(type, e.sensorType)
+ << (typeErrorReported = true, "Type in event does not match type of sensor registered.");
+ }
+ if (!tokenErrorReported) {
+ EXPECT_EQ(eventToken, e.sensorHandle)
+ << (tokenErrorReported = true,
+ "Event token does not match that retured from configDirectReport");
+ }
+ if (!timestampErrorReported) {
+ EXPECT_GT(e.timestamp, lastTimestamp)
+ << (timestampErrorReported = true, "Timestamp not monotonically increasing");
+ }
lastTimestamp = e.timestamp;
}
+ std::string s;
+ EXPECT_TRUE(checker.check(events, &s)) << s;
+
// stop sensor and unregister channel
configDirectReport(sensor.sensorHandle, channelHandle, RateLevel::STOP,
[&eventToken] (auto result, auto) {
- ASSERT_EQ(result, Result::OK);
+ EXPECT_EQ(result, Result::OK);
});
- ASSERT_EQ(unregisterDirectChannel(channelHandle), Result::OK);
+ EXPECT_EQ(unregisterDirectChannel(channelHandle), Result::OK);
+}
+
+// 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 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 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 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 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 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 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 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 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());
}
int main(int argc, char **argv) {
diff --git a/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp b/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp
index 0ef4063..3fbef18 100644
--- a/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp
+++ b/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp
@@ -40,7 +40,6 @@
using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback;
using ::android::hardware::Return;
-using ::android::hardware::Status;
using ::android::hardware::Void;
using ::android::sp;
diff --git a/tests/Android.bp b/tests/Android.bp
index 6606d94..31dc75e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -23,4 +23,5 @@
"versioning/1.0",
"versioning/2.2",
"versioning/2.3",
+ "versioning/2.4",
]
diff --git a/tests/extension/light/2.0/Android.bp b/tests/extension/light/2.0/Android.bp
index 5203da6..123bea1 100644
--- a/tests/extension/light/2.0/Android.bp
+++ b/tests/extension/light/2.0/Android.bp
@@ -51,6 +51,7 @@
"libutils",
"libcutils",
"android.hardware.light@2.0",
+ "android.hidl.base@1.0",
],
export_shared_lib_headers: [
"libhidlbase",
@@ -58,5 +59,6 @@
"libhwbinder",
"libutils",
"android.hardware.light@2.0",
+ "android.hidl.base@1.0",
],
}
diff --git a/tests/versioning/2.3/Android.bp b/tests/versioning/2.3/Android.bp
index 122c484..3cc2076 100644
--- a/tests/versioning/2.3/Android.bp
+++ b/tests/versioning/2.3/Android.bp
@@ -63,6 +63,7 @@
"libcutils",
"android.hardware.tests.versioning@1.0",
"android.hardware.tests.versioning@2.2",
+ "android.hidl.base@1.0",
],
export_shared_lib_headers: [
"libhidlbase",
@@ -71,5 +72,6 @@
"libutils",
"android.hardware.tests.versioning@1.0",
"android.hardware.tests.versioning@2.2",
+ "android.hidl.base@1.0",
],
}
diff --git a/tests/versioning/2.4/Android.bp b/tests/versioning/2.4/Android.bp
new file mode 100644
index 0000000..9d8303c
--- /dev/null
+++ b/tests/versioning/2.4/Android.bp
@@ -0,0 +1,63 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+ name: "android.hardware.tests.versioning@2.4_hal",
+ srcs: [
+ "IFoo.hal",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tests.versioning@2.4_genc++",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.versioning@2.4",
+ srcs: [
+ ":android.hardware.tests.versioning@2.4_hal",
+ ],
+ out: [
+ "android/hardware/tests/versioning/2.4/FooAll.cpp",
+ ],
+}
+
+genrule {
+ name: "android.hardware.tests.versioning@2.4_genc++_headers",
+ tools: ["hidl-gen"],
+ cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.versioning@2.4",
+ srcs: [
+ ":android.hardware.tests.versioning@2.4_hal",
+ ],
+ out: [
+ "android/hardware/tests/versioning/2.4/IFoo.h",
+ "android/hardware/tests/versioning/2.4/IHwFoo.h",
+ "android/hardware/tests/versioning/2.4/BnHwFoo.h",
+ "android/hardware/tests/versioning/2.4/BpHwFoo.h",
+ "android/hardware/tests/versioning/2.4/BsFoo.h",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.tests.versioning@2.4",
+ generated_sources: ["android.hardware.tests.versioning@2.4_genc++"],
+ generated_headers: ["android.hardware.tests.versioning@2.4_genc++_headers"],
+ export_generated_headers: ["android.hardware.tests.versioning@2.4_genc++_headers"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "android.hardware.tests.versioning@2.2",
+ "android.hardware.tests.versioning@2.3",
+ "android.hidl.base@1.0",
+ ],
+ export_shared_lib_headers: [
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libutils",
+ "android.hardware.tests.versioning@2.2",
+ "android.hardware.tests.versioning@2.3",
+ "android.hidl.base@1.0",
+ ],
+}
diff --git a/tests/versioning/2.4/Android.mk b/tests/versioning/2.4/Android.mk
new file mode 100644
index 0000000..e41397f
--- /dev/null
+++ b/tests/versioning/2.4/Android.mk
@@ -0,0 +1,80 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.tests.versioning@2.4-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+ android.hardware.tests.versioning@2.2-java \
+ android.hardware.tests.versioning@2.3-java \
+ android.hidl.base@1.0-java \
+
+
+#
+# Build IFoo.hal
+#
+GEN := $(intermediates)/android/hardware/tests/versioning/V2_4/IFoo.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IFoo.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.tests.versioning@2.4::IFoo
+
+$(GEN): $(LOCAL_PATH)/IFoo.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.tests.versioning@2.4-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android.hardware.tests.versioning@2.2-java-static \
+ android.hardware.tests.versioning@2.3-java-static \
+ android.hidl.base@1.0-java-static \
+
+
+#
+# Build IFoo.hal
+#
+GEN := $(intermediates)/android/hardware/tests/versioning/V2_4/IFoo.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IFoo.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.tests.versioning@2.4::IFoo
+
+$(GEN): $(LOCAL_PATH)/IFoo.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/omx/1.0/IOmxProducerListener.hal b/tests/versioning/2.4/IFoo.hal
similarity index 60%
copy from media/omx/1.0/IOmxProducerListener.hal
copy to tests/versioning/2.4/IFoo.hal
index 7fde93b..358b56f 100644
--- a/media/omx/1.0/IOmxProducerListener.hal
+++ b/tests/versioning/2.4/IFoo.hal
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,11 @@
* limitations under the License.
*/
-package android.hardware.media.omx@1.0;
+package android.hardware.tests.versioning@2.4;
-/**
- * Ref: frameworks/native/include/gui/IProducerListener.h: IProducerListener
- * This is a wrapper/wrapped HAL interface for the actual binder interface.
- */
-interface IOmxProducerListener {
- oneway onBufferReleased();
- needsReleaseNotify() generates (bool result);
+import @2.3::IFoo;
+
+// Must extend @2.3::IFoo.
+interface IFoo extends @2.3::IFoo {
+
};
-
diff --git a/update-makefiles.sh b/update-makefiles.sh
index d0cb91c..88cc97b 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -1,52 +1,8 @@
#!/bin/bash
-if [ ! -d hardware/interfaces ] ; then
- echo "Where is hardware/interfaces?";
- exit 1;
-fi
+source system/tools/hidl/update-makefiles-helper.sh
-if [ ! -d system/libhidl/transport ] ; then
- echo "Where is system/libhidl/transport?";
- exit 1;
-fi
+do_makefiles_update \
+ "android.hardware:hardware/interfaces" \
+ "android.hidl:system/libhidl/transport"
-packages=$(pushd hardware/interfaces > /dev/null; \
- find . -type f -name \*.hal -exec dirname {} \; | sort -u | \
- cut -c3- | \
- awk -F'/' \
- '{printf("android.hardware"); for(i=1;i<NF;i++){printf(".%s", $i);}; printf("@%s\n", $NF);}'; \
- popd > /dev/null)
-
-for p in $packages; do
- echo "Updating $p";
- hidl-gen -Lmakefile -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
- rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
- hidl-gen -Landroidbp -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
- rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
-done
-
-# subdirectories of hardware/interfaces which contain an Android.bp file
-android_dirs=$(find hardware/interfaces/*/ \
- -name "Android.bp" \
- -printf "%h\n" \
- | cut -d "/" -f1-3 \
- | sort | uniq)
-
-echo "Updating Android.bp files."
-
-for bp_dir in $android_dirs; do
- bp="$bp_dir/Android.bp"
- # locations of Android.bp files in specific subdirectory of hardware/interfaces
- android_bps=$(find $bp_dir \
- -name "Android.bp" \
- ! -path $bp_dir/Android.bp \
- -printf "%h\n" \
- | sort)
-
- echo "// This is an autogenerated file, do not edit." > "$bp";
- echo "subdirs = [" >> "$bp";
- for a in $android_bps; do
- echo " \"${a#$bp_dir/}\"," >> "$bp";
- done
- echo "]" >> "$bp";
-done
diff --git a/usb/1.0/default/service.cpp b/usb/1.0/default/service.cpp
index b4db241..4605a4c 100644
--- a/usb/1.0/default/service.cpp
+++ b/usb/1.0/default/service.cpp
@@ -28,12 +28,11 @@
using android::hardware::usb::V1_0::implementation::Usb;
int main() {
- const char instance[] = "usb_hal";
android::sp<IUsb> service = new Usb();
configureRpcThreadpool(1, true /*callerWillJoin*/);
- service->registerAsService(instance);
+ service->registerAsService();
ALOGI("USB HAL Ready.");
joinRpcThreadpool();
diff --git a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
index 54db8c2..ea6d4a9 100644
--- a/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
+++ b/usb/1.0/vts/functional/VtsHalUsbV1_0TargetTest.cpp
@@ -47,8 +47,6 @@
using ::android::hardware::Void;
using ::android::sp;
-#define USB_SERVICE_NAME "usb_hal"
-
// The main test class for the USB hidl HAL
class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase {
public:
@@ -97,7 +95,7 @@
virtual void SetUp() override {
ALOGI("Setup");
- usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>(USB_SERVICE_NAME);
+ usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>();
ASSERT_NE(usb, nullptr);
usb_cb_2 = new UsbCallback(*this, 2);
diff --git a/vibrator/1.0/Android.mk b/vibrator/1.0/Android.mk
index 4e1ba6a..d921a7e 100644
--- a/vibrator/1.0/Android.mk
+++ b/vibrator/1.0/Android.mk
@@ -17,6 +17,25 @@
#
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (Status)
#
GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -73,6 +92,25 @@
#
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (Status)
#
GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -114,5 +152,39 @@
include $(BUILD_STATIC_JAVA_LIBRARY)
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.vibrator@1.0-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IVibrator.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava-constants \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vibrator@1.0
+
+$(GEN):
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/vibrator/1.0/IVibrator.hal b/vibrator/1.0/IVibrator.hal
index 0a4ffca..757ad0d 100644
--- a/vibrator/1.0/IVibrator.hal
+++ b/vibrator/1.0/IVibrator.hal
@@ -17,7 +17,8 @@
package android.hardware.vibrator@1.0;
interface IVibrator {
- /** Turn on vibrator
+ /**
+ * Turn on vibrator
*
* This function must only be called after the previous timeout has expired or
* was canceled (through off()).
@@ -26,10 +27,46 @@
*/
on(uint32_t timeoutMs) generates (Status vibratorOnRet);
- /** Turn off vibrator
+ /**
+ * Turn off vibrator
*
* Cancel a previously-started vibration, if any.
* @return vibratorOffRet whether vibrator command was successful or not.
*/
off() generates (Status vibratorOffRet);
+
+ /**
+ * Returns whether the vibrator supports changes to its vibrational amplitude.
+ */
+ supportsAmplitudeControl() generates (bool supports);
+
+ /**
+ * Sets the motor's vibrational amplitude.
+ *
+ * Changes the force being produced by the underlying motor.
+ *
+ * @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.
+ * @return status Whether the command was successful or not. Must return
+ * Status::UNSUPPORTED_OPERATION if setting the amplitude is
+ * not supported by the device.
+ */
+ setAmplitude(uint8_t amplitude) generates (Status status);
+
+ /**
+ * Fire off a predefined haptic event.
+ *
+ * @param event The type of haptic event to trigger.
+ * @return status Whether the effect was successfully performed or not. Must
+ * return Status::UNSUPPORTED_OPERATION is 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(Effect effect, EffectStrength strength) generates (Status status, uint32_t lengthMs);
};
diff --git a/vibrator/1.0/default/Vibrator.cpp b/vibrator/1.0/default/Vibrator.cpp
index 8c82bcd..19cf3dc 100644
--- a/vibrator/1.0/default/Vibrator.cpp
+++ b/vibrator/1.0/default/Vibrator.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "VibratorService"
+#include <inttypes.h>
+
#include <log/log.h>
#include <hardware/hardware.h>
@@ -36,7 +38,7 @@
int32_t ret = mDevice->vibrator_on(mDevice, timeout_ms);
if (ret != 0) {
ALOGE("on command failed : %s", strerror(-ret));
- return Status::ERR;
+ return Status::UNKNOWN_ERROR;
}
return Status::OK;
}
@@ -45,11 +47,24 @@
int32_t ret = mDevice->vibrator_off(mDevice);
if (ret != 0) {
ALOGE("off command failed : %s", strerror(-ret));
- return Status::ERR;
+ return Status::UNKNOWN_ERROR;
}
return Status::OK;
}
+Return<bool> Vibrator::supportsAmplitudeControl() {
+ return false;
+}
+
+Return<Status> Vibrator::setAmplitude(uint8_t) {
+ return Status::UNSUPPORTED_OPERATION;
+}
+
+Return<void> Vibrator::perform(Effect, EffectStrength, perform_cb _hidl_cb) {
+ _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
+ return Void();
+}
+
IVibrator* HIDL_FETCH_IVibrator(const char * /*hal*/) {
vibrator_device_t *vib_device;
const hw_module_t *hw_module = nullptr;
diff --git a/vibrator/1.0/default/Vibrator.h b/vibrator/1.0/default/Vibrator.h
index 061b364..bea6ea8 100644
--- a/vibrator/1.0/default/Vibrator.h
+++ b/vibrator/1.0/default/Vibrator.h
@@ -26,23 +26,18 @@
namespace V1_0 {
namespace implementation {
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using ::android::hardware::vibrator::V1_0::Status;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
struct Vibrator : public IVibrator {
Vibrator(vibrator_device_t *device);
// Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
Return<Status> on(uint32_t timeoutMs) override;
Return<Status> off() override;
+ Return<bool> supportsAmplitudeControl() override;
+ Return<Status> setAmplitude(uint8_t amplitude) override;
+ Return<void> perform(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
- private:
- vibrator_device_t *mDevice;
+private:
+ vibrator_device_t *mDevice;
};
extern "C" IVibrator* HIDL_FETCH_IVibrator(const char* name);
diff --git a/vibrator/1.0/types.hal b/vibrator/1.0/types.hal
index 8fc5683..a080c07 100644
--- a/vibrator/1.0/types.hal
+++ b/vibrator/1.0/types.hal
@@ -16,7 +16,33 @@
package android.hardware.vibrator@1.0;
-enum Status: uint32_t {
- OK = 0,
- ERR = 1
+enum Status : uint32_t {
+ OK,
+ UNKNOWN_ERROR,
+ BAD_VALUE,
+ UNSUPPORTED_OPERATION
+};
+
+@export
+enum Effect : uint32_t {
+ /**
+ * A single click effect.
+ *
+ * This effect should produce a sharp, crisp click sensation.
+ */
+ CLICK,
+ /**
+ * A double click effect.
+ *
+ * This effect should produce two sequential sharp, crisp click sensations with a minimal
+ * amount of time between them.
+ */
+ DOUBLE_CLICK
+};
+
+@export
+enum EffectStrength : uint8_t {
+ LIGHT,
+ MEDIUM,
+ STRONG
};
diff --git a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
index a978f2c..f415ad5 100644
--- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
+++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
@@ -22,6 +22,8 @@
#include <VtsHalHidlTargetTestBase.h>
#include <unistd.h>
+using ::android::hardware::vibrator::V1_0::Effect;
+using ::android::hardware::vibrator::V1_0::EffectStrength;
using ::android::hardware::vibrator::V1_0::IVibrator;
using ::android::hardware::vibrator::V1_0::Status;
using ::android::hardware::Return;
@@ -50,12 +52,49 @@
private:
};
+static void validatePerformEffect(Status status, uint32_t lengthMs) {
+ ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
+ if (status == Status::OK) {
+ ASSERT_GT(lengthMs, static_cast<uint32_t>(0));
+ } else {
+ ASSERT_EQ(lengthMs, static_cast<uint32_t>(0));
+ }
+}
+
TEST_F(VibratorHidlTest, OnThenOffBeforeTimeout) {
EXPECT_EQ(Status::OK, vibrator->on(2000));
sleep(1);
EXPECT_EQ(Status::OK, vibrator->off());
}
+TEST_F(VibratorHidlTest, PerformEffect) {
+ vibrator->perform(Effect::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
+ vibrator->perform(Effect::DOUBLE_CLICK, EffectStrength::LIGHT, validatePerformEffect);
+}
+
+TEST_F(VibratorHidlTest, ChangeVibrationalAmplitude) {
+ if (vibrator->supportsAmplitudeControl()) {
+ EXPECT_EQ(Status::OK, vibrator->setAmplitude(1));
+ EXPECT_EQ(Status::OK, vibrator->on(2000));
+ EXPECT_EQ(Status::OK, vibrator->setAmplitude(128));
+ sleep(1);
+ EXPECT_EQ(Status::OK, vibrator->setAmplitude(255));
+ sleep(1);
+ }
+}
+
+TEST_F(VibratorHidlTest, AmplitudeOutsideRangeFails) {
+ if (vibrator->supportsAmplitudeControl()) {
+ EXPECT_EQ(Status::BAD_VALUE, vibrator->setAmplitude(0));
+ }
+}
+
+TEST_F(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
+ if (!vibrator->supportsAmplitudeControl()) {
+ EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setAmplitude(1));
+ }
+}
+
int main(int argc, char **argv) {
::testing::AddGlobalTestEnvironment(new VibratorHidlEnvironment);
::testing::InitGoogleTest(&argc, argv);
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIface.hal b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
index dc1388a..fb4323c 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIface.hal
@@ -611,7 +611,7 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
- setWfdDeviceInfo(uint8_t[8] info) generates (SupplicantStatus status);
+ setWfdDeviceInfo(uint8_t[6] info) generates (SupplicantStatus status);
/**
* Creates a NFC handover request message.
@@ -672,4 +672,15 @@
*/
reportNfcHandoverInitiation(vec<uint8_t> select)
generates (SupplicantStatus status);
+
+ /**
+ * Persist the current configuration to disk.
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ saveConfig() generates (SupplicantStatus status);
};
diff --git a/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal b/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal
index b6ee57f..8a54bf4 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.hal
@@ -105,7 +105,7 @@
MacAddress srcAddress, MacAddress p2pDeviceAddress,
uint8_t[8] primaryDeviceType, string deviceName,
bitfield<WpsConfigMethods> configMethods, uint8_t deviceCapabilities,
- bitfield<P2pGroupCapabilityMask> groupCapabilities, uint8_t[8] wfdDeviceInfo);
+ bitfield<P2pGroupCapabilityMask> groupCapabilities, uint8_t[6] wfdDeviceInfo);
/**
* Used to indicate that a P2P device has been lost.
diff --git a/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal b/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal
index d32b47e..6ec7143 100644
--- a/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal
+++ b/wifi/supplicant/1.0/ISupplicantP2pNetwork.hal
@@ -100,4 +100,34 @@
* @return isGo true if group owner, false otherwise.
*/
isGo() generates (SupplicantStatus status, bool isGo);
+
+ /**
+ * Set the list of P2P Clients in a persistent group (GO).
+ * This is a list of P2P Clients (P2P Device Address) that have joined
+ * the persistent group. This is maintained on the GO for persistent
+ * group entries (disabled == 2).
+ *
+ * @param clients MAC address of the clients.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantP2ptusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ setClientList(vec<MacAddress> clients) generates (SupplicantStatus status);
+
+ /**
+ * Get the list of P2P Clients in a persistent group (GO).
+ * This is a list of P2P Clients (P2P Device Address) that have joined
+ * the persistent group. This is maintained on the GO for persistent
+ * group entries (disabled == 2).
+ *
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantP2ptusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ * @return clients MAC address of the clients.
+ */
+ getClientList() generates (SupplicantStatus status, vec<MacAddress> clients);
};
diff --git a/wifi/supplicant/1.0/ISupplicantStaIface.hal b/wifi/supplicant/1.0/ISupplicantStaIface.hal
index 68eb179..f89017c 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIface.hal
@@ -460,4 +460,19 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|
*/
removeExtRadioWork(uint32_t id) generates (SupplicantStatus status);
+
+ /**
+ * Enable/Disable auto reconnect to networks.
+ * Use this to prevent wpa_supplicant from trying to connect to networks
+ * on its own.
+ *
+ * @param enable true to enable, false to disable.
+ * @return status Status of the operation.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+ * |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+ */
+ enableAutoReconnect(bool enable) generates (SupplicantStatus status);
};
diff --git a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
index 2223022..166ad96 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
@@ -176,6 +176,176 @@
};
/**
+ * Status codes (IEEE Std 802.11-2016, 9.4.1.9, Table 9-46).
+ */
+ enum StatusCode : uint32_t {
+ SUCCESS = 0,
+ UNSPECIFIED_FAILURE = 1,
+ TDLS_WAKEUP_ALTERNATE = 2,
+ TDLS_WAKEUP_REJECT = 3,
+ SECURITY_DISABLED = 5,
+ UNACCEPTABLE_LIFETIME = 6,
+ NOT_IN_SAME_BSS = 7,
+ CAPS_UNSUPPORTED = 10,
+ REASSOC_NO_ASSOC = 11,
+ ASSOC_DENIED_UNSPEC = 12,
+ NOT_SUPPORTED_AUTH_ALG = 13,
+ UNKNOWN_AUTH_TRANSACTION = 14,
+ CHALLENGE_FAIL = 15,
+ AUTH_TIMEOUT = 16,
+ AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+ ASSOC_DENIED_RATES = 18,
+ ASSOC_DENIED_NOSHORT = 19,
+ SPEC_MGMT_REQUIRED = 22,
+ PWR_CAPABILITY_NOT_VALID = 23,
+ SUPPORTED_CHANNEL_NOT_VALID = 24,
+ ASSOC_DENIED_NO_SHORT_SLOT_TIME = 25,
+ ASSOC_DENIED_NO_HT = 27,
+ R0KH_UNREACHABLE = 28,
+ ASSOC_DENIED_NO_PCO = 29,
+ ASSOC_REJECTED_TEMPORARILY = 30,
+ ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
+ UNSPECIFIED_QOS_FAILURE = 32,
+ DENIED_INSUFFICIENT_BANDWIDTH = 33,
+ DENIED_POOR_CHANNEL_CONDITIONS = 34,
+ DENIED_QOS_NOT_SUPPORTED = 35,
+ REQUEST_DECLINED = 37,
+ INVALID_PARAMETERS = 38,
+ REJECTED_WITH_SUGGESTED_CHANGES = 39,
+ INVALID_IE = 40,
+ GROUP_CIPHER_NOT_VALID = 41,
+ PAIRWISE_CIPHER_NOT_VALID = 42,
+ AKMP_NOT_VALID = 43,
+ UNSUPPORTED_RSN_IE_VERSION = 44,
+ INVALID_RSN_IE_CAPAB = 45,
+ CIPHER_REJECTED_PER_POLICY = 46,
+ TS_NOT_CREATED = 47,
+ DIRECT_LINK_NOT_ALLOWED = 48,
+ DEST_STA_NOT_PRESENT = 49,
+ DEST_STA_NOT_QOS_STA = 50,
+ ASSOC_DENIED_LISTEN_INT_TOO_LARGE = 51,
+ INVALID_FT_ACTION_FRAME_COUNT = 52,
+ INVALID_PMKID = 53,
+ INVALID_MDIE = 54,
+ INVALID_FTIE = 55,
+ REQUESTED_TCLAS_NOT_SUPPORTED = 56,
+ INSUFFICIENT_TCLAS_PROCESSING_RESOURCES = 57,
+ TRY_ANOTHER_BSS = 58,
+ GAS_ADV_PROTO_NOT_SUPPORTED = 59,
+ NO_OUTSTANDING_GAS_REQ = 60,
+ GAS_RESP_NOT_RECEIVED = 61,
+ STA_TIMED_OUT_WAITING_FOR_GAS_RESP = 62,
+ GAS_RESP_LARGER_THAN_LIMIT = 63,
+ REQ_REFUSED_HOME = 64,
+ ADV_SRV_UNREACHABLE = 65,
+ REQ_REFUSED_SSPN = 67,
+ REQ_REFUSED_UNAUTH_ACCESS = 68,
+ INVALID_RSNIE = 72,
+ U_APSD_COEX_NOT_SUPPORTED = 73,
+ U_APSD_COEX_MODE_NOT_SUPPORTED = 74,
+ BAD_INTERVAL_WITH_U_APSD_COEX = 75,
+ ANTI_CLOGGING_TOKEN_REQ = 76,
+ FINITE_CYCLIC_GROUP_NOT_SUPPORTED = 77,
+ CANNOT_FIND_ALT_TBTT = 78,
+ TRANSMISSION_FAILURE = 79,
+ REQ_TCLAS_NOT_SUPPORTED = 80,
+ TCLAS_RESOURCES_EXCHAUSTED = 81,
+ REJECTED_WITH_SUGGESTED_BSS_TRANSITION = 82,
+ REJECT_WITH_SCHEDULE = 83,
+ REJECT_NO_WAKEUP_SPECIFIED = 84,
+ SUCCESS_POWER_SAVE_MODE = 85,
+ PENDING_ADMITTING_FST_SESSION = 86,
+ PERFORMING_FST_NOW = 87,
+ PENDING_GAP_IN_BA_WINDOW = 88,
+ REJECT_U_PID_SETTING = 89,
+ REFUSED_EXTERNAL_REASON = 92,
+ REFUSED_AP_OUT_OF_MEMORY = 93,
+ REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED = 94,
+ QUERY_RESP_OUTSTANDING = 95,
+ REJECT_DSE_BAND = 96,
+ TCLAS_PROCESSING_TERMINATED = 97,
+ TS_SCHEDULE_CONFLICT = 98,
+ DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
+ MCCAOP_RESERVATION_CONFLICT = 100,
+ MAF_LIMIT_EXCEEDED = 101,
+ MCCA_TRACK_LIMIT_EXCEEDED = 102,
+ DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+ ASSOC_DENIED_NO_VHT = 104,
+ ENABLEMENT_DENIED = 105,
+ RESTRICTION_FROM_AUTHORIZED_GDB = 106,
+ AUTHORIZATION_DEENABLED = 107,
+ FILS_AUTHENTICATION_FAILURE = 112,
+ UNKNOWN_AUTHENTICATION_SERVER = 113
+ };
+
+ /**
+ * Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+ */
+ enum ReasonCode : uint32_t {
+ UNSPECIFIED = 1,
+ PREV_AUTH_NOT_VALID = 2,
+ DEAUTH_LEAVING = 3,
+ DISASSOC_DUE_TO_INACTIVITY = 4,
+ DISASSOC_AP_BUSY = 5,
+ CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+ CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+ DISASSOC_STA_HAS_LEFT = 8,
+ STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+ PWR_CAPABILITY_NOT_VALID = 10,
+ SUPPORTED_CHANNEL_NOT_VALID = 11,
+ BSS_TRANSITION_DISASSOC = 12,
+ INVALID_IE = 13,
+ MICHAEL_MIC_FAILURE = 14,
+ FOURWAY_HANDSHAKE_TIMEOUT = 15,
+ GROUP_KEY_UPDATE_TIMEOUT = 16,
+ IE_IN_4WAY_DIFFERS = 17,
+ GROUP_CIPHER_NOT_VALID = 18,
+ PAIRWISE_CIPHER_NOT_VALID = 19,
+ AKMP_NOT_VALID = 20,
+ UNSUPPORTED_RSN_IE_VERSION = 21,
+ INVALID_RSN_IE_CAPAB = 22,
+ IEEE_802_1X_AUTH_FAILED = 23,
+ CIPHER_SUITE_REJECTED = 24,
+ TDLS_TEARDOWN_UNREACHABLE = 25,
+ TDLS_TEARDOWN_UNSPECIFIED = 26,
+ SSP_REQUESTED_DISASSOC = 27,
+ NO_SSP_ROAMING_AGREEMENT = 28,
+ BAD_CIPHER_OR_AKM = 29,
+ NOT_AUTHORIZED_THIS_LOCATION = 30,
+ SERVICE_CHANGE_PRECLUDES_TS = 31,
+ UNSPECIFIED_QOS_REASON = 32,
+ NOT_ENOUGH_BANDWIDTH = 33,
+ DISASSOC_LOW_ACK = 34,
+ EXCEEDED_TXOP = 35,
+ STA_LEAVING = 36,
+ END_TS_BA_DLS = 37,
+ UNKNOWN_TS_BA = 38,
+ TIMEOUT = 39,
+ PEERKEY_MISMATCH = 45,
+ AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+ EXTERNAL_SERVICE_REQUIREMENTS = 47,
+ INVALID_FT_ACTION_FRAME_COUNT = 48,
+ INVALID_PMKID = 49,
+ INVALID_MDE = 50,
+ INVALID_FTE = 51,
+ MESH_PEERING_CANCELLED = 52,
+ MESH_MAX_PEERS = 53,
+ MESH_CONFIG_POLICY_VIOLATION = 54,
+ MESH_CLOSE_RCVD = 55,
+ MESH_MAX_RETRIES = 56,
+ MESH_CONFIRM_TIMEOUT = 57,
+ MESH_INVALID_GTK = 58,
+ MESH_INCONSISTENT_PARAMS = 59,
+ MESH_INVALID_SECURITY_CAP = 60,
+ MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+ MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+ MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+ MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+ MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+ MESH_CHANNEL_SWITCH_UNSPECIFIED = 66
+ };
+
+ /**
* Used to indicate that a new network has been added.
*
* @param id Network ID allocated to the corresponding network.
@@ -268,7 +438,7 @@
* from access point. Refer to section 8.4.1.7 of IEEE802.11 spec.
*/
oneway onDisconnected(
- Bssid bssid, bool locallyGenerated, uint32_t reasonCode);
+ Bssid bssid, bool locallyGenerated, ReasonCode reasonCode);
/**
* Used to indicate an association rejection recieved from the AP
@@ -281,7 +451,7 @@
* @param timedOut Whether failure is due to timeout rather
* than explicit rejection response from the AP.
*/
- oneway onAssociationRejected(Bssid bssid, uint32_t statusCode, bool timedOut);
+ oneway onAssociationRejected(Bssid bssid, StatusCode statusCode, bool timedOut);
/**
* Used to indicate the timeout of authentication to an AP.
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 ab1b6a3..c6ac03c 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
@@ -18,8 +18,33 @@
#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicant.h>
+
#include "supplicant_hidl_test_utils.h"
+using ::android::sp;
+using ::android::hardware::hidl_vec;
+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;
+
+class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ startSupplicantAndWaitForHidlService();
+ supplicant_ = getSupplicant();
+ ASSERT_NE(supplicant_.get(), nullptr);
+ }
+
+ virtual void TearDown() override { stopSupplicant(); }
+
+ protected:
+ // ISupplicant object used for all tests in this fixture.
+ sp<ISupplicant> supplicant_;
+};
+
/*
* Create:
* Ensures that an instance of the ISupplicant proxy object is
@@ -30,3 +55,131 @@
EXPECT_NE(nullptr, getSupplicant().get());
stopSupplicant();
}
+
+/*
+ * ListInterfaces
+ */
+TEST_F(SupplicantHidlTest, ListInterfaces) {
+ std::vector<ISupplicant::IfaceInfo> ifaces;
+ supplicant_->listInterfaces(
+ [&](const SupplicantStatus& status,
+ const hidl_vec<ISupplicant::IfaceInfo>& hidl_ifaces) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ ifaces = hidl_ifaces;
+ });
+
+ EXPECT_NE(ifaces.end(),
+ std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) {
+ return iface.type == IfaceType::STA;
+ }));
+ EXPECT_NE(ifaces.end(),
+ std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) {
+ return iface.type == IfaceType::P2P;
+ }));
+}
+
+/*
+ * GetInterface
+ */
+TEST_F(SupplicantHidlTest, GetInterface) {
+ std::vector<ISupplicant::IfaceInfo> ifaces;
+ supplicant_->listInterfaces(
+ [&](const SupplicantStatus& status,
+ const hidl_vec<ISupplicant::IfaceInfo>& hidl_ifaces) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ ifaces = hidl_ifaces;
+ });
+
+ ASSERT_NE(0u, ifaces.size());
+ supplicant_->getInterface(
+ ifaces[0],
+ [&](const SupplicantStatus& status, const sp<ISupplicantIface>& iface) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_NE(nullptr, iface.get());
+ });
+}
+
+/*
+ * SetDebugParams
+ */
+TEST_F(SupplicantHidlTest, SetDebugParams) {
+ bool show_timestamp = true;
+ bool show_keys = true;
+ ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+ supplicant_->setDebugParams(level,
+ show_timestamp, // show timestamps
+ show_keys, // show keys
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+}
+
+/*
+ * GetDebugLevel
+ */
+TEST_F(SupplicantHidlTest, GetDebugLevel) {
+ bool show_timestamp = true;
+ bool show_keys = true;
+ ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+ supplicant_->setDebugParams(level,
+ show_timestamp, // show timestamps
+ show_keys, // show keys
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ EXPECT_EQ(level, supplicant_->getDebugLevel());
+}
+
+/*
+ * IsDebugShowTimestampEnabled
+ */
+TEST_F(SupplicantHidlTest, IsDebugShowTimestampEnabled) {
+ bool show_timestamp = true;
+ bool show_keys = true;
+ ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+ supplicant_->setDebugParams(level,
+ show_timestamp, // show timestamps
+ show_keys, // show keys
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ EXPECT_EQ(show_timestamp, supplicant_->isDebugShowTimestampEnabled());
+}
+
+/*
+ * IsDebugShowKeysEnabled
+ */
+TEST_F(SupplicantHidlTest, IsDebugShowKeysEnabled) {
+ bool show_timestamp = true;
+ bool show_keys = true;
+ ISupplicant::DebugLevel level = ISupplicant::DebugLevel::EXCESSIVE;
+
+ supplicant_->setDebugParams(level,
+ show_timestamp, // show timestamps
+ show_keys, // show keys
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ EXPECT_EQ(show_keys, supplicant_->isDebugShowKeysEnabled());
+}
+
+/*
+ * SetConcurrenyPriority
+ */
+TEST_F(SupplicantHidlTest, SetConcurrencyPriority) {
+ supplicant_->setConcurrencyPriority(
+ IfaceType::STA, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ supplicant_->setConcurrencyPriority(
+ IfaceType::P2P, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
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 fdee0c6..1fcfc8c 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
@@ -17,9 +17,9 @@
#include <android-base/logging.h>
#include <VtsHalHidlTargetTestBase.h>
-#include <hidl/HidlTransportSupport.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
+#include <hidl/HidlTransportSupport.h>
#include <wifi_hal/driver_tool.h>
#include <wifi_system/interface_tool.h>
@@ -174,7 +174,7 @@
}
sp<ISupplicant> getSupplicant() {
- return getService<ISupplicant>(kSupplicantServiceName);
+ return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>();
}
sp<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 332b57b..72a3c42 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
@@ -18,8 +18,144 @@
#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
+
#include "supplicant_hidl_test_utils.h"
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+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;
+
+namespace {
+constexpr uint8_t kTestSsidPostfix[] = {'t', 'e', 's', 't'};
+constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+constexpr uint8_t kTestPeerMacAddr[] = {0x56, 0x67, 0x55, 0xf4, 0x56, 0x92};
+constexpr char kTestConnectPin[] = "34556665";
+constexpr char kTestGroupIfName[] = "TestGroup";
+constexpr uint32_t kTestConnectGoIntent = 6;
+constexpr uint32_t kTestFindTimeout = 5;
+constexpr SupplicantNetworkId kTestNetworkId = 5;
+constexpr uint32_t kTestChannel = 1;
+constexpr uint32_t kTestOperatingClass = 81;
+constexpr uint32_t kTestFreqRange[] = {2412, 2432};
+constexpr uint32_t kTestExtListenPeriod = 400;
+constexpr uint32_t kTestExtListenInterval = 400;
+} // namespace
+
+class SupplicantP2pIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ startSupplicantAndWaitForHidlService();
+ EXPECT_TRUE(turnOnExcessiveLogging());
+ p2p_iface_ = getSupplicantP2pIface();
+ 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(); }
+
+ protected:
+ // 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_;
+};
+
+class IfaceCallback : public ISupplicantP2pIfaceCallback {
+ Return<void> onNetworkAdded(uint32_t /* id */) override { return Void(); }
+ Return<void> onNetworkRemoved(uint32_t /* id */) override { return Void(); }
+ Return<void> onDeviceFound(
+ const hidl_array<uint8_t, 6>& /* srcAddress */,
+ const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+ const hidl_array<uint8_t, 8>& /* primaryDeviceType */,
+ const hidl_string& /* deviceName */, uint16_t /* configMethods */,
+ uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */,
+ const hidl_array<uint8_t, 6>& /* wfdDeviceInfo */) override {
+ return Void();
+ }
+ Return<void> onDeviceLost(
+ const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+ return Void();
+ }
+ Return<void> onFindStopped() override { return Void(); }
+ Return<void> onGoNegotiationRequest(
+ const hidl_array<uint8_t, 6>& /* srcAddress */,
+ ISupplicantP2pIfaceCallback::WpsDevPasswordId /* passwordId */)
+ override {
+ return Void();
+ }
+ Return<void> onGoNegotiationCompleted(
+ ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override {
+ return Void();
+ }
+ Return<void> onGroupFormationSuccess() override { return Void(); }
+ Return<void> onGroupFormationFailure(
+ const hidl_string& /* failureReason */) override {
+ return Void();
+ }
+ Return<void> onGroupStarted(
+ const hidl_string& /* groupIfname */, bool /* isGo */,
+ const hidl_vec<uint8_t>& /* ssid */, uint32_t /* frequency */,
+ const hidl_array<uint8_t, 32>& /* psk */,
+ const hidl_string& /* passphrase */,
+ const hidl_array<uint8_t, 6>& /* goDeviceAddress */,
+ bool /* isPersistent */) override {
+ return Void();
+ }
+ Return<void> onGroupRemoved(const hidl_string& /* groupIfname */,
+ bool /* isGo */) override {
+ return Void();
+ }
+ Return<void> onInvitationReceived(
+ const hidl_array<uint8_t, 6>& /* srcAddress */,
+ const hidl_array<uint8_t, 6>& /* goDeviceAddress */,
+ const hidl_array<uint8_t, 6>& /* bssid */,
+ uint32_t /* persistentNetworkId */,
+ uint32_t /* operatingFrequency */) override {
+ return Void();
+ }
+ Return<void> onInvitationResult(
+ const hidl_array<uint8_t, 6>& /* bssid */,
+ ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override {
+ return Void();
+ }
+ Return<void> onProvisionDiscoveryCompleted(
+ const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+ bool /* isRequest */,
+ ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode /* status */,
+ uint16_t /* configMethods */,
+ const hidl_string& /* generatedPin */) override {
+ return Void();
+ }
+ Return<void> onServiceDiscoveryResponse(
+ const hidl_array<uint8_t, 6>& /* srcAddress */,
+ uint16_t /* updateIndicator */,
+ const hidl_vec<uint8_t>& /* tlvs */) override {
+ return Void();
+ }
+ Return<void> onStaAuthorized(
+ const hidl_array<uint8_t, 6>& /* srcAddress */,
+ const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+ return Void();
+ }
+ Return<void> onStaDeauthorized(
+ const hidl_array<uint8_t, 6>& /* srcAddress */,
+ const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+ return Void();
+ }
+};
+
/*
* Create:
* Ensures that an instance of the ISupplicantP2pIface proxy object is
@@ -30,3 +166,248 @@
EXPECT_NE(nullptr, getSupplicantP2pIface().get());
stopSupplicant();
}
+
+/*
+ * RegisterCallback
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, RegisterCallback) {
+ p2p_iface_->registerCallback(
+ new IfaceCallback(), [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * GetDeviceAddress
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetDeviceAddress) {
+ p2p_iface_->getDeviceAddress(
+ [](const SupplicantStatus& status,
+ const hidl_array<uint8_t, 6>& /* mac_addr */) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetSsidPostfix
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetSsidPostfix) {
+ std::vector<uint8_t> ssid(kTestSsidPostfix,
+ kTestSsidPostfix + sizeof(kTestSsidPostfix));
+ p2p_iface_->setSsidPostfix(ssid, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * Find
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Find) {
+ p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * StopFind
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, StopFind) {
+ p2p_iface_->find(kTestFindTimeout, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+
+ p2p_iface_->stopFind([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+
+ p2p_iface_->stopFind([](const SupplicantStatus& status) {
+ EXPECT_NE(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * Flush
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Flush) {
+ p2p_iface_->flush([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * Connect
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Connect) {
+ p2p_iface_->connect(
+ mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
+ kTestConnectPin, false, false, kTestConnectGoIntent,
+ [](const SupplicantStatus& status, const hidl_string& /* pin */) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * CancelConnect
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, CancelConnect) {
+ p2p_iface_->connect(
+ mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
+ kTestConnectPin, false, false, kTestConnectGoIntent,
+ [](const SupplicantStatus& status, const hidl_string& /* pin */) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+
+ p2p_iface_->cancelConnect([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * ProvisionDiscovery
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, ProvisionDiscovery) {
+ p2p_iface_->provisionDiscovery(
+ mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
+ [](const SupplicantStatus& status) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * AddGroup
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, AddGroup) {
+ p2p_iface_->addGroup(false, kTestNetworkId,
+ [](const SupplicantStatus& /* status */) {
+ // TODO: Figure out the initialization sequence for
+ // this to work.
+ // EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ // status.code);
+ });
+}
+
+/*
+ * Reject
+ */
+TEST_F(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);
+ });
+}
+
+/*
+ * Invite
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Invite) {
+ p2p_iface_->invite(kTestGroupIfName, mac_addr_, peer_mac_addr_,
+ [](const SupplicantStatus& status) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN,
+ status.code);
+ });
+}
+
+/*
+ * Reinvoke
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, Reinvoke) {
+ p2p_iface_->reinvoke(
+ kTestNetworkId, mac_addr_, [](const SupplicantStatus& status) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
+ status.code);
+ });
+}
+
+/*
+ * ConfigureExtListen
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, ConfigureExtListen) {
+ p2p_iface_->configureExtListen(kTestExtListenPeriod, kTestExtListenInterval,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+}
+
+/*
+ * SetListenChannel
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetListenChannel) {
+ p2p_iface_->setListenChannel(
+ kTestChannel, kTestOperatingClass, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetDisallowedFrequencies
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetDisallowedFrequencies) {
+ std::vector<ISupplicantP2pIface::FreqRange> ranges = {
+ {kTestFreqRange[0], kTestFreqRange[1]}};
+ p2p_iface_->setDisallowedFrequencies(
+ ranges, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * GetSsid
+ */
+TEST_F(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,
+ const hidl_vec<uint8_t>& /* ssid */) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * GetGroupCapability
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, GetGroupCapability) {
+ std::array<uint8_t, 6> mac_addr;
+ memcpy(mac_addr.data(), kTestMacAddr, mac_addr.size());
+ p2p_iface_->getGroupCapability(
+ mac_addr, [](const SupplicantStatus& status, uint32_t /* caps */) {
+ // This is not going to work with fake values.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * FlushServices
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, FlushServices) {
+ p2p_iface_->flushServices([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetMiracastMode
+ */
+TEST_F(SupplicantP2pIfaceHidlTest, SetMiracastMode) {
+ p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::DISABLED,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::SOURCE,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ p2p_iface_->setMiracastMode(ISupplicantP2pIface::MiracastMode::SINK,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+}
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 c50539b..c2a58b6 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
@@ -18,8 +18,122 @@
#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
+
#include "supplicant_hidl_test_utils.h"
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+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;
+
+namespace {
+constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+constexpr ISupplicantStaIface::AnqpInfoId kTestAnqpInfoIds[] = {
+ ISupplicantStaIface::AnqpInfoId::VENUE_NAME,
+ ISupplicantStaIface::AnqpInfoId::NAI_REALM,
+ ISupplicantStaIface::AnqpInfoId::DOMAIN_NAME};
+constexpr ISupplicantStaIface::Hs20AnqpSubtypes kTestHs20Types[] = {
+ ISupplicantStaIface::Hs20AnqpSubtypes::WAN_METRICS,
+ ISupplicantStaIface::Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME};
+constexpr char kTestHs20IconFile[] = "TestFile";
+constexpr int8_t kTestCountryCode[] = {'U', 'S'};
+} // namespace
+
+class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ startSupplicantAndWaitForHidlService();
+ EXPECT_TRUE(turnOnExcessiveLogging());
+ sta_iface_ = getSupplicantStaIface();
+ ASSERT_NE(sta_iface_.get(), nullptr);
+
+ memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
+ }
+
+ virtual void TearDown() override { stopSupplicant(); }
+
+ protected:
+ // 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_;
+};
+
+class IfaceCallback : public ISupplicantStaIfaceCallback {
+ Return<void> onNetworkAdded(uint32_t /* id */) override { return Void(); }
+ Return<void> onNetworkRemoved(uint32_t /* id */) override { return Void(); }
+ Return<void> onStateChanged(
+ ISupplicantStaIfaceCallback::State /* newState */,
+ const hidl_array<uint8_t, 6>& /*bssid */, uint32_t /* id */,
+ const hidl_vec<uint8_t>& /* ssid */) override {
+ return Void();
+ }
+ Return<void> onAnqpQueryDone(
+ const hidl_array<uint8_t, 6>& /* bssid */,
+ const ISupplicantStaIfaceCallback::AnqpData& /* data */,
+ const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */)
+ override {
+ return Void();
+ }
+ virtual Return<void> onHs20IconQueryDone(
+ const hidl_array<uint8_t, 6>& /* bssid */,
+ const hidl_string& /* fileName */,
+ const hidl_vec<uint8_t>& /* data */) override {
+ return Void();
+ }
+ virtual Return<void> onHs20SubscriptionRemediation(
+ const hidl_array<uint8_t, 6>& /* bssid */,
+ ISupplicantStaIfaceCallback::OsuMethod /* osuMethod */,
+ const hidl_string& /* url*/) override {
+ return Void();
+ }
+ Return<void> onHs20DeauthImminentNotice(
+ const hidl_array<uint8_t, 6>& /* bssid */, uint32_t /* reasonCode */,
+ uint32_t /* reAuthDelayInSec */,
+ const hidl_string& /* url */) override {
+ return Void();
+ }
+ Return<void> onDisconnected(const hidl_array<uint8_t, 6>& /* bssid */,
+ bool /* locallyGenerated */,
+ uint32_t /* reasonCode */) override {
+ return Void();
+ }
+ Return<void> onAssociationRejected(
+ const hidl_array<uint8_t, 6>& /* bssid */, uint32_t /* statusCode */,
+ bool /*timedOut */) override {
+ return Void();
+ }
+ Return<void> onAuthenticationTimeout(
+ const hidl_array<uint8_t, 6>& /* bssid */) override {
+ return Void();
+ }
+ Return<void> onEapFailure() override { return Void(); }
+ Return<void> onWpsEventSuccess() override { return Void(); }
+ Return<void> onWpsEventFail(
+ const hidl_array<uint8_t, 6>& /* bssid */,
+ ISupplicantStaIfaceCallback::WpsConfigError /* configError */,
+ ISupplicantStaIfaceCallback::WpsErrorIndication /* errorInd */)
+ override {
+ return Void();
+ }
+ Return<void> onWpsEventPbcOverlap() override { return Void(); }
+ Return<void> onExtRadioWorkStart(uint32_t /* id */) override {
+ return Void();
+ }
+ Return<void> onExtRadioWorkTimeout(uint32_t /* id*/) override {
+ return Void();
+ }
+};
+
/*
* Create:
* Ensures that an instance of the ISupplicantStaIface proxy object is
@@ -30,3 +144,257 @@
EXPECT_NE(nullptr, getSupplicantStaIface().get());
stopSupplicant();
}
+
+/*
+ * RegisterCallback
+ */
+TEST_F(SupplicantStaIfaceHidlTest, RegisterCallback) {
+ sta_iface_->registerCallback(
+ new IfaceCallback(), [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * listNetworks.
+ */
+TEST_F(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();
+ EXPECT_NE(nullptr, sta_network.get());
+
+ sta_iface_->listNetworks([](const SupplicantStatus& status,
+ const hidl_vec<SupplicantNetworkId>& ids) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_LT(0u, ids.size());
+ });
+}
+
+/*
+ * Reassociate.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, Reassociate) {
+ sta_iface_->reassociate([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * Reconnect.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, Reconnect) {
+ sta_iface_->reconnect([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
+ status.code);
+ });
+}
+
+/*
+ * Disconnect.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, Disconnect) {
+ sta_iface_->disconnect([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetPowerSave.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetPowerSave) {
+ sta_iface_->setPowerSave(true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_iface_->setPowerSave(false, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * InitiateTdlsDiscover.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsDiscover) {
+ sta_iface_->initiateTdlsDiscover(
+ mac_addr_, [](const SupplicantStatus& status) {
+ // These requests will fail unless the MAC address mentioned is
+ // actually around.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * InitiateTdlsSetup.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsSetup) {
+ sta_iface_->initiateTdlsSetup(
+ mac_addr_, [](const SupplicantStatus& status) {
+ // These requests will fail unless the MAC address mentioned is
+ // actually around.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * InitiateTdlsTeardown.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateTdlsTeardown) {
+ sta_iface_->initiateTdlsTeardown(
+ mac_addr_, [](const SupplicantStatus& status) {
+ // These requests will fail unless the MAC address mentioned is
+ // actually around.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * InitiateAnqpQuery.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateAnqpQuery) {
+ std::vector<ISupplicantStaIface::AnqpInfoId> anqp_ids(
+ kTestAnqpInfoIds, kTestAnqpInfoIds + sizeof(kTestAnqpInfoIds));
+ std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> hs_types(
+ kTestHs20Types, kTestHs20Types + sizeof(kTestHs20Types));
+ sta_iface_->initiateAnqpQuery(
+ mac_addr_, anqp_ids, hs_types, [](const SupplicantStatus& status) {
+ // These requests will fail unless the BSSID mentioned is actually
+ // present in scan results.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * InitiateHs20IconQuery.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, InitiateHs20IconQuery) {
+ sta_iface_->initiateHs20IconQuery(
+ mac_addr_, kTestHs20IconFile, [](const SupplicantStatus& status) {
+ // These requests will fail unless the BSSID mentioned is actually
+ // present in scan results.
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+ });
+}
+
+/*
+ * GetMacAddress.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetMacAddress) {
+ sta_iface_->getMacAddress([](const SupplicantStatus& status,
+ const hidl_array<uint8_t, 6>& mac_addr) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ std::array<uint8_t, 6> std_mac_addr(mac_addr);
+ EXPECT_GT(6, std::count(std_mac_addr.begin(), std_mac_addr.end(), 0));
+ });
+}
+
+/*
+ * StartRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, StartRxFilter) {
+ sta_iface_->startRxFilter([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * StopRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, StopRxFilter) {
+ sta_iface_->stopRxFilter([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * AddRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, AddRxFilter) {
+ sta_iface_->addRxFilter(ISupplicantStaIface::RxFilterType::V4_MULTICAST,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ sta_iface_->addRxFilter(ISupplicantStaIface::RxFilterType::V6_MULTICAST,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+}
+
+/*
+ * RemoveRxFilter.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, RemoveRxFilter) {
+ sta_iface_->removeRxFilter(ISupplicantStaIface::RxFilterType::V4_MULTICAST,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+ sta_iface_->removeRxFilter(ISupplicantStaIface::RxFilterType::V6_MULTICAST,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS,
+ status.code);
+ });
+}
+
+/*
+ * SetBtCoexistenceMode.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetBtCoexistenceMode) {
+ sta_iface_->setBtCoexistenceMode(
+ ISupplicantStaIface::BtCoexistenceMode::ENABLED,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_iface_->setBtCoexistenceMode(
+ ISupplicantStaIface::BtCoexistenceMode::DISABLED,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_iface_->setBtCoexistenceMode(
+ ISupplicantStaIface::BtCoexistenceMode::SENSE,
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetBtCoexistenceScanModeEnabled.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetBtCoexistenceScanModeEnabled) {
+ sta_iface_->setBtCoexistenceScanModeEnabled(
+ true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_iface_->setBtCoexistenceScanModeEnabled(
+ false, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetSuspendModeEnabled.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetSuspendModeEnabled) {
+ sta_iface_->setSuspendModeEnabled(true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_iface_->setSuspendModeEnabled(
+ false, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SetCountryCode.
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetCountryCode) {
+ sta_iface_->setCountryCode(
+ kTestCountryCode, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
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 cde75fa..aa84e9a 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
@@ -18,8 +18,104 @@
#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+
#include "supplicant_hidl_test_utils.h"
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+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;
+
+namespace {
+constexpr char kTestSsidStr[] = "TestSsid1234";
+constexpr char kTestPsk[] = "TestPsk123";
+constexpr char kTestIdStr[] = "TestIdstr";
+constexpr char kTestEapPasswdStr[] = "TestEapPasswd1234";
+constexpr char kTestEapCert[] = "keystore://CERT";
+constexpr char kTestEapPrivateKeyId[] = "key_id";
+constexpr char kTestEapMatch[] = "match";
+constexpr char kTestEapEngineID[] = "engine_id";
+constexpr uint8_t kTestBssid[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+constexpr uint8_t kTestWepKey[] = {0x56, 0x67, 0x67, 0xf4, 0x56};
+constexpr uint8_t kTestKc[] = {0x56, 0x67, 0x67, 0xf4, 0x76, 0x87, 0x98, 0x12};
+constexpr uint8_t kTestSres[] = {0x56, 0x67, 0x67, 0xf4};
+constexpr uint8_t kTestRes[] = {0x56, 0x67, 0x67, 0xf4, 0x67};
+constexpr uint8_t kTestIk[] = {[0 ... 15] = 0x65};
+constexpr uint8_t kTestCk[] = {[0 ... 15] = 0x45};
+constexpr uint8_t kTestIdentity[] = {0x45, 0x67, 0x98, 0x67, 0x56};
+constexpr uint32_t kTestWepTxKeyIdx = 2;
+constexpr uint32_t kTestKeyMgmt = (ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK |
+ ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP);
+constexpr uint32_t kTestProto = (ISupplicantStaNetwork::ProtoMask::OSEN |
+ ISupplicantStaNetwork::ProtoMask::RSN);
+constexpr uint32_t kTestAuthAlg = (ISupplicantStaNetwork::AuthAlgMask::OPEN |
+ ISupplicantStaNetwork::AuthAlgMask::SHARED);
+constexpr uint32_t kTestGroupCipher =
+ (ISupplicantStaNetwork::GroupCipherMask::CCMP |
+ ISupplicantStaNetwork::GroupCipherMask::WEP104);
+constexpr uint32_t kTestPairwiseCipher =
+ (ISupplicantStaNetwork::PairwiseCipherMask::CCMP |
+ ISupplicantStaNetwork::PairwiseCipherMask::TKIP);
+} // namespace
+
+class SupplicantStaNetworkHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ startSupplicantAndWaitForHidlService();
+ EXPECT_TRUE(turnOnExcessiveLogging());
+ sta_network_ = createSupplicantStaNetwork();
+ ASSERT_NE(sta_network_.get(), nullptr);
+
+ ssid_.assign(kTestSsidStr, kTestSsidStr + strlen(kTestSsidStr));
+ }
+
+ virtual void TearDown() override { stopSupplicant(); }
+
+ 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);
+ });
+ }
+
+ // ISupplicantStaNetwork object used for all tests in this fixture.
+ sp<ISupplicantStaNetwork> sta_network_;
+ // SSID to use for various tests.
+ std::vector<uint8_t> ssid_;
+};
+
+class NetworkCallback : public ISupplicantStaNetworkCallback {
+ Return<void> onNetworkEapSimGsmAuthRequest(
+ const ISupplicantStaNetworkCallback::NetworkRequestEapSimGsmAuthParams&
+ /* params */) override {
+ return Void();
+ }
+ Return<void> onNetworkEapSimUmtsAuthRequest(
+ const ISupplicantStaNetworkCallback::NetworkRequestEapSimUmtsAuthParams&
+ /* params */) override {
+ return Void();
+ }
+ Return<void> onNetworkEapIdentityRequest() override { return Void(); }
+};
+
/*
* Create:
* Ensures that an instance of the ISupplicantStaNetwork proxy object is
@@ -30,3 +126,535 @@
EXPECT_NE(nullptr, createSupplicantStaNetwork().get());
stopSupplicant();
}
+
+/*
+ * RegisterCallback
+ */
+TEST_F(SupplicantStaNetworkHidlTest, RegisterCallback) {
+ sta_network_->registerCallback(
+ new NetworkCallback(), [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/* Tests out the various setter/getter methods. */
+/*
+ * SetGetSsid
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetSsid) {
+ sta_network_->setSsid(ssid_, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getSsid(
+ [&](const SupplicantStatus& status, const hidl_vec<uint8_t>& get_ssid) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(ssid_, std::vector<uint8_t>(get_ssid));
+ });
+}
+
+/*
+ * SetGetBssid
+ */
+TEST_F(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) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getBssid([&](const SupplicantStatus& status,
+ const hidl_array<uint8_t, 6>& get_bssid_hidl) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ std::array<uint8_t, 6> get_bssid;
+ memcpy(get_bssid.data(), get_bssid_hidl.data(), get_bssid.size());
+ EXPECT_EQ(set_bssid, get_bssid);
+ });
+}
+
+/*
+ * SetGetKeyMgmt
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetKeyMgmt) {
+ sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getKeyMgmt(
+ [&](const SupplicantStatus& status, uint32_t key_mgmt) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(key_mgmt, kTestKeyMgmt);
+ });
+}
+
+/*
+ * SetGetProto
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetProto) {
+ sta_network_->setProto(kTestProto, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getProto([&](const SupplicantStatus& status, uint32_t proto) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(proto, kTestProto);
+ });
+}
+
+/*
+ * SetGetKeyAuthAlg
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetAuthAlg) {
+ sta_network_->setAuthAlg(kTestAuthAlg, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getAuthAlg(
+ [&](const SupplicantStatus& status, uint32_t auth_alg) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(auth_alg, kTestAuthAlg);
+ });
+}
+
+/*
+ * SetGetGroupCipher
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetGroupCipher) {
+ sta_network_->setGroupCipher(
+ kTestGroupCipher, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getGroupCipher(
+ [&](const SupplicantStatus& status, uint32_t group_cipher) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(group_cipher, kTestGroupCipher);
+ });
+}
+
+/*
+ * SetGetPairwiseCipher
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetPairwiseCipher) {
+ sta_network_->setPairwiseCipher(
+ kTestPairwiseCipher, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getPairwiseCipher(
+ [&](const SupplicantStatus& status, uint32_t pairwise_cipher) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(pairwise_cipher, kTestPairwiseCipher);
+ });
+}
+
+/*
+ * SetGetPskPassphrase
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetPskPassphrase) {
+ sta_network_->setPskPassphrase(
+ kTestPsk, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getPskPassphrase(
+ [&](const SupplicantStatus& status, const hidl_string& psk) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestPsk, std::string(psk.c_str()));
+ });
+}
+
+/*
+ * SetGetWepKeys
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetWepTxKeyIdx) {
+ sta_network_->setWepTxKeyIdx(
+ kTestWepTxKeyIdx, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getWepTxKeyIdx(
+ [&](const SupplicantStatus& status, uint32_t key_idx) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestWepTxKeyIdx, key_idx);
+ });
+}
+
+/*
+ * SetGetWepKeys
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetWepKeys) {
+ for (uint32_t i = 0;
+ i < static_cast<uint32_t>(
+ ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM);
+ i++) {
+ std::vector<uint8_t> set_wep_key(std::begin(kTestWepKey),
+ std::end(kTestWepKey));
+ sta_network_->setWepKey(
+ i, set_wep_key, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getWepKey(i, [&](const SupplicantStatus& status,
+ const hidl_vec<uint8_t>& get_wep_key) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(set_wep_key, std::vector<uint8_t>(get_wep_key));
+ });
+ }
+}
+
+/*
+ * SetGetScanSsid
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetScanSsid) {
+ sta_network_->setScanSsid(
+ true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getScanSsid(
+ [&](const SupplicantStatus& status, bool scan_ssid) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(true, scan_ssid);
+ });
+}
+
+/*
+ * SetGetRequirePmf
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetRequirePmf) {
+ sta_network_->setRequirePmf(
+ true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getRequirePmf(
+ [&](const SupplicantStatus& status, bool require_pmf) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(true, require_pmf);
+ });
+}
+
+/*
+ * SetGetIdStr
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetIdStr) {
+ sta_network_->setIdStr(
+ kTestIdStr, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getIdStr(
+ [&](const SupplicantStatus& status, const hidl_string& id_str) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestIdStr, std::string(id_str.c_str()));
+ });
+}
+
+
+/*
+ * SetGetEapMethod
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapMethod) {
+ ISupplicantStaNetwork::EapMethod set_eap_method =
+ ISupplicantStaNetwork::EapMethod::PEAP;
+ sta_network_->setEapMethod(
+ set_eap_method, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapMethod(
+ [&](const SupplicantStatus& status,
+ ISupplicantStaNetwork::EapMethod eap_method) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(set_eap_method, eap_method);
+ });
+}
+
+/*
+ * SetGetEapPhase2Method
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPhase2Method) {
+ ISupplicantStaNetwork::EapPhase2Method set_eap_phase2_method =
+ ISupplicantStaNetwork::EapPhase2Method::NONE;
+ sta_network_->setEapPhase2Method(
+ set_eap_phase2_method, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapPhase2Method(
+ [&](const SupplicantStatus& status,
+ ISupplicantStaNetwork::EapPhase2Method eap_phase2_method) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(set_eap_phase2_method, eap_phase2_method);
+ });
+}
+
+/*
+ * SetGetEapIdentity
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapIdentity) {
+ std::vector<uint8_t> set_identity(kTestIdentity, kTestIdentity + sizeof(kTestIdentity));
+ sta_network_->setEapIdentity(
+ set_identity, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapIdentity(
+ [&](const SupplicantStatus& status, const std::vector<uint8_t>& identity) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(set_identity, identity);
+ });
+}
+
+/*
+ * SetGetEapAnonymousIdentity
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapAnonymousIdentity) {
+ std::vector<uint8_t> set_identity(kTestIdentity, kTestIdentity + sizeof(kTestIdentity));
+ sta_network_->setEapAnonymousIdentity(
+ set_identity, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapAnonymousIdentity(
+ [&](const SupplicantStatus& status, const std::vector<uint8_t>& identity) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(set_identity, identity);
+ });
+}
+
+/*
+ * SetGetEapPassword
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPassword) {
+ std::vector<uint8_t> set_eap_passwd(
+ kTestEapPasswdStr, kTestEapPasswdStr + strlen(kTestEapPasswdStr));
+ sta_network_->setEapPassword(
+ set_eap_passwd, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapPassword([&](const SupplicantStatus& status,
+ const hidl_vec<uint8_t>& eap_passwd) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(set_eap_passwd, std::vector<uint8_t>(eap_passwd));
+ });
+}
+
+/*
+ * SetGetEapCACert
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapCACert) {
+ sta_network_->setEapCACert(
+ kTestEapCert, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapCACert([&](const SupplicantStatus& status,
+ const hidl_string& eap_cert) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapCert, std::string(eap_cert.c_str()));
+ });
+}
+
+/*
+ * SetGetEapCAPath
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapCAPath) {
+ sta_network_->setEapCAPath(
+ kTestEapCert, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapCAPath([&](const SupplicantStatus& status,
+ const hidl_string& eap_cert) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapCert, std::string(eap_cert.c_str()));
+ });
+}
+
+/*
+ * SetGetEapClientCert
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapClientCert) {
+ sta_network_->setEapClientCert(
+ kTestEapCert, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapClientCert([&](const SupplicantStatus& status,
+ const hidl_string& eap_cert) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapCert, std::string(eap_cert.c_str()));
+ });
+}
+
+/*
+ * SetGetEapPrivateKeyId
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapPrivateKeyId) {
+ sta_network_->setEapPrivateKeyId(
+ kTestEapPrivateKeyId, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapPrivateKeyId([&](const SupplicantStatus& status,
+ const hidl_string& key_id) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapPrivateKeyId, std::string(key_id.c_str()));
+ });
+}
+
+/*
+ * SetGetEapAltSubjectMatch
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapAltSubjectMatch) {
+ sta_network_->setEapAltSubjectMatch(
+ kTestEapMatch, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapAltSubjectMatch([&](const SupplicantStatus& status,
+ const hidl_string& match) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapMatch, std::string(match.c_str()));
+ });
+}
+
+/*
+ * SetGetEapDomainSuffixMatch
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapDomainSuffixMatch) {
+ sta_network_->setEapDomainSuffixMatch(
+ kTestEapMatch, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapDomainSuffixMatch([&](const SupplicantStatus& status,
+ const hidl_string& match) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapMatch, std::string(match.c_str()));
+ });
+}
+
+/*
+ * SetGetEapEngine
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapEngine) {
+ sta_network_->setEapEngine(
+ true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapEngine([&](const SupplicantStatus& status,
+ bool enable) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(true, enable);
+ });
+}
+
+/*
+ * SetGetEapEngineID
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SetGetEapEngineID) {
+ sta_network_->setEapEngineID(
+ kTestEapEngineID, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->getEapEngineID([&](const SupplicantStatus& status,
+ const hidl_string& id) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(kTestEapEngineID, std::string(id.c_str()));
+ });
+}
+
+/*
+ * Enable
+ */
+TEST_F(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) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+
+ sta_network_->enable(false, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->enable(true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+
+ // Now remove the network and ensure that the calls fail.
+ removeNetwork();
+ sta_network_->enable(true, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_INVALID, status.code);
+ });
+}
+
+/*
+ * Disable
+ */
+TEST_F(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) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+
+ sta_network_->disable([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ // Now remove the network and ensure that the calls fail.
+ removeNetwork();
+ sta_network_->disable([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_INVALID, status.code);
+ });
+}
+
+/*
+ * Select.
+ */
+TEST_F(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) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ sta_network_->setKeyMgmt(kTestKeyMgmt, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+
+ sta_network_->select([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+ // Now remove the network and ensure that the calls fail.
+ removeNetwork();
+ sta_network_->select([](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::FAILURE_NETWORK_INVALID, status.code);
+ });
+}
+
+/*
+ * SendNetworkEapSimGsmAuthResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimGsmAuthResponse) {
+ std::vector<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
+ params;
+ ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams param;
+ memcpy(param.kc.data(), kTestKc, param.kc.size());
+ memcpy(param.sres.data(), kTestSres, param.sres.size());
+ params.push_back(param);
+ sta_network_->sendNetworkEapSimGsmAuthResponse(
+ params, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SendNetworkEapSimUmtsAuthResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapSimUmtsAuthResponse) {
+ ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams params;
+ params.res = std::vector<uint8_t>(kTestRes, kTestRes + sizeof(kTestRes));
+ memcpy(params.ik.data(), kTestIk, params.ik.size());
+ memcpy(params.ck.data(), kTestCk, params.ck.size());
+ sta_network_->sendNetworkEapSimUmtsAuthResponse(
+ params, [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * SendNetworkEapIdentityResponse
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse) {
+ sta_network_->sendNetworkEapIdentityResponse(
+ std::vector<uint8_t>(kTestIdentity,
+ kTestIdentity + sizeof(kTestIdentity)),
+ [](const SupplicantStatus& status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}