Merge changes Ifd7ec3dc,Ia28c9217
* changes:
audio: Clarify documentation for some methods
audio: Provide documentation for enums in 'common' package
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 0e18f48..543acf6 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -7,7 +7,7 @@
"name": "vts_treble_vintf_vendor_test"
},
{
- "name": "hidl_implementation_test"
+ "name": "hal_implementation_test"
}
]
}
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index a94a37e..e325889 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -47,6 +47,9 @@
"common/src/VehicleUtils.cpp",
"common/src/VmsUtils.cpp",
],
+ shared_libs: [
+ "libbase",
+ ],
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["common/include"],
}
@@ -109,6 +112,9 @@
"tests/VehiclePropConfigIndex_test.cpp",
"tests/VmsUtils_test.cpp",
],
+ shared_libs: [
+ "libbase",
+ ],
header_libs: ["libbase_headers"],
test_suites: ["general-tests"],
}
@@ -173,7 +179,7 @@
"libqemu_pipe",
],
cflags: [
- "-Wno-unused-parameter"
+ "-Wno-unused-parameter",
],
}
@@ -200,6 +206,6 @@
"android.hardware.automotive.vehicle@2.0-virtualization-utils",
],
cflags: [
- "-Wno-unused-parameter"
+ "-Wno-unused-parameter",
],
}
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
index c1e9e88..fcfe761 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
@@ -73,7 +73,9 @@
int32_t propId) override;
Return<void> debugDump(debugDump_cb _hidl_cb = nullptr) override;
-private:
+ Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
+ private:
using VehiclePropValuePtr = VehicleHal::VehiclePropValuePtr;
// Returns true if needs to call again shortly.
using RetriableAction = std::function<bool()>;
@@ -96,6 +98,22 @@
bool checkReadPermission(const VehiclePropConfig &config) const;
void onAllClientsUnsubscribed(int32_t propertyId);
+ // Dump and commands
+ // TODO: most functions below (exception dump() and cmdSetOne()) should be const, but they rely
+ // on IVehicle.get(), which isn't...
+ void cmdDump(int fd, const hidl_vec<hidl_string>& options);
+ void cmdDumpOneProperty(int fd, int32_t prop, int32_t areaId);
+ void cmdDumpOneProperty(int fd, int rowNumber, const VehiclePropConfig& config);
+
+ static bool checkArgumentsSize(int fd, const hidl_vec<hidl_string>& options, size_t minSize);
+ static bool checkCallerHasWritePermissions(int fd);
+ static bool safelyParseInt(int fd, int index, std::string s, int* out);
+ void cmdHelp(int fd) const;
+ void cmdListAllProperties(int fd) const;
+ void cmdDumpAllProperties(int fd);
+ void cmdDumpSpecificProperties(int fd, const hidl_vec<hidl_string>& options);
+ void cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options);
+
static bool isSubscribable(const VehiclePropConfig& config,
SubscribeFlags flags);
static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index 393d3ec..4249a61 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -21,11 +21,18 @@
#include <cmath>
#include <fstream>
-#include <android/log.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
#include <android/hardware/automotive/vehicle/2.0/BpHwVehicleCallback.h>
+#include <android/log.h>
+
+#include <hwbinder/IPCThreadState.h>
#include "VehicleUtils.h"
+// TODO: figure out how to include private/android_filesystem_config.h instead...
+#define AID_ROOT 0 /* traditional unix root user */
+
namespace android {
namespace hardware {
namespace automotive {
@@ -34,6 +41,10 @@
using namespace std::placeholders;
+using ::android::base::EqualsIgnoreCase;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+
constexpr std::chrono::milliseconds kHalEventBatchingTimeWindow(10);
const VehiclePropValue kEmptyValue{};
@@ -172,6 +183,231 @@
return Void();
}
+Return<void> VehicleHalManager::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+ if (fd.getNativeHandle() != nullptr && fd->numFds > 0) {
+ cmdDump(fd->data[0], options);
+ } else {
+ ALOGE("Invalid parameters passed to debug()");
+ }
+ return Void();
+}
+
+void VehicleHalManager::cmdDump(int fd, const hidl_vec<hidl_string>& options) {
+ if (options.size() == 0) {
+ cmdDumpAllProperties(fd);
+ return;
+ }
+ std::string option = options[0];
+ if (EqualsIgnoreCase(option, "--help")) {
+ cmdHelp(fd);
+ } else if (EqualsIgnoreCase(option, "--list")) {
+ cmdListAllProperties(fd);
+ } else if (EqualsIgnoreCase(option, "--get")) {
+ cmdDumpSpecificProperties(fd, options);
+ } else if (EqualsIgnoreCase(option, "--set")) {
+ cmdSetOneProperty(fd, options);
+ } else {
+ dprintf(fd, "Invalid option: %s\n", option.c_str());
+ }
+}
+
+bool VehicleHalManager::checkCallerHasWritePermissions(int fd) {
+ // Double check that's only called by root - it should be be blocked at the HIDL debug() level,
+ // but it doesn't hurt to make sure...
+ if (hardware::IPCThreadState::self()->getCallingUid() != AID_ROOT) {
+ dprintf(fd, "Must be root\n");
+ return false;
+ }
+ return true;
+}
+
+bool VehicleHalManager::checkArgumentsSize(int fd, const hidl_vec<hidl_string>& options,
+ size_t minSize) {
+ size_t size = options.size();
+ if (size >= minSize) {
+ return true;
+ }
+ dprintf(fd, "Invalid number of arguments: required at least %zu, got %zu\n", minSize, size);
+ return false;
+}
+
+bool VehicleHalManager::safelyParseInt(int fd, int index, std::string s, int* out) {
+ if (!android::base::ParseInt(s, out)) {
+ dprintf(fd, "non-integer argument at index %d: %s\n", index, s.c_str());
+ return false;
+ }
+ return true;
+}
+
+void VehicleHalManager::cmdHelp(int fd) const {
+ dprintf(fd, "Usage: \n\n");
+ dprintf(fd, "[no args]: dumps (id and value) all supported properties \n");
+ dprintf(fd, "--help: shows this help\n");
+ dprintf(fd, "--list: lists the ids of all supported properties\n");
+ dprintf(fd, "--get <PROP1> [PROP2] [PROPN]: dumps the value of specific properties \n");
+ // TODO: support other formats (int64, float, bytes)
+ dprintf(fd,
+ "--set <PROP> <i|s> <VALUE_1> [<i|s> <VALUE_N>]: sets the value of property PROP, using"
+ " arbitrary number of key/value parameters (i for int32, s for string). Notice that "
+ "the string value can be set just once, while the other can have multiple values "
+ "(so they're used in the respective array)\n");
+}
+
+void VehicleHalManager::cmdListAllProperties(int fd) const {
+ auto& halConfig = mConfigIndex->getAllConfigs();
+ size_t size = halConfig.size();
+ if (size == 0) {
+ dprintf(fd, "no properties to list\n");
+ return;
+ }
+ int i = 0;
+ dprintf(fd, "listing %zu properties\n", size);
+ for (const auto& config : halConfig) {
+ dprintf(fd, "%d: %d\n", ++i, config.prop);
+ }
+}
+
+void VehicleHalManager::cmdDumpAllProperties(int fd) {
+ auto& halConfig = mConfigIndex->getAllConfigs();
+ size_t size = halConfig.size();
+ if (size == 0) {
+ dprintf(fd, "no properties to dump\n");
+ return;
+ }
+ int rowNumber = 0;
+ dprintf(fd, "dumping %zu properties\n", size);
+ for (auto& config : halConfig) {
+ cmdDumpOneProperty(fd, ++rowNumber, config);
+ }
+}
+
+void VehicleHalManager::cmdDumpOneProperty(int fd, int rowNumber, const VehiclePropConfig& config) {
+ size_t numberAreas = config.areaConfigs.size();
+ if (numberAreas == 0) {
+ if (rowNumber > 0) {
+ dprintf(fd, "%d: ", rowNumber);
+ }
+ cmdDumpOneProperty(fd, config.prop, /* areaId= */ 0);
+ return;
+ }
+ for (size_t j = 0; j < numberAreas; ++j) {
+ if (rowNumber > 0) {
+ if (numberAreas > 1) {
+ dprintf(fd, "%d/%zu: ", rowNumber, j);
+ } else {
+ dprintf(fd, "%d: ", rowNumber);
+ }
+ }
+ cmdDumpOneProperty(fd, config.prop, config.areaConfigs[j].areaId);
+ }
+}
+
+void VehicleHalManager::cmdDumpSpecificProperties(int fd, const hidl_vec<hidl_string>& options) {
+ if (!checkArgumentsSize(fd, options, 2)) return;
+
+ // options[0] is the command itself...
+ int rowNumber = 0;
+ size_t size = options.size();
+ for (size_t i = 1; i < size; ++i) {
+ int prop;
+ if (!safelyParseInt(fd, i, options[i], &prop)) return;
+ const auto* config = getPropConfigOrNull(prop);
+ if (config == nullptr) {
+ dprintf(fd, "No property %d\n", prop);
+ continue;
+ }
+ if (size > 2) {
+ // Only show row number if there's more than 1
+ rowNumber++;
+ }
+ cmdDumpOneProperty(fd, rowNumber, *config);
+ }
+}
+
+void VehicleHalManager::cmdDumpOneProperty(int fd, int32_t prop, int32_t areaId) {
+ VehiclePropValue input;
+ input.prop = prop;
+ input.areaId = areaId;
+ auto callback = [&](StatusCode status, const VehiclePropValue& output) {
+ if (status == StatusCode::OK) {
+ dprintf(fd, "%s\n", toString(output).c_str());
+ } else {
+ dprintf(fd, "Could not get property %d. Error: %s\n", prop, toString(status).c_str());
+ }
+ };
+ get(input, callback);
+}
+
+void VehicleHalManager::cmdSetOneProperty(int fd, const hidl_vec<hidl_string>& options) {
+ if (!checkCallerHasWritePermissions(fd) || !checkArgumentsSize(fd, options, 3)) return;
+
+ size_t size = options.size();
+
+ // Syntax is --set PROP Type1 Value1 TypeN ValueN, so number of arguments must be even
+ if (size % 2 != 0) {
+ dprintf(fd, "must pass even number of arguments (passed %zu)\n", size);
+ return;
+ }
+ int numberValues = (size - 2) / 2;
+
+ VehiclePropValue prop;
+ if (!safelyParseInt(fd, 1, options[1], &prop.prop)) return;
+ prop.timestamp = 0;
+ prop.areaId = 0; // TODO: add option to pass areaId as parameter
+ prop.status = VehiclePropertyStatus::AVAILABLE;
+
+ // First pass calculate sizes
+ int sizeInt32 = 0;
+ int stringIndex = 0;
+ for (int i = 2, kv = 1; kv <= numberValues; kv++) {
+ // iterate through the kv=1..n key/value pairs, accessing indexes i / i+1 at each step
+ std::string type = options[i];
+ std::string value = options[i + 1];
+ if (EqualsIgnoreCase(type, "i")) {
+ sizeInt32++;
+ } else if (EqualsIgnoreCase(type, "s")) {
+ if (stringIndex != 0) {
+ dprintf(fd,
+ "defining string value (%s) again at index %d (already defined at %d=%s"
+ ")\n",
+ value.c_str(), i, stringIndex, options[stringIndex + 1].c_str());
+ return;
+ }
+ stringIndex = i;
+ } else {
+ dprintf(fd, "invalid (%s) type at index %d\n", type.c_str(), i);
+ return;
+ }
+ i += 2;
+ }
+ prop.value.int32Values.resize(sizeInt32);
+
+ // Second pass: populate it
+ int indexInt32 = 0;
+ for (int i = 2, kv = 1; kv <= numberValues; kv++) {
+ // iterate through the kv=1..n key/value pairs, accessing indexes i / i+1 at each step
+ int valueIndex = i + 1;
+ std::string type = options[i];
+ std::string value = options[valueIndex];
+ if (EqualsIgnoreCase(type, "i")) {
+ int safeInt;
+ if (!safelyParseInt(fd, valueIndex, value, &safeInt)) return;
+ prop.value.int32Values[indexInt32++] = safeInt;
+ } else if (EqualsIgnoreCase(type, "s")) {
+ prop.value.stringValue = value;
+ }
+ i += 2;
+ }
+ ALOGD("Setting prop %s", toString(prop).c_str());
+ auto status = set(prop);
+ if (status == StatusCode::OK) {
+ dprintf(fd, "Set property %s\n", toString(prop).c_str());
+ } else {
+ dprintf(fd, "Failed to set property %s: %s\n", toString(prop).c_str(),
+ toString(status).c_str());
+ }
+}
+
void VehicleHalManager::init() {
ALOGI("VehicleHalManager::init");
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index bf85da2..e19987c 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -87,23 +87,23 @@
/**
* This property is used for test purpose to set properties' value from vehicle.
* For example: Mocking hard button press triggering a HVAC fan speed change.
- * Android set kSetPropertyFromVehcileForTest with an array of integer {HVAC_FAN_SPEED, value of
+ * Android set kSetPropertyFromVehicleForTest with an array of integer {HVAC_FAN_SPEED, value of
* fan speed} and a long value indicates the timestamp of the events .
* It only works with integer type properties.
*/
-const int32_t kSetIntPropertyFromVehcileForTest =
+const int32_t kSetIntPropertyFromVehicleForTest =
0x1112 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
/**
* This property is used for test purpose to set properties' value from vehicle.
* It only works with float type properties.
*/
-const int32_t kSetFloatPropertyFromVehcileForTest =
+const int32_t kSetFloatPropertyFromVehicleForTest =
0x1113 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
/**
* This property is used for test purpose to set properties' value from vehicle.
* It only works with boolean type properties.
*/
-const int32_t kSetBooleanPropertyFromVehcileForTest =
+const int32_t kSetBooleanPropertyFromVehicleForTest =
0x1114 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
/**
@@ -695,7 +695,7 @@
{
.config =
{
- .prop = kSetIntPropertyFromVehcileForTest,
+ .prop = kSetIntPropertyFromVehicleForTest,
.access = VehiclePropertyAccess::WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.configArray = {0, 0, 0, 2, 1, 0, 0, 0, 0},
@@ -705,7 +705,7 @@
{
.config =
{
- .prop = kSetFloatPropertyFromVehcileForTest,
+ .prop = kSetFloatPropertyFromVehicleForTest,
.access = VehiclePropertyAccess::WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.configArray = {0, 0, 1, 0, 1, 0, 1, 0, 0},
@@ -715,7 +715,7 @@
{
.config =
{
- .prop = kSetBooleanPropertyFromVehcileForTest,
+ .prop = kSetBooleanPropertyFromVehicleForTest,
.access = VehiclePropertyAccess::WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.configArray = {0, 1, 1, 0, 1, 0, 0, 0, 0},
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
index 222fe5e..d9867bd 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -202,8 +202,8 @@
case kGenerateFakeDataControllingProperty:
return handleGenerateFakeDataRequest(value);
- // set the value from vehcile side, used in end to end test.
- case kSetIntPropertyFromVehcileForTest: {
+ // set the value from vehicle side, used in end to end test.
+ case kSetIntPropertyFromVehicleForTest: {
auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::INT32, 1);
updatedPropValue->prop = value.value.int32Values[0];
updatedPropValue->value.int32Values[0] = value.value.int32Values[1];
@@ -212,7 +212,7 @@
onPropertyValueFromCar(*updatedPropValue, updateStatus);
return StatusCode::OK;
}
- case kSetFloatPropertyFromVehcileForTest: {
+ case kSetFloatPropertyFromVehicleForTest: {
auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1);
updatedPropValue->prop = value.value.int32Values[0];
updatedPropValue->value.floatValues[0] = value.value.floatValues[0];
@@ -221,7 +221,7 @@
onPropertyValueFromCar(*updatedPropValue, updateStatus);
return StatusCode::OK;
}
- case kSetBooleanPropertyFromVehcileForTest: {
+ case kSetBooleanPropertyFromVehicleForTest: {
auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1);
updatedPropValue->prop = value.value.int32Values[1];
updatedPropValue->value.int32Values[0] = value.value.int32Values[0];
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index a91bd88..7a5f2d2 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2473,7 +2473,8 @@
* which in turn would disable the other user-related properties (for example, the Android
* system would never issue them and user-related requests from the HAL layer would be ignored
* by the Android System). But if it supports user management, then it must support all
- * user-related properties (INITIAL_USER_INFO, SWITCH_USER, TODO(b/146207078):others).
+ * user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, REMOVE_USER,
+ * and USER_IDENTIFICATION_ASSOCIATION).
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ_WRITE
@@ -2649,6 +2650,161 @@
| VehiclePropertyGroup:SYSTEM
| VehiclePropertyType:MIXED
| VehicleArea:GLOBAL),
+
+ /**
+ * Called by the Android System after an Android user was created.
+ *
+ * The HAL can use this property to create its equivalent user.
+ *
+ * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
+ * must respond with a property change indicating whether the request succeeded or failed. If
+ * it failed, the Android system will remove the user.
+ *
+ * The format of the request is defined by CreateUserRequest and the format of the response by
+ * CreateUserResponse.
+ *
+ * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
+ * created, the request would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 11 // Android id of the created user
+ * int32[2]: 3 // Android flags (ephemeral guest) of the created user
+ * int32[3]: 10 // current user
+ * int32[4]: 0 // current user flags (none)
+ * int32[5]: 3 // number of users
+ * int32[6]: 0 // 1st user (user 0)
+ * int32[7]: 0 // 1st user flags (none)
+ * int32[8]: 10 // 2nd user (user 10)
+ * int32[9]: 0 // 2nd user flags (none)
+ * int32[19]: 11 // 3rd user (user 11)
+ * int32[11]: 3 // 3rd user flags (ephemeral guest)
+ * string: "ElGuesto" // name of the new user
+ *
+ * Then if the request succeeded, the HAL would return:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 1 // CreateUserStatus::SUCCESS
+ *
+ * But if it failed:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 2 // CreateUserStatus::FAILURE
+ * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
+ * // which in turn can take the proper action.
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ_WRITE
+ */
+ CREATE_USER = (
+ 0x0F09
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:MIXED
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Called by the Android System after an Android user was removed.
+ *
+ * The HAL can use this property to remove its equivalent user.
+ *
+ * This is write-only call - the Android System is not expecting a reply from the HAL. Hence,
+ * this request should not fail - if the equivalent HAL user cannot be removed, then HAL should
+ * mark it as inactive or recover in some other way.
+ *
+ * The request is made by setting the VehiclePropValue with the contents defined by
+ * RemoveUserRequest.
+ *
+ * For example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request
+ * would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 11 // (Android user id of the removed user)
+ * int32[2]: 0 // (Android user flags of the removed user)
+ * int32[3]: 10 // current user
+ * int32[4]: 0 // current user flags (none)
+ * int32[5]: 2 // number of users
+ * int32[6]: 0 // 1st user (user 0)
+ * int32[7]: 0 // 1st user flags (none)
+ * int32[8]: 10 // 2nd user (user 10)
+ * int32[9]: 0 // 2nd user flags (none)
+ *
+ * @change_mode VehiclePropertyChangeMode:STATIC
+ * @access VehiclePropertyAccess:WRITE
+ */
+ REMOVE_USER = (
+ 0x0F0A
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:MIXED
+ | VehicleArea:GLOBAL),
+
+ /**
+ * Property used to associate (or query the association) the current user with vehicle-specific
+ * identification mechanisms (such as key FOB).
+ *
+ * To query the association, the Android system gets the property, passing a VehiclePropValue
+ * containing the types of associations are being queried, as defined by
+ * UserIdentificationGetRequest. The HAL must return right away, updating the VehiclePropValue
+ * with a UserIdentificationResponse. Notice that user identification should have already
+ * happened while system is booting up and the VHAL implementation should only return the
+ * already identified association (like the key FOB used to unlock the car), instead of starting
+ * a new association from the get call.
+ *
+ * To associate types, the Android system sets the property, passing a VehiclePropValue
+ * containing the types and values of associations being set, as defined by the
+ * UserIdentificationSetRequest. The HAL will then use a property change event (whose
+ * VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of
+ * the types after the request.
+ *
+ * For example, to query if the current user (10) is associated with the FOB that unlocked the
+ * car and a custom mechanism provided by the OEM, the request would be:
+ *
+ * int32[0]: 10 (Android user id)
+ * int32[1]: 0 (Android user flags)
+ * int32[2]: 2 (number of types queried)
+ * int32[3]: 1 (1st type queried, UserIdentificationAssociationType::KEY_FOB)
+ * int32[4]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)
+ *
+ * If the user is associated with the FOB but not with the custom mechanism, the response would
+ * be:
+ *
+ * int32[9]: 2 (number of associations in the response)
+ * int32[1]: 1 (1st type: UserIdentificationAssociationType::KEY_FOB)
+ * int32[2]: 2 (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+ * int32[3]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[4]: 4 (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)
+ *
+ * Then to associate the user with the custom mechanism, a set request would be made:
+ *
+ * int32[0]: 10 (Android user id)
+ * int32[0]: 0 (Android user flags)
+ * int32[1]: 1 (number of associations being set)
+ * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[3]: 1 (1st value: UserIdentificationAssociationSETValue::ASSOCIATE_CURRENT_USER)
+ *
+ * If the request succeeded, the response would be simply:
+ *
+ * int32[0]: 2 (number of associations in the response)
+ * int32[1]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[2]: 1 (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+ *
+ * Notice that the set request adds associations, but doesn't remove the existing ones. In the
+ * example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to
+ * associate the user with just CUSTOM_1 but not FOB, then the request should have been:
+ *
+ * int32[0]: 10 (Android user id)
+ * int32[1]: 2 (number of types set)
+ * int32[2]: 1 (1st type: UserIdentificationAssociationType::KEY_FOB)
+ * int32[3]: 2 (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER)
+ * int32[3]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[5]: 1 (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ_WRITE
+ */
+ USER_IDENTIFICATION_ASSOCIATION = (
+ 0x0F0B
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:MIXED
+ | VehicleArea:GLOBAL),
};
/**
@@ -4184,10 +4340,10 @@
/**
* HAL-specific error message.
*
- * This argument is optional, and when defined (and the status is FAILURE), it's passed "as-is"
- * to the caller. It could be used to show custom error messages to the end user.
+ * This argument is optional, and when defined, it's passed "as-is" to the caller. It could be
+ * used to show custom error messages to the end user.
*/
- string failureMessage;
+ string errorMessage;
};
/**
@@ -4199,3 +4355,253 @@
/** The request failed and the HAL user remained the same. */
FAILURE = 2,
};
+
+/**
+ * Defines the format of a CREATE_USER property.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+struct CreateUserRequest {
+ /**
+ * Arbitrary id used to map the response to the request.
+ */
+ UserRequestId requestId;
+
+ /**
+ * Basic information about Android user that was created.
+ */
+ UserInfo newUserInfo;
+
+ /**
+ * Name of the new Android user.
+ */
+ string newUserName;
+
+ /**
+ * Information about the current state of the Android system.
+ */
+ UsersInfo usersInfo;
+};
+
+/**
+ * Defines the result of a CreateUserRequest.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+struct CreateUserResponse {
+ /**
+ * Id of the request being responded.
+ */
+ UserRequestId requestId;
+
+ /**
+ * Status of the request.
+ */
+ CreateUserStatus status;
+
+ /**
+ * HAL-specific error message.
+ *
+ * This argument is optional, and when defined, it's passed "as-is" to the caller. It could be
+ * used to show custom error messages to the end user.
+ */
+ string errorMessage;
+};
+
+/**
+ * Status of the response to a CreateUserRequest.
+ */
+enum CreateUserStatus : int32_t {
+ /**
+ * The request succeeded (for example, HAL created a new internal user, or associated the
+ * Android user to an existing internal user).
+ */
+ SUCCESS = 1,
+
+ /**
+ * The request failed (and Android will remove the Android user).
+ */
+ FAILURE = 2,
+};
+
+/**
+ * Defines the format of a REMOVE_USER property.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+struct RemoveUserRequest {
+ /**
+ * Arbitrary id used to map the response to the request.
+ */
+ UserRequestId requestId;
+
+ /**
+ * Information about the Android user that was removed.
+ */
+ UserInfo removedUserInfo;
+
+ /**
+ * Information about the current state of the Android system.
+ */
+ UsersInfo usersInfo;
+};
+
+/**
+ * Types of mechanisms used to identify an Android user.
+ *
+ * See USER_IDENTIFICATION_ASSOCIATION for more details and example.
+ */
+enum UserIdentificationAssociationType: int32_t {
+ /** Key used to unlock the car. */
+ KEY_FOB = 1,
+ /** Custom mechanism defined by the OEM. */
+ CUSTOM_1 = 101,
+ /** Custom mechanism defined by the OEM. */
+ CUSTOM_2 = 102,
+ /** Custom mechanism defined by the OEM. */
+ CUSTOM_3 = 103,
+ /** Custom mechanism defined by the OEM. */
+ CUSTOM_4 = 104,
+};
+
+/**
+ * Whether a UserIdentificationAssociationType is associate with an Android user.
+ */
+enum UserIdentificationAssociationValue : int32_t {
+ /**
+ * Used when the status of an association could not be determined.
+ *
+ * For example, in a set() request, it would indicate a failure to set the given type.
+ */
+ UNKNOWN = 1,
+
+ /**
+ * The identification type is associated with the current foreground Android user.
+ */
+ ASSOCIATED_CURRENT_USER = 2,
+
+ /**
+ * The identification type is associated with another Android user.
+ */
+ ASSOCIATED_ANOTHER_USER = 3,
+
+ /**
+ * The identification type is not associated with any Android user.
+ */
+ NOT_ASSOCIATED_ANY_USER = 4,
+};
+
+/**
+ * Used to set a UserIdentificationAssociationType with an Android user.
+ */
+enum UserIdentificationAssociationSetValue : int32_t {
+ /**
+ * Associate the identification type with the current foreground Android user.
+ */
+ ASSOCIATE_CURRENT_USER = 1,
+
+ /**
+ * Disassociate the identification type from the current foreground Android user.
+ */
+ DISASSOCIATE_CURRENT_USER = 2,
+
+ /**
+ * Disassociate the identification type from all Android users.
+ */
+ DISASSOCIATE_ALL_USERS = 3,
+};
+
+/**
+ * Defines the format of a get() call to USER_IDENTIFICATION_ASSOCIATION.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+struct UserIdentificationGetRequest {
+ /**
+ * Information about the current foreground Android user.
+ */
+ UserInfo userInfo;
+
+ /**
+ * Number of association being queried.
+ */
+ int32_t numberAssociationTypes;
+
+ /**
+ * Types of association being queried.
+ */
+ vec<UserIdentificationAssociationType> associationTypes;
+};
+
+/**
+ * Defines the format of a set() call to USER_IDENTIFICATION_ASSOCIATION.
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+struct UserIdentificationSetRequest {
+ /**
+ * Information about the current foreground Android user.
+ */
+ UserInfo userInfo;
+
+ /**
+ * Number of association being set.
+ */
+ int32_t numberAssociations;
+
+ /**
+ * Associations being set.
+ */
+ vec<UserIdentificationAssociationSetValue> associations;
+};
+
+/**
+ * Defines the result of a USER_IDENTIFICATION_ASSOCIATION - both for get() and set().
+ *
+ * NOTE: this struct is not used in the HAL properties directly, it must be converted to
+ * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
+ */
+struct UserIdentificationResponse {
+ /**
+ * Number of associations being returned.
+ */
+ int32_t numberAssociation;
+
+ /**
+ * Values associated with the user.
+ */
+ vec<UserIdentificationAssociation> associations;
+
+ /**
+ * HAL-specific error message.
+ *
+ * This argument is optional, and when defined, it's passed "as-is" to the caller. It could be
+ * used to show custom error messages to the end user.
+ */
+ string errorMessage;
+};
+
+/**
+ * Helper struct used when getting a user/identification association type.
+ */
+struct UserIdentificationAssociation {
+
+ UserIdentificationAssociationType type;
+
+ UserIdentificationAssociationValue value;
+};
+
+/**
+ * Helper struct used when setting a user/identification association type.
+ */
+struct UserIdentificationSetAssociation {
+
+ UserIdentificationAssociationType type;
+
+ UserIdentificationAssociationSetValue value;
+};
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 9a8f336..8eb7587 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -161,7 +161,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
- <version>1.0-3</version>
+ <version>1.3</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index ba9fb45..03af671 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -14,13 +14,30 @@
// limitations under the License.
//
+cc_defaults {
+ name: "neuralnetworks_vts_functional_defaults",
+ defaults: ["VtsHalTargetTestDefaults"],
+ arch: {
+ x86: {
+ cflags: [ "-D_Float16=__fp16",
+ "-Xclang", "-fnative-half-type",
+ "-Xclang", "-fallow-half-arguments-and-returns" ],
+ },
+ x86_64: {
+ cflags: [ "-D_Float16=__fp16",
+ "-Xclang", "-fnative-half-type",
+ "-Xclang", "-fallow-half-arguments-and-returns" ],
+ },
+ },
+}
+
cc_library_static {
name: "VtsHalNeuralNetworksV1_0_utils",
srcs: [
"Callbacks.cpp",
"Utils.cpp",
],
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
export_include_dirs: ["include"],
shared_libs: [
"libfmq",
@@ -42,7 +59,7 @@
cc_test {
name: "VtsHalNeuralnetworksV1_0TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
srcs: [
"BasicTests.cpp",
"TestAssertions.cpp",
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 69e1761..9ba1925 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -16,7 +16,7 @@
cc_test {
name: "VtsHalNeuralnetworksV1_1TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
srcs: [
"BasicTests.cpp",
"TestAssertions.cpp",
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index fc727b7..7886910 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -16,7 +16,7 @@
cc_library_static {
name: "VtsHalNeuralNetworksV1_2Callbacks",
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
export_include_dirs: ["include"],
srcs: [
"Callbacks.cpp",
@@ -33,7 +33,7 @@
cc_test {
name: "VtsHalNeuralnetworksV1_2TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
srcs: [
"BasicTests.cpp",
"CompilationCachingTests.cpp",
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index 8e7e9b9..f936267 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -16,7 +16,7 @@
cc_library_static {
name: "VtsHalNeuralNetworksV1_3_utils",
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
export_include_dirs: ["include"],
srcs: [
"Callbacks.cpp",
@@ -35,7 +35,7 @@
cc_test {
name: "VtsHalNeuralnetworksV1_3TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: ["neuralnetworks_vts_functional_defaults"],
srcs: [
"BasicTests.cpp",
"CompilationCachingTests.cpp",
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
index 9f57934..2715891 100644
--- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <VtsCoreUtil.h>
+
#include <android-base/logging.h>
#include <cutils/properties.h>
@@ -62,11 +64,19 @@
hostapd_instance_name_);
hostapd_ = IHostapd::getService(hostapd_instance_name_);
ASSERT_NE(hostapd_.get(), nullptr);
+ isAcsSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_acs_supported");
+ isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_wpa3_sae_supported");
}
virtual void TearDown() override { stopHostapd(hostapd_instance_name_); }
protected:
+ bool isWpa3SaeSupport_ = false;
+ bool isAcsSupport_ = false;
std::string getPrimaryWlanIfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
@@ -208,10 +218,10 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getPskNwParams());
- // TODO: b/140172237, fix this in R.
- // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -219,11 +229,11 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
- // TODO: b/140172237, fix this in R
- // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -231,11 +241,11 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcsAndInvalidFreqRange(),
getPskNwParams());
- // TODO: b/140172237, fix this in R
- // EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+ EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -243,10 +253,10 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getOpenNwParams());
- // TODO: b/140172237, fix this in R
- // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+ EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
}
/**
@@ -274,6 +284,7 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getSaeTransitionNwParams());
@@ -285,6 +296,7 @@
* Access point creation should pass.
*/
TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithoutAcs(), getSaeNwParams());
EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -295,16 +307,15 @@
* Access point creation & removal should pass.
*/
TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
+ if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
getIfaceParamsWithAcs(), getPskNwParams());
- // TODO: b/140172237, fix this in R
- /*
EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
auto status =
HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
- EXPECT_EQ(android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
- status.code);
- */
+ EXPECT_EQ(
+ android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
+ status.code);
}
/**
@@ -349,6 +360,7 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidSaeTransitionNwParams());
@@ -360,6 +372,7 @@
* Access point creation should fail.
*/
TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
+ if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
auto status =
HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
getInvalidSaeNwParams());