Merge "Use std::unordered_map for mTagToTypeMap"
diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk
index 12713d3..edf1761 100644
--- a/audio/2.0/default/Android.mk
+++ b/audio/2.0/default/Android.mk
@@ -31,6 +31,7 @@
LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := \
+ libbinder \
libhidlbase \
libhidltransport \
liblog \
diff --git a/audio/2.0/default/service.cpp b/audio/2.0/default/service.cpp
index 3cf7134..d554481 100644
--- a/audio/2.0/default/service.cpp
+++ b/audio/2.0/default/service.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
#include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
+#include <binder/ProcessState.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/LegacySupport.h>
@@ -36,6 +37,9 @@
using android::OK;
int main(int /* argc */, char* /* argv */ []) {
+ android::ProcessState::initWithDriver("/dev/vndbinder");
+ // start a threadpool for vndbinder interactions
+ android::ProcessState::self()->startThreadPool();
configureRpcThreadpool(16, true /*callerWillJoin*/);
android::status_t status;
status = registerPassthroughServiceImplementation<IDevicesFactory>();
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index b9f505d..bf8b547 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -90,13 +90,15 @@
#define EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES 2
#define ACL_BROADCAST_FLAG_OFFSET 6
-#define ACL_BROADCAST_FLAG_ACTIVE_SLAVE 0x1
-#define ACL_BROADCAST_ACTIVE_SLAVE (ACL_BROADCAST_FLAG_ACTIVE_SLAVE << ACL_BROADCAST_FLAG_OFFSET)
+#define ACL_BROADCAST_FLAG_POINT_TO_POINT 0x0
+#define ACL_BROADCAST_POINT_TO_POINT \
+ (ACL_BROADCAST_FLAG_POINT_TO_POINT << ACL_BROADCAST_FLAG_OFFSET)
#define ACL_PACKET_BOUNDARY_FLAG_OFFSET 4
-#define ACL_PACKET_BOUNDARY_FLAG_COMPLETE 0x3
-#define ACL_PACKET_BOUNDARY_COMPLETE \
- (ACL_PACKET_BOUNDARY_FLAG_COMPLETE << ACL_PACKET_BOUNDARY_FLAG_OFFSET)
+#define ACL_PACKET_BOUNDARY_FLAG_FIRST_AUTO_FLUSHABLE 0x2
+#define ACL_PACKET_BOUNDARY_FIRST_AUTO_FLUSHABLE \
+ (ACL_PACKET_BOUNDARY_FLAG_FIRST_AUTO_FLUSHABLE \
+ << ACL_PACKET_BOUNDARY_FLAG_OFFSET)
constexpr char kCallbackNameAclEventReceived[] = "aclDataReceived";
constexpr char kCallbackNameHciEventReceived[] = "hciEventReceived";
@@ -189,6 +191,7 @@
virtual void TearDown() override {
bluetooth->close();
+ handle_no_ops();
EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
@@ -204,6 +207,8 @@
// Helper functions to try to get a handle on verbosity
void enterLoopbackMode(std::vector<uint16_t>& sco_handles,
std::vector<uint16_t>& acl_handles);
+ void handle_no_ops();
+ void wait_for_event(bool timeout_is_error);
void wait_for_command_complete_event(hidl_vec<uint8_t> cmd);
int wait_for_completed_packets_event(uint16_t handle);
@@ -269,31 +274,50 @@
int max_sco_data_packets;
};
-// Receive and check status events until a COMMAND_COMPLETE is received.
-void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
- // Allow intermediate COMMAND_STATUS events
- int status_event_count = 0;
+// Discard NO-OPs from the event queue.
+void BluetoothHidlTest::handle_no_ops() {
+ while (event_queue.size() > 0) {
+ hidl_vec<uint8_t> event = event_queue.front();
+ EXPECT_GE(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ bool event_is_no_op =
+ (event[EVENT_CODE_BYTE] == EVENT_COMMAND_COMPLETE) &&
+ (event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE] == 0x00) &&
+ (event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1] == 0x00);
+ event_is_no_op |= (event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS) &&
+ (event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE] == 0x00) &&
+ (event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1] == 0x00);
+ if (event_is_no_op) {
+ event_queue.pop();
+ } else {
+ return;
+ }
+ }
+}
+
+// Receive an event, discarding NO-OPs.
+void BluetoothHidlTest::wait_for_event(bool timeout_is_error = true) {
hidl_vec<uint8_t> event;
do {
- EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
- .no_timeout);
+ bool no_timeout =
+ bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout;
+ EXPECT_TRUE(no_timeout || !timeout_is_error);
+ if (no_timeout && timeout_is_error) {
EXPECT_LT(static_cast<size_t>(0), event_queue.size());
- if (event_queue.size() == 0) {
- event.resize(0);
- break;
}
- event = event_queue.front();
- event_queue.pop();
- EXPECT_GT(event.size(),
- static_cast<size_t>(EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1));
- if (event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS) {
- EXPECT_EQ(EVENT_COMMAND_STATUS_LENGTH, event[EVENT_LENGTH_BYTE]);
- EXPECT_EQ(cmd[0], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE]);
- EXPECT_EQ(cmd[1], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1]);
- EXPECT_EQ(event[EVENT_COMMAND_STATUS_STATUS_BYTE], HCI_STATUS_SUCCESS);
- status_event_count++;
+ if (event_queue.size() == 0) {
+ // WaitForCallback timed out.
+ return;
}
- } while (event.size() > 0 && event[EVENT_CODE_BYTE] == EVENT_COMMAND_STATUS);
+ handle_no_ops();
+ } while (event_queue.size() == 0);
+}
+
+// Wait until a COMMAND_COMPLETE is received.
+void BluetoothHidlTest::wait_for_command_complete_event(hidl_vec<uint8_t> cmd) {
+ wait_for_event();
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
EXPECT_GT(event.size(),
static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
@@ -308,10 +332,7 @@
hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_BUFFER_SIZE;
bluetooth->sendHciCommand(cmd);
- EXPECT_TRUE(
- bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
-
- EXPECT_LT(static_cast<size_t>(0), event_queue.size());
+ wait_for_event();
if (event_queue.size() == 0) return;
hidl_vec<uint8_t> event = event_queue.front();
@@ -341,6 +362,7 @@
// Send an HCI command (in Loopback mode) and check the response.
void BluetoothHidlTest::sendAndCheckHCI(int num_packets) {
ThroughputLogger logger = {__func__};
+ int command_size = 0;
for (int n = 0; n < num_packets; n++) {
// Send an HCI packet
std::vector<uint8_t> write_name = COMMAND_HCI_WRITE_LOCAL_NAME;
@@ -350,11 +372,9 @@
for (size_t i = 0; i < new_name_length; i++)
write_name.push_back(static_cast<uint8_t>(new_name[i]));
// And the packet number
- {
- size_t i = new_name_length - 1;
- for (int digits = n; digits > 0; digits = digits / 10, i--)
- write_name[i] = static_cast<uint8_t>('0' + digits % 10);
- }
+ size_t i = new_name_length - 1;
+ for (int digits = n; digits > 0; digits = digits / 10, i--)
+ write_name[i] = static_cast<uint8_t>('0' + digits % 10);
// And padding
for (size_t i = 0; i < 248 - new_name_length; i++)
write_name.push_back(static_cast<uint8_t>(0));
@@ -363,8 +383,9 @@
bluetooth->sendHciCommand(cmd);
// Check the loopback of the HCI packet
- EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
- .no_timeout);
+ wait_for_event();
+ if (event_queue.size() == 0) return;
+
hidl_vec<uint8_t> event = event_queue.front();
event_queue.pop();
size_t compare_length =
@@ -374,11 +395,21 @@
EXPECT_EQ(EVENT_LOOPBACK_COMMAND, event[EVENT_CODE_BYTE]);
EXPECT_EQ(compare_length, event[EVENT_LENGTH_BYTE]);
- if (n == 0) logger.setTotalBytes(cmd.size() * num_packets * 2);
+
+ // Don't compare past the end of the event.
+ if (compare_length + EVENT_FIRST_PAYLOAD_BYTE > event.size()) {
+ compare_length = event.size() - EVENT_FIRST_PAYLOAD_BYTE;
+ ALOGE("Only comparing %d bytes", static_cast<int>(compare_length));
+ }
+
+ if (n == num_packets - 1) {
+ command_size = cmd.size();
+ }
for (size_t i = 0; i < compare_length; i++)
EXPECT_EQ(cmd[i], event[EVENT_FIRST_PAYLOAD_BYTE + i]);
}
+ logger.setTotalBytes(command_size * num_packets * 2);
}
// Send a SCO data packet (in Loopback mode) and check the response.
@@ -408,8 +439,6 @@
EXPECT_EQ(sco_packet.size(), sco_loopback.size());
size_t successful_bytes = 0;
- if (n == 0) logger.setTotalBytes(num_packets * size * 2);
-
for (size_t i = 0; i < sco_packet.size(); i++) {
if (sco_packet[i] == sco_loopback[i]) {
successful_bytes = i;
@@ -423,6 +452,7 @@
}
EXPECT_EQ(sco_packet.size(), successful_bytes + 1);
}
+ logger.setTotalBytes(num_packets * size * 2);
}
// Send an ACL data packet (in Loopback mode) and check the response.
@@ -435,8 +465,8 @@
std::vector<uint8_t> acl_vector;
acl_vector.push_back(static_cast<uint8_t>(handle & 0xff));
acl_vector.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
- ACL_BROADCAST_ACTIVE_SLAVE |
- ACL_PACKET_BOUNDARY_COMPLETE);
+ ACL_BROADCAST_POINT_TO_POINT |
+ ACL_PACKET_BOUNDARY_FIRST_AUTO_FLUSHABLE);
acl_vector.push_back(static_cast<uint8_t>(size & 0xff));
acl_vector.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
for (size_t i = 0; i < size; i++) {
@@ -454,8 +484,6 @@
EXPECT_EQ(acl_packet.size(), acl_loopback.size());
size_t successful_bytes = 0;
- if (n == 0) logger.setTotalBytes(num_packets * size * 2);
-
for (size_t i = 0; i < acl_packet.size(); i++) {
if (acl_packet[i] == acl_loopback[i]) {
successful_bytes = i;
@@ -469,25 +497,28 @@
}
EXPECT_EQ(acl_packet.size(), successful_bytes + 1);
}
+ logger.setTotalBytes(num_packets * size * 2);
}
// Return the number of completed packets reported by the controller.
int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
- if (!bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout) {
- ALOGW("%s: WaitForCallback timed out.", __func__);
- }
- int packets_processed = 0;
- while (event_queue.size() > 0) {
- hidl_vec<uint8_t> event = event_queue.front();
- event_queue.pop();
+ int packets_processed = 0;
+ wait_for_event(false);
+ if (event_queue.size() == 0) {
+ ALOGW("%s: WaitForCallback timed out.", __func__);
+ return packets_processed;
+ }
+ while (event_queue.size() > 0) {
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
- EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
- EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
+ EXPECT_EQ(EVENT_NUMBER_OF_COMPLETED_PACKETS, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(1, event[EVENT_NUMBER_OF_COMPLETED_PACKETS_NUM_HANDLES]);
- uint16_t event_handle = event[3] + (event[4] << 8);
- EXPECT_EQ(handle, event_handle);
+ uint16_t event_handle = event[3] + (event[4] << 8);
+ EXPECT_EQ(handle, event_handle);
- packets_processed += event[5] + (event[6] << 8);
+ packets_processed += event[5] + (event[6] << 8);
}
return packets_processed;
}
@@ -500,45 +531,48 @@
// Receive connection complete events with data channels
int connection_event_count = 0;
- hidl_vec<uint8_t> event;
- do {
- EXPECT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived)
- .no_timeout);
- event = event_queue.front();
- event_queue.pop();
- EXPECT_GT(event.size(),
- static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
- if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
- EXPECT_GT(event.size(),
- static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
- EXPECT_EQ(event[EVENT_LENGTH_BYTE],
- EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
- uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
-
- EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
- connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
-
- // Save handles
- uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
- event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1]
- << 8;
- if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
- sco_handles.push_back(handle);
- else
- acl_handles.push_back(handle);
-
- ALOGD("Connect complete type = %d handle = %d",
- event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
- connection_event_count++;
+ bool command_complete_received = false;
+ while (true) {
+ wait_for_event(false);
+ if (event_queue.size() == 0) {
+ // Fail if there was no event received or no connections completed.
+ EXPECT_TRUE(command_complete_received);
+ EXPECT_LT(0, connection_event_count);
+ return;
}
- } while (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE);
+ hidl_vec<uint8_t> event = event_queue.front();
+ event_queue.pop();
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ if (event[EVENT_CODE_BYTE] == EVENT_CONNECTION_COMPLETE) {
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_CONNECTION_COMPLETE_TYPE));
+ EXPECT_EQ(event[EVENT_LENGTH_BYTE],
+ EVENT_CONNECTION_COMPLETE_PARAM_LENGTH);
+ uint8_t connection_type = event[EVENT_CONNECTION_COMPLETE_TYPE];
- EXPECT_GT(connection_event_count, 0);
+ EXPECT_TRUE(connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO ||
+ connection_type == EVENT_CONNECTION_COMPLETE_TYPE_ACL);
- EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
- EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
- EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
- EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+ // Save handles
+ uint16_t handle = event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE] |
+ event[EVENT_CONNECTION_COMPLETE_HANDLE_LSBYTE + 1] << 8;
+ if (connection_type == EVENT_CONNECTION_COMPLETE_TYPE_SCO)
+ sco_handles.push_back(handle);
+ else
+ acl_handles.push_back(handle);
+
+ ALOGD("Connect complete type = %d handle = %d",
+ event[EVENT_CONNECTION_COMPLETE_TYPE], handle);
+ connection_event_count++;
+ } else {
+ EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_SUCCESS, event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+ command_complete_received = true;
+ }
+ }
}
// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
@@ -557,8 +591,8 @@
hidl_vec<uint8_t> cmd = COMMAND_HCI_READ_LOCAL_VERSION_INFORMATION;
bluetooth->sendHciCommand(cmd);
- EXPECT_TRUE(
- bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
+ wait_for_event();
+ if (event_queue.size() == 0) return;
hidl_vec<uint8_t> event = event_queue.front();
event_queue.pop();
@@ -578,19 +612,26 @@
hidl_vec<uint8_t> cmd = COMMAND_HCI_SHOULD_BE_UNKNOWN;
bluetooth->sendHciCommand(cmd);
- EXPECT_TRUE(
- bluetooth_cb->WaitForCallback(kCallbackNameHciEventReceived).no_timeout);
+ wait_for_event();
+ if (event_queue.size() == 0) return;
hidl_vec<uint8_t> event = event_queue.front();
event_queue.pop();
- EXPECT_GT(event.size(),
- static_cast<size_t>(EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1));
- EXPECT_EQ(EVENT_COMMAND_COMPLETE, event[EVENT_CODE_BYTE]);
- EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
- EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
- EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
- event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+ EXPECT_GT(event.size(),
+ static_cast<size_t>(EVENT_COMMAND_COMPLETE_STATUS_BYTE));
+ if (event[EVENT_CODE_BYTE] == EVENT_COMMAND_COMPLETE) {
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_COMPLETE_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+ event[EVENT_COMMAND_COMPLETE_STATUS_BYTE]);
+ } else {
+ EXPECT_EQ(EVENT_COMMAND_STATUS, event[EVENT_CODE_BYTE]);
+ EXPECT_EQ(cmd[0], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE]);
+ EXPECT_EQ(cmd[1], event[EVENT_COMMAND_STATUS_OPCODE_LSBYTE + 1]);
+ EXPECT_EQ(HCI_STATUS_UNKNOWN_HCI_COMMAND,
+ event[EVENT_COMMAND_STATUS_STATUS_BYTE]);
+ }
}
// Enter loopback mode, but don't send any packets.
@@ -603,8 +644,6 @@
// Enter loopback mode and send single packets.
TEST_F(BluetoothHidlTest, LoopbackModeSinglePackets) {
setBufferSizes();
- EXPECT_LT(0, max_sco_data_packet_length);
- EXPECT_LT(0, max_acl_data_packet_length);
std::vector<uint16_t> sco_connection_handles;
std::vector<uint16_t> acl_connection_handles;
@@ -615,6 +654,7 @@
// This should work, but breaks on some current platforms. Figure out how to
// grandfather older devices but test new ones.
if (0 && sco_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_sco_data_packet_length);
sendAndCheckSCO(1, max_sco_data_packet_length, sco_connection_handles[0]);
int sco_packets_sent = 1;
int completed_packets = wait_for_completed_packets_event(sco_connection_handles[0]);
@@ -625,6 +665,7 @@
}
if (acl_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_acl_data_packet_length);
sendAndCheckACL(1, max_acl_data_packet_length, acl_connection_handles[0]);
int acl_packets_sent = 1;
int completed_packets = wait_for_completed_packets_event(acl_connection_handles[0]);
@@ -648,6 +689,7 @@
// This should work, but breaks on some current platforms. Figure out how to
// grandfather older devices but test new ones.
if (0 && sco_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_sco_data_packet_length);
sendAndCheckSCO(NUM_SCO_PACKETS_BANDWIDTH, max_sco_data_packet_length,
sco_connection_handles[0]);
int sco_packets_sent = NUM_SCO_PACKETS_BANDWIDTH;
@@ -659,6 +701,7 @@
}
if (acl_connection_handles.size() > 0) {
+ EXPECT_LT(0, max_acl_data_packet_length);
sendAndCheckACL(NUM_ACL_PACKETS_BANDWIDTH, max_acl_data_packet_length,
acl_connection_handles[0]);
int acl_packets_sent = NUM_ACL_PACKETS_BANDWIDTH;
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index bb4886d..b032357 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -107,7 +107,6 @@
const camera_metadata_t *paramBuffer = nullptr;
if (0 < requestedConfiguration.sessionParams.size()) {
- ::android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams;
V3_2::implementation::convertFromHidl(requestedConfiguration.sessionParams, ¶mBuffer);
}
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 14f82bc..9a02ce8 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -638,12 +638,6 @@
}
}
- // The document in aeAvailableTargetFpsRanges section says the minFps should
- // not be larger than 15.
- // We cannot support fixed 30fps but Android requires (min, max) and
- // (max, max) ranges.
- // TODO: populate more, right now this does not support 30,30 if the device
- // has higher than 30 fps modes
std::vector<int32_t> fpsRanges;
// Variable range
fpsRanges.push_back(minFps);
@@ -693,7 +687,7 @@
#undef UPDATE
void ExternalCameraDevice::getFrameRateList(
- int fd, float fpsUpperBound, SupportedV4L2Format* format) {
+ int fd, double fpsUpperBound, SupportedV4L2Format* format) {
format->frameRates.clear();
v4l2_frmivalenum frameInterval {
@@ -715,7 +709,7 @@
if (framerate > fpsUpperBound) {
continue;
}
- ALOGI("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f",
+ ALOGV("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f",
frameInterval.index,
frameInterval.pixel_format & 0xFF,
(frameInterval.pixel_format >> 8) & 0xFF,
@@ -738,71 +732,68 @@
}
}
-CroppingType ExternalCameraDevice::initCroppingType(
- /*inout*/std::vector<SupportedV4L2Format>* pSortedFmts) {
- std::vector<SupportedV4L2Format>& sortedFmts = *pSortedFmts;
+void ExternalCameraDevice::trimSupportedFormats(
+ CroppingType cropType,
+ /*inout*/std::vector<SupportedV4L2Format>* pFmts) {
+ std::vector<SupportedV4L2Format>& sortedFmts = *pFmts;
+ if (cropType == VERTICAL) {
+ std::sort(sortedFmts.begin(), sortedFmts.end(),
+ [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+ if (a.width == b.width) {
+ return a.height < b.height;
+ }
+ return a.width < b.width;
+ });
+ } else {
+ std::sort(sortedFmts.begin(), sortedFmts.end(),
+ [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+ if (a.height == b.height) {
+ return a.width < b.width;
+ }
+ return a.height < b.height;
+ });
+ }
+
+ if (sortedFmts.size() == 0) {
+ ALOGE("%s: input format list is empty!", __FUNCTION__);
+ return;
+ }
+
const auto& maxSize = sortedFmts[sortedFmts.size() - 1];
float maxSizeAr = ASPECT_RATIO(maxSize);
- float minAr = kMaxAspectRatio;
- float maxAr = kMinAspectRatio;
+
+ // Remove formats that has aspect ratio not croppable from largest size
+ std::vector<SupportedV4L2Format> out;
for (const auto& fmt : sortedFmts) {
float ar = ASPECT_RATIO(fmt);
- if (ar < minAr) {
- minAr = ar;
- }
- if (ar > maxAr) {
- maxAr = ar;
- }
- }
-
- CroppingType ct = VERTICAL;
- if (isAspectRatioClose(maxSizeAr, maxAr)) {
- // Ex: 16:9 sensor, cropping horizontally to get to 4:3
- ct = HORIZONTAL;
- } else if (isAspectRatioClose(maxSizeAr, minAr)) {
- // Ex: 4:3 sensor, cropping vertically to get to 16:9
- ct = VERTICAL;
- } else {
- ALOGI("%s: camera maxSizeAr %f is not close to minAr %f or maxAr %f",
- __FUNCTION__, maxSizeAr, minAr, maxAr);
- if ((maxSizeAr - minAr) < (maxAr - maxSizeAr)) {
- ct = VERTICAL;
+ if (isAspectRatioClose(ar, maxSizeAr)) {
+ out.push_back(fmt);
+ } else if (cropType == HORIZONTAL && ar < maxSizeAr) {
+ out.push_back(fmt);
+ } else if (cropType == VERTICAL && ar > maxSizeAr) {
+ out.push_back(fmt);
} else {
- ct = HORIZONTAL;
+ ALOGV("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)",
+ __FUNCTION__, fmt.width, fmt.height,
+ cropType == VERTICAL ? "vertically" : "horizontally",
+ maxSize.width, maxSize.height);
}
-
- // Remove formats that has aspect ratio not croppable from largest size
- std::vector<SupportedV4L2Format> out;
- for (const auto& fmt : sortedFmts) {
- float ar = ASPECT_RATIO(fmt);
- if (isAspectRatioClose(ar, maxSizeAr)) {
- out.push_back(fmt);
- } else if (ct == HORIZONTAL && ar < maxSizeAr) {
- out.push_back(fmt);
- } else if (ct == VERTICAL && ar > maxSizeAr) {
- out.push_back(fmt);
- } else {
- ALOGD("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)",
- __FUNCTION__, fmt.width, fmt.height,
- ct == VERTICAL ? "vertically" : "horizontally",
- maxSize.width, maxSize.height);
- }
- }
- sortedFmts = out;
}
- ALOGI("%s: camera croppingType is %s", __FUNCTION__,
- ct == VERTICAL ? "VERTICAL" : "HORIZONTAL");
- return ct;
+ sortedFmts = out;
}
-void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
+std::vector<SupportedV4L2Format>
+ExternalCameraDevice::getCandidateSupportedFormatsLocked(
+ int fd, CroppingType cropType,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits) {
+ std::vector<SupportedV4L2Format> outFmts;
struct v4l2_fmtdesc fmtdesc {
.index = 0,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
int ret = 0;
while (ret == 0) {
ret = TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc));
- ALOGD("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret,
+ ALOGV("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret,
fmtdesc.pixelformat & 0xFF,
(fmtdesc.pixelformat >> 8) & 0xFF,
(fmtdesc.pixelformat >> 16) & 0xFF,
@@ -835,13 +826,20 @@
.fourcc = fmtdesc.pixelformat
};
- float fpsUpperBound = -1.0;
- for (const auto& limit : mCfg.fpsLimits) {
- if (format.width <= limit.size.width &&
- format.height <= limit.size.height) {
- fpsUpperBound = limit.fpsUpperBound;
- break;
+ double fpsUpperBound = -1.0;
+ for (const auto& limit : fpsLimits) {
+ if (cropType == VERTICAL) {
+ if (format.width <= limit.size.width) {
+ fpsUpperBound = limit.fpsUpperBound;
+ break;
+ }
+ } else { // HORIZONTAL
+ if (format.height <= limit.size.height) {
+ fpsUpperBound = limit.fpsUpperBound;
+ break;
+ }
}
+
}
if (fpsUpperBound < 0.f) {
continue;
@@ -849,7 +847,7 @@
getFrameRateList(fd, fpsUpperBound, &format);
if (!format.frameRates.empty()) {
- mSupportedFormats.push_back(format);
+ outFmts.push_back(format);
}
}
}
@@ -857,16 +855,66 @@
}
fmtdesc.index++;
}
+ trimSupportedFormats(cropType, &outFmts);
+ return outFmts;
+}
- std::sort(mSupportedFormats.begin(), mSupportedFormats.end(),
- [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
- if (a.width == b.width) {
- return a.height < b.height;
- }
- return a.width < b.width;
- });
+void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
- mCroppingType = initCroppingType(&mSupportedFormats);
+ std::vector<SupportedV4L2Format> horizontalFmts =
+ getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits);
+ std::vector<SupportedV4L2Format> verticalFmts =
+ getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits);
+
+ size_t horiSize = horizontalFmts.size();
+ size_t vertSize = verticalFmts.size();
+
+ if (horiSize == 0 && vertSize == 0) {
+ ALOGE("%s: cannot find suitable cropping type!", __FUNCTION__);
+ return;
+ }
+
+ if (horiSize == 0) {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ return;
+ } else if (vertSize == 0) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ return;
+ }
+
+ const auto& maxHoriSize = horizontalFmts[horizontalFmts.size() - 1];
+ const auto& maxVertSize = verticalFmts[verticalFmts.size() - 1];
+
+ // Try to keep largest possible output size
+ // When they are the same or ambiguous, pick the one support more sizes
+ if (maxHoriSize.width == maxVertSize.width &&
+ maxHoriSize.height == maxVertSize.height) {
+ if (horiSize > vertSize) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ } else {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ }
+ } else if (maxHoriSize.width >= maxVertSize.width &&
+ maxHoriSize.height >= maxVertSize.height) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ } else if (maxHoriSize.width <= maxVertSize.width &&
+ maxHoriSize.height <= maxVertSize.height) {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ } else {
+ if (horiSize > vertSize) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ } else {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ }
+ }
}
} // namespace implementation
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 5346f80..01d7371 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -160,7 +160,6 @@
SupportedV4L2Format streamingFmt;
std::unordered_set<uint32_t> inflightFrames;
{
- Mutex::Autolock _l(mLock);
bool sessionLocked = tryLock(mLock);
if (!sessionLocked) {
dprintf(fd, "!! ExternalCameraDeviceSession mLock may be deadlocked !!\n");
@@ -180,12 +179,13 @@
streaming ? "streaming" : "not streaming");
if (streaming) {
// TODO: dump fps later
- dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d\n",
+ dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d @ %ffps\n",
streamingFmt.fourcc & 0xFF,
(streamingFmt.fourcc >> 8) & 0xFF,
(streamingFmt.fourcc >> 16) & 0xFF,
(streamingFmt.fourcc >> 24) & 0xFF,
- streamingFmt.width, streamingFmt.height);
+ streamingFmt.width, streamingFmt.height,
+ mV4l2StreamingFps);
size_t numDequeuedV4l2Buffers = 0;
{
@@ -291,7 +291,6 @@
config_v32.streams[i] = requestedConfiguration.streams[i].v3_2;
}
- // Ignore requestedConfiguration.sessionParams. External camera does not support it
Status status = configureStreams(config_v32, &outStreams_v33);
V3_4::HalStreamConfiguration outStreams;
@@ -451,6 +450,23 @@
}
}
+int ExternalCameraDeviceSession::waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk) {
+ std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
+ mLock.unlock();
+ auto st = mV4L2BufferReturned.wait_for(lk, timeout);
+ // Here we introduce a order where mV4l2BufferLock is acquired before mLock, while
+ // the normal lock acquisition order is reversed. This is fine because in most of
+ // cases we are protected by mInterfaceLock. The only thread that can cause deadlock
+ // is the OutputThread, where we do need to make sure we don't acquire mLock then
+ // mV4l2BufferLock
+ mLock.lock();
+ if (st == std::cv_status::timeout) {
+ ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
+ return -1;
+ }
+ return 0;
+}
+
Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request) {
Status status = initStatus();
if (status != Status::OK) {
@@ -510,15 +526,59 @@
return Status::ILLEGAL_ARGUMENT;
}
+ camera_metadata_entry fpsRange = mLatestReqSetting.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
+ if (fpsRange.count == 2) {
+ double requestFpsMax = fpsRange.data.i32[1];
+ double closestFps = 0.0;
+ double fpsError = 1000.0;
+ bool fpsSupported = false;
+ for (const auto& fr : mV4l2StreamingFmt.frameRates) {
+ double f = fr.getDouble();
+ if (std::fabs(requestFpsMax - f) < 1.0) {
+ fpsSupported = true;
+ break;
+ }
+ if (std::fabs(requestFpsMax - f) < fpsError) {
+ fpsError = std::fabs(requestFpsMax - f);
+ closestFps = f;
+ }
+ }
+ if (!fpsSupported) {
+ /* This can happen in a few scenarios:
+ * 1. The application is sending a FPS range not supported by the configured outputs.
+ * 2. The application is sending a valid FPS range for all cofigured outputs, but
+ * the selected V4L2 size can only run at slower speed. This should be very rare
+ * though: for this to happen a sensor needs to support at least 3 different aspect
+ * ratio outputs, and when (at least) two outputs are both not the main aspect ratio
+ * of the webcam, a third size that's larger might be picked and runs into this
+ * issue.
+ */
+ ALOGW("%s: cannot reach fps %d! Will do %f instead",
+ __FUNCTION__, fpsRange.data.i32[1], closestFps);
+ requestFpsMax = closestFps;
+ }
+
+ if (requestFpsMax != mV4l2StreamingFps) {
+ {
+ std::unique_lock<std::mutex> lk(mV4l2BufferLock);
+ while (mNumDequeuedV4l2Buffers != 0) {
+ // Wait until pipeline is idle before reconfigure stream
+ int waitRet = waitForV4L2BufferReturnLocked(lk);
+ if (waitRet != 0) {
+ ALOGE("%s: wait for pipeline idle failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+ }
+ }
+ configureV4l2StreamLocked(mV4l2StreamingFmt, requestFpsMax);
+ }
+ }
+
status = importRequest(request, allBufPtrs, allFences);
if (status != Status::OK) {
return status;
}
- // TODO: program fps range per capture request here
- // or limit the set of availableFpsRange
-
-
nsecs_t shutterTs = 0;
sp<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
if ( frameIn == nullptr) {
@@ -1979,7 +2039,46 @@
return OK;
}
-int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Format& v4l2Fmt) {
+int ExternalCameraDeviceSession::setV4l2FpsLocked(double fps) {
+ // VIDIOC_G_PARM/VIDIOC_S_PARM: set fps
+ v4l2_streamparm streamparm = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
+ // The following line checks that the driver knows about framerate get/set.
+ int ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_G_PARM, &streamparm));
+ if (ret != 0) {
+ if (errno == -EINVAL) {
+ ALOGW("%s: device does not support VIDIOC_G_PARM", __FUNCTION__);
+ }
+ return -errno;
+ }
+ // Now check if the device is able to accept a capture framerate set.
+ if (!(streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) {
+ ALOGW("%s: device does not support V4L2_CAP_TIMEPERFRAME", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ // fps is float, approximate by a fraction.
+ const int kFrameRatePrecision = 10000;
+ streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision;
+ streamparm.parm.capture.timeperframe.denominator =
+ (fps * kFrameRatePrecision);
+
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
+ ALOGE("%s: failed to set framerate to %f: %s", __FUNCTION__, fps, strerror(errno));
+ return -1;
+ }
+
+ double retFps = streamparm.parm.capture.timeperframe.denominator /
+ static_cast<double>(streamparm.parm.capture.timeperframe.numerator);
+ if (std::fabs(fps - retFps) > 1.0) {
+ ALOGE("%s: expect fps %f, got %f instead", __FUNCTION__, fps, retFps);
+ return -1;
+ }
+ mV4l2StreamingFps = fps;
+ return 0;
+}
+
+int ExternalCameraDeviceSession::configureV4l2StreamLocked(
+ const SupportedV4L2Format& v4l2Fmt, double requestFps) {
int ret = v4l2StreamOffLocked();
if (ret != OK) {
ALOGE("%s: stop v4l2 streaming failed: ret %d", __FUNCTION__, ret);
@@ -2016,46 +2115,31 @@
uint32_t bufferSize = fmt.fmt.pix.sizeimage;
ALOGI("%s: V4L2 buffer size is %d", __FUNCTION__, bufferSize);
- float maxFps = -1.f;
- float fps = 1000.f;
- const float kDefaultFps = 30.f;
- // Try to pick the slowest fps that is at least 30
- for (const auto& fr : v4l2Fmt.frameRates) {
- double f = fr.getDouble();
- if (maxFps < f) {
- maxFps = f;
- }
- if (f >= kDefaultFps && f < fps) {
- fps = f;
- }
- }
- if (fps == 1000.f) {
- fps = maxFps;
- }
-
- // VIDIOC_G_PARM/VIDIOC_S_PARM: set fps
- v4l2_streamparm streamparm = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
- // The following line checks that the driver knows about framerate get/set.
- if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_G_PARM, &streamparm)) >= 0) {
- // Now check if the device is able to accept a capture framerate set.
- if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
- // |frame_rate| is float, approximate by a fraction.
- const int kFrameRatePrecision = 10000;
- streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision;
- streamparm.parm.capture.timeperframe.denominator =
- (fps * kFrameRatePrecision);
-
- if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
- ALOGE("%s: failed to set framerate to %f", __FUNCTION__, fps);
- return UNKNOWN_ERROR;
+ const double kDefaultFps = 30.0;
+ double fps = 1000.0;
+ if (requestFps != 0.0) {
+ fps = requestFps;
+ } else {
+ double maxFps = -1.0;
+ // Try to pick the slowest fps that is at least 30
+ for (const auto& fr : v4l2Fmt.frameRates) {
+ double f = fr.getDouble();
+ if (maxFps < f) {
+ maxFps = f;
+ }
+ if (f >= kDefaultFps && f < fps) {
+ fps = f;
}
}
+ if (fps == 1000.0) {
+ fps = maxFps;
+ }
}
- float retFps = streamparm.parm.capture.timeperframe.denominator /
- streamparm.parm.capture.timeperframe.numerator;
- if (std::fabs(fps - retFps) > std::numeric_limits<float>::epsilon()) {
- ALOGE("%s: expect fps %f, got %f instead", __FUNCTION__, fps, retFps);
- return BAD_VALUE;
+
+ int fpsRet = setV4l2FpsLocked(fps);
+ if (fpsRet != 0 && fpsRet != -EINVAL) {
+ ALOGE("%s: set fps failed: %s", __FUNCTION__, strerror(fpsRet));
+ return fpsRet;
}
uint32_t v4lBufferCount = (fps >= kDefaultFps) ?
@@ -2136,17 +2220,8 @@
{
std::unique_lock<std::mutex> lk(mV4l2BufferLock);
if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
- std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
- mLock.unlock();
- auto st = mV4L2BufferReturned.wait_for(lk, timeout);
- // Here we introduce a case where mV4l2BufferLock is acquired before mLock, while
- // the normal lock acquisition order is reversed, but this is fine because in most of
- // cases we are protected by mInterfaceLock. The only thread that can compete these
- // locks are the OutputThread, where we do need to make sure we don't acquire mLock then
- // mV4l2BufferLock
- mLock.lock();
- if (st == std::cv_status::timeout) {
- ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
+ int waitRet = waitForV4L2BufferReturnLocked(lk);
+ if (waitRet != 0) {
return ret;
}
}
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index 9c0ad7f..5315097 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -177,8 +177,11 @@
status_t initDefaultRequests();
status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
Status configureStreams(const V3_2::StreamConfiguration&, V3_3::HalStreamConfiguration* out);
- int configureV4l2StreamLocked(const SupportedV4L2Format& fmt);
+ // fps = 0.0 means default, which is
+ // slowest fps that is at least 30, or fastest fps if 30 is not supported
+ int configureV4l2StreamLocked(const SupportedV4L2Format& fmt, double fps = 0.0);
int v4l2StreamOffLocked();
+ int setV4l2FpsLocked(double fps);
// TODO: change to unique_ptr for better tracking
sp<V4L2Frame> dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs); // Called with mLock hold
@@ -212,6 +215,8 @@
ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const;
+ int waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk);
+
class OutputThread : public android::Thread {
public:
OutputThread(wp<ExternalCameraDeviceSession> parent, CroppingType);
@@ -307,6 +312,7 @@
bool mV4l2Streaming = false;
SupportedV4L2Format mV4l2StreamingFmt;
+ double mV4l2StreamingFps = 0.0;
size_t mV4L2BufferCount = 0;
static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing)
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
index 5880469..a52f0e4 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
@@ -78,7 +78,6 @@
/* End of Methods from ::android::hardware::camera::device::V3_2::ICameraDevice */
protected:
- void getFrameRateList(int fd, float fpsUpperBound, SupportedV4L2Format* format);
// Init supported w/h/format/fps in mSupportedFormats. Caller still owns fd
void initSupportedFormatsLocked(int fd);
@@ -92,7 +91,15 @@
status_t initOutputCharsKeys(int fd,
::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
- static CroppingType initCroppingType(/*inout*/std::vector<SupportedV4L2Format>*);
+ static void getFrameRateList(int fd, double fpsUpperBound, SupportedV4L2Format* format);
+
+ // Get candidate supported formats list of input cropping type.
+ static std::vector<SupportedV4L2Format> getCandidateSupportedFormatsLocked(
+ int fd, CroppingType cropType,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits);
+ // Trim supported format list by the cropping type. Also sort output formats by width/height
+ static void trimSupportedFormats(CroppingType cropType,
+ /*inout*/std::vector<SupportedV4L2Format>* pFmts);
Mutex mLock;
bool mInitFailed = false;
diff --git a/gnss/1.1/IGnssCallback.hal b/gnss/1.1/IGnssCallback.hal
index 9fd71ae..fdd2ebe 100644
--- a/gnss/1.1/IGnssCallback.hal
+++ b/gnss/1.1/IGnssCallback.hal
@@ -39,11 +39,19 @@
/**
* Callback for requesting Location.
*
- * HAL implementation shall call this when it wants the framework to provide location to assist
- * with GNSS HAL operation. For example, to assist with time to first fix, and/or error
- * recovery, it may ask for a location that is independent from GNSS (e.g. from the "network"
- * LocationProvier), or to provide a Device-Based-Hybrid location to supplement A-GPS/GNSS
- * emergency call flows managed by the GNSS HAL.
+ * HAL implementation must call this when it wants the framework to provide locations to assist
+ * with GNSS HAL operation, for example, to assist with time to first fix, error recovery, or to
+ * supplement GNSS location for other clients of the GNSS HAL.
+ *
+ * If a request is made with independentFromGnss set to true, the framework must avoid
+ * providing locations derived from GNSS locations (such as "fused" location), to help improve
+ * information independence for situations such as error recovery.
+ *
+ * In response to this method call, GNSS HAL can expect zero, one, or more calls to
+ * IGnss::injectLocation or IGnss::injectBestLocation, dependent on availability of location
+ * from other sources, which may happen at some arbitrary delay. Generally speaking, HAL
+ * implementations must be able to handle calls to IGnss::injectLocation or
+ * IGnss::injectBestLocation at any time.
*
* @param independentFromGnss True if requesting a location that is independent from GNSS.
*/
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
new file mode 100644
index 0000000..977a22f
--- /dev/null
+++ b/gnss/1.1/default/Android.bp
@@ -0,0 +1,20 @@
+cc_binary {
+ name: "android.hardware.gnss@1.1-service",
+ init_rc: ["android.hardware.gnss@1.1-service.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "Gnss.cpp",
+ "GnssConfiguration.cpp",
+ "GnssMeasurement.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "libutils",
+ "liblog",
+ "android.hardware.gnss@1.1",
+ "android.hardware.gnss@1.0",
+ ],
+}
diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp
new file mode 100644
index 0000000..308ba70
--- /dev/null
+++ b/gnss/1.1/default/Gnss.cpp
@@ -0,0 +1,147 @@
+#define LOG_TAG "Gnss"
+
+#include "Gnss.h"
+#include <log/log.h>
+#include "GnssConfiguration.h"
+#include "GnssMeasurement.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+Return<bool> Gnss::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback>&) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::start() {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::stop() {
+ // TODO implement
+ return bool{};
+}
+
+Return<void> Gnss::cleanup() {
+ // TODO implement
+ return Void();
+}
+
+Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::injectLocation(double, double, float) {
+ // TODO implement
+ return bool{};
+}
+
+Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) {
+ // TODO implement
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence,
+ uint32_t, uint32_t, uint32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IAGnssRil>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IGnssGeofencing>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IAGnss>> Gnss::getExtensionAGnss() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IAGnss>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IGnssNi>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+ // TODO implement
+ return new GnssMeasurement();
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>>
+Gnss::getExtensionGnssNavigationMessage() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IGnssXtra>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>>
+Gnss::getExtensionGnssConfiguration() {
+ // TODO implement
+ return new GnssConfiguration();
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IGnssDebug>{};
+}
+
+Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ // TODO implement
+ return ::android::sp<::android::hardware::gnss::V1_0::IGnssBatching>{};
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(const sp<::android::hardware::gnss::V1_1::IGnssCallback>&) {
+ ALOGI("Gnss::setCallback_1_1");
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> Gnss::setPositionMode_1_1(
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t, uint32_t,
+ bool) {
+ // TODO implement
+ return bool{};
+}
+
+Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>>
+Gnss::getExtensionGnssConfiguration_1_1() {
+ // TODO implement
+ return new GnssConfiguration();
+}
+
+Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>>
+Gnss::getExtensionGnssMeasurement_1_1() {
+ // TODO implement
+ return new GnssMeasurement();
+}
+
+Return<bool> Gnss::injectBestLocation(const ::android::hardware::gnss::V1_0::GnssLocation&) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.1/default/Gnss.h b/gnss/1.1/default/Gnss.h
new file mode 100644
index 0000000..e9ad34b
--- /dev/null
+++ b/gnss/1.1/default/Gnss.h
@@ -0,0 +1,79 @@
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
+
+#include <android/hardware/gnss/1.1/IGnss.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct Gnss : public IGnss {
+ // Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+ Return<bool> setCallback(
+ const sp<::android::hardware::gnss::V1_0::IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<void> deleteAidingData(
+ ::android::hardware::gnss::V1_0::IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode mode,
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> getExtensionGnssGeofencing()
+ override;
+ Return<sp<::android::hardware::gnss::V1_0::IAGnss>> getExtensionAGnss() override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> getExtensionGnssNi() override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> getExtensionGnssMeasurement()
+ override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>>
+ getExtensionGnssNavigationMessage() override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> getExtensionXtra() override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>> getExtensionGnssConfiguration()
+ override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+ Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+ Return<bool> setCallback_1_1(
+ const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) override;
+ Return<bool> setPositionMode_1_1(
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode mode,
+ ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
+ bool lowPowerMode) override;
+ Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>>
+ getExtensionGnssConfiguration_1_1() override;
+ Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1()
+ override;
+ Return<bool> injectBestLocation(
+ const ::android::hardware::gnss::V1_0::GnssLocation& location) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
diff --git a/gnss/1.1/default/GnssConfiguration.cpp b/gnss/1.1/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..d05f317
--- /dev/null
+++ b/gnss/1.1/default/GnssConfiguration.cpp
@@ -0,0 +1,58 @@
+#include "GnssConfiguration.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<::android::hardware::gnss::V1_1::IGnssConfiguration::BlacklistedSource>&) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.1/default/GnssConfiguration.h b/gnss/1.1/default/GnssConfiguration.h
new file mode 100644
index 0000000..4f7ed2b
--- /dev/null
+++ b/gnss/1.1/default/GnssConfiguration.h
@@ -0,0 +1,46 @@
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/1.1/IGnssConfiguration.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct GnssConfiguration : public IGnssConfiguration {
+ // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override;
+ Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override;
+ Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<::android::hardware::gnss::V1_1::IGnssConfiguration::BlacklistedSource>&
+ blacklist) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
diff --git a/gnss/1.1/default/GnssMeasurement.cpp b/gnss/1.1/default/GnssMeasurement.cpp
new file mode 100644
index 0000000..e88badd
--- /dev/null
+++ b/gnss/1.1/default/GnssMeasurement.cpp
@@ -0,0 +1,35 @@
+#include "GnssMeasurement.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus>
+GnssMeasurement::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssMeasurementCallback>&) {
+ // TODO implement
+ return ::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+Return<void> GnssMeasurement::close() {
+ // TODO implement
+ return Void();
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus>
+GnssMeasurement::setCallback_1_1(
+ const sp<::android::hardware::gnss::V1_1::IGnssMeasurementCallback>&, bool) {
+ // TODO implement
+ return ::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus{};
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.1/default/GnssMeasurement.h b/gnss/1.1/default/GnssMeasurement.h
new file mode 100644
index 0000000..650cb27
--- /dev/null
+++ b/gnss/1.1/default/GnssMeasurement.h
@@ -0,0 +1,42 @@
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
+
+#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct GnssMeasurement : public IGnssMeasurement {
+ // Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+ Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<::android::hardware::gnss::V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+ Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus>
+ setCallback_1_1(const sp<::android::hardware::gnss::V1_1::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
diff --git a/gnss/1.1/default/android.hardware.gnss@1.1-service.rc b/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
new file mode 100644
index 0000000..0cf7c49
--- /dev/null
+++ b/gnss/1.1/default/android.hardware.gnss@1.1-service.rc
@@ -0,0 +1,4 @@
+service gnss-1-1 /vendor/bin/hw/android.hardware.gnss@1.1-service
+ class hal
+ user system
+ group system
diff --git a/gnss/1.1/default/service.cpp b/gnss/1.1/default/service.cpp
new file mode 100644
index 0000000..b3ef710
--- /dev/null
+++ b/gnss/1.1/default/service.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "android.hardware.gnss@1.1-service"
+
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include "Gnss.h"
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::gnss::V1_1::implementation::Gnss;
+using ::android::hardware::gnss::V1_1::IGnss;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::OK;
+using ::android::sp;
+
+int main(int /* argc */, char* /* argv */ []) {
+ sp<IGnss> gnss = new Gnss();
+ configureRpcThreadpool(1, true /* will join */);
+ if (gnss->registerAsService() != OK) {
+ ALOGE("Could not register gnss 1.1 service.");
+ return 1;
+ }
+ joinRpcThreadpool();
+
+ ALOGE("Service exited!");
+ return 1;
+}
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index f0ce938..8646a4c 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -186,35 +186,29 @@
// see if service can handle model
bool fullySupportsModel = false;
- ErrorStatus supportedStatus;
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
-
Return<void> supportedCall = device->getSupportedOperations(
- model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
- supportedStatus = status;
+ model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
+ ASSERT_EQ(ErrorStatus::NONE, status);
ASSERT_NE(0ul, supported.size());
fullySupportsModel =
std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
});
ASSERT_TRUE(supportedCall.isOk());
- ASSERT_EQ(ErrorStatus::NONE, supportedStatus);
+
+ // launch prepare model
+ sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+ ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
+ ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
// retrieve prepared model
preparedModelCallback->wait();
ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
- if (fullySupportsModel) {
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- } else {
- EXPECT_TRUE(prepareReturnStatus == ErrorStatus::NONE ||
- prepareReturnStatus == ErrorStatus::GENERAL_FAILURE);
- }
// early termination if vendor service cannot fully prepare model
- if (!fullySupportsModel && prepareReturnStatus == ErrorStatus::GENERAL_FAILURE) {
+ if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
ASSERT_EQ(nullptr, preparedModel.get());
LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
"prepare model that it does not support.";
@@ -223,6 +217,7 @@
<< std::endl;
return;
}
+ EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel.get());
EvaluatePreparedModel(preparedModel, is_ignored, examples);
@@ -235,36 +230,30 @@
// see if service can handle model
bool fullySupportsModel = false;
- ErrorStatus supportedStatus;
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
-
Return<void> supportedCall = device->getSupportedOperations_1_1(
- model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
- supportedStatus = status;
+ model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
+ ASSERT_EQ(ErrorStatus::NONE, status);
ASSERT_NE(0ul, supported.size());
fullySupportsModel =
std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
});
ASSERT_TRUE(supportedCall.isOk());
- ASSERT_EQ(ErrorStatus::NONE, supportedStatus);
+
+ // launch prepare model
+ sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+ ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus =
device->prepareModel_1_1(model, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
+ ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
// retrieve prepared model
preparedModelCallback->wait();
ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
- if (fullySupportsModel) {
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- } else {
- EXPECT_TRUE(prepareReturnStatus == ErrorStatus::NONE ||
- prepareReturnStatus == ErrorStatus::GENERAL_FAILURE);
- }
// early termination if vendor service cannot fully prepare model
- if (!fullySupportsModel && prepareReturnStatus == ErrorStatus::GENERAL_FAILURE) {
+ if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
ASSERT_EQ(nullptr, preparedModel.get());
LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
"prepare model that it does not support.";
@@ -273,6 +262,7 @@
<< std::endl;
return;
}
+ EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel.get());
// If in relaxed mode, set the error range to be 5ULP of FP16.
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp
index e838997..59e5b80 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp
@@ -52,26 +52,51 @@
using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-inline sp<IPreparedModel> doPrepareModelShortcut(sp<IDevice>& device) {
+static void doPrepareModelShortcut(const sp<IDevice>& device, sp<IPreparedModel>* preparedModel) {
+ ASSERT_NE(nullptr, preparedModel);
Model model = createValidTestModel_1_0();
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- if (preparedModelCallback == nullptr) {
- return nullptr;
- }
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
- if (!prepareLaunchStatus.isOk() || prepareLaunchStatus != ErrorStatus::NONE) {
- return nullptr;
- }
+ // see if service can handle model
+ bool fullySupportsModel = false;
+ Return<void> supportedOpsLaunchStatus = device->getSupportedOperations(
+ model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
+ ASSERT_EQ(ErrorStatus::NONE, status);
+ ASSERT_NE(0ul, supported.size());
+ fullySupportsModel =
+ std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
+ });
+ ASSERT_TRUE(supportedOpsLaunchStatus.isOk());
+ // launch prepare model
+ sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+ ASSERT_NE(nullptr, preparedModelCallback.get());
+ Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+ ASSERT_TRUE(prepareLaunchStatus.isOk());
+ ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
+
+ // retrieve prepared model
preparedModelCallback->wait();
ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
- if (prepareReturnStatus != ErrorStatus::NONE || preparedModel == nullptr) {
- return nullptr;
- }
+ *preparedModel = preparedModelCallback->getPreparedModel();
- return preparedModel;
+ // The getSupportedOperations call returns a list of operations that are
+ // guaranteed not to fail if prepareModel is called, and
+ // 'fullySupportsModel' is true i.f.f. the entire model is guaranteed.
+ // If a driver has any doubt that it can prepare an operation, it must
+ // return false. So here, if a driver isn't sure if it can support an
+ // operation, but reports that it successfully prepared the model, the test
+ // can continue.
+ if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
+ ASSERT_EQ(nullptr, preparedModel->get());
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+ "prepare model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "prepare model that it does not support."
+ << std::endl;
+ return;
+ }
+ ASSERT_EQ(ErrorStatus::NONE, prepareReturnStatus);
+ ASSERT_NE(nullptr, preparedModel->get());
}
// create device test
@@ -132,18 +157,8 @@
// prepare simple model positive test
TEST_F(NeuralnetworksHidlTest, SimplePrepareModelPositiveTest) {
- Model model = createValidTestModel_1_0();
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
- ASSERT_TRUE(prepareLaunchStatus.isOk());
- EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
-
- preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
- EXPECT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ doPrepareModelShortcut(device, &preparedModel);
}
// prepare simple model negative test 1
@@ -184,8 +199,11 @@
std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
const uint32_t OUTPUT = 1;
- sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
- ASSERT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(doPrepareModelShortcut(device, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
Request request = createValidTestRequest();
auto postWork = [&] {
@@ -218,8 +236,11 @@
// execute simple graph negative test 1
TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest1) {
- sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
- ASSERT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(doPrepareModelShortcut(device, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
Request request = createInvalidTestRequest1();
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
@@ -235,8 +256,11 @@
// execute simple graph negative test 2
TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest2) {
- sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
- ASSERT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(doPrepareModelShortcut(device, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
Request request = createInvalidTestRequest2();
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp
index d2e99a7..17f6744 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp
@@ -59,27 +59,52 @@
using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-inline sp<IPreparedModel> doPrepareModelShortcut(sp<IDevice>& device) {
+static void doPrepareModelShortcut(const sp<IDevice>& device, sp<IPreparedModel>* preparedModel) {
+ ASSERT_NE(nullptr, preparedModel);
Model model = createValidTestModel_1_1();
+ // see if service can handle model
+ bool fullySupportsModel = false;
+ Return<void> supportedOpsLaunchStatus = device->getSupportedOperations_1_1(
+ model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
+ ASSERT_EQ(ErrorStatus::NONE, status);
+ ASSERT_NE(0ul, supported.size());
+ fullySupportsModel =
+ std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
+ });
+ ASSERT_TRUE(supportedOpsLaunchStatus.isOk());
+
+ // launch prepare model
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- if (preparedModelCallback == nullptr) {
- return nullptr;
- }
+ ASSERT_NE(nullptr, preparedModelCallback.get());
Return<ErrorStatus> prepareLaunchStatus =
device->prepareModel_1_1(model, preparedModelCallback);
- if (!prepareLaunchStatus.isOk() || prepareLaunchStatus != ErrorStatus::NONE) {
- return nullptr;
- }
+ ASSERT_TRUE(prepareLaunchStatus.isOk());
+ ASSERT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
+ // retrieve prepared model
preparedModelCallback->wait();
ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
- if (prepareReturnStatus != ErrorStatus::NONE || preparedModel == nullptr) {
- return nullptr;
- }
+ *preparedModel = preparedModelCallback->getPreparedModel();
- return preparedModel;
+ // The getSupportedOperations call returns a list of operations that are
+ // guaranteed not to fail if prepareModel is called, and
+ // 'fullySupportsModel' is true i.f.f. the entire model is guaranteed.
+ // If a driver has any doubt that it can prepare an operation, it must
+ // return false. So here, if a driver isn't sure if it can support an
+ // operation, but reports that it successfully prepared the model, the test
+ // can continue.
+ if (!fullySupportsModel && prepareReturnStatus != ErrorStatus::NONE) {
+ ASSERT_EQ(nullptr, preparedModel->get());
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+ "prepare model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "prepare model that it does not support."
+ << std::endl;
+ return;
+ }
+ ASSERT_EQ(ErrorStatus::NONE, prepareReturnStatus);
+ ASSERT_NE(nullptr, preparedModel->get());
}
// create device test
@@ -142,19 +167,8 @@
// prepare simple model positive test
TEST_F(NeuralnetworksHidlTest, SimplePrepareModelPositiveTest) {
- Model model = createValidTestModel_1_1();
- sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- ASSERT_NE(nullptr, preparedModelCallback.get());
- Return<ErrorStatus> prepareLaunchStatus =
- device->prepareModel_1_1(model, preparedModelCallback);
- ASSERT_TRUE(prepareLaunchStatus.isOk());
- EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
-
- preparedModelCallback->wait();
- ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
- EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
- sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
- EXPECT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ doPrepareModelShortcut(device, &preparedModel);
}
// prepare simple model negative test 1
@@ -197,8 +211,11 @@
std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
const uint32_t OUTPUT = 1;
- sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
- ASSERT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(doPrepareModelShortcut(device, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
Request request = createValidTestRequest();
auto postWork = [&] {
@@ -231,8 +248,11 @@
// execute simple graph negative test 1
TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest1) {
- sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
- ASSERT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(doPrepareModelShortcut(device, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
Request request = createInvalidTestRequest1();
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
@@ -248,8 +268,11 @@
// execute simple graph negative test 2
TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest2) {
- sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
- ASSERT_NE(nullptr, preparedModel.get());
+ sp<IPreparedModel> preparedModel;
+ ASSERT_NO_FATAL_FAILURE(doPrepareModelShortcut(device, &preparedModel));
+ if (preparedModel == nullptr) {
+ return;
+ }
Request request = createInvalidTestRequest2();
sp<ExecutionCallback> executionCallback = new ExecutionCallback();
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index 06a7f77..c3769f8 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -362,3 +362,296 @@
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
}
}
+
+/*
+ * Test IRadio.setIndicationFilter_1_2()
+ */
+TEST_F(RadioHidlTest_v1_2, setIndicationFilter_1_2) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res =
+ radio_v1_2->setIndicationFilter_1_2(serial, static_cast<int>(IndicationFilter::ALL));
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setIndicationFilter_1_2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setSignalStrengthReportingCriteria() with invalid hysteresisDb
+ */
+TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
+ serial, 5000,
+ 10, // hysteresisDb too large given threshold list deltas
+ {-109, -103, -97, -89}, V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_invalidHysteresisDb, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+}
+
+/*
+ * Test IRadio.setSignalStrengthReportingCriteria() with empty parameters
+ */
+TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_EmptyParams) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(serial, 0, 0, {},
+ V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_EmptyParams, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setSignalStrengthReportingCriteria() for GERAN
+ */
+TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Geran) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
+ serial, 5000, 2, {-109, -103, -97, -89}, V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Geran, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setSignalStrengthReportingCriteria() for UTRAN
+ */
+TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Utran) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
+ serial, 5000, 2, {-110, -97, -73, -49, -25}, V1_2::AccessNetwork::UTRAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Utran, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setSignalStrengthReportingCriteria() for EUTRAN
+ */
+TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Eutran) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
+ serial, 5000, 2, {-140, -128, -118, -108, -98, -44}, V1_2::AccessNetwork::EUTRAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Eutran, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setSignalStrengthReportingCriteria() for CDMA2000
+ */
+TEST_F(RadioHidlTest_v1_2, setSignalStrengthReportingCriteria_Cdma2000) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setSignalStrengthReportingCriteria(
+ serial, 5000, 2, {-105, -90, -75, -65}, V1_2::AccessNetwork::CDMA2000);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Cdma2000, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
+ */
+TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
+ serial, 5000,
+ 5000, // hysteresisDlKbps too big for thresholds delta
+ 100, {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000}, V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisDlKbps, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+}
+
+/*
+ * Test IRadio.setLinkCapacityReportingCriteria() invalid hysteresisUlKbps
+ */
+TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
+ serial, 5000, 500,
+ 1000, // hysteresisUlKbps too big for thresholds delta
+ {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000}, V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+}
+
+/*
+ * Test IRadio.setLinkCapacityReportingCriteria() empty params
+ */
+TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_emptyParams) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(serial, 0, 0, 0, {}, {},
+ V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_emptyParams, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setLinkCapacityReportingCriteria() GERAN
+ */
+TEST_F(RadioHidlTest_v1_2, setLinkCapacityReportingCriteria_Geran) {
+ const int serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_2->setLinkCapacityReportingCriteria(
+ serial, 5000, 500, 100, {1000, 5000, 10000, 20000}, {500, 1000, 5000, 10000},
+ V1_2::AccessNetwork::GERAN);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
+ toString(radioRsp_v1_2->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
+ * Test IRadio.setupDataCall_1_2() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, setupDataCall_1_2) {
+ const int serial = GetRandomSerialNumber();
+
+ V1_2::AccessNetwork accessNetwork = V1_2::AccessNetwork::EUTRAN;
+
+ 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;
+
+ V1_2::DataRequestReason reason = V1_2::DataRequestReason::NORMAL;
+ std::vector<hidl_string> addresses = {""};
+ std::vector<hidl_string> dnses = {""};
+
+ Return<void> res = radio_v1_2->setupDataCall_1_2(serial, accessNetwork, dataProfileInfo,
+ modemCognitive, roamingAllowed, isRoaming,
+ reason, addresses, dnses);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_2->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW, RadioError::REQUEST_NOT_SUPPORTED}));
+ } else if (cardStatus.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_2->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
+
+/*
+ * Test IRadio.deactivateDataCall_1_2() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, deactivateDataCall_1_2) {
+ const int serial = GetRandomSerialNumber();
+ int cid = 1;
+ V1_2::DataRequestReason reason = V1_2::DataRequestReason::NORMAL;
+
+ Return<void> res = radio_v1_2->deactivateDataCall_1_2(serial, cid, reason);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+ if (cardStatus.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_2->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_STATE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_2->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_CALL_ID,
+ RadioError::INVALID_STATE, RadioError::INVALID_ARGUMENTS,
+ RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED}));
+ }
+}
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index 781c12a..f9919a2 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -33,6 +33,7 @@
using namespace ::android::hardware::radio::V1_1;
using namespace ::android::hardware::radio::V1_0;
+using ::android::hardware::hidl_bitfield;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
@@ -399,6 +400,11 @@
const KeepaliveStatus& status);
Return<void> stopKeepaliveResponse(const RadioResponseInfo& info);
+
+ /* 1.2 Api */
+ Return<void> setSignalStrengthReportingCriteriaResponse(const RadioResponseInfo& info);
+
+ Return<void> setLinkCapacityReportingCriteriaResponse(const RadioResponseInfo& info);
};
/* Callback class for radio indication */
@@ -410,6 +416,23 @@
RadioIndication_v1_2(RadioHidlTest_v1_2& parent_v1_2);
virtual ~RadioIndication_v1_2() = default;
+ /* 1.2 Api */
+ Return<void> networkScanResult_1_2(RadioIndicationType type,
+ const V1_2::NetworkScanResult& result);
+
+ Return<void> cellInfoList_1_2(RadioIndicationType type,
+ const ::android::hardware::hidl_vec<V1_2::CellInfo>& records);
+
+ Return<void> currentLinkCapacityEstimate(RadioIndicationType type,
+ const V1_2::LinkCapacityEstimate& lce);
+
+ Return<void> currentPhysicalChannelConfigs(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<V1_2::PhysicalChannelConfig>& configs);
+
+ Return<void> currentSignalStrength_1_2(RadioIndicationType type,
+ const V1_2::SignalStrength& signalStrength);
+
/* 1.1 Api */
Return<void> carrierInfoForImsiEncryption(RadioIndicationType info);
diff --git a/radio/1.2/vts/functional/radio_indication.cpp b/radio/1.2/vts/functional/radio_indication.cpp
index 97dee27..57f5cb0 100644
--- a/radio/1.2/vts/functional/radio_indication.cpp
+++ b/radio/1.2/vts/functional/radio_indication.cpp
@@ -18,6 +18,34 @@
RadioIndication_v1_2::RadioIndication_v1_2(RadioHidlTest_v1_2& parent) : parent_v1_2(parent) {}
+/* 1.2 Apis */
+Return<void> RadioIndication_v1_2::networkScanResult_1_2(
+ RadioIndicationType /*type*/, const V1_2::NetworkScanResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_2::cellInfoList_1_2(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<V1_2::CellInfo>& /*records*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_2::currentLinkCapacityEstimate(
+ RadioIndicationType /*type*/, const V1_2::LinkCapacityEstimate& /*lce*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_2::currentPhysicalChannelConfigs(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<V1_2::PhysicalChannelConfig>& /*configs*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_2::currentSignalStrength_1_2(
+ RadioIndicationType /*type*/, const V1_2::SignalStrength& /*signalStrength*/) {
+ return Void();
+}
+
/* 1.1 Apis */
Return<void> RadioIndication_v1_2::carrierInfoForImsiEncryption(RadioIndicationType /*info*/) {
return Void();
diff --git a/radio/1.2/vts/functional/radio_response.cpp b/radio/1.2/vts/functional/radio_response.cpp
index 12d7005..9bf4531 100644
--- a/radio/1.2/vts/functional/radio_response.cpp
+++ b/radio/1.2/vts/functional/radio_response.cpp
@@ -150,8 +150,10 @@
return Void();
}
-Return<void> RadioResponse_v1_2::setupDataCallResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse_v1_2::setupDataCallResponse(const RadioResponseInfo& info,
const SetupDataCallResult& /*dcResponse*/) {
+ rspInfo = info;
+ parent_v1_2.notify();
return Void();
}
@@ -205,7 +207,9 @@
return Void();
}
-Return<void> RadioResponse_v1_2::deactivateDataCallResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_2::deactivateDataCallResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_2.notify();
return Void();
}
@@ -657,6 +661,7 @@
return Void();
}
+/* 1.1 Apis */
Return<void> RadioResponse_v1_2::setCarrierInfoForImsiEncryptionResponse(
const RadioResponseInfo& /*info*/) {
return Void();
@@ -686,3 +691,18 @@
Return<void> RadioResponse_v1_2::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
return Void();
}
+
+/* 1.2 Apis */
+Return<void> RadioResponse_v1_2::setSignalStrengthReportingCriteriaResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_2.notify();
+ return Void();
+}
+
+Return<void> RadioResponse_v1_2::setLinkCapacityReportingCriteriaResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_2.notify();
+ return Void();
+}
diff --git a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
index 2045e44..59c354f 100644
--- a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
+++ b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
@@ -92,6 +92,10 @@
se_cb_ = new SecureElementHalCallback();
ASSERT_NE(se_cb_, nullptr);
+ se_->init(se_cb_);
+ auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
+ EXPECT_TRUE(res.no_timeout);
+ EXPECT_TRUE(res.args->state_);
}
sp<ISecureElement> se_;
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index f742ecd..ee6a68e 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -24,6 +24,7 @@
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
"android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
"libcrypto",
"libgmock",
@@ -46,6 +47,7 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
"android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi@1.0",
"libcrypto",
"libgmock",
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 6dd64ec..bdedfba 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
@@ -16,6 +16,7 @@
#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <cutils/properties.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
@@ -90,6 +91,18 @@
}
return false;
}
+
+std::string getStaIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ property_get("wifi.interface", buffer.data(), "wlan0");
+ return buffer.data();
+}
+
+std::string getP2pIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ property_get("wifi.direct.interface", buffer.data(), "p2p0");
+ return buffer.data();
+}
} // namespace
// Utility class to wait for wpa_supplicant's HIDL service registration.
@@ -165,9 +178,56 @@
ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
}
+bool is_1_1(const sp<ISupplicant>& supplicant) {
+ sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
+ supplicant_1_1 =
+ ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
+ supplicant);
+ return supplicant_1_1.get() != nullptr;
+}
+
+void addSupplicantStaIface_1_1(const sp<ISupplicant>& supplicant) {
+ sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
+ supplicant_1_1 =
+ ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
+ supplicant);
+ ASSERT_TRUE(supplicant_1_1.get());
+ ISupplicant::IfaceInfo info = {IfaceType::STA, getStaIfaceName()};
+ supplicant_1_1->addInterface(
+ info, [&](const SupplicantStatus& status,
+ const sp<ISupplicantIface>& /* iface */) {
+ ASSERT_TRUE(
+ (SupplicantStatusCode::SUCCESS == status.code) ||
+ (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
+ });
+}
+
+void addSupplicantP2pIface_1_1(const sp<ISupplicant>& supplicant) {
+ sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
+ supplicant_1_1 =
+ ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
+ supplicant);
+ ASSERT_TRUE(supplicant_1_1.get());
+ ISupplicant::IfaceInfo info = {IfaceType::P2P, getP2pIfaceName()};
+ supplicant_1_1->addInterface(
+ info, [&](const SupplicantStatus& status,
+ const sp<ISupplicantIface>& /* iface */) {
+ ASSERT_TRUE(
+ (SupplicantStatusCode::SUCCESS == status.code) ||
+ (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
+ });
+}
+
sp<ISupplicant> getSupplicant() {
- return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
- gEnv->getServiceName<ISupplicant>());
+ sp<ISupplicant> supplicant =
+ ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
+ gEnv->getServiceName<ISupplicant>());
+ // For 1.1 supplicant, we need to add interfaces at initialization.
+ if (is_1_1(supplicant)) {
+ addSupplicantStaIface_1_1(supplicant);
+ addSupplicantP2pIface_1_1(supplicant);
+ }
+ return supplicant;
}
sp<ISupplicantStaIface> getSupplicantStaIface() {
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 4426ab6..d4a768f 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -21,6 +21,7 @@
#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
#include <VtsHalHidlTargetTestEnvBase.h>
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
index 188dba3..3efe15d 100644
--- a/wifi/supplicant/1.1/vts/functional/Android.bp
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -40,6 +40,7 @@
srcs: [
"VtsHalWifiSupplicantV1_1TargetTest.cpp",
"supplicant_hidl_test.cpp",
+ "supplicant_sta_network_hidl_test.cpp",
],
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp
index 8cc4a9f..3f17740 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp
@@ -21,8 +21,13 @@
#include "supplicant_hidl_test_utils_1_1.h"
using ::android::hardware::wifi::supplicant::V1_1::ISupplicant;
+using ::android::hardware::wifi::supplicant::V1_1::ISupplicantStaNetwork;
using ::android::sp;
sp<ISupplicant> getSupplicant_1_1() {
return ISupplicant::castFrom(getSupplicant());
}
+
+sp<ISupplicantStaNetwork> createSupplicantStaNetwork_1_1() {
+ return ISupplicantStaNetwork::castFrom(createSupplicantStaNetwork());
+}
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
index c42a35b..e7ce54a 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
@@ -18,8 +18,12 @@
#define SUPPLICANT_HIDL_TEST_UTILS_1_1_H
#include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaNetwork.h>
android::sp<android::hardware::wifi::supplicant::V1_1::ISupplicant>
getSupplicant_1_1();
+android::sp<android::hardware::wifi::supplicant::V1_1::ISupplicantStaNetwork>
+ createSupplicantStaNetwork_1_1();
+
#endif /* SUPPLICANT_HIDL_TEST_UTILS_1_1_H */
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp
new file mode 100644
index 0000000..fa52556
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaNetwork.h>
+
+#include "supplicant_hidl_test_utils.h"
+#include "supplicant_hidl_test_utils_1_1.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::supplicant::V1_1::ISupplicantStaNetwork;
+namespace {
+constexpr uint8_t kTestIdentity[] = {0x45, 0x67, 0x98, 0x67, 0x56};
+constexpr uint8_t kTestEncryptedIdentity[] = {0x35, 0x37, 0x58, 0x57, 0x26};
+} // namespace
+
+class SupplicantStaNetworkHidlTest
+ : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ startSupplicantAndWaitForHidlService();
+ EXPECT_TRUE(turnOnExcessiveLogging());
+ sta_network_ = createSupplicantStaNetwork_1_1();
+ ASSERT_NE(sta_network_.get(), nullptr);
+ }
+
+ virtual void TearDown() override { stopSupplicant(); }
+
+ protected:
+ // ISupplicantStaNetwork object used for all tests in this fixture.
+ sp<ISupplicantStaNetwork> sta_network_;
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the ISupplicantStaNetwork proxy object is
+ * successfully created.
+ */
+TEST(SupplicantStaNetworkHidlTestNoFixture, Create) {
+ startSupplicantAndWaitForHidlService();
+ EXPECT_NE(nullptr, createSupplicantStaNetwork_1_1().get());
+ stopSupplicant();
+}
+
+/*
+ * Ensure that the encrypted imsi identity is set successfully.
+ */
+TEST_F(SupplicantStaNetworkHidlTest, setEapEncryptedImsiIdentity) {
+ std::vector<uint8_t> encrypted_identity(
+ kTestEncryptedIdentity,
+ kTestEncryptedIdentity + sizeof(kTestEncryptedIdentity));
+ sta_network_->setEapEncryptedImsiIdentity(
+ encrypted_identity, [](const SupplicantStatus &status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}
+
+/*
+ * Ensure that the identity and the encrypted imsi identity are sent
+ * successfully.
+ */
+TEST_F(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse_1_1) {
+ sta_network_->sendNetworkEapIdentityResponse_1_1(
+ std::vector<uint8_t>(kTestIdentity,
+ kTestIdentity + sizeof(kTestIdentity)),
+ std::vector<uint8_t>(kTestEncryptedIdentity,
+ kTestIdentity + sizeof(kTestEncryptedIdentity)),
+ [](const SupplicantStatus &status) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}